summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroyuki Eguchi <h-eguchi@az.jp.nec.com>2017-01-27 17:40:43 +0900
committerHiroyuki Eguchi <h-eguchi@az.jp.nec.com>2017-01-27 17:40:43 +0900
commit8fca7e375363139362cdd9a15724754225933171 (patch)
tree172333a4da8c93d66fadef4f92870f9b1acf1a6c
first commit
-rw-r--r--LICENSE176
-rw-r--r--README.rst58
-rw-r--r--babel-django.cfg5
-rw-r--r--babel-djangojs.cfg14
-rw-r--r--devstack/plugin.sh60
-rw-r--r--devstack/settings2
-rw-r--r--doc/Makefile152
-rw-r--r--doc/source/conf.py441
-rw-r--r--doc/source/index.rst78
-rw-r--r--doc/source/releases/0.1.0.rst2
-rwxr-xr-xmanage.py23
-rw-r--r--meteos_ui/__init__.py0
-rw-r--r--meteos_ui/api/__init__.py0
-rw-r--r--meteos_ui/api/client.py226
-rw-r--r--meteos_ui/api/rest_api.py337
-rw-r--r--meteos_ui/content/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/__init__.py14
-rw-r--r--meteos_ui/content/machine_learning/datasets/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/datasets/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/datasets/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/datasets/urls.py20
-rw-r--r--meteos_ui/content/machine_learning/experiments/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/experiments/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/experiments/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/experiments/urls.py20
-rw-r--r--meteos_ui/content/machine_learning/learnings/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/learnings/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/learnings/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/learnings/urls.py20
-rw-r--r--meteos_ui/content/machine_learning/model_evaluations/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/model_evaluations/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/model_evaluations/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/model_evaluations/urls.py20
-rw-r--r--meteos_ui/content/machine_learning/models/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/models/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/models/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/models/urls.py20
-rw-r--r--meteos_ui/content/machine_learning/templates/__init__.py0
-rw-r--r--meteos_ui/content/machine_learning/templates/panel.py23
-rw-r--r--meteos_ui/content/machine_learning/templates/tests.py19
-rw-r--r--meteos_ui/content/machine_learning/templates/urls.py20
-rw-r--r--meteos_ui/enabled/_1710_machine_learning_panel_group.py36
-rw-r--r--meteos_ui/enabled/_1720_machine_learning_templates_panel.py21
-rw-r--r--meteos_ui/enabled/_1730_machine_learning_experiments_panel.py21
-rw-r--r--meteos_ui/enabled/_1740_machine_learning_datasets_panel.py21
-rw-r--r--meteos_ui/enabled/_1750_machine_learning_models_panel.py21
-rw-r--r--meteos_ui/enabled/_1760_machine_learning_model_evaluations_panel.py21
-rw-r--r--meteos_ui/enabled/_1770_machine_learning_learnings_panel.py21
-rw-r--r--meteos_ui/enabled/__init__.py0
-rw-r--r--meteos_ui/karma.conf.js154
-rw-r--r--meteos_ui/models.py3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/dataset-model.js75
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.html32
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.html76
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/create/spec/template.spec.controller.js44
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.js156
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/datasets.scss3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/datasets/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/experiment-model.js71
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/info/info.html32
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/spec/spec.html28
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/create/spec/template.spec.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/details/drawer.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/experiments.module.js168
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/experiments.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/experiments.scss3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/experiments/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/info/info.html32
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/learning-model.js71
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/spec/spec.html28
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/create/spec/template.spec.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/details/drawer.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/learnings.module.js180
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/learnings.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/learnings.scss3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/learnings/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/machine_learning.module.js41
-rw-r--r--meteos_ui/static/dashboard/machine_learning/machine_learning.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/machine_learning.scss8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/meteos.service.js340
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/info/info.html24
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/model_evaluation-model.js73
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/spec/spec.html62
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/create/spec/template.spec.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/details/drawer.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/model_evaluations.module.js180
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/model_evaluations.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/model_evaluations.scss3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/model_evaluations/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/info/info.html32
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/model-model.js76
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/spec/spec.html84
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/create/spec/template.spec.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/details/drawer.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/models.module.js168
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/models.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/models.scss3
-rw-r--r--meteos_ui/static/dashboard/machine_learning/models/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/actions.module.js66
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/create-workflow.service.js56
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/create.service.js97
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/info/info.help.html8
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/info/info.html32
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/info/template.info.controller.js34
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/spec/spec.help.html14
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/spec/spec.html76
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/spec/template.spec.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/create/template-model.js75
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/delete/delete.service.js149
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/details/drawer.controller.js36
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/details/drawer.html22
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/operations/pause.service.js69
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/panel.html4
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/templates.module.js180
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/templates.module.spec.js23
-rw-r--r--meteos_ui/static/dashboard/machine_learning/templates/templates.scss3
-rw-r--r--meteos_ui/test/__init__.py0
-rw-r--r--meteos_ui/test/settings.py37
-rw-r--r--meteos_ui/version.py3
-rw-r--r--package.json28
-rw-r--r--releasenotes/source/_static/.placeholder0
-rw-r--r--releasenotes/source/_templates/.placeholder0
-rw-r--r--releasenotes/source/conf.py276
-rw-r--r--releasenotes/source/index.rst16
-rw-r--r--releasenotes/source/unreleased.rst5
-rw-r--r--requirements.txt40
-rwxr-xr-xrun_tests.sh583
-rw-r--r--setup.cfg28
-rw-r--r--setup.py27
-rw-r--r--test-requirements.txt30
-rw-r--r--test-shim.js96
-rw-r--r--tools/install_venv.py71
-rw-r--r--tools/install_venv_common.py172
-rwxr-xr-xtools/with_venv.sh7
-rw-r--r--tox.ini74
177 files changed, 9520 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..68c771a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,176 @@
1
2 Apache License
3 Version 2.0, January 2004
4 http://www.apache.org/licenses/
5
6 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8 1. Definitions.
9
10 "License" shall mean the terms and conditions for use, reproduction,
11 and distribution as defined by Sections 1 through 9 of this document.
12
13 "Licensor" shall mean the copyright owner or entity authorized by
14 the copyright owner that is granting the License.
15
16 "Legal Entity" shall mean the union of the acting entity and all
17 other entities that control, are controlled by, or are under common
18 control with that entity. For the purposes of this definition,
19 "control" means (i) the power, direct or indirect, to cause the
20 direction or management of such entity, whether by contract or
21 otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 outstanding shares, or (iii) beneficial ownership of such entity.
23
24 "You" (or "Your") shall mean an individual or Legal Entity
25 exercising permissions granted by this License.
26
27 "Source" form shall mean the preferred form for making modifications,
28 including but not limited to software source code, documentation
29 source, and configuration files.
30
31 "Object" form shall mean any form resulting from mechanical
32 transformation or translation of a Source form, including but
33 not limited to compiled object code, generated documentation,
34 and conversions to other media types.
35
36 "Work" shall mean the work of authorship, whether in Source or
37 Object form, made available under the License, as indicated by a
38 copyright notice that is included in or attached to the work
39 (an example is provided in the Appendix below).
40
41 "Derivative Works" shall mean any work, whether in Source or Object
42 form, that is based on (or derived from) the Work and for which the
43 editorial revisions, annotations, elaborations, or other modifications
44 represent, as a whole, an original work of authorship. For the purposes
45 of this License, Derivative Works shall not include works that remain
46 separable from, or merely link (or bind by name) to the interfaces of,
47 the Work and Derivative Works thereof.
48
49 "Contribution" shall mean any work of authorship, including
50 the original version of the Work and any modifications or additions
51 to that Work or Derivative Works thereof, that is intentionally
52 submitted to Licensor for inclusion in the Work by the copyright owner
53 or by an individual or Legal Entity authorized to submit on behalf of
54 the copyright owner. For the purposes of this definition, "submitted"
55 means any form of electronic, verbal, or written communication sent
56 to the Licensor or its representatives, including but not limited to
57 communication on electronic mailing lists, source code control systems,
58 and issue tracking systems that are managed by, or on behalf of, the
59 Licensor for the purpose of discussing and improving the Work, but
60 excluding communication that is conspicuously marked or otherwise
61 designated in writing by the copyright owner as "Not a Contribution."
62
63 "Contributor" shall mean Licensor and any individual or Legal Entity
64 on behalf of whom a Contribution has been received by Licensor and
65 subsequently incorporated within the Work.
66
67 2. Grant of Copyright License. Subject to the terms and conditions of
68 this License, each Contributor hereby grants to You a perpetual,
69 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 copyright license to reproduce, prepare Derivative Works of,
71 publicly display, publicly perform, sublicense, and distribute the
72 Work and such Derivative Works in Source or Object form.
73
74 3. Grant of Patent License. Subject to the terms and conditions of
75 this License, each Contributor hereby grants to You a perpetual,
76 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 (except as stated in this section) patent license to make, have made,
78 use, offer to sell, sell, import, and otherwise transfer the Work,
79 where such license applies only to those patent claims licensable
80 by such Contributor that are necessarily infringed by their
81 Contribution(s) alone or by combination of their Contribution(s)
82 with the Work to which such Contribution(s) was submitted. If You
83 institute patent litigation against any entity (including a
84 cross-claim or counterclaim in a lawsuit) alleging that the Work
85 or a Contribution incorporated within the Work constitutes direct
86 or contributory patent infringement, then any patent licenses
87 granted to You under this License for that Work shall terminate
88 as of the date such litigation is filed.
89
90 4. Redistribution. You may reproduce and distribute copies of the
91 Work or Derivative Works thereof in any medium, with or without
92 modifications, and in Source or Object form, provided that You
93 meet the following conditions:
94
95 (a) You must give any other recipients of the Work or
96 Derivative Works a copy of this License; and
97
98 (b) You must cause any modified files to carry prominent notices
99 stating that You changed the files; and
100
101 (c) You must retain, in the Source form of any Derivative Works
102 that You distribute, all copyright, patent, trademark, and
103 attribution notices from the Source form of the Work,
104 excluding those notices that do not pertain to any part of
105 the Derivative Works; and
106
107 (d) If the Work includes a "NOTICE" text file as part of its
108 distribution, then any Derivative Works that You distribute must
109 include a readable copy of the attribution notices contained
110 within such NOTICE file, excluding those notices that do not
111 pertain to any part of the Derivative Works, in at least one
112 of the following places: within a NOTICE text file distributed
113 as part of the Derivative Works; within the Source form or
114 documentation, if provided along with the Derivative Works; or,
115 within a display generated by the Derivative Works, if and
116 wherever such third-party notices normally appear. The contents
117 of the NOTICE file are for informational purposes only and
118 do not modify the License. You may add Your own attribution
119 notices within Derivative Works that You distribute, alongside
120 or as an addendum to the NOTICE text from the Work, provided
121 that such additional attribution notices cannot be construed
122 as modifying the License.
123
124 You may add Your own copyright statement to Your modifications and
125 may provide additional or different license terms and conditions
126 for use, reproduction, or distribution of Your modifications, or
127 for any such Derivative Works as a whole, provided Your use,
128 reproduction, and distribution of the Work otherwise complies with
129 the conditions stated in this License.
130
131 5. Submission of Contributions. Unless You explicitly state otherwise,
132 any Contribution intentionally submitted for inclusion in the Work
133 by You to the Licensor shall be under the terms and conditions of
134 this License, without any additional terms or conditions.
135 Notwithstanding the above, nothing herein shall supersede or modify
136 the terms of any separate license agreement you may have executed
137 with Licensor regarding such Contributions.
138
139 6. Trademarks. This License does not grant permission to use the trade
140 names, trademarks, service marks, or product names of the Licensor,
141 except as required for reasonable and customary use in describing the
142 origin of the Work and reproducing the content of the NOTICE file.
143
144 7. Disclaimer of Warranty. Unless required by applicable law or
145 agreed to in writing, Licensor provides the Work (and each
146 Contributor provides its Contributions) on an "AS IS" BASIS,
147 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 implied, including, without limitation, any warranties or conditions
149 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 PARTICULAR PURPOSE. You are solely responsible for determining the
151 appropriateness of using or redistributing the Work and assume any
152 risks associated with Your exercise of permissions under this License.
153
154 8. Limitation of Liability. In no event and under no legal theory,
155 whether in tort (including negligence), contract, or otherwise,
156 unless required by applicable law (such as deliberate and grossly
157 negligent acts) or agreed to in writing, shall any Contributor be
158 liable to You for damages, including any direct, indirect, special,
159 incidental, or consequential damages of any character arising as a
160 result of this License or out of the use or inability to use the
161 Work (including but not limited to damages for loss of goodwill,
162 work stoppage, computer failure or malfunction, or any and all
163 other commercial damages or losses), even if such Contributor
164 has been advised of the possibility of such damages.
165
166 9. Accepting Warranty or Additional Liability. While redistributing
167 the Work or Derivative Works thereof, You may choose to offer,
168 and charge a fee for, acceptance of support, warranty, indemnity,
169 or other liability obligations and/or rights consistent with this
170 License. However, in accepting such obligations, You may act only
171 on Your own behalf and on Your sole responsibility, not on behalf
172 of any other Contributor, and only if You agree to indemnify,
173 defend, and hold each Contributor harmless for any liability
174 incurred by, or claims asserted against, such Contributor by reason
175 of your accepting any such warranty or additional liability.
176
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..dbc6f48
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,58 @@
1==========
2meteos-ui
3==========
4
5Meteos UI
6
7* Free software: Apache license
8* Source: http://git.openstack.org/cgit/openstack/meteos-ui
9* Bugs: http://bugs.launchpad.net/meteos-ui
10
11Enabling in DevStack
12--------------------
13
14Add this repo as an external repository into your ``local.conf`` file::
15
16 [[local|localrc]]
17 enable_plugin meteos-ui https://github.com/openstack/meteos-ui
18
19Manual Installation
20-------------------
21
22Begin by cloning the Horizon and Meteos UI repositories::
23
24 git clone https://github.com/openstack/horizon
25 git clone https://github.com/openstack/meteos-ui
26
27Create a virtual environment and install Horizon dependencies::
28
29 cd horizon
30 python tools/install_venv.py
31
32Set up your ``local_settings.py`` file::
33
34 cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
35
36Open up the copied ``local_settings.py`` file in your preferred text
37editor. You will want to customize several settings:
38
39- ``OPENSTACK_HOST`` should be configured with the hostname of your
40 OpenStack server. Verify that the ``OPENSTACK_KEYSTONE_URL`` and
41 ``OPENSTACK_KEYSTONE_DEFAULT_ROLE`` settings are correct for your
42 environment. (They should be correct unless you modified your
43 OpenStack server to change them.)
44
45Install Meteos UI with all dependencies in your virtual environment::
46
47 tools/with_venv.sh pip install -e ../meteos-ui/
48
49And enable it in Horizon::
50
51 cp ../meteos-ui/meteos_ui/enabled/* openstack_dashboard/local/enabled/
52
53To run horizon with the newly enabled Meteos UI plugin run::
54
55 ./run_tests.sh --runserver 0.0.0.0:8080
56
57to have the application start on port 8080 and the horizon dashboard will be
58available in your browser at http://localhost:8080/
diff --git a/babel-django.cfg b/babel-django.cfg
new file mode 100644
index 0000000..ad09d34
--- /dev/null
+++ b/babel-django.cfg
@@ -0,0 +1,5 @@
1[extractors]
2django = django_babel.extract:extract_django
3
4[python: **.py]
5[django: templates/**.html]
diff --git a/babel-djangojs.cfg b/babel-djangojs.cfg
new file mode 100644
index 0000000..a8273b6
--- /dev/null
+++ b/babel-djangojs.cfg
@@ -0,0 +1,14 @@
1[extractors]
2# We use a custom extractor to find translatable strings in AngularJS
3# templates. The extractor is included in horizon.utils for now.
4# See http://babel.pocoo.org/docs/messages/#referencing-extraction-methods for
5# details on how this works.
6angular = horizon.utils.babel_extract_angular:extract_angular
7
8[javascript: **.js]
9
10# We need to look into all static folders for HTML files.
11# The **/static ensures that we also search within
12# /openstack_dashboard/dashboards/XYZ/static which will ensure
13# that plugins are also translated.
14[angular: **/static/**.html]
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
new file mode 100644
index 0000000..6d89c6f
--- /dev/null
+++ b/devstack/plugin.sh
@@ -0,0 +1,60 @@
1# plugin.sh - DevStack plugin.sh dispatch script meteos-ui
2
3METEOS_UI_DIR=$(cd $(dirname $BASH_SOURCE)/.. && pwd)
4
5function install_meteos_ui {
6 # NOTE(shu-mutou): workaround for devstack bug: 1540328
7 # where devstack install 'test-requirements' but should not do it
8 # for meteos-ui project as it installs Horizon from url.
9 # Remove following two 'mv' commands when mentioned bug is fixed.
10 mv $METEOS_UI_DIR/test-requirements.txt $METEOS_UI_DIR/_test-requirements.txt
11
12 setup_develop ${METEOS_UI_DIR}
13
14 mv $METEOS_UI_DIR/_test-requirements.txt $METEOS_UI_DIR/test-requirements.txt
15}
16
17function configure_meteos_ui {
18 cp -a ${METEOS_UI_DIR}/meteos_ui/enabled/* ${DEST}/horizon/openstack_dashboard/local/enabled/
19 # NOTE: If locale directory does not exist, compilemessages will fail,
20 # so check for an existence of locale directory is required.
21 if [ -d ${METEOS_UI_DIR}/meteos_ui/locale ]; then
22 (cd ${METEOS_UI_DIR}/meteos_ui; DJANGO_SETTINGS_MODULE=openstack_dashboard.settings ../manage.py compilemessages)
23 fi
24}
25
26# check for service enabled
27if is_service_enabled meteos-ui; then
28
29 if [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
30 # Set up system services
31 # no-op
32 :
33
34 elif [[ "$1" == "stack" && "$2" == "install" ]]; then
35 # Perform installation of service source
36 echo_summary "Installing Meteos UI"
37 install_meteos_ui
38
39 elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
40 # Configure after the other layer 1 and 2 services have been configured
41 echo_summary "Configurng Meteos UI"
42 configure_meteos_ui
43
44 elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
45 # no-op
46 :
47 fi
48
49 if [[ "$1" == "unstack" ]]; then
50 # no-op
51 :
52 fi
53
54 if [[ "$1" == "clean" ]]; then
55 # Remove state and transient data
56 # Remember clean.sh first calls unstack.sh
57 # no-op
58 :
59 fi
60fi
diff --git a/devstack/settings b/devstack/settings
new file mode 100644
index 0000000..541a4ab
--- /dev/null
+++ b/devstack/settings
@@ -0,0 +1,2 @@
1# settings file for meteos-ui plugin
2enable_service meteos-ui
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..369a7cc
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,152 @@
1# Makefile for Sphinx documentation
2
3# You can set these variables from the command line.
4SPHINXOPTS =
5SPHINXBUILD = sphinx-build
6PAPER =
7BUILDDIR = build
8
9# Internal variables.
10PAPEROPT_a4 = -D latex_paper_size=a4
11PAPEROPT_letter = -D latex_paper_size=letter
12ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
13# the i18n builder cannot share the environment and doctrees with the others
14I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
15
16.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
17
18help:
19 @echo "Please use \`make <target>' where <target> is one of"
20 @echo " html to make standalone HTML files"
21 @echo " dirhtml to make HTML files named index.html in directories"
22 @echo " singlehtml to make a single large HTML file"
23 @echo " pickle to make pickle files"
24 @echo " json to make JSON files"
25 @echo " htmlhelp to make HTML files and a HTML help project"
26 @echo " qthelp to make HTML files and a qthelp project"
27 @echo " devhelp to make HTML files and a Devhelp project"
28 @echo " epub to make an epub"
29 @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
30 @echo " latexpdf to make LaTeX files and run them through pdflatex"
31 @echo " text to make text files"
32 @echo " man to make manual pages"
33 @echo " texinfo to make Texinfo files"
34 @echo " info to make Texinfo files and run them through makeinfo"
35 @echo " gettext to make PO message catalogs"
36 @echo " changes to make an overview of all changed/added/deprecated items"
37 @echo " linkcheck to check all external links for integrity"
38 @echo " doctest to run all doctests embedded in the documentation (if enabled)"
39
40clean:
41 -rm -rf $(BUILDDIR)/*
42
43html:
44 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
45 @echo
46 @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
47
48dirhtml:
49 $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
50 @echo
51 @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
52
53singlehtml:
54 $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
55 @echo
56 @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
57
58pickle:
59 $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
60 @echo
61 @echo "Build finished; now you can process the pickle files."
62
63json:
64 $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
65 @echo
66 @echo "Build finished; now you can process the JSON files."
67
68htmlhelp:
69 $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
70 @echo
71 @echo "Build finished; now you can run HTML Help Workshop with the" \
72 ".hhp project file in $(BUILDDIR)/htmlhelp."
73
74qthelp:
75 $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
76 @echo
77 @echo "Build finished; now you can run "qcollectiongenerator" with the" \
78 ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
79 @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Meteos-UI.qhcp"
80 @echo "To view the help file:"
81 @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Meteos-UI.qhc"
82
83devhelp:
84 $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
85 @echo
86 @echo "Build finished."
87 @echo "To view the help file:"
88 @echo "# mkdir -p $$HOME/.local/share/devhelp/Meteos-UI"
89 @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Meteos-UI"
90 @echo "# devhelp"
91
92epub:
93 $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
94 @echo
95 @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
96
97latex:
98 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
99 @echo
100 @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
101 @echo "Run \`make' in that directory to run these through (pdf)latex" \
102 "(use \`make latexpdf' here to do that automatically)."
103
104latexpdf:
105 $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
106 @echo "Running LaTeX files through pdflatex..."
107 $(MAKE) -C $(BUILDDIR)/latex all-pdf
108 @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
109
110text:
111 $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
112 @echo
113 @echo "Build finished. The text files are in $(BUILDDIR)/text."
114
115man:
116 $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
117 @echo
118 @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
119
120texinfo:
121 $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
122 @echo
123 @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
124 @echo "Run \`make' in that directory to run these through makeinfo" \
125 "(use \`make info' here to do that automatically)."
126
127info:
128 $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
129 @echo "Running Texinfo files through makeinfo..."
130 make -C $(BUILDDIR)/texinfo info
131 @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
132
133gettext:
134 $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
135 @echo
136 @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
137
138changes:
139 $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
140 @echo
141 @echo "The overview file is in $(BUILDDIR)/changes."
142
143linkcheck:
144 $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
145 @echo
146 @echo "Link check complete; look for any errors in the above output " \
147 "or in $(BUILDDIR)/linkcheck/output.txt."
148
149doctest:
150 $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
151 @echo "Testing of doctests in the sources finished, look at the " \
152 "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/source/conf.py b/doc/source/conf.py
new file mode 100644
index 0000000..c197b29
--- /dev/null
+++ b/doc/source/conf.py
@@ -0,0 +1,441 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12#
13# Horizon documentation build configuration file, created by
14# sphinx-quickstart on Thu Oct 27 11:38:59 2011.
15#
16# This file is execfile()d with the current directory set to its
17# containing dir.
18#
19# Note that not all possible configuration values are present in this
20# autogenerated file.
21#
22# All configuration values have a default; values that are commented out
23# serve to show the default.
24
25from __future__ import print_function
26
27import os
28import subprocess
29import sys
30
31BASE_DIR = os.path.dirname(os.path.abspath(__file__))
32ROOT = os.path.abspath(os.path.join(BASE_DIR, "..", ".."))
33
34sys.path.insert(0, ROOT)
35
36# This is required for ReadTheDocs.org, but isn't a bad idea anyway.
37os.environ.setdefault('DJANGO_SETTINGS_MODULE',
38 'meteos_ui.test.settings')
39
40from meteos_ui \
41 import version as meteosui_ver
42
43
44def write_autodoc_index():
45
46 def find_autodoc_modules(module_name, sourcedir):
47 """returns a list of modules in the SOURCE directory."""
48 modlist = []
49 os.chdir(os.path.join(sourcedir, module_name))
50 print("SEARCHING %s" % sourcedir)
51 for root, dirs, files in os.walk("."):
52 for filename in files:
53 if filename == 'tests.py':
54 continue
55 if filename.endswith(".py"):
56 # remove the pieces of the root
57 elements = root.split(os.path.sep)
58 # replace the leading "." with the module name
59 elements[0] = module_name
60 # and get the base module name
61 base, extension = os.path.splitext(filename)
62 if not (base == "__init__"):
63 elements.append(base)
64 result = ".".join(elements)
65 # print result
66 modlist.append(result)
67 return modlist
68
69 RSTDIR = os.path.abspath(os.path.join(BASE_DIR, "sourcecode"))
70 SRCS = [('meteos_ui', ROOT), ]
71
72 EXCLUDED_MODULES = ()
73 CURRENT_SOURCES = {}
74
75 if not(os.path.exists(RSTDIR)):
76 os.mkdir(RSTDIR)
77 CURRENT_SOURCES[RSTDIR] = ['autoindex.rst']
78
79 INDEXOUT = open(os.path.join(RSTDIR, "autoindex.rst"), "w")
80 INDEXOUT.write("""
81=================
82Source Code Index
83=================
84
85.. contents::
86 :depth: 1
87 :local:
88
89""")
90
91 for modulename, path in SRCS:
92 sys.stdout.write("Generating source documentation for %s\n" %
93 modulename)
94 INDEXOUT.write("\n%s\n" % modulename.capitalize())
95 INDEXOUT.write("%s\n" % ("=" * len(modulename),))
96 INDEXOUT.write(".. toctree::\n")
97 INDEXOUT.write(" :maxdepth: 1\n")
98 INDEXOUT.write("\n")
99
100 MOD_DIR = os.path.join(RSTDIR, modulename)
101 CURRENT_SOURCES[MOD_DIR] = []
102 if not(os.path.exists(MOD_DIR)):
103 os.mkdir(MOD_DIR)
104 for module in find_autodoc_modules(modulename, path):
105 if any([module.startswith(exclude) for exclude
106 in EXCLUDED_MODULES]):
107 print("Excluded module %s." % module)
108 continue
109 mod_path = os.path.join(path, *module.split("."))
110 generated_file = os.path.join(MOD_DIR, "%s.rst" % module)
111
112 INDEXOUT.write(" %s/%s\n" % (modulename, module))
113
114 # Find the __init__.py module if this is a directory
115 if os.path.isdir(mod_path):
116 source_file = ".".join((os.path.join(mod_path, "__init__"),
117 "py",))
118 else:
119 source_file = ".".join((os.path.join(mod_path), "py"))
120
121 CURRENT_SOURCES[MOD_DIR].append("%s.rst" % module)
122 # Only generate a new file if the source has changed or we don't
123 # have a doc file to begin with.
124 if not os.access(generated_file, os.F_OK) or (
125 os.stat(generated_file).st_mtime <
126 os.stat(source_file).st_mtime):
127 print("Module %s updated, generating new documentation."
128 % module)
129 FILEOUT = open(generated_file, "w")
130 header = "The :mod:`%s` Module" % module
131 FILEOUT.write("%s\n" % ("=" * len(header),))
132 FILEOUT.write("%s\n" % header)
133 FILEOUT.write("%s\n" % ("=" * len(header),))
134 FILEOUT.write(".. automodule:: %s\n" % module)
135 FILEOUT.write(" :members:\n")
136 FILEOUT.write(" :undoc-members:\n")
137 FILEOUT.write(" :show-inheritance:\n")
138 FILEOUT.write(" :noindex:\n")
139 FILEOUT.close()
140
141 INDEXOUT.close()
142
143 # Delete auto-generated .rst files for sources which no longer exist
144 for directory, subdirs, files in list(os.walk(RSTDIR)):
145 for old_file in files:
146 if old_file not in CURRENT_SOURCES.get(directory, []):
147 print("Removing outdated file for %s" % old_file)
148 os.remove(os.path.join(directory, old_file))
149
150
151write_autodoc_index()
152
153# If extensions (or modules to document with autodoc) are in another directory,
154# add these directories to sys.path here. If the directory is relative to the
155# documentation root, use os.path.abspath to make it absolute, like shown here.
156# sys.path.insert(0, os.path.abspath('.'))
157
158# -- General configuration ----------------------------------------------------
159
160# If your documentation needs a minimal Sphinx version, state it here.
161# needs_sphinx = '1.0'
162
163# Add any Sphinx extension module names here, as strings.
164# They can be extensions coming with Sphinx (named 'sphinx.ext.*')
165# or your custom ones.
166extensions = ['sphinx.ext.autodoc',
167 'sphinx.ext.todo',
168 'sphinx.ext.coverage',
169 'sphinx.ext.viewcode',
170 'oslosphinx',
171 ]
172
173# Add any paths that contain templates here, relative to this directory.
174templates_path = ['_templates']
175
176# The suffix of source filenames.
177source_suffix = '.rst'
178
179# The encoding of source files.
180# source_encoding = 'utf-8-sig'
181
182# The master toctree document.
183master_doc = 'index'
184
185# General information about the project.
186project = u'Meteos UI'
187copyright = u'2016, OpenStack Foundation'
188
189# The version info for the project you're documenting, acts as replacement for
190# |version| and |release|, also used in various other places throughout the
191# built documents.
192#
193# The short X.Y version.
194version = meteosui_ver.version_info.version_string()
195# The full version, including alpha/beta/rc tags.
196release = meteosui_ver.version_info.release_string()
197
198# The language for content autogenerated by Sphinx. Refer to documentation
199# for a list of supported languages.
200# language = None
201
202# There are two options for replacing |today|: either, you set today to some
203# non-false value, then it is used:
204# today = ''
205# Else, today_fmt is used as the format for a strftime call.
206# today_fmt = '%B %d, %Y'
207
208# List of patterns, relative to source directory, that match files and
209# directories to ignore when looking for source files.
210exclude_patterns = ['**/#*', '**~', '**/#*#']
211
212# The reST default role (used for this markup: `text`)
213# to use for all documents.
214# default_role = None
215
216# If true, '()' will be appended to :func: etc. cross-reference text.
217# add_function_parentheses = True
218
219# If true, the current module name will be prepended to all description
220# unit titles (such as .. function::).
221# add_module_names = True
222
223# If true, sectionauthor and moduleauthor directives will be shown in the
224# output. They are ignored by default.
225show_authors = False
226
227# The name of the Pygments (syntax highlighting) style to use.
228pygments_style = 'sphinx'
229
230# A list of ignored prefixes for module index sorting.
231# modindex_common_prefix = []
232
233primary_domain = 'py'
234nitpicky = False
235
236
237# -- Options for HTML output --------------------------------------------------
238
239# The theme to use for HTML and HTML Help pages. See the documentation for
240# a list of builtin themes.
241# html_theme_path = ['.']
242# html_theme = '_theme'
243
244# Theme options are theme-specific and customize the look and feel of a theme
245# further. For a list of options available for each theme, see the
246# documentation.
247html_theme_options = {
248 "nosidebar": "false"
249}
250
251# Add any paths that contain custom themes here, relative to this directory.
252# html_theme_path = []
253
254# The name for this set of Sphinx documents. If None, it defaults to
255# "<project> v<release> documentation".
256# html_title = None
257
258# A shorter title for the navigation bar. Default is the same as html_title.
259# html_short_title = None
260
261# The name of an image file (relative to this directory) to place at the top
262# of the sidebar.
263# html_logo = None
264
265# The name of an image file (within the static path) to use as favicon of the
266# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
267# pixels large.
268# html_favicon = None
269
270# Add any paths that contain custom static files (such as style sheets) here,
271# relative to this directory. They are copied after the builtin static files,
272# so a file named "default.css" will overwrite the builtin "default.css".
273html_static_path = ['_static']
274
275# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
276# using the given strftime format.
277# html_last_updated_fmt = '%b %d, %Y'
278git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
279 "-n1"]
280html_last_updated_fmt = subprocess.check_output(git_cmd,
281 stdin=subprocess.PIPE)
282
283# If true, SmartyPants will be used to convert quotes and dashes to
284# typographically correct entities.
285# html_use_smartypants = True
286
287# Custom sidebar templates, maps document names to template names.
288# html_sidebars = {}
289
290# Additional templates that should be rendered to pages, maps page names to
291# template names.
292# html_additional_pages = {}
293
294# If false, no module index is generated.
295# html_domain_indices = True
296
297# If false, no index is generated.
298# html_use_index = True
299
300# If true, the index is split into individual pages for each letter.
301# html_split_index = False
302
303# If true, links to the reST sources are added to the pages.
304# html_show_sourcelink = True
305
306# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
307# html_show_sphinx = True
308
309# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
310# html_show_copyright = True
311
312# If true, an OpenSearch description file will be output, and all pages will
313# contain a <link> tag referring to it. The value of this option must be the
314# base URL from which the finished HTML is served.
315# html_use_opensearch = ''
316
317# This is the file name suffix for HTML files (e.g. ".xhtml").
318# html_file_suffix = None
319
320# Output file base name for HTML help builder.
321htmlhelp_basename = 'Horizondoc'
322
323
324# -- Options for LaTeX output -------------------------------------------------
325
326latex_elements = {
327 # The paper size ('letterpaper' or 'a4paper').
328 # 'papersize': 'letterpaper',
329
330 # The font size ('10pt', '11pt' or '12pt').
331 # 'pointsize': '10pt',
332
333 # Additional stuff for the LaTeX preamble.
334 # 'preamble': '',
335}
336
337# Grouping the document tree into LaTeX files. List of tuples
338# (source start file, target name, title, author, documentclass
339# [howto/manual]).
340latex_documents = [
341 ('index', 'Horizon.tex', u'Horizon Documentation',
342 u'OpenStack Foundation', 'manual'),
343]
344
345# The name of an image file (relative to this directory) to place at the top of
346# the title page.
347# latex_logo = None
348
349# For "manual" documents, if this is true, then toplevel headings are parts,
350# not chapters.
351# latex_use_parts = False
352
353# If true, show page references after internal links.
354# latex_show_pagerefs = False
355
356# If true, show URL addresses after external links.
357# latex_show_urls = False
358
359# Documents to append as an appendix to all manuals.
360# latex_appendices = []
361
362# If false, no module index is generated.
363# latex_domain_indices = True
364
365
366# -- Options for manual page output -------------------------------------------
367
368# One entry per manual page. List of tuples
369# (source start file, name, description, authors, manual section).
370man_pages = [
371 ('index', u'Meteos UI Documentation',
372 'Documentation for the Meteos UI plugin to the Openstack\
373 Dashboard (Horizon)',
374 [u'OpenStack'], 1)
375]
376
377# If true, show URL addresses after external links.
378# man_show_urls = False
379
380
381# -- Options for Texinfo output -----------------------------------------------
382
383# Grouping the document tree into Texinfo files. List of tuples
384# (source start file, target name, title, author,
385# dir menu entry, description, category)
386texinfo_documents = [
387 ('index', 'Horizon', u'Horizon Documentation', u'OpenStack',
388 'Horizon', 'One line description of project.', 'Miscellaneous'),
389]
390
391# Documents to append as an appendix to all manuals.
392# texinfo_appendices = []
393
394# If false, no module index is generated.
395# texinfo_domain_indices = True
396
397# How to display URL addresses: 'footnote', 'no', or 'inline'.
398# texinfo_show_urls = 'footnote'
399
400
401# -- Options for Epub output --------------------------------------------------
402
403# Bibliographic Dublin Core info.
404epub_title = u'Horizon'
405epub_author = u'OpenStack'
406epub_publisher = u'OpenStack'
407epub_copyright = u'2012, OpenStack'
408
409# The language of the text. It defaults to the language option
410# or en if the language is not set.
411# epub_language = ''
412
413# The scheme of the identifier. Typical schemes are ISBN or URL.
414# epub_scheme = ''
415
416# The unique identifier of the text. This can be an ISBN number
417# or the project homepage.
418# epub_identifier = ''
419
420# A unique identification for the text.
421# epub_uid = ''
422
423# A tuple containing the cover image and cover page html template filenames.
424# epub_cover = ()
425
426# HTML files that should be inserted before the pages created by sphinx.
427# The format is a list of tuples containing the path and title.
428# epub_pre_files = []
429
430# HTML files shat should be inserted after the pages created by sphinx.
431# The format is a list of tuples containing the path and title.
432# epub_post_files = []
433
434# A list of files that should not be packed into the epub file.
435# epub_exclude_files = []
436
437# The depth of the table of contents in toc.ncx.
438# epub_tocdepth = 3
439
440# Allow duplicate toc entries.
441# epub_tocdup = True
diff --git a/doc/source/index.rst b/doc/source/index.rst
new file mode 100644
index 0000000..48f5346
--- /dev/null
+++ b/doc/source/index.rst
@@ -0,0 +1,78 @@
1==========
2meteos-ui
3==========
4
5Meteos UI
6
7* Free software: Apache license
8* Source: http://git.openstack.org/cgit/openstack/meteos-ui
9* Bugs: http://bugs.launchpad.net/meteos-ui
10
11Enabling in DevStack
12--------------------
13
14Add this repo as an external repository into your ``local.conf`` file::
15
16 [[local|localrc]]
17 enable_plugin meteos-ui https://github.com/openstack/meteos-ui
18
19Manual Installation
20-------------------
21
22Begin by cloning the Horizon and Meteos UI repositories::
23
24 git clone https://github.com/openstack/horizon
25 git clone https://github.com/openstack/meteos-ui
26
27Create a virtual environment and install Horizon dependencies::
28
29 cd horizon
30 python tools/install_venv.py
31
32Set up your ``local_settings.py`` file::
33
34 cp openstack_dashboard/local/local_settings.py.example openstack_dashboard/local/local_settings.py
35
36Open up the copied ``local_settings.py`` file in your preferred text
37editor. You will want to customize several settings:
38
39- ``OPENSTACK_HOST`` should be configured with the hostname of your
40 OpenStack server. Verify that the ``OPENSTACK_KEYSTONE_URL`` and
41 ``OPENSTACK_KEYSTONE_DEFAULT_ROLE`` settings are correct for your
42 environment. (They should be correct unless you modified your
43 OpenStack server to change them.)
44
45Install Meteos UI with all dependencies in your virtual environment::
46
47 tools/with_venv.sh pip install -e ../meteos-ui/
48
49And enable it in Horizon::
50
51 cp ../meteos-ui/meteos_ui/enabled/* openstack_dashboard/local/enabled/
52
53To run horizon with the newly enabled Meteos UI plugin run::
54
55 ./run_tests.sh --runserver 0.0.0.0:8080
56
57to have the application start on port 8080 and the horizon dashboard will be
58available in your browser at http://localhost:8080/
59
60Release Notes
61=============
62
63.. toctree::
64 :glob:
65 :maxdepth: 1
66
67 releases/*
68
69Source Code Reference
70=====================
71
72.. toctree::
73 :glob:
74 :maxdepth: 1
75
76 sourcecode/autoindex
77
78
diff --git a/doc/source/releases/0.1.0.rst b/doc/source/releases/0.1.0.rst
new file mode 100644
index 0000000..489d83b
--- /dev/null
+++ b/doc/source/releases/0.1.0.rst
@@ -0,0 +1,2 @@
1Meteos UI 0.1.0
2============
diff --git a/manage.py b/manage.py
new file mode 100755
index 0000000..172fb99
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,23 @@
1#!/usr/bin/env python
2
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import os
16import sys
17
18from django.core.management import execute_from_command_line # noqa
19
20if __name__ == "__main__":
21 os.environ.setdefault("DJANGO_SETTINGS_MODULE",
22 "meteos_ui.test.settings")
23 execute_from_command_line(sys.argv)
diff --git a/meteos_ui/__init__.py b/meteos_ui/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/__init__.py
diff --git a/meteos_ui/api/__init__.py b/meteos_ui/api/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/api/__init__.py
diff --git a/meteos_ui/api/client.py b/meteos_ui/api/client.py
new file mode 100644
index 0000000..b4d5d24
--- /dev/null
+++ b/meteos_ui/api/client.py
@@ -0,0 +1,226 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13
14from horizon import exceptions
15from horizon.utils.memoized import memoized
16import logging
17from openstack_dashboard.api import base
18from meteosclient.api import client as meteos_client
19
20
21LOG = logging.getLogger(__name__)
22
23TEMPLATE_CREATE_ATTRS = ['display_name', 'display_description', 'image_id',
24 'master_nodes_num', 'master_flavor_id',
25 'worker_nodes_num', 'worker_flavor_id',
26 'spark_version', 'floating_ip_pool']
27EXPERIMENT_CREATE_ATTRS = ['display_name', 'display_description', 'key_name',
28 'neutron_management_network', 'template_id']
29DATASET_CREATE_ATTRS = ['method', 'source_dataset_url', 'display_name',
30 'display_description', 'experiment_id', 'params',
31 'swift_tenant', 'swift_username', 'swift_password']
32MODEL_CREATE_ATTRS = ['source_dataset_url', 'display_name',
33 'display_description', 'experiment_id',
34 'model_type', 'model_params', 'dataset_format',
35 'swift_tenant', 'swift_username', 'swift_password']
36MODEL_EVA_CREATE_ATTRS = ['source_dataset_url', 'display_name',
37 'display_description', 'model_id', 'dataset_format',
38 'swift_tenant', 'swift_username', 'swift_password']
39LEARNING_CREATE_ATTRS = ['display_name', 'display_description',
40 'model_id', 'method', 'args']
41
42
43@memoized
44def meteosclient(request):
45 meteos_url = ""
46 try:
47 meteos_url = base.url_for(request, 'machine-learning')
48 except exceptions.ServiceCatalogException:
49 LOG.debug('No Machine Learning service is configured.')
50 return None
51
52 LOG.debug('meteosclient connection created using the token "%s" and url'
53 '"%s"' % (request.user.token.id, meteos_url))
54 c = meteos_client.Client(username=request.user.username,
55 project_id=request.user.tenant_id,
56 input_auth_token=request.user.token.id,
57 meteos_url=meteos_url)
58 return c
59
60
61def template_create(request, **kwargs):
62 args = {}
63 for (key, value) in kwargs.items():
64 if key in TEMPLATE_CREATE_ATTRS:
65 args[str(key)] = str(value)
66 else:
67 raise exceptions.BadRequest(
68 "Key must be in %s" % ",".join(TEMPLATE_CREATE_ATTRS))
69 return meteosclient(request).templates.create(**args)
70
71
72def template_delete(request, id):
73 return meteosclient(request).templates.delete(id)
74
75
76def template_list(request, search_opts=None, limit=None, marker=None,
77 sort_key=None, sort_dir=None):
78 return meteosclient(request).templates.list(search_opts,
79 limit,
80 marker,
81 sort_key,
82 sort_dir)
83
84
85def template_show(request, id):
86 return meteosclient(request).templates.get(id)
87
88
89def experiment_create(request, **kwargs):
90 args = {}
91 for (key, value) in kwargs.items():
92 if key in EXPERIMENT_CREATE_ATTRS:
93 args[str(key)] = str(value)
94 else:
95 raise exceptions.BadRequest(
96 "Key must be in %s" % ",".join(EXPERIMENT_CREATE_ATTRS))
97 return meteosclient(request).experiments.create(**args)
98
99
100def experiment_delete(request, id):
101 return meteosclient(request).experiments.delete(id)
102
103
104def experiment_list(request, search_opts=None, limit=None, marker=None,
105 sort_key=None, sort_dir=None):
106 return meteosclient(request).experiments.list(search_opts,
107 limit,
108 marker,
109 sort_key,
110 sort_dir)
111
112
113def experiment_show(request, id):
114 return meteosclient(request).experiments.get(id)
115
116
117def dataset_create(request, **kwargs):
118 args = {}
119 for (key, value) in kwargs.items():
120 if key in DATASET_CREATE_ATTRS:
121 args[str(key)] = str(value)
122 else:
123 raise exceptions.BadRequest(
124 "Key must be in %s" % ",".join(DATASET_CREATE_ATTRS))
125 return meteosclient(request).datasets.create(**args)
126
127
128def dataset_delete(request, id):
129 return meteosclient(request).datasets.delete(id)
130
131
132def dataset_list(request, search_opts=None, limit=None, marker=None,
133 sort_key=None, sort_dir=None):
134 return meteosclient(request).datasets.list(search_opts,
135 limit,
136 marker,
137 sort_key,
138 sort_dir)
139
140
141def dataset_show(request, id):
142 return meteosclient(request).datasets.get(id)
143
144
145def model_create(request, **kwargs):
146 args = {}
147 for (key, value) in kwargs.items():
148 if key in MODEL_CREATE_ATTRS:
149 args[str(key)] = str(value)
150 else:
151 raise exceptions.BadRequest(
152 "Key must be in %s" % ",".join(MODEL_CREATE_ATTRS))
153 return meteosclient(request).models.create(**args)
154
155
156def model_delete(request, id):
157 return meteosclient(request).models.delete(id)
158
159
160def model_list(request, search_opts=None, limit=None, marker=None,
161 sort_key=None, sort_dir=None):
162 return meteosclient(request).models.list(search_opts,
163 limit,
164 marker,
165 sort_key,
166 sort_dir)
167
168
169def model_show(request, id):
170 return meteosclient(request).models.get(id)
171
172
173def model_evaluation_create(request, **kwargs):
174 args = {}
175 for (key, value) in kwargs.items():
176 if key in MODEL_EVA_CREATE_ATTRS:
177 args[str(key)] = str(value)
178 else:
179 raise exceptions.BadRequest(
180 "Key must be in %s" % ",".join(MODEL_EVA_CREATE_ATTRS))
181 return meteosclient(request).model_evaluations.create(**args)
182
183
184def model_evaluation_delete(request, id):
185 return meteosclient(request).model_evaluations.delete(id)
186
187
188def model_evaluation_list(request, search_opts=None, limit=None, marker=None,
189 sort_key=None, sort_dir=None):
190 return meteosclient(request).model_evaluations.list(search_opts,
191 limit,
192 marker,
193 sort_key,
194 sort_dir)
195
196
197def model_evaluation_show(request, id):
198 return meteosclient(request).model_evaluations.get(id)
199
200
201def learning_create(request, **kwargs):
202 args = {}
203 for (key, value) in kwargs.items():
204 if key in LEARNING_CREATE_ATTRS:
205 args[str(key)] = str(value)
206 else:
207 raise exceptions.BadRequest(
208 "Key must be in %s" % ",".join(LEARNING_CREATE_ATTRS))
209 return meteosclient(request).learnings.create(**args)
210
211
212def learning_delete(request, id):
213 return meteosclient(request).learnings.delete(id)
214
215
216def learning_list(request, search_opts=None, limit=None, marker=None,
217 sort_key=None, sort_dir=None):
218 return meteosclient(request).learnings.list(search_opts,
219 limit,
220 marker,
221 sort_key,
222 sort_dir)
223
224
225def learning_show(request, id):
226 return meteosclient(request).learnings.get(id)
diff --git a/meteos_ui/api/rest_api.py b/meteos_ui/api/rest_api.py
new file mode 100644
index 0000000..3d615b7
--- /dev/null
+++ b/meteos_ui/api/rest_api.py
@@ -0,0 +1,337 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.views import generic
14
15from meteos_ui.api import client
16
17from openstack_dashboard.api.rest import urls
18from openstack_dashboard.api.rest import utils as rest_utils
19
20
21@urls.register
22class Template(generic.View):
23 """API for retrieving a single template"""
24 url_regex = r'meteos/templates/(?P<id>[^/]+)$'
25
26 @rest_utils.ajax()
27 def get(self, request, id):
28 """Get a specific template"""
29 return change_to_id(client.template_show(request, id).to_dict())
30
31
32@urls.register
33class TemplateActions(generic.View):
34 """API for retrieving a single template"""
35 url_regex = r'meteos/templates/(?P<id>[^/]+)/(?P<action>[^/]+)$'
36
37
38@urls.register
39class Templates(generic.View):
40 """API for Meteos Templates"""
41 url_regex = r'meteos/templates/$'
42
43 @rest_utils.ajax()
44 def get(self, request):
45 """Get a list of the Templates for a project.
46
47 The returned result is an object with property 'items' and each
48 item under this is a Template.
49 """
50 result = client.template_list(request)
51 return {'items': [n.to_dict() for n in result]}
52
53 @rest_utils.ajax(data_required=True)
54 def delete(self, request):
55 """Delete one or more Templates by id.
56
57 Returns HTTP 204 (no content) on successful deletion.
58 """
59 for id in request.DATA:
60 client.template_delete(request, id)
61
62 @rest_utils.ajax(data_required=True)
63 def post(self, request):
64 """Create a new Template.
65
66 Returns the new Template object on success.
67 """
68 new_template = client.template_create(request, **request.DATA)
69 return rest_utils.CreatedResponse(
70 '/api/meteos/template/%s' % new_template.id,
71 new_template.to_dict())
72
73
74@urls.register
75class Experiment(generic.View):
76 """API for retrieving a single experiment"""
77 url_regex = r'meteos/experiments/(?P<id>[^/]+)$'
78
79 @rest_utils.ajax()
80 def get(self, request, id):
81 """Get a specific experiment"""
82 return change_to_id(client.experiment_show(request, id).to_dict())
83
84
85@urls.register
86class ExperimentActions(generic.View):
87 """API for retrieving a single experiment"""
88 url_regex = r'meteos/experiments/(?P<id>[^/]+)/(?P<action>[^/]+)$'
89
90
91@urls.register
92class Experiments(generic.View):
93 """API for Meteos Experiments"""
94 url_regex = r'meteos/experiments/$'
95
96 @rest_utils.ajax()
97 def get(self, request):
98 """Get a list of the Experiments for a project.
99
100 The returned result is an object with property 'items' and each
101 item under this is a Experiment.
102 """
103 result = client.experiment_list(request)
104 return {'items': [n.to_dict() for n in result]}
105
106 @rest_utils.ajax(data_required=True)
107 def delete(self, request):
108 """Delete one or more Experiments by id.
109
110 Returns HTTP 204 (no content) on successful deletion.
111 """
112 for id in request.DATA:
113 client.experiment_delete(request, id)
114
115 @rest_utils.ajax(data_required=True)
116 def post(self, request):
117 """Create a new Experiment.
118
119 Returns the new Experiment object on success.
120 """
121 new_experiment = client.experiment_create(request, **request.DATA)
122 return rest_utils.CreatedResponse(
123 '/api/meteos/experiment/%s' % new_experiment.id,
124 new_experiment.to_dict())
125
126
127@urls.register
128class Dataset(generic.View):
129 """API for retrieving a single dataset"""
130 url_regex = r'meteos/datasets/(?P<id>[^/]+)$'
131
132 @rest_utils.ajax()
133 def get(self, request, id):
134 """Get a specific dataset"""
135 return change_to_id(client.dataset_show(request, id).to_dict())
136
137
138@urls.register
139class DatasetActions(generic.View):
140 """API for retrieving a single dataset"""
141 url_regex = r'meteos/datasets/(?P<id>[^/]+)/(?P<action>[^/]+)$'
142
143
144@urls.register
145class Datasets(generic.View):
146 """API for Meteos Datasets"""
147 url_regex = r'meteos/datasets/$'
148
149 @rest_utils.ajax()
150 def get(self, request):
151 """Get a list of the Datasets for a project.
152
153 The returned result is an object with property 'items' and each
154 item under this is a Dataset.
155 """
156 result = client.dataset_list(request)
157 return {'items': [n.to_dict() for n in result]}
158
159 @rest_utils.ajax(data_required=True)
160 def delete(self, request):
161 """Delete one or more Datasets by id.
162
163 Returns HTTP 204 (no content) on successful deletion.
164 """
165 for id in request.DATA:
166 client.dataset_delete(request, id)
167
168 @rest_utils.ajax(data_required=True)
169 def post(self, request):
170 """Create a new Dataset.
171
172 Returns the new Dataset object on success.
173 """
174 new_dataset = client.dataset_create(request, **request.DATA)
175 return rest_utils.CreatedResponse(
176 '/api/meteos/dataset/%s' % new_dataset.id,
177 new_dataset.to_dict())
178
179
180@urls.register
181class Model(generic.View):
182 """API for retrieving a single model"""
183 url_regex = r'meteos/models/(?P<id>[^/]+)$'
184
185 @rest_utils.ajax()
186 def get(self, request, id):
187 """Get a specific model"""
188 return change_to_id(client.model_show(request, id).to_dict())
189
190
191@urls.register
192class ModelActions(generic.View):
193 """API for retrieving a single model"""
194 url_regex = r'meteos/models/(?P<id>[^/]+)/(?P<action>[^/]+)$'
195
196
197@urls.register
198class Models(generic.View):
199 """API for Meteos Models"""
200 url_regex = r'meteos/models/$'
201
202 @rest_utils.ajax()
203 def get(self, request):
204 """Get a list of the Models for a project.
205
206 The returned result is an object with property 'items' and each
207 item under this is a Model.
208 """
209 result = client.model_list(request)
210 return {'items': [n.to_dict() for n in result]}
211
212 @rest_utils.ajax(data_required=True)
213 def delete(self, request):
214 """Delete one or more Models by id.
215
216 Returns HTTP 204 (no content) on successful deletion.
217 """
218 for id in request.DATA:
219 client.model_delete(request, id)
220
221 @rest_utils.ajax(data_required=True)
222 def post(self, request):
223 """Create a new Model.
224
225 Returns the new Model object on success.
226 """
227 new_model = client.model_create(request, **request.DATA)
228 return rest_utils.CreatedResponse(
229 '/api/meteos/model/%s' % new_model.id,
230 new_model.to_dict())
231
232
233@urls.register
234class ModelEvaluation(generic.View):
235 """API for retrieving a single model_evaluation"""
236 url_regex = r'meteos/model_evaluations/(?P<id>[^/]+)$'
237
238 @rest_utils.ajax()
239 def get(self, request, id):
240 """Get a specific model_evaluation"""
241 return change_to_id(client.model_evaluation_show(request, id).to_dict())
242
243
244@urls.register
245class ModelEvaluationActions(generic.View):
246 """API for retrieving a single model_evaluation"""
247 url_regex = r'meteos/model_evaluations/(?P<id>[^/]+)/(?P<action>[^/]+)$'
248
249
250@urls.register
251class ModelEvaluations(generic.View):
252 """API for Meteos ModelEvaluations"""
253 url_regex = r'meteos/model_evaluations/$'
254
255 @rest_utils.ajax()
256 def get(self, request):
257 """Get a list of the ModelEvaluations for a project.
258
259 The returned result is an object with property 'items' and each
260 item under this is a ModelEvaluation.
261 """
262 result = client.model_evaluation_list(request)
263 return {'items': [n.to_dict() for n in result]}
264
265 @rest_utils.ajax(data_required=True)
266 def delete(self, request):
267 """Delete one or more ModelEvaluations by id.
268
269 Returns HTTP 204 (no content) on successful deletion.
270 """
271 for id in request.DATA:
272 client.model_evaluation_delete(request, id)
273
274 @rest_utils.ajax(data_required=True)
275 def post(self, request):
276 """Create a new ModelEvaluation.
277
278 Returns the new ModelEvaluation object on success.
279 """
280 new_model_evaluation = client.model_evaluation_create(request,
281 **request.DATA)
282 return rest_utils.CreatedResponse(
283 '/api/meteos/model_evaluation/%s' % new_model_evaluation.id,
284 new_model_evaluation.to_dict())
285
286
287@urls.register
288class Learning(generic.View):
289 """API for retrieving a single learning"""
290 url_regex = r'meteos/learnings/(?P<id>[^/]+)$'
291
292 @rest_utils.ajax()
293 def get(self, request, id):
294 """Get a specific learning"""
295 return change_to_id(client.learning_show(request, id).to_dict())
296
297
298@urls.register
299class LearningActions(generic.View):
300 """API for retrieving a single learning"""
301 url_regex = r'meteos/learnings/(?P<id>[^/]+)/(?P<action>[^/]+)$'
302
303
304@urls.register
305class Learnings(generic.View):
306 """API for Meteos Learnings"""
307 url_regex = r'meteos/learnings/$'
308
309 @rest_utils.ajax()
310 def get(self, request):
311 """Get a list of the Learnings for a project.
312
313 The returned result is an object with property 'items' and each
314 item under this is a Learning.
315 """
316 result = client.learning_list(request)
317 return {'items': [n.to_dict() for n in result]}
318
319 @rest_utils.ajax(data_required=True)
320 def delete(self, request):
321 """Delete one or more Learnings by id.
322
323 Returns HTTP 204 (no content) on successful deletion.
324 """
325 for id in request.DATA:
326 client.learning_delete(request, id)
327
328 @rest_utils.ajax(data_required=True)
329 def post(self, request):
330 """Create a new Learning.
331
332 Returns the new Learning object on success.
333 """
334 new_learning = client.learning_create(request, **request.DATA)
335 return rest_utils.CreatedResponse(
336 '/api/meteos/learning/%s' % new_learning.id,
337 new_learning.to_dict())
diff --git a/meteos_ui/content/__init__.py b/meteos_ui/content/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/__init__.py
diff --git a/meteos_ui/content/machine_learning/__init__.py b/meteos_ui/content/machine_learning/__init__.py
new file mode 100644
index 0000000..b9127ca
--- /dev/null
+++ b/meteos_ui/content/machine_learning/__init__.py
@@ -0,0 +1,14 @@
1# Licensed under the Apache License, Version 2.0 (the "License");
2# you may not use this file except in compliance with the License.
3# You may obtain a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS,
9# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10# See the License for the specific language governing permissions and
11# limitations under the License.
12
13# Register the REST API URLs so they can be called from the JavaScript files
14import meteos_ui.api.rest_api # noqa
diff --git a/meteos_ui/content/machine_learning/datasets/__init__.py b/meteos_ui/content/machine_learning/datasets/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/datasets/__init__.py
diff --git a/meteos_ui/content/machine_learning/datasets/panel.py b/meteos_ui/content/machine_learning/datasets/panel.py
new file mode 100644
index 0000000..1b8e7b8
--- /dev/null
+++ b/meteos_ui/content/machine_learning/datasets/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class Datasets(horizon.Panel):
22 name = _("Datasets")
23 slug = "machine_learning.datasets"
diff --git a/meteos_ui/content/machine_learning/datasets/tests.py b/meteos_ui/content/machine_learning/datasets/tests.py
new file mode 100644
index 0000000..88dfd86
--- /dev/null
+++ b/meteos_ui/content/machine_learning/datasets/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class DatasetTests(test.TestCase):
17 # Unit tests for Dataset.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/datasets/urls.py b/meteos_ui/content/machine_learning/datasets/urls.py
new file mode 100644
index 0000000..a80a028
--- /dev/null
+++ b/meteos_ui/content/machine_learning/datasets/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("Datasets")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/content/machine_learning/experiments/__init__.py b/meteos_ui/content/machine_learning/experiments/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/experiments/__init__.py
diff --git a/meteos_ui/content/machine_learning/experiments/panel.py b/meteos_ui/content/machine_learning/experiments/panel.py
new file mode 100644
index 0000000..248a79d
--- /dev/null
+++ b/meteos_ui/content/machine_learning/experiments/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class Experiments(horizon.Panel):
22 name = _("Experiments")
23 slug = "machine_learning.experiments"
diff --git a/meteos_ui/content/machine_learning/experiments/tests.py b/meteos_ui/content/machine_learning/experiments/tests.py
new file mode 100644
index 0000000..a4745b1
--- /dev/null
+++ b/meteos_ui/content/machine_learning/experiments/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class ExperimentTests(test.TestCase):
17 # Unit tests for Experiment.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/experiments/urls.py b/meteos_ui/content/machine_learning/experiments/urls.py
new file mode 100644
index 0000000..ce771ab
--- /dev/null
+++ b/meteos_ui/content/machine_learning/experiments/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("Experiments")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/content/machine_learning/learnings/__init__.py b/meteos_ui/content/machine_learning/learnings/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/learnings/__init__.py
diff --git a/meteos_ui/content/machine_learning/learnings/panel.py b/meteos_ui/content/machine_learning/learnings/panel.py
new file mode 100644
index 0000000..3820987
--- /dev/null
+++ b/meteos_ui/content/machine_learning/learnings/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class Learnings(horizon.Panel):
22 name = _("Learnings")
23 slug = "machine_learning.learnings"
diff --git a/meteos_ui/content/machine_learning/learnings/tests.py b/meteos_ui/content/machine_learning/learnings/tests.py
new file mode 100644
index 0000000..58105ba
--- /dev/null
+++ b/meteos_ui/content/machine_learning/learnings/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class LearningTests(test.TestCase):
17 # Unit tests for Learning.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/learnings/urls.py b/meteos_ui/content/machine_learning/learnings/urls.py
new file mode 100644
index 0000000..1cb32ca
--- /dev/null
+++ b/meteos_ui/content/machine_learning/learnings/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("Learnings")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/content/machine_learning/model_evaluations/__init__.py b/meteos_ui/content/machine_learning/model_evaluations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/model_evaluations/__init__.py
diff --git a/meteos_ui/content/machine_learning/model_evaluations/panel.py b/meteos_ui/content/machine_learning/model_evaluations/panel.py
new file mode 100644
index 0000000..ee60aa5
--- /dev/null
+++ b/meteos_ui/content/machine_learning/model_evaluations/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class ModelEvaluations(horizon.Panel):
22 name = _("ModelEvaluations")
23 slug = "machine_learning.model_evaluations"
diff --git a/meteos_ui/content/machine_learning/model_evaluations/tests.py b/meteos_ui/content/machine_learning/model_evaluations/tests.py
new file mode 100644
index 0000000..7b82268
--- /dev/null
+++ b/meteos_ui/content/machine_learning/model_evaluations/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class ModelEvaluationTests(test.TestCase):
17 # Unit tests for ModelEvaluation.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/model_evaluations/urls.py b/meteos_ui/content/machine_learning/model_evaluations/urls.py
new file mode 100644
index 0000000..ad640eb
--- /dev/null
+++ b/meteos_ui/content/machine_learning/model_evaluations/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("ModelEvaluations")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/content/machine_learning/models/__init__.py b/meteos_ui/content/machine_learning/models/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/models/__init__.py
diff --git a/meteos_ui/content/machine_learning/models/panel.py b/meteos_ui/content/machine_learning/models/panel.py
new file mode 100644
index 0000000..8b5a649
--- /dev/null
+++ b/meteos_ui/content/machine_learning/models/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class Models(horizon.Panel):
22 name = _("Models")
23 slug = "machine_learning.models"
diff --git a/meteos_ui/content/machine_learning/models/tests.py b/meteos_ui/content/machine_learning/models/tests.py
new file mode 100644
index 0000000..3406af1
--- /dev/null
+++ b/meteos_ui/content/machine_learning/models/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class ModelTests(test.TestCase):
17 # Unit tests for Model.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/models/urls.py b/meteos_ui/content/machine_learning/models/urls.py
new file mode 100644
index 0000000..dacfe3c
--- /dev/null
+++ b/meteos_ui/content/machine_learning/models/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("Models")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/content/machine_learning/templates/__init__.py b/meteos_ui/content/machine_learning/templates/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/content/machine_learning/templates/__init__.py
diff --git a/meteos_ui/content/machine_learning/templates/panel.py b/meteos_ui/content/machine_learning/templates/panel.py
new file mode 100644
index 0000000..786749a
--- /dev/null
+++ b/meteos_ui/content/machine_learning/templates/panel.py
@@ -0,0 +1,23 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14import horizon
15
16# This panel will be loaded from horizon, because specified in enabled file.
17# To register REST api, import below here.
18from meteos_ui.api import rest_api # noqa
19
20
21class Templates(horizon.Panel):
22 name = _("Templates")
23 slug = "machine_learning.templates"
diff --git a/meteos_ui/content/machine_learning/templates/tests.py b/meteos_ui/content/machine_learning/templates/tests.py
new file mode 100644
index 0000000..9a8e20f
--- /dev/null
+++ b/meteos_ui/content/machine_learning/templates/tests.py
@@ -0,0 +1,19 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from openstack_dashboard.test import helpers as test
14
15
16class TemplateTests(test.TestCase):
17 # Unit tests for Template.
18 def test_me(self):
19 self.assertTrue(1 + 1 == 2)
diff --git a/meteos_ui/content/machine_learning/templates/urls.py b/meteos_ui/content/machine_learning/templates/urls.py
new file mode 100644
index 0000000..c64eab2
--- /dev/null
+++ b/meteos_ui/content/machine_learning/templates/urls.py
@@ -0,0 +1,20 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.conf.urls import url
14from django.utils.translation import ugettext_lazy as _
15from horizon.browsers import views
16
17title = _("Templates")
18urlpatterns = [
19 url('', views.AngularIndexView.as_view(title=title), name='index'),
20]
diff --git a/meteos_ui/enabled/_1710_machine_learning_panel_group.py b/meteos_ui/enabled/_1710_machine_learning_panel_group.py
new file mode 100644
index 0000000..7834cdd
--- /dev/null
+++ b/meteos_ui/enabled/_1710_machine_learning_panel_group.py
@@ -0,0 +1,36 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13from django.utils.translation import ugettext_lazy as _
14
15# The slug of the panel group to be added to HORIZON_CONFIG. Required.
16PANEL_GROUP = 'machine_learning'
17# The display name of the PANEL_GROUP. Required.
18PANEL_GROUP_NAME = _('Machine Learning')
19# The slug of the dashboard the PANEL_GROUP associated with. Required.
20PANEL_GROUP_DASHBOARD = 'project'
21
22ADD_INSTALLED_APPS = ['meteos_ui']
23
24ADD_ANGULAR_MODULES = [
25 'horizon.dashboard.machine_learning'
26]
27
28ADD_JS_FILES = [
29 'horizon/lib/angular/angular-route.js'
30]
31
32ADD_SCSS_FILES = [
33 'dashboard/machine_learning/machine_learning.scss'
34]
35
36AUTO_DISCOVER_STATIC_FILES = True
diff --git a/meteos_ui/enabled/_1720_machine_learning_templates_panel.py b/meteos_ui/enabled/_1720_machine_learning_templates_panel.py
new file mode 100644
index 0000000..030cd6e
--- /dev/null
+++ b/meteos_ui/enabled/_1720_machine_learning_templates_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.templates'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.templates.panel.Templates'
diff --git a/meteos_ui/enabled/_1730_machine_learning_experiments_panel.py b/meteos_ui/enabled/_1730_machine_learning_experiments_panel.py
new file mode 100644
index 0000000..781b0f0
--- /dev/null
+++ b/meteos_ui/enabled/_1730_machine_learning_experiments_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.experiments'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.experiments.panel.Experiments'
diff --git a/meteos_ui/enabled/_1740_machine_learning_datasets_panel.py b/meteos_ui/enabled/_1740_machine_learning_datasets_panel.py
new file mode 100644
index 0000000..4dbc29a
--- /dev/null
+++ b/meteos_ui/enabled/_1740_machine_learning_datasets_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.datasets'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.datasets.panel.Datasets'
diff --git a/meteos_ui/enabled/_1750_machine_learning_models_panel.py b/meteos_ui/enabled/_1750_machine_learning_models_panel.py
new file mode 100644
index 0000000..e673399
--- /dev/null
+++ b/meteos_ui/enabled/_1750_machine_learning_models_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.models'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.models.panel.Models'
diff --git a/meteos_ui/enabled/_1760_machine_learning_model_evaluations_panel.py b/meteos_ui/enabled/_1760_machine_learning_model_evaluations_panel.py
new file mode 100644
index 0000000..7792c96
--- /dev/null
+++ b/meteos_ui/enabled/_1760_machine_learning_model_evaluations_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.model_evaluations'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.model_evaluations.panel.ModelEvaluations'
diff --git a/meteos_ui/enabled/_1770_machine_learning_learnings_panel.py b/meteos_ui/enabled/_1770_machine_learning_learnings_panel.py
new file mode 100644
index 0000000..ebc4da4
--- /dev/null
+++ b/meteos_ui/enabled/_1770_machine_learning_learnings_panel.py
@@ -0,0 +1,21 @@
1# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13# The slug of the panel to be added to HORIZON_CONFIG. Required.
14PANEL = 'machine_learning.learnings'
15# The slug of the panel group the PANEL is associated with.
16PANEL_GROUP = 'machine_learning'
17# The slug of the dashboard the PANEL associated with. Required.
18PANEL_DASHBOARD = 'project'
19
20# Python panel class of the PANEL to be added.
21ADD_PANEL = 'meteos_ui.content.machine_learning.learnings.panel.Learnings'
diff --git a/meteos_ui/enabled/__init__.py b/meteos_ui/enabled/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meteos_ui/enabled/__init__.py
diff --git a/meteos_ui/karma.conf.js b/meteos_ui/karma.conf.js
new file mode 100644
index 0000000..c4e8b5b
--- /dev/null
+++ b/meteos_ui/karma.conf.js
@@ -0,0 +1,154 @@
1/*
2 * Licensed under the Apache License, Version 2.0 (the 'License');
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an 'AS IS' BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15'use strict';
16
17var fs = require('fs');
18var path = require('path');
19
20module.exports = function (config) {
21 // This tox venv is setup in the post-install npm step
22 var toxPath = '../.tox/py27/lib/python2.7/site-packages/';
23
24 config.set({
25 preprocessors: {
26 // Used to collect templates for preprocessing.
27 // NOTE: the templates must also be listed in the files section below.
28 './static/**/*.html': ['ng-html2js'],
29 // Used to indicate files requiring coverage reports.
30 './static/**/!(*.spec).js': ['coverage'],
31 },
32
33 // Sets up module to process templates.
34 ngHtml2JsPreprocessor: {
35 prependPrefix: '/',
36 moduleName: 'templates'
37 },
38
39 basePath: './',
40
41 // Contains both source and test files.
42 files: [
43 /*
44 * shim, partly stolen from /i18n/js/horizon/
45 * Contains expected items not provided elsewhere (dynamically by
46 * Django or via jasmine template.
47 */
48 '../test-shim.js',
49
50 // from jasmine.html
51 toxPath + 'xstatic/pkg/jquery/data/jquery.js',
52 toxPath + 'xstatic/pkg/angular/data/angular.js',
53 toxPath + 'xstatic/pkg/angular/data/angular-route.js',
54 toxPath + 'xstatic/pkg/angular/data/angular-mocks.js',
55 toxPath + 'xstatic/pkg/angular/data/angular-cookies.js',
56 toxPath + 'xstatic/pkg/angular_bootstrap/data/angular-bootstrap.js',
57 toxPath + 'xstatic/pkg/angular_gettext/data/angular-gettext.js',
58 toxPath + 'xstatic/pkg/angular_fileupload/data/ng-file-upload-all.js',
59 toxPath + 'xstatic/pkg/angular/data/angular-sanitize.js',
60 toxPath + 'xstatic/pkg/d3/data/d3.js',
61 toxPath + 'xstatic/pkg/rickshaw/data/rickshaw.js',
62 toxPath + 'xstatic/pkg/angular_smart_table/data/smart-table.js',
63 toxPath + 'xstatic/pkg/angular_lrdragndrop/data/lrdragndrop.js',
64 toxPath + 'xstatic/pkg/spin/data/spin.js',
65 toxPath + 'xstatic/pkg/spin/data/spin.jquery.js',
66 toxPath + 'xstatic/pkg/tv4/data/tv4.js',
67 toxPath + 'xstatic/pkg/objectpath/data/ObjectPath.js',
68 toxPath + 'xstatic/pkg/angular_schema_form/data/schema-form.js',
69
70 // TODO: These should be mocked.
71 toxPath + '/horizon/static/horizon/js/horizon.js',
72
73 /**
74 * Include framework source code from horizon that we need.
75 * Otherwise, karma will not be able to find them when testing.
76 * These files should be mocked in the foreseeable future.
77 */
78 toxPath + 'horizon/static/framework/**/*.module.js',
79 toxPath + 'horizon/static/framework/**/!(*.spec|*.mock).js',
80 toxPath + 'openstack_dashboard/static/**/*.module.js',
81 toxPath + 'openstack_dashboard/static/**/!(*.spec|*.mock).js',
82 toxPath + 'openstack_dashboard/dashboards/**/static/**/*.module.js',
83 toxPath + 'openstack_dashboard/dashboards/**/static/**/!(*.spec|*.mock).js',
84
85 /**
86 * First, list all the files that defines application's angular modules.
87 * Those files have extension of `.module.js`. The order among them is
88 * not significant.
89 */
90 './static/**/*.module.js',
91
92 /**
93 * Followed by other JavaScript files that defines angular providers
94 * on the modules defined in files listed above. And they are not mock
95 * files or spec files defined below. The order among them is not
96 * significant.
97 */
98 './static/**/!(*.spec|*.mock).js',
99
100 /**
101 * Then, list files for mocks with `mock.js` extension. The order
102 * among them should not be significant.
103 */
104 toxPath + 'openstack_dashboard/static/**/*.mock.js',
105 //'./static/**/*.mock.js',
106
107 /**
108 * Finally, list files for spec with `spec.js` extension. The order
109 * among them should not be significant.
110 */
111 './static/**/*.spec.js',
112
113 /**
114 * Angular external templates
115 */
116 './static/**/*.html'
117 ],
118
119 autoWatch: true,
120
121 frameworks: ['jasmine'],
122
123 browsers: ['Chrome'],
124
125 phantomjsLauncher: {
126 // Have phantomjs exit if a ResourceError is encountered
127 // (useful if karma exits without killing phantom)
128 exitOnResourceError: true
129 },
130
131 reporters: ['progress', 'coverage', 'threshold'],
132
133 plugins: [
134 'karma-chrome-launcher',
135 'karma-jasmine',
136 'karma-ng-html2js-preprocessor',
137 'karma-coverage',
138 'karma-threshold-reporter'
139 ],
140
141 coverageReporter: {
142 type: 'html',
143 dir: '../cover/meteos_ui'
144 },
145
146 // Coverage threshold values.
147 thresholdReporter: {
148 statements: 45,
149 branches: 0,
150 functions: 15,
151 lines: 45
152 }
153 });
154};
diff --git a/meteos_ui/models.py b/meteos_ui/models.py
new file mode 100644
index 0000000..1b3d5f9
--- /dev/null
+++ b/meteos_ui/models.py
@@ -0,0 +1,3 @@
1"""
2Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
3"""
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/actions.module.js b/meteos_ui/static/dashboard/machine_learning/datasets/actions.module.js
new file mode 100644
index 0000000..2502f8e
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/actions.module.js
@@ -0,0 +1,66 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc overview
20 * @ngname horizon.dashboard.machine_learning.datasets.actions
21 *
22 * @description
23 * Provides all of the actions for datasets.
24 */
25 angular.module('horizon.dashboard.machine_learning.datasets.actions', ['horizon.framework', 'horizon.dashboard.machine_learning'])
26 .run(registerDatasetActions);
27
28 registerDatasetActions.$inject = [
29 'horizon.framework.conf.resource-type-registry.service',
30 'horizon.framework.util.i18n.gettext',
31 'horizon.dashboard.machine_learning.datasets.create.service',
32 'horizon.dashboard.machine_learning.datasets.delete.service',
33 'horizon.dashboard.machine_learning.datasets.resourceType',
34 ];
35
36 function registerDatasetActions(
37 registry,
38 gettext,
39 createDatasetService,
40 deleteDatasetService,
41 resourceType)
42 {
43 var datasetsResourceType = registry.getResourceType(resourceType);
44
45 datasetsResourceType.globalActions
46 .append({
47 id: 'createDatasetAction',
48 service: createDatasetService,
49 template: {
50 type: 'create',
51 text: gettext('Create Dataset')
52 }
53 });
54
55 datasetsResourceType.batchActions
56 .append({
57 id: 'batchDeleteDatasetAction',
58 service: deleteDatasetService,
59 template: {
60 type: 'delete-selected',
61 text: gettext('Delete Datasets')
62 }
63 });
64 }
65
66})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/create-workflow.service.js b/meteos_ui/static/dashboard/machine_learning/datasets/create/create-workflow.service.js
new file mode 100644
index 0000000..7454e1d
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/create-workflow.service.js
@@ -0,0 +1,56 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 angular
19 .module('horizon.dashboard.machine_learning.datasets')
20 .factory('horizon.dashboard.machine_learning.datasets.workflow', datasetWorkflow);
21
22 datasetWorkflow.$inject = [
23 'horizon.dashboard.machine_learning.basePath',
24 'horizon.app.core.workflow.factory',
25 'horizon.framework.util.i18n.gettext'
26 ];
27
28 function datasetWorkflow(basePath, dashboardWorkflow, gettext) {
29 return dashboardWorkflow({
30 title: gettext('Create Dataset'),
31
32 steps: [
33 {
34 title: gettext('Info'),
35 templateUrl: basePath + 'datasets/create/info/info.html',
36 helpUrl: basePath + 'datasets/create/info/info.help.html',
37 formName: 'datasetInfoForm'
38 },
39 {
40 title: gettext('Spec'),
41 templateUrl: basePath + 'datasets/create/spec/spec.html',
42 helpUrl: basePath + 'datasets/create/spec/spec.help.html',
43 formName: 'datasetSpecForm'
44 },
45 ],
46
47 btnText: {
48 finish: gettext('Create')
49 },
50
51 btnIcon: {
52 finish: 'fa fa-check'
53 }
54 });
55 }
56})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/create.service.js b/meteos_ui/static/dashboard/machine_learning/datasets/create/create.service.js
new file mode 100644
index 0000000..e1e1612
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/create.service.js
@@ -0,0 +1,97 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc overview
20 * @name horizon.dashboard.machine_learning.datasets.create.service
21 * @description Service for the dataset create modal
22 */
23 angular
24 .module('horizon.dashboard.machine_learning.datasets')
25 .factory('horizon.dashboard.machine_learning.datasets.create.service', createService);
26
27 createService.$inject = [
28 '$location',
29 'horizon.app.core.openstack-service-api.policy',
30 'horizon.framework.util.actions.action-result.service',
31 'horizon.framework.util.i18n.gettext',
32 'horizon.framework.util.q.extensions',
33 'horizon.framework.widgets.modal.wizard-modal.service',
34 'horizon.framework.widgets.toast.service',
35 'horizon.dashboard.machine_learning.datasets.datasetModel',
36 'horizon.dashboard.machine_learning.datasets.events',
37 'horizon.dashboard.machine_learning.datasets.resourceType',
38 'horizon.dashboard.machine_learning.datasets.workflow'
39 ];
40
41 function createService(
42 $location, policy, actionResult, gettext, $qExtensions, wizardModalService, toast, model, events, resourceType, createWorkflow
43 ) {
44 var scope;
45 var message = {
46 success: gettext('Dataset %s was successfully created.')
47 };
48
49 var service = {
50 initAction: initAction,
51 perform: perform,
52 allowed: allowed
53 };
54
55 return service;
56
57 //////////////
58
59 function initAction() {
60 }
61
62 function perform(selected, newScope) {
63 scope = newScope;
64 scope.workflow = createWorkflow;
65 scope.model = model;
66 scope.model.init();
67 // for creation according to selected item
68 scope.selected = selected;
69 return wizardModalService.modal({
70 scope: scope,
71 workflow: createWorkflow,
72 submit: submit
73 }).result;
74 }
75
76 function allowed() {
77 return $qExtensions.booleanAsPromise(true);
78 //return policy.ifAllowed({ rules: [['dataset', 'add_dataset']] });
79 }
80
81 function submit(){
82 return model.createDataset().then(success);
83 }
84
85 function success(response) {
86 response.data.id = response.data.id;
87 toast.add('success', interpolate(message.success, [response.data.id]));
88 var result = actionResult.getActionResult()
89 .created(resourceType, response.data.id);
90 if(result.result.failed.length == 0 && result.result.created.length > 0){
91 $location.path('/project/machine_learning/datasets');
92 }else{
93 return result.result;
94 }
95 }
96 }
97})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/dataset-model.js b/meteos_ui/static/dashboard/machine_learning/datasets/create/dataset-model.js
new file mode 100644
index 0000000..3c06217
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/dataset-model.js
@@ -0,0 +1,75 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 angular
19 .module('horizon.dashboard.machine_learning.datasets')
20 .factory('horizon.dashboard.machine_learning.datasets.datasetModel', datasetModel);
21
22 datasetModel.$inject = [
23 'horizon.app.core.openstack-service-api.meteos'
24 ];
25
26 function datasetModel(meteos) {
27 var model = {
28 newDatasetSpec: {},
29
30 // API methods
31 init: init,
32 createDataset: createDataset
33 };
34
35 function initNewDatasetSpec() {
36 model.newDatasetSpec = {
37 method: null,
38 display_name: null,
39 display_description: null,
40 source_dataset_url: null,
41 experiment_id: null,
42 params: null,
43 swift_tenant: null,
44 swift_username: null,
45 swift_password: null
46 };
47 }
48
49 function init() {
50 // Reset the new Dataset spec
51 initNewDatasetSpec();
52 }
53
54 function createDataset() {
55 var finalSpec = angular.copy(model.newDatasetSpec);
56
57 cleanNullProperties(finalSpec);
58
59 return meteos.createDataset(finalSpec);
60 }
61
62 function cleanNullProperties(finalSpec) {
63 // Initially clean fields that don't have any value.
64 // Not only "null", blank too.
65 for (var key in finalSpec) {
66 if (finalSpec.hasOwnProperty(key) && finalSpec[key] === null
67 || finalSpec[key] === "") {
68 delete finalSpec[key];
69 }
70 }
71 }
72
73 return model;
74 }
75})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.help.html b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.help.html
new file mode 100644
index 0000000..466e501
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.help.html
@@ -0,0 +1,8 @@
1<dl>
2 <dt translate>Dataset Name</dt>
3 <dd translate>An arbitrary human-readable name.</dd>
4 <dt translate>Dataset Description</dt>
5 <dd translate>An arbitrary human-readable description.</dd>
6 <dt translate>Template</dt>
7 <dd translate>Name or ID of dataset template.</dd>
8</dl>
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.html b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.html
new file mode 100644
index 0000000..6fdc3cf
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/info.html
@@ -0,0 +1,32 @@
1<div ng-controller="createDatasetInfoController as ctrl">
2 <div class="row">
3 <div class="col-xs-12">
4 <div class="form-group">
5 <label class="control-label" for="dataset-name" translate>Dataset Name</label>
6 <input name="dataset-name" type="text" class="form-control" id="dataset-name"
7 ng-model="model.newDatasetSpec.display_name"
8 placeholder="{$ 'Name of the dataset to create.'|translate $}">
9 </div>
10 </div>
11 <div class="col-xs-12">
12 <div class="form-group">
13 <label class="control-label" for="dataset-description" translate>Dataset Description</label>
14 <input name="dataset-description" type="text" class="form-control" id="dataset-description"
15 ng-model="model.newDatasetSpec.display_description"
16 placeholder="{$ 'Description of the dataset to create.'|translate $}">
17 </div>
18 </div>
19 <div class="col-xs-12">
20 <div class="form-group">
21 <label class="control-label" for="dataset-experiment-id">
22 <translate>Experiment</translate>
23 <span class="hz-icon-required fa fa-asterisk"></span>
24 </label>
25 <input name="dataset-experiment-id" type="text" class="form-control" id="dataset-experiment-id"
26 ng-model="model.newDatasetSpec.experiment_id"
27 ng-required="true"
28 placeholder="{$ 'ID of the experiment.'|translate $}">
29 </div>
30 </div>
31 </div>
32</div>
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/info/template.info.controller.js b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/template.info.controller.js
new file mode 100644
index 0000000..de3f4b9
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/info/template.info.controller.js
@@ -0,0 +1,34 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc controller
20 * @name createDatasetInfoController
21 * @ngController
22 * @description
23 * Controller for the dataset info step in create workflow
24 */
25 angular
26 .module('horizon.dashboard.machine_learning.datasets')
27 .controller('createDatasetInfoController', createDatasetInfoController);
28
29 createDatasetInfoController.$inject = [
30 ];
31
32 function createDatasetInfoController() {
33 }
34})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.help.html b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.help.html
new file mode 100644
index 0000000..f20f2f6
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.help.html
@@ -0,0 +1,14 @@
1<dl>
2 <dt translate>Spark Version</dt>
3 <dd translate> Version of Apache Spark.</dd>
4 <dt translate>Master Nodes</dt>
5 <dd translate> Number of Master Node.</dd>
6 <dt translate>Master Flavor</dt>
7 <dd translate> Flavor ID of Master Node.</dd>
8 <dt translate>Worker Nodes</dt>
9 <dd translate> Number of Worker Node.</dd>
10 <dt translate>Worker Flavor</dt>
11 <dd translate> Flavor ID of Worker Node.</dd>
12 <dt translate>Floating IP Pool</dt>
13 <dd translate> The UUID of Neutron External Network.</dd>
14</dl>
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.html b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.html
new file mode 100644
index 0000000..6826812
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/spec.html
@@ -0,0 +1,76 @@
1<div ng-controller="createDatasetSpecController as ctrl">
2 <div class="row">
3 <div class="col-xs-12">
4 <div class="form-group">
5 <label class="control-label" for="dataset-method">
6 <translate>Method</translate>
7 <span class="hz-icon-required fa fa-asterisk"></span>
8 </label>
9 <div class="form-field">
10 <div class="btn-group">
11 <label class="btn btn-default"
12 ng-repeat="option in ctrl.datasetMethodOptions"
13 ng-model="model.newDatasetSpec.method"
14 uib-btn-radio="option.value">{$ ::option.label $}</label>
15 </div>
16 </div>
17 </div>
18 </div>
19 <div class="col-xs-12">
20 <div class="form-group">
21 <label class="control-label" for="dataset-source-dataset-url">
22 <translate>Source Dataset URL</translate>
23 <span class="hz-icon-required fa fa-asterisk"></span>
24 </label>
25 <input name="dataset-source-dataset-url" type="text" class="form-control" id="dataset-source-dataset-url"
26 ng-model="model.newDatasetSpec.source_dataset_url"
27 ng-required="true"
28 placeholder="{$ 'URL of Dataset stored Swift of Internal HDFS.'|translate $}">
29 </div>
30 </div>
31 <div class="col-xs-12">
32 <div class="form-group">
33 <label class="control-label" for="dataset-params">
34 <translate>Params</translate>
35 <span class="hz-icon-required fa fa-asterisk"></span>
36 </label>
37 <input name="dataset-params" type="text" class="form-control" id="dataset-params"
38 ng-model="model.newDatasetSpec.params"
39 placeholder="{$ 'Parameters when parsing dataset.'|translate $}">
40 </div>
41 </div>
42 <div class="col-xs-12">
43 <div class="form-group">
44 <label class="control-label" for="dataset-swift-tenant">
45 <translate>Swift Tenant</translate>
46 <span class="hz-icon-required fa fa-asterisk"></span>
47 </label>
48 <input name="dataset-swift-tenant" type="text" class="form-control" id="dataset-swift-tenant"
49 ng-model="model.newDatasetSpec.swift_tenant"
50 placeholder="{$ 'Tenant name of Swift.'|translate $}">
51 </div>
52 </div>
53 <div class="col-xs-12">
54 <div class="form-group">
55 <label class="control-label" for="dataset-swift-username">
56 <translate>Swift User Name</translate>
57 <span class="hz-icon-required fa fa-asterisk"></span>
58 </label>
59 <input name="dataset-swift-username" type="text" class="form-control" id="dataset-swift-username"
60 ng-model="model.newDatasetSpec.swift_username"
61 placeholder="{$ 'User name of Swift.'|translate $}">
62 </div>
63 </div>
64 <div class="col-xs-12">
65 <div class="form-group">
66 <label class="control-label" for="dataset-swift-password">
67 <translate>Swift User Password</translate>
68 <span class="hz-icon-required fa fa-asterisk"></span>
69 </label>
70 <input name="dataset-swift-password" type="text" class="form-control" id="dataset-swift-password"
71 ng-model="model.newDatasetSpec.swift_password"
72 placeholder="{$ 'Password of Swift User.'|translate $}">
73 </div>
74 </div>
75 </div>
76</div>
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/template.spec.controller.js b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/template.spec.controller.js
new file mode 100644
index 0000000..074b27e
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/create/spec/template.spec.controller.js
@@ -0,0 +1,44 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc controller
20 * @name createDatasetSpecController
21 * @ngController
22 * @description
23 * Controller for the dataset spec step in create workflow
24 */
25 angular
26 .module('horizon.dashboard.machine_learning.datasets')
27 .controller('createDatasetSpecController', createDatasetSpecController);
28
29 createDatasetSpecController.$inject = [
30 '$scope',
31 'horizon.framework.util.i18n.gettext'
32 ];
33
34 function createDatasetSpecController($scope, gettext) {
35 var ctrl = this;
36
37 ctrl.datasetMethodOptions = [
38 { label: gettext('Download'), value: 'download' },
39 { label: gettext('Parse'), value: 'parse' }
40 ];
41
42 }
43
44})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.js b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.js
new file mode 100644
index 0000000..d653559
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.js
@@ -0,0 +1,156 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc overview
20 * @name horizon.dashboard.machine_learning.datasets
21 * @ngModule
22 * @description
23 * Provides all the services and widgets require to display the dataset
24 * panel
25 */
26 angular
27 .module('horizon.dashboard.machine_learning.datasets', [
28 'ngRoute',
29 'horizon.dashboard.machine_learning.datasets.actions'
30 ])
31 .constant('horizon.dashboard.machine_learning.datasets.events', events())
32 .constant('horizon.dashboard.machine_learning.datasets.resourceType', 'OS::Meteos::Dataset')
33 .run(run)
34 .config(config);
35
36 /**
37 * @ngdoc constant
38 * @name horizon.dashboard.machine_learning.datasets.events
39 * @description A list of events used by Dataset
40 */
41 function events() {
42 return {
43 CREATE_SUCCESS: 'horizon.dashboard.machine_learning.datasets.CREATE_SUCCESS',
44 DELETE_SUCCESS: 'horizon.dashboard.machine_learning.datasets.DELETE_SUCCESS'
45 };
46 }
47
48 run.$inject = [
49 'horizon.framework.conf.resource-type-registry.service',
50 'horizon.app.core.openstack-service-api.meteos',
51 'horizon.dashboard.machine_learning.datasets.basePath',
52 'horizon.dashboard.machine_learning.datasets.resourceType'
53 ];
54
55 function run(registry, meteos, basePath, resourceType) {
56 registry.getResourceType(resourceType)
57 .setNames(gettext('Machine Learning'), gettext('Datasets'))
58 // for detail summary view on table row.
59 .setSummaryTemplateUrl(basePath + 'details/drawer.html')
60 // for table row items and detail summary view.
61 .setProperty('name', {
62 label: gettext('Name')
63 })
64 .setProperty('id', {
65 label: gettext('ID')
66 })
67 .setProperty('status', {
68 label: gettext('Status')
69 })
70 .setProperty('source_dataset_url', {
71 label: gettext('Source Dataset URL')
72 })
73 .setListFunction(listFunction)
74 .tableColumns
75 .append({
76 id: 'name',
77 priority: 1,
78 sortDefault: true,
79 filters: ['noName'],
80 urlFunction: urlFunction
81 })
82 .append({
83 id: 'id',
84 priority: 3
85 })
86 .append({
87 id: 'status',
88 priority: 2
89 })
90 .append({
91 id: 'source_dataset_url',
92 priority: 2
93 })
94 // for magic-search
95 registry.getResourceType(resourceType).filterFacets
96 .append({
97 'label': gettext('Name'),
98 'name': 'name',
99 'singleton': true
100 })
101 .append({
102 'label': gettext('ID'),
103 'name': 'id',
104 'singleton': true
105 })
106 .append({
107 'label': gettext('Status'),
108 'name': 'status',
109 'singleton': true
110 })
111 .append({
112 'label': gettext('Source Dataset URL'),
113 'name': 'source_dataset_url',
114 'singleton': true
115 });
116
117 function listFunction(params) {
118 return meteos.getDatasets(params).then(modifyResponse);
119
120 function modifyResponse(response) {
121 return {data: {items: response.data.items.map(addTrackBy)}};
122
123 function addTrackBy(item) {
124 item.trackBy = item.id;
125 return item;
126 }
127 }
128 }
129
130 function urlFunction(item) {
131 return 'project/ngdetails/OS::Meteos::Dataset/' + item.id;
132 }
133 }
134
135 config.$inject = [
136 '$provide',
137 '$windowProvider',
138 '$routeProvider'
139 ];
140
141 /**
142 * @name config
143 * @param {Object} $provide
144 * @param {Object} $windowProvider
145 * @param {Object} $routeProvider
146 * @description Routes used by this module.
147 * @returns {undefined} Returns nothing
148 */
149 function config($provide, $windowProvider, $routeProvider) {
150 var path = $windowProvider.$get().STATIC_URL + 'dashboard/machine_learning/datasets/';
151 $provide.constant('horizon.dashboard.machine_learning.datasets.basePath', path);
152 $routeProvider.when('/project/machine_learning/datasets', {
153 templateUrl: path + 'panel.html'
154 });
155 }
156})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.spec.js b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.spec.js
new file mode 100644
index 0000000..c2354aa
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.module.spec.js
@@ -0,0 +1,23 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14(function() {
15 'use strict';
16
17 describe('horizon.dashboard.machine_learning.datasets', function() {
18 it('should exist', function() {
19 expect(angular.module('horizon.dashboard.machine_learning.datasets')).toBeDefined();
20 });
21 });
22
23})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/datasets.scss b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.scss
new file mode 100644
index 0000000..160d1aa
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/datasets.scss
@@ -0,0 +1,3 @@
1.logs {
2 margin-top: 18px;
3} \ No newline at end of file
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/delete/delete.service.js b/meteos_ui/static/dashboard/machine_learning/datasets/delete/delete.service.js
new file mode 100644
index 0000000..91ec49f
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/delete/delete.service.js
@@ -0,0 +1,149 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use self file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 angular
19 .module('horizon.dashboard.machine_learning.datasets')
20 .factory('horizon.dashboard.machine_learning.datasets.delete.service', deleteService);
21
22 deleteService.$inject = [
23 '$location',
24 '$q',
25 'horizon.app.core.openstack-service-api.meteos',
26 'horizon.app.core.openstack-service-api.policy',
27 'horizon.framework.util.actions.action-result.service',
28 'horizon.framework.util.i18n.gettext',
29 'horizon.framework.util.q.extensions',
30 'horizon.framework.widgets.modal.deleteModalService',
31 'horizon.framework.widgets.toast.service',
32 'horizon.dashboard.machine_learning.datasets.resourceType',
33 'horizon.dashboard.machine_learning.datasets.events'
34 ];
35
36 /**
37 * @ngDoc factory
38 * @name horizon.dashboard.machine_learning.datasets.delete.service
39 * @Description
40 * Brings up the delete datasets confirmation modal dialog.
41 * On submit, delete selected resources.
42 * On cancel, do nothing.
43 */
44 function deleteService(
45 $location, $q, meteos, policy, actionResult, gettext, $qExtensions, deleteModal, toast, resourceType, events
46 ) {
47 var scope;
48 var context = {
49 labels: null,
50 deleteEntity: deleteEntity,
51 successEvent: events.DELETE_SUCCESS
52 };
53 var service = {
54 initAction: initAction,
55 allowed: allowed,
56 perform: perform
57 };
58 var notAllowedMessage = gettext("You are not allowed to delete datasets: %s");
59
60 return service;
61
62 //////////////
63
64 function initAction() {
65 }
66
67 function allowed() {
68 return $qExtensions.booleanAsPromise(true);
69 }
70
71 // delete selected resource objects
72 function perform(selected, newScope) {
73 scope = newScope;
74 var selected = angular.isArray(selected) ? selected : [selected];
75 context.labels = labelize(selected.length);
76 return $qExtensions.allSettled(selected.map(checkPermission)).then(afterCheck);
77 }
78
79 function labelize(count){
80 return {
81 title: ngettext('Confirm Delete Dataset',
82 'Confirm Delete Datasets', count),
83 /* eslint-disable max-len */
84 message: ngettext('You have selected "%s". Please confirm your selection. Deleted dataset is not recoverable.',
85 'You have selected "%s". Please confirm your selection. Deleted datasets are not recoverable.', count),
86 /* eslint-enable max-len */
87 submit: ngettext('Delete Dataset',
88 'Delete Datasets', count),
89 success: ngettext('Deleted Dataset: %s.',
90 'Deleted Datasets: %s.', count),
91 error: ngettext('Unable to delete Dataset: %s.',
92 'Unable to delete Datasets: %s.', count)
93 };
94 }
95
96 // for batch delete
97 function checkPermission(selected) {
98 return {promise: allowed(selected), context: selected};
99 }
100
101 // for batch delete
102 function afterCheck(result){
103 var outcome = $q.reject(); // Reject the promise by default
104 if (result.fail.length > 0) {
105 toast.add('error', getMessage(notAllowedMessage, result.fail));
106 outcome = $q.reject(result.fail);
107 }
108 if (result.pass.length > 0) {
109 outcome = deleteModal.open(scope, result.pass.map(getEntity), context).then(createResult);
110 }
111 return outcome;
112 }
113
114 function createResult(deleteModalResult) {
115 // To make the result of this action generically useful, reformat the return
116 // from the deleteModal into a standard form
117 var result = actionResult.getActionResult();
118 deleteModalResult.pass.forEach(function markDeleted(item) {
119 result.deleted(resourceType, getEntity(item).id);
120 });
121 deleteModalResult.fail.forEach(function markFailed(item) {
122 result.failed(resourceType, getEntity(item).id);
123 });
124 if(result.result.failed.length == 0 && result.result.deleted.length > 0){
125 $location.path('/project/machine_learning/datasets');
126 }else{
127 return result.result;
128 }
129 }
130
131 function getMessage(message, entities) {
132 return interpolate(message, [entities.map(getName).join(", ")]);
133 }
134
135 function getName(result) {
136 return getEntity(result).name;
137 }
138
139 // for batch delete
140 function getEntity(result) {
141 return result.context;
142 }
143
144 // call delete REST API
145 function deleteEntity(id){
146 return meteos.deleteDataset(id, true);
147 }
148 }
149})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.controller.js b/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.controller.js
new file mode 100644
index 0000000..9bf8ef6
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.controller.js
@@ -0,0 +1,36 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain
4 * a copy of the License at
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11 * License for the specific language governing permissions and limitations
12 * under the License.
13 */
14
15(function() {
16 'use strict';
17
18 /**
19 * @ngdoc controller
20 * @name horizon.dashboard.machine_learning.datasets.DrawerController
21 * @description
22 * This is the controller for the drawer (summary) view.
23 * Its primary purpose is to provide the metadata definitions to
24 * the dataset via the ctrl.metadataDefs member.
25 */
26 angular
27 .module('horizon.dashboard.machine_learning.datasets')
28 .controller('horizon.dashboard.machine_learning.datasets.DrawerController', controller);
29
30 controller.$inject = [
31 ];
32
33 function controller() {
34 }
35
36})();
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.html b/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.html
new file mode 100644
index 0000000..beddc61
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/details/drawer.html
@@ -0,0 +1,14 @@
1<div ng-controller="horizon.dashboard.machine_learning.datasets.DrawerController as drawerCtrl">
2 <div class="row">
3 <span class="rsp-alt-p3">
4 <dl class="col-md-4">
5 <dt translate>ID</dt>
6 <dd>{$ item.id $}</dd>
7 </dl>
8 <dl class="col-md-4">
9 <dt translate>Description</dt>
10 <dd>{$ item.description $}</dd>
11 </dl>
12 </span>
13 </div>
14</div>
diff --git a/meteos_ui/static/dashboard/machine_learning/datasets/panel.html b/meteos_ui/static/dashboard/machine_learning/datasets/panel.html
new file mode 100644
index 0000000..28e9536
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/datasets/panel.html
@@ -0,0 +1,4 @@
1<hz-resource-panel resource-type-name="OS::Meteos::Dataset">
2 <hz-resource-table resource-type-name="OS::Meteos::Dataset"
3 track-by="trackBy"></hz-resource-table>
4</hz-resource-panel>
diff --git a/meteos_ui/static/dashboard/machine_learning/experiments/actions.module.js b/meteos_ui/static/dashboard/machine_learning/experiments/actions.module.js
new file mode 100644
index 0000000..0dfcea9
--- /dev/null
+++ b/meteos_ui/static/dashboard/machine_learning/experiments/actions.module.js
@@ -0,0 +1,66 @@
1/**
2 * Licensed under the Apache License, Version 2.0 (the "License"); you may
3 * not use this file except in compliance with the License. You may obtain