From 988a635353215a7b85d930ca592e0da9e148fb0c Mon Sep 17 00:00:00 2001
From: vermeul <swen@ethz.ch>
Date: Thu, 28 Feb 2019 16:08:38 +0100
Subject: [PATCH] changed property assignments

---
 pybis/src/python/pybis/entity_types.py        | 110 ++++++++++++++++++
 pybis/src/python/pybis/property_assignment.py |  12 +-
 pybis/src/python/pybis/pybis.py               |  55 +++++----
 3 files changed, 152 insertions(+), 25 deletions(-)
 create mode 100644 pybis/src/python/pybis/entity_types.py

diff --git a/pybis/src/python/pybis/entity_types.py b/pybis/src/python/pybis/entity_types.py
new file mode 100644
index 00000000000..aa6207615ec
--- /dev/null
+++ b/pybis/src/python/pybis/entity_types.py
@@ -0,0 +1,110 @@
+from tabulate import tabulate
+from texttable import Texttable
+from pybis.utils import check_datatype, split_identifier, format_timestamp, is_identifier, is_permid, nvl
+from pandas import DataFrame
+
+
+class EntityType():
+    """ holds are properties, that are assigned to an entity, eg. sample or experiment
+    """
+
+    def __init__(self, openbis_obj, data):
+        self.openbis = openbis_obj
+        self.data = data
+
+    def __str__(self):
+        """String representation of this entity type
+        """
+        return self.data['code']
+
+    def _attrs(self):
+        return ['code', 'description', 'autoGeneratedCode', 'subcodeUnique',
+            'generatedCodePrefix', 'listable', 'showContainer', 'showParents',
+            'showParentMetadata', 'validationPlugin']
+
+    def __dir__(self):
+        return self._attrs()
+
+    def __getattr__(self, name):
+        if name in self._attrs():
+            if name in self.data:
+                return self.data[name]
+            else:
+                return ''
+
+    def __eq__(self, other):
+        return str(self) == str(other)
+
+    def __ne__(self, other):
+        return str(self) != str(other)
+
+    def get_propertyAssignments(self):
+        attrs = ['code', 'label', 'description', 'dataType', 'mandatory', 'showInEditView', 'ordinal']
+        pas = [ {**pa['propertyType'], **pa} for pa in self.data['propertyAssignments'] ]
+        return DataFrame(pas, columns=attrs)
+
+    def codes(self):
+        codes = []
+        for pa in self.data['propertyAssignments']:
+            codes.append(pa['propertyType']['code'].lower())
+        return codes
+
+
+    def _repr_html_(self):
+        def nvl(val, string=''):
+            if val is None:
+                return string
+            return val
+
+        html = "<p>{}: <b>{}</b>".format(
+            self.data['@type'].split('.')[-1],
+            self.data['code'], 
+        )
+
+        html += """
+            <table border="1" class="dataframe">
+            <thead>
+                <tr style="text-align: right;">
+                <th>attribute</th>
+                <th>value</th>
+                </tr>
+            </thead>
+            <tbody>
+        """
+
+        for attr in self._attrs():
+            if attr == 'validationPlugin':
+                continue
+            html += "<tr> <td>{}</td> <td>{}</td> </tr>".format(
+                attr, nvl(getattr(self, attr, ''), '')
+            )
+
+        html += """
+            </tbody>
+            </table>
+        """
+
+        if self.validationPlugin:
+            html += "<p/><b>Validation Plugin</b>"
+            html += """
+                <table border="1" class="dataframe">
+                <thead>
+                    <tr style="text-align: right;">
+                    <th>attribute</th>
+                    <th>value</th>
+                    </tr>
+                </thead>
+                <tbody>
+            """
+            for attr in ['name', 'description', 'pluginType', 'pluginKind',
+                'available', 'entityKinds']:
+                html += "<tr> <td>{}</td> <td>{}</td> </tr>".format(
+                    attr, self.validationPlugin.get(attr)
+                )
+            html += """
+                </tbody>
+                </table>
+            """
+
+        return html
+
diff --git a/pybis/src/python/pybis/property_assignment.py b/pybis/src/python/pybis/property_assignment.py
index fd821c05ca9..7b4ca0a1611 100644
--- a/pybis/src/python/pybis/property_assignment.py
+++ b/pybis/src/python/pybis/property_assignment.py
@@ -1,6 +1,7 @@
 from tabulate import tabulate
 from texttable import Texttable
 from pybis.utils import check_datatype, split_identifier, format_timestamp, is_identifier, is_permid, nvl
+from pandas import DataFrame
 
 
 class PropertyAssignments():
@@ -42,6 +43,10 @@ class PropertyAssignments():
     def __ne__(self, other):
         return str(self) != str(other)
 
+    def get_propertyAssignments(self):
+        attrs = ['code', 'dataType', 'description', 'label', 'mandatory', 'ordinal']
+        pas = [ {**pa['propertyType'], **pa} for pa in self.data['propertyAssignments'] ]
+        return DataFrame(pas, columns=attrs)
 
     def codes(self):
         codes = []
@@ -109,11 +114,7 @@ class PropertyAssignments():
 
         #if 'autoGeneratedCode' in self.data:
         #    html += "<p>Code autogenerated: {}</p>".format(
-        #        self.data['autoGeneratedCode'])
-
-        html += """
-        <p><b>Property Assignments</b>
-<table border="1" class="dataframe">
+        """
   <thead>
     <tr style="text-align: right;">
       <th>property</th>
@@ -169,3 +170,4 @@ description: {}""".format (
         table.set_cols_width([28,28,28,28,9])
         table.set_cols_align(['l','l','l','l','l'])
         return title + "\n\n" + table.draw()
+
diff --git a/pybis/src/python/pybis/pybis.py b/pybis/src/python/pybis/pybis.py
index 2360ab72ebc..7cbd24f3261 100644
--- a/pybis/src/python/pybis/pybis.py
+++ b/pybis/src/python/pybis/pybis.py
@@ -30,7 +30,7 @@ from . import data_set as pbds
 from .utils import parse_jackson, check_datatype, split_identifier, format_timestamp, is_identifier, is_permid, nvl, VERBOSE
 from .utils import extract_attr, extract_permid, extract_code,extract_deletion,extract_identifier,extract_nested_identifier,extract_nested_permid,extract_property_assignments,extract_role_assignments,extract_person, extract_person_details,extract_id,extract_userId
 from .property import PropertyHolder
-from .property_assignment import PropertyAssignments
+from .entity_types import EntityType
 from .vocabulary import Vocabulary, VocabularyTerm
 from .openbis_object import OpenBisObject 
 from .definitions import get_definition_for_entity, fetch_option, get_fetchoption_for_entity, get_type_for_entity, get_method_for_entity
@@ -2099,7 +2099,9 @@ class Openbis:
         return Things(self, 'tag', tags[attrs], 'permId')
 
 
-    def search_semantic_annotations(self, permId=None, entityType=None, propertyType=None, only_data = False):
+    def search_semantic_annotations(self, 
+        permId=None, entityType=None, propertyType=None, only_data=False
+    ):
         """ Get a list of semantic annotations for permId, entityType, propertyType or 
         property type assignment (DataFrame object).
         :param permId: permId of the semantic annotation.
@@ -2323,10 +2325,10 @@ class Openbis:
         """ Returns a list of all available sample types
         """
         return self._get_types_of(
-            "searchSampleTypes",
-            "Sample",
-            type,
-            ["generatedCodePrefix"]
+            method_name         = "searchSampleTypes",
+            entity              = "Sample",
+            type_name           = type,
+            optional_attributes = ["generatedCodePrefix"]
         )
 
     get_object_types = get_sample_types # Alias
@@ -2334,10 +2336,10 @@ class Openbis:
     def get_sample_type(self, type):
         try:
             property_asignments = self._get_types_of(
-                "searchSampleTypes",
-                "Sample",
-                type,
-                ["generatedCodePrefix", "validationPluginId"]
+                method_name         = "searchSampleTypes",
+                entity              = "Sample",
+                type_name           = type,
+                optional_attributes = ["generatedCodePrefix", "validationPluginId"]
             )
             return SampleType(self, property_asignments.data)
         except Exception:
@@ -2349,9 +2351,9 @@ class Openbis:
         """ Returns a list of all available experiment types
         """
         return self._get_types_of(
-            "searchExperimentTypes",
-            "Experiment",
-            type
+            method_name         = "searchExperimentTypes",
+            entity              = "Experiment",
+            type_name           = type
         )
 
     get_collection_types = get_experiment_types  # Alias
@@ -2359,9 +2361,9 @@ class Openbis:
     def get_experiment_type(self, type):
         try:
             return self._get_types_of(
-                "searchExperimentTypes",
-                "Experiment",
-                type
+                method_name         = "searchExperimentTypes",
+                entity              = "Experiment",
+                type_name           = type
             )
         except Exception:
            raise ValueError("No such experiment type: {}".format(type))
@@ -2371,11 +2373,19 @@ class Openbis:
     def get_material_types(self, type=None):
         """ Returns a list of all available material types
         """
-        return self._get_types_of("searchMaterialTypes", "Material", type)
+        return self._get_types_of(
+            method_name         = "searchMaterialTypes",
+            entity              = "Material",
+            type_name           = type
+        )
 
     def get_material_type(self, type):
         try:
-            return self._get_types_of("searchMaterialTypes", "Material", type)
+            return self._get_types_of(
+                method_name         = "searchMaterialTypes", 
+                entity              = "Material", 
+                type_name           = type
+            ) 
         except Exception:
             raise ValueError("No such material type: {}".format(type))
 
@@ -2386,7 +2396,12 @@ class Openbis:
 
     def get_dataset_type(self, type):
         try:
-            return self._get_types_of("searchDataSetTypes", "DataSet", type, optional_attributes=['kind'])
+            return self._get_types_of(
+                method_name         = "searchDataSetTypes", 
+                entity              = "DataSet",
+                type_name           = type,
+                optional_attributes = ['kind']
+            )
         except Exception:
             raise ValueError("No such dataSet type: {}".format(type))
 
@@ -2424,7 +2439,7 @@ class Openbis:
         parse_jackson(resp)
 
         if type_name is not None and len(resp['objects']) == 1:
-            return PropertyAssignments(
+            return EntityType(
                 openbis_obj = self,
                 data        = resp['objects'][0]
             )
-- 
GitLab