first commit
[osm/LW-UI.git] / projecthandler / models.py
diff --git a/projecthandler/models.py b/projecthandler/models.py
new file mode 100644 (file)
index 0000000..66fb7a5
--- /dev/null
@@ -0,0 +1,333 @@
+#
+#   Copyright 2017 CNIT - Consorzio Nazionale Interuniversitario per le Telecomunicazioni
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an  BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils import timezone
+import jsonfield
+from StringIO import StringIO
+import zipfile
+import json
+import yaml
+from lib.util import Util
+from model_utils.managers import InheritanceManager
+import logging
+import os, shutil
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger('models.py')
+
+project_types = {}
+
+
+class Project(models.Model):
+    """ Base class for project types
+
+    data_project stores a validated JSON representation of the project
+    get_dataproject() method returns the python dict representation of the project
+
+
+    """
+    owner = models.ForeignKey('sf_user.CustomUser', db_column='owner')
+    name = models.CharField(max_length=20, default='')
+    created_date = models.DateTimeField(default=timezone.now)
+    updated_date = models.DateTimeField(default=timezone.now, blank=True, null=True)
+    info = models.TextField(default='No info')
+    data_project = jsonfield.JSONField(default={})
+    """Stores a validated JSON representation of the project"""
+
+    validated = models.BooleanField(default=False)
+
+    #InheritanceManager
+    objects = InheritanceManager()
+   
+
+    @classmethod
+    def get_project_types(cls):
+        global project_types
+        return project_types        
+
+    @classmethod
+    def add_project_type(cls, type, my_class):
+        global project_types
+        project_types [type]= my_class
+
+
+    @classmethod
+    def create_project(cls, name, user, validated, info, data_project):
+        project = cls.objects.create(name=name, owner=user, validated=False, info=info,
+                                                       data_project=data_project)
+        return project
+
+    @classmethod
+    def get_graph_model(cls, file_path):
+        """Returns the model of the graph of the project type as a yaml object
+
+        Returns an empty dict if there is no file with the model
+        """
+        # file_path = GRAPH_MODEL_FULL_NAME
+        graph_model = {}
+        try:
+            graph_model = Util.loadyamlfile(file_path)
+        except Exception as e:
+            log.exception(e)
+            pass
+        return graph_model       
+
+    def get_type(self):
+        return "Base"
+
+    #@classmethod
+    def get_dataproject(self):
+        """ Return the python dict representation of the project data
+
+        """
+        #current_data = json.loads(self.data_project)
+        current_data = Util.json_loads_byteified(self.data_project)
+
+        return current_data
+
+    #@classmethod
+    def get_overview_data(self):
+        result = {
+            'owner': self.owner,
+            'name': self.name,
+            'updated_date': self.updated_date,
+            'info': self.info,
+            'validated': self.validated
+        }
+
+        return result
+
+    def set_data_project(self, new_data, validated):
+        self.data_project = new_data
+        self.set_validated(validated)
+        self.update()
+
+    def update(self):
+        self.updated_date = timezone.now()
+        self.save()
+
+    def __str__(self):
+        return self.name
+
+    def edit_graph_positions(self, positions):
+        # print positions
+        try:
+            current_data = json.loads(self.data_project)
+            if 'positions' not in current_data:
+                current_data['positions'] = {}
+            if 'vertices' not in current_data['positions']:
+                current_data['positions']['vertices'] = {}
+            if 'vertices' in positions:
+                current_data['positions']['vertices'].update(positions['vertices'])
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def get_descriptors(self, type_descriptor):
+        """Returns all descriptors of a given type"""
+
+        try:
+            current_data = json.loads(self.data_project)
+            result = current_data[type_descriptor]
+        except Exception as e:
+            log.debug(e)
+            result = {}
+        return result
+
+    def get_descriptor(self, descriptor_id, type_descriptor):
+        """Returns a specific descriptor"""
+
+        try:
+            current_data = json.loads(self.data_project)
+            result = current_data[type_descriptor][descriptor_id]
+            print descriptor_id, type_descriptor, result
+        except Exception as e:
+            log.debug(e)
+            result = {}
+
+        return result
+
+    def delete_descriptor(self, type_descriptor, descriptor_id):
+        try:
+            log.debug('delete descriptor'+ descriptor_id + ' ' + type_descriptor)
+            current_data = json.loads(self.data_project)
+            del (current_data[type_descriptor][descriptor_id])
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def clone_descriptor(self, type_descriptor, descriptor_id, new_id):
+        try:
+            current_data = json.loads(self.data_project)
+            descriptor = current_data[type_descriptor][descriptor_id]
+            new_descriptor = self.get_clone_descriptor(descriptor, type_descriptor, new_id)
+            current_data[type_descriptor][new_id] = new_descriptor
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def edit_descriptor(self, type_descriptor, descriptor_id, new_data, data_type):
+        try:
+
+            ##FIXME questa parte va completamente rivista cosi' ha varie lacune
+            #log.info('editing ',+ descriptor_id + ' ' + type_descriptor + ' ' + data_type)
+            current_data = json.loads(self.data_project)
+            new_descriptor = new_data
+            if data_type == 'json':
+                new_descriptor = json.loads(new_data)
+            elif data_type == 'yaml':
+                yaml_object = yaml.load(new_data)
+                new_descriptor = json.loads(Util.yaml2json(yaml_object))
+            if type_descriptor != 'click' and type_descriptor != 'oshi' and type_descriptor !='cran':
+                reference_schema = self.get_json_schema_by_type(type_descriptor)
+                Util.validate_json_schema(reference_schema, new_descriptor)
+            current_data[type_descriptor][descriptor_id] = new_descriptor
+            self.data_project = current_data
+            self.update()
+            result = True
+        except Exception as e:
+            log.debug(e)
+            result = False
+        return result
+
+    def get_zip_archive(self):
+        in_memory = StringIO()
+        try:
+            current_data = json.loads(self.data_project)
+            zip = zipfile.ZipFile(in_memory, "w", zipfile.ZIP_DEFLATED)
+            for desc_type in current_data:
+                for current_desc in current_data[desc_type]:
+                    zip.writestr(current_desc + '.json', json.dumps(current_data[desc_type][current_desc]))
+
+            zip.close()
+        except Exception as e:
+            log.debug(e)
+
+        in_memory.flush()
+        return in_memory
+
+    def get_positions(self):
+        """Returns the positions of nodes"""
+        try:
+            current_data = json.loads(self.data_project)
+            positions = {}
+            if 'positions' in current_data:
+                positions = current_data['positions']
+        except Exception as e:
+            log.debug(e)
+
+        return positions
+
+    def get_deployment_descriptor(self, **kwargs):
+        """Returns the deployment descriptor"""
+        raise NotImplementedError
+
+    def get_node_overview(self, **kwargs):
+        """Returns the node overview"""
+        raise NotImplementedError
+
+    def get_all_ns_descriptors(self, nsd_id):
+        raise NotImplementedError
+
+    def translate_push_ns_on_repository(self, translator, nsd_id, repository, **kwargs):
+        raise NotImplementedError
+
+
+class ProjectStateless(Project):
+
+    def get_descriptors(self, type_descriptor):
+        """Returns all descriptors of a given type"""
+        raise NotImplementedError
+
+    def delete_descriptor(self, type_descriptor, descriptor_id):
+        raise NotImplementedError
+
+    def get_all_ns_descriptors(self, nsd_id):
+        pass
+
+    def translate_push_ns_on_repository(self, translator, nsd_id, repository, **kwargs):
+        pass
+
+    def get_deployment_descriptor(self, **kwargs):
+        pass
+
+    def get_node_overview(self, **kwargs):
+        pass
+
+    def get_dataproject(self):
+        raise NotImplementedError
+
+    def get_overview_data(self):
+        raise NotImplementedError
+
+class Repository(models.Model):
+    """ Repository
+    """
+    name = models.CharField(max_length=20, default='')
+    base_url = models.TextField(default='')
+    last_update = models.DateTimeField(default=timezone.now)
+    DIR_NAME = "/tmp/git_repo/"
+
+    def fetch_repository(self):
+        """
+        :return: git.remote.FetchInfo object
+        """
+        if os.path.isdir(self.DIR_NAME):
+            shutil.rmtree(self.DIR_NAME)
+
+        os.mkdir(self.DIR_NAME)
+        repo = git.Repo.init(self.DIR_NAME)
+        origin = repo.create_remote('origin', self.base_url)
+        origin.fetch()
+        fetch_info = origin.pull('master')[0]
+        return fetch_info
+
+    def push_repository(self, msg=None):
+        """
+        :param msg: Commit message
+        :return: git.remote.PushInfo object
+        """
+        repo = git.Repo.init(self.DIR_NAME)
+        origin = repo.remote('origin')
+        repo.git.add('--all')
+        repo.git.commit('-m \'[RDCL3D commit] ' + msg + '\'')
+        push_info = origin.push('master')[0]
+        return push_info
+
+    def to_json(self):
+        """
+        :return: JSON data of object
+        """
+        return {
+            'name': self.name,
+            'base_url': self.base_url.rstrip('\/'),
+            'last_update': self.last_update
+        }