Browse Source

Resolve "label interface"

Eric Tröbs 4 years ago
parent
commit
748e55f610

+ 1 - 0
.gitignore

@@ -35,4 +35,5 @@ __pycache__/
 # projects and models
 /projects/
 /models/
+/labels/
 dist/

+ 6 - 1
app.py

@@ -2,7 +2,8 @@
 
 from pycs.ApplicationStatus import ApplicationStatus
 from pycs.frontend.WebServer import WebServer
-from pycs.models.ModelManager import ModelManager
+from pycs.projects.LabelManager import LabelManager
+from pycs.projects.ModelManager import ModelManager
 from pycs.projects.ProjectManager import ProjectManager
 
 if __name__ == '__main__':
@@ -14,6 +15,10 @@ if __name__ == '__main__':
     print('- load model manager')
     model_manager = ModelManager(app_status)
 
+    # load label manager
+    print('- load label manager')
+    label_manager = LabelManager(app_status)
+
     # load project manager
     print('- load project manager')
     project_manager = ProjectManager(app_status)

+ 1 - 0
pycs/ApplicationStatus.py

@@ -21,6 +21,7 @@ class ApplicationStatus(ObservableDict):
         super().__init__({
             'settings': settings,
             'models': {},
+            'labels': {},
             'projects': {}
         })
 

+ 1 - 1
pycs/frontend/WebServer.py

@@ -74,7 +74,7 @@ class WebServer:
         @self.__flask.route('/projects', methods=['POST'])
         def create_project():
             data = request.get_json(force=True)
-            app_status['projects'].create_project(data['name'], data['description'], data['model'], data['unmanaged'])
+            app_status['projects'].create_project(data['name'], data['description'], data['model'], data['label'], data['unmanaged'])
 
             return response()
 

+ 36 - 0
pycs/labels/LabelProvider.py

@@ -0,0 +1,36 @@
+import typing
+
+
+class LabelProvider:
+    def __init__(self, root_folder, configuration):
+        """
+        prepare everything needed to provide labels
+
+        :param root_folder: relative path to label folder
+        :param configuration: object parsed from configuration.json
+        """
+        raise NotImplementedError
+
+    def close(self):
+        """
+        is called everytime a label provider is not used anymore
+
+        :return:
+        """
+        raise NotImplementedError
+
+    def get_labels(self) -> typing.List[dict]:
+        """
+        return all available labels
+
+        :return:
+        """
+        raise NotImplementedError
+
+    # TODO documentation
+    @staticmethod
+    def create_label(identifier, name):
+        return {
+            'id': identifier,
+            'name': name
+        }

+ 20 - 0
pycs/projects/LabelManager.py

@@ -0,0 +1,20 @@
+from glob import glob
+from json import load
+from os import path
+
+from pycs import ApplicationStatus
+
+
+class LabelManager:
+    def __init__(self, app_status: ApplicationStatus):
+        # TODO create models folder if it does not exist
+
+        # find labels
+        for folder in glob('labels/*'):
+            # load configuration.json
+            with open(path.join(folder, 'configuration.json'), 'r') as file:
+                label = load(file)
+                label['path'] = folder
+
+                label_id = label['id']
+                app_status['labels'][label_id] = label

+ 0 - 0
pycs/models/ModelManager.py → pycs/projects/ModelManager.py


+ 6 - 4
pycs/projects/Project.py

@@ -130,10 +130,12 @@ class Project(ObservableDict):
     def remove_media_file(self, file_id):
         del self['data'][file_id]
 
-    def add_label(self, name):
-        label_uuid = str(uuid1())
-        self['labels'][label_uuid] = {
-            'id': label_uuid,
+    def add_label(self, name, identifier=None):
+        if identifier is None:
+            identifier = str(uuid1())
+
+        self['labels'][identifier] = {
+            'id': identifier,
             'name': name
         }
 

+ 14 - 1
pycs/projects/ProjectManager.py

@@ -35,7 +35,7 @@ class ProjectManager(ObservableDict):
         with open(path.join('projects', uuid, 'project.json'), 'w') as file:
             dump(copy, file, indent=4)
 
-    def create_project(self, name, description, model, unmanaged=None):
+    def create_project(self, name, description, model, label, unmanaged=None):
         # create dict representation
         uuid = str(uuid1())
 
@@ -58,6 +58,19 @@ class ProjectManager(ObservableDict):
             'jobs': {}
         }, self)
 
+        # add labels if id is valid
+        if label in self.parent['labels']:
+            code_path = path.join(self.parent['labels'][label]['path'], self.parent['labels'][label]['code']['module'])
+            module_name = code_path.replace('/', '.').replace('\\', '.')
+            class_name = self.parent['labels'][label]['code']['class']
+
+            mod = __import__(module_name, fromlist=[class_name])
+            cl = getattr(mod, class_name)
+
+            provider = cl(self.parent['labels'][label]['path'], self.parent['labels'][label])
+            for label in provider.get_labels():
+                self[uuid].add_label(label['name'], identifier=label['id'])
+
         # create project.json
         self.write_project(uuid)
 

+ 2 - 0
test/test_application_status.py

@@ -9,6 +9,7 @@ class TestApplicationStatus(unittest.TestCase):
         self.assertEqual({
             'settings': {},
             'models': {},
+            'labels': {},
             'projects': {}
         }, aso)
 
@@ -22,6 +23,7 @@ class TestApplicationStatus(unittest.TestCase):
         self.assertEqual({
             'settings': settings,
             'models': {},
+            'labels': {},
             'projects': {}
         }, aso)
 

+ 23 - 0
webui/src/components/projects/project-creation-window.vue

@@ -33,6 +33,11 @@
         </ul>
       </div>
 
+      <select-input :values="labels"
+                    v-model="label">
+        Label Provider
+      </select-input>
+
       <text-input placeholder="path to folder (leave empty to disable)"
                   v-model="unmanaged">
         Unmanaged Storage
@@ -75,6 +80,7 @@ export default {
       description: '',
       descriptionError: false,
       model: null,
+      label: null,
       unmanaged: ''
     }
   },
@@ -101,6 +107,22 @@ export default {
 
       return result;
     },
+    labels: function () {
+      let result = [{
+        'id': null,
+        'name': 'None'
+      }];
+
+      for (let o in this.status.labels) {
+        result.push({
+          'id': this.status.labels[o].id,
+          'name': this.status.labels[o].name,
+          'value': this.status.labels[o].id,
+        });
+      }
+
+      return result;
+    },
     current: function () {
       for (let model of this.models) {
         if (model.id === this.model) {
@@ -127,6 +149,7 @@ export default {
         name: this.name,
         description: this.description,
         model: this.model,
+        label: this.label,
         unmanaged: this.unmanaged === '' ? null : this.unmanaged
       });
       this.$emit('cancel', null);