From 451f581ba31b6a56fd058cd63db377b1f13ff695 Mon Sep 17 00:00:00 2001
From: Yves Noirjean <yves.noirjean@id.ethz.ch>
Date: Wed, 13 Dec 2017 12:48:21 +0100
Subject: [PATCH] pybis: added linkedData support to DataSet; created
 GitDataSetUpdate; using parse_jackson in pybis.get_dataset

---
 src/python/PyBis/pybis/data_set.py | 84 +++++++++++++++++++++++++++++-
 src/python/PyBis/pybis/pybis.py    | 37 ++++++++++++-
 src/python/PyBis/pybis/utils.py    |  3 +-
 3 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/src/python/PyBis/pybis/data_set.py b/src/python/PyBis/pybis/data_set.py
index 5f40d21da08..709c1ca79fc 100644
--- a/src/python/PyBis/pybis/data_set.py
+++ b/src/python/PyBis/pybis/data_set.py
@@ -25,7 +25,6 @@ class GitDataSetCreation(object):
         """Initialize the command object with the necessary parameters.
         :param openbis: The openBIS API object.
         :param data_set_type: The type of the data set
-        :param data_set_type: The type of the data set
         :param path: The path to the git repository
         :param commit_id: The git commit id
         :param repository_id: The git repository id - same for copies
@@ -176,3 +175,86 @@ class GitDataSetCreation(object):
         transfer_to_file_creation(content, result, 'directory')
         transfer_to_file_creation(content, result, 'path')
         return result
+
+
+class GitDataSetUpdate(object):
+
+    def __init__(self, openbis, path, commit_id, repository_id, edms_id, data_set_id):
+        """Initialize the command object with the necessary parameters.
+        :param openbis: The openBIS API object.
+        :param path: The path to the git repository
+        :param commit_id: The git commit id
+        :param repository_id: The git repository id - same for copies
+        :param edms_id: If of the external data managment system
+        :param data_set_id: Id of the data set to be updated
+        """
+        self.openbis = openbis
+        self.path = path
+        self.commit_id = commit_id
+        self.repository_id = repository_id
+        self.edms_id =edms_id
+        self.data_set_id = data_set_id
+
+
+    def new_content_copy(self):
+        """ Create a data set update for adding a content copy.
+        :return: A DataSetUpdate object
+        """
+        data_set_update = self.get_data_set_update()
+        self.send_request(data_set_update)
+
+
+    def send_request(self, data_set_update):
+        request = {
+            "method": "updateDataSets",
+            "params": [
+                self.openbis.token,
+                [data_set_update]
+            ]
+        }
+        self.openbis._post_request(self.openbis.as_v3, request)
+
+
+    def get_data_set_update(self):
+        return {
+            "@type": "as.dto.dataset.update.DataSetUpdate",
+            "dataSetId": self.get_data_set_id(),
+            "linkedData": self.get_linked_data()
+        }
+
+
+    def get_data_set_id(self):
+        return {
+            "@type": "as.dto.dataset.id.DataSetPermId",
+            "permId": self.data_set_id
+        }
+
+
+    def get_linked_data(self):
+        return {
+            "@type": "as.dto.common.update.FieldUpdateValue",
+            "isModified": True,
+            "value": {
+                "@type": "as.dto.dataset.update.LinkedDataUpdate",
+                "contentCopies": {
+                    "@type": "as.dto.dataset.update.ContentCopyListUpdateValue",
+                    "actions": [ {
+                        "@type": "as.dto.common.update.ListUpdateActionAdd",
+                        "items": [ self.get_content_copy_creation() ]
+                    } ]
+                }
+            }
+        }
+
+
+    def get_content_copy_creation(self):
+        return {
+            "@type": "as.dto.dataset.create.ContentCopyCreation",
+            "externalDmsId": {
+                "@type": "as.dto.externaldms.id.ExternalDmsPermId",
+                "permId": self.edms_id
+            },
+            "path": self.path,
+            "gitCommitHash": self.commit_id,
+            "gitRepositoryId" : self.repository_id,
+        }
diff --git a/src/python/PyBis/pybis/pybis.py b/src/python/PyBis/pybis/pybis.py
index 514481af8ae..314363bc1e1 100644
--- a/src/python/PyBis/pybis/pybis.py
+++ b/src/python/PyBis/pybis/pybis.py
@@ -1761,6 +1761,8 @@ class Openbis:
         if resp is None or len(resp) == 0:
             raise ValueError('no such dataset found: ' + permid)
 
+        parse_jackson(resp)
+
         for permid in resp:
             if only_data:
                 return resp[permid]
@@ -1958,6 +1960,17 @@ class Openbis:
         return pbds.GitDataSetCreation(self, data_set_type, path, commit_id, repository_id, dms, sample, experiment,
                                        properties, dss_code, parents, data_set_code, contents).new_git_data_set()
 
+    def new_content_copy(self, path, commit_id, repository_id, edms_id, data_set_id):
+        """
+        Create a content copy in an existing link data set.
+        :param path: path of the new content copy
+        "param commit_id: commit id of the new content copy
+        "param repository_id: repository id of the content copy
+        "param edms_id: Id of the external data managment system of the content copy
+        "param data_set_id: Id of the data set to which the new content copy belongs
+        """
+        return pbds.GitDataSetUpdate(self, path, commit_id, repository_id, edms_id, data_set_id).new_content_copy()
+
     @staticmethod
     def sample_to_sample_id(sample):
         """Take sample which may be a string or object and return an identifier for it."""
@@ -2263,6 +2276,22 @@ class OpenBisObject():
         return self.a.__repr__()
 
 
+class LinkedData():
+    def __init__(self, data=None):
+        self.data = data if data is not None else []
+        self.attrs = ['externalCode', 'contentCopies']
+
+    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 ''
+
+
 class PhysicalData():
     def __init__(self, data=None):
         if data is None:
@@ -2347,7 +2376,7 @@ class DataSet(OpenBisObject):
         return [
             'props', 'get_parents()', 'get_children()', 
             'add_parents()', 'add_children()', 'del_parents()', 'del_children()',
-            'sample', 'experiment', 'physicalData',
+            'sample', 'experiment', 'physicalData', 'linkedData',
             'tags', 'set_tags()', 'add_tags()', 'del_tags()',
             'add_attachment()', 'get_attachments()', 'download_attachments()',
             "get_files(start_folder='/')", 'file_list',
@@ -2379,7 +2408,11 @@ class DataSet(OpenBisObject):
     def physicalData(self):
         if 'physicalData' in self.data:
             return PhysicalData(self.data['physicalData'])
-            # return self.data['physicalData']
+
+    @property
+    def linkedData(self):
+        if 'linkedData' in self.data:
+            return LinkedData(self.data['linkedData'])
 
     @property
     def status(self):
diff --git a/src/python/PyBis/pybis/utils.py b/src/python/PyBis/pybis/utils.py
index 7e46c9d4cab..a16f6ac7dda 100644
--- a/src/python/PyBis/pybis/utils.py
+++ b/src/python/PyBis/pybis/utils.py
@@ -9,7 +9,8 @@ def parse_jackson(input_json):
     """
     interesting=['tags', 'registrator', 'modifier', 'type', 'parents', 
         'children', 'containers', 'properties', 'experiment', 'sample',
-        'project', 'space', 'propertyType', 'entityType', 'propertyType', 'propertyAssignment'
+        'project', 'space', 'propertyType', 'entityType', 'propertyType', 'propertyAssignment',
+        'externalDms'
     ]
     found = {} 
     def build_cache(graph):
-- 
GitLab