diff --git a/README.md b/README.md index a5780861b..2577147da 100644 --- a/README.md +++ b/README.md @@ -120,12 +120,12 @@ The documentation is a collection of [markdown](https://en.wikipedia.org/wiki/Ma After updates of the files, build and check the result with the following commands: ```bash -make build-docs -make serve-docs +make docs-build +make docs-serve ``` To update the changes to the official documentation pages run: ```bash -make publish-docs +make docs-publish ``` diff --git a/docs/dsp-tools-information-for-developers.md b/docs/dsp-tools-information-for-developers.md index 2201f3e88..4c586e88b 100644 --- a/docs/dsp-tools-information-for-developers.md +++ b/docs/dsp-tools-information-for-developers.md @@ -114,12 +114,12 @@ The documentation is a collection of [markdown](https://en.wikipedia.org/wiki/Ma After updates of the files, build and check the result with the following commands: ```bash -make build-docs -make serve-docs +make docs-build +make docs-serve ``` To update the changes to the official documentation pages run: ```bash -make publish-docs +make docs-publish ``` diff --git a/knora/dsplib/models/BUILD.bazel b/knora/dsplib/models/BUILD.bazel index 05a69de08..76a4bf004 100644 --- a/knora/dsplib/models/BUILD.bazel +++ b/knora/dsplib/models/BUILD.bazel @@ -54,12 +54,13 @@ py_library( visibility = ["//visibility:public"], srcs = ["listnode.py"], deps = [ + "//knora/dsplib/utils:set_encoder", ":connection", ":helpers", ":langstring", ":project", ], - imports = ["."], + imports = [".", ".."], ) py_library( @@ -101,6 +102,7 @@ py_library( visibility = ["//visibility:public"], srcs = ["project.py"], deps = [ + "//knora/dsplib/utils:set_encoder", ":helpers", ":langstring", ":connection", @@ -114,12 +116,13 @@ py_library( visibility = ["//visibility:public"], srcs = ["propertyclass.py"], deps = [ + "//knora/dsplib/utils:set_encoder", ":connection", ":helpers", ":langstring", ":listnode" ], - imports = ["."], + imports = [".", ".."], ) py_library( @@ -146,11 +149,12 @@ py_library( visibility = ["//visibility:public"], srcs = ["resourceclass.py"], deps = [ + "//knora/dsplib/utils:set_encoder", ":connection", ":helpers", ":langstring", ], - imports = ["."], + imports = [".", ".."], ) py_library( diff --git a/knora/dsplib/models/listnode.py b/knora/dsplib/models/listnode.py index ed7a94264..2ac977868 100644 --- a/knora/dsplib/models/listnode.py +++ b/knora/dsplib/models/listnode.py @@ -10,46 +10,40 @@ from .langstring import Languages, LangString from .model import Model from .project import Project - - -class SetEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, set): - return list(obj) - return json.JSONEncoder.default(self, obj) - +from ..utils.set_encoder import SetEncoder """ -This module implements the handling (CRUD) of Knora ListNodes and adds some function to read whole lists. +This module implements the handling (CRUD) of list nodes and adds some function to read whole lists. CREATE: - * Instantiate a new object of the class ListNode with all required parameters - * Call the ``create``-method on the instance + * Instantiate a new object of the class ListNode + * Call the ``create`` method on the instance READ: - * Instantiate a new object with ``id``(IRI of list(-node) given - * Call the ``read``-method on the instance - * Access the information that has been provided to the instance + * Instantiate a new object with ``id`` (IRI of listnode) + * Call the ``read`` method on the instance + * Access information about the instance UPDATE: * Only partially implemented. Only "label" and "comment" attributes may be changed. * You need an instance of an existing ListNode by reading an instance * Change the attributes by assigning the new values - * Call the ``update```method on the instance + * Call the ``update`` method on the instance DELETE - * NOT YET IMPLEMENTED BY Knora backend! - * Instantiate a new objects with ``id``(IRI of project) given, or use any instance that has the id set - * Call the ``delete``-method on the instance - -In addition there is a static methods ``getAllProjects`` which returns a list of all projects + * NOT YET IMPLEMENTED! """ -def list_creator(con: Connection, project: Project, parent_node: 'ListNode', nodes: List[dict]): - nodelist: List['ListNode'] = [] +def list_creator(con: Connection, + project: Project, + parent_node: 'ListNode', + nodes: List[dict]) -> List['ListNode']: + + nodelist: List[ListNode] = [] + for node in nodes: - newnode = ListNode( + new_node = ListNode( con=con, project=project, label=node["labels"], @@ -57,102 +51,105 @@ def list_creator(con: Connection, project: Project, parent_node: 'ListNode', nod name=node["name"], parent=parent_node ) - if node.get('nodes') is not None: - newnode.children = list_creator(con, project, newnode, node['nodes']) - nodelist.append(newnode) + + if node.get('nodes'): + new_node.children = list_creator(con, project, new_node, node['nodes']) + + nodelist.append(new_node) + return nodelist @strict class ListNode(Model): """ - This class represents a list node or a while list from Knora + This class represents a list node Attributes ---------- con : Connection - A Connection instance to a Knora server (for some operation a login has to be performedwith valid credentials) + A Connection instance to a DSP server (for some operation a login has to be performed with valid credentials) id : str - IRI of the project [readonly, cannot be modified after creation of instance] + IRI of the list node [readonly, cannot be modified after creation of instance] project : str IRI of project. Only used for the creation of a new list (root node) [write]. label : LangString - A LangString instance with language depenedent labels. Setting this attributes overwites all entries + A LangString instance with language dependent labels. Setting this attribute overwrites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. - comment : LangString - A LangString instance with language depenedent comments. Setting this attributes overwites all entries - with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". + comments : LangString + A LangString instance with language dependent comments. Setting this attributes overwrites all entries + with the new ones. In order to add/remove a specific entry, use "addComment" or "rmComment". name : str - A unique name for the ListNode (unique regarding the whole list) [read/write]. + A unique name for the ListNode (unique inside this list) [read/write]. parent : IRI | ListNode Is required and allowed only for the CREATE operation. Otherwise use the "children" attribute [write]. isRootNode : bool - Is True if the ListNode is a root node of a list Cannot be set [read]. + Is True if the ListNode is the root node of a list. Cannot be set [read]. children : List[ListNode] - Contains a list of children nodes. This attribute is only avaliable for nodes that have been read by the - method "getAllNodes()"! [read] + Contains a list of child nodes. This attribute is only available for nodes that have been read by the + method "getAllNodes()" [read]. rootNodeIri : str - IRI of the root node. This attribute is only avaliable for nodes that have been read by the - method "getAllNodes()"! [read] + IRI of the root node. This attribute is only available for nodes that have been read by the + method "getAllNodes()" [read]. Methods ------- - create : Knora ListNode information object - Creates a new project and returns the information from the project as it is in Knora. Used to create new lists - or append new ListNodes to an existing list. If appending, the attribute "parent" must not be None! + create : ListNode information object + Creates a new list (node) and returns the information from the list (node). Use it to create new lists + or append new ListNodes to an existing list. - read : Knora ListNode information object - Read single list node + read : ListNode information object + Returns information about a single list node - update : Knora ListNode information object - Updates the changed attributes and returns the updated information from the ListNode as it is in Knora + update : ListNode information object + Updates the changed attributes and returns the updated information from the ListNode - delete : Knora result code - Deletes a ListNode and returns the result code [NOT YET IMPLEMENTED!] + delete : + NOT YET IMPLEMENTED getAllNodes : ListNode - Get all nodes of a list. The IRI of the root node must be supplied. + Get all nodes of a list. The IRI of the root node has to be supplied. getAllLists [static]: - returns all lists of a given project. + Returns all lists of a project. print : None - Prints the ListNode information to stdout (no recursion for children!) + Prints the ListNode information to stdout (not recursive) """ - _id: Union[str, None] - _project: Union[str, None] - _label: LangString - _comments: LangString - _name: Union[str, None] - _parent: Union[str, None] + _id: Optional[str] + _project: Optional[str] + _label: Optional[LangString] + _comments: Optional[LangString] + _name: Optional[str] + _parent: Optional[str] _isRootNode: bool - _children: Union[List['ListNode'], None] - _rootNodeIri: Union[str, None] + _children: Optional[List['ListNode']] + _rootNodeIri: Optional[str] def __init__(self, con: Connection, id: Optional[str] = None, project: Optional[Union[Project, str]] = None, label: LangString = None, - comments: LangString = None, + comments: Optional[LangString] = None, name: Optional[str] = None, parent: Optional[Union['ListNode', str]] = None, - isRootNode: Optional[bool] = None, + isRootNode: bool = False, children: Optional[List['ListNode']] = None, rootNodeIri: Optional[str] = None): """ @@ -165,46 +162,43 @@ def __init__(self, UPDATE: * Only "label", "comments" and "name" may be changed DELETE: - * Not yet implemented in the Knora-backend + * Not yet implemented :param con: A valid Connection instance with a user logged in that has the appropriate permissions :param id: IRI of the project [readonly, cannot be modified after creation of instance] :param project: IRI of project. Only used for the creation of a new list (root node) [write]. - :param label: A LangString instance with language depenedent labels. Setting this attributes overwites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. - :param comments: A LangString instance with language depenedent comments. Setting this attributes overwites all entries with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". + :param label: A LangString instance with language dependent labels. Setting this attributes overwites all entries with the new ones. In order to add/remove a specific entry, use "addLabel" or "rmLabel". At least one label is required [read/write]. + :param comments: A LangString instance with language dependent comments. Setting this attributes overwites all entries with the new ones.In order to add/remove a specific entry, use "addComment" or "rmComment". :param name: A unique name for the ListNode (unique regarding the whole list) [read/write]. :param parent: Is required and allowed only for the CREATE operation. Otherwise use the "children" attribute [write]. :param isRootNode: Is True if the ListNode is a root node of a list Cannot be set [read]. - :param children: Contains a list of children nodes. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] - :param rootNodeIri: IRI of the root node. This attribute is only avaliable for nodes that have been read by the method "getAllNodes()"! [read] + :param children: Contains a list of children nodes. This attribute is only available for nodes that have been read by the method "getAllNodes()"! [read] + :param rootNodeIri: IRI of the root node. This attribute is only available for nodes that have been read by the method "getAllNodes()"! [read] """ super().__init__(con) - self._project = project.id if isinstance(project, Project) else str(project) if project is not None else None - self._id = str(id) if id is not None else None + self._project = project.id if isinstance(project, Project) else str(project) if project else None + self._id = str(id) if id else None self._label = LangString(label) - self._comments = LangString(comments) - self._name = str(name) if name is not None else None + self._comments = LangString(comments) if comments else None + self._name = str(name) if name else None if parent and isinstance(parent, ListNode): self._parent = parent.id else: self._parent = str(parent) if parent else None self._isRootNode = isRootNode - if children is not None: + if children: if isinstance(children, List) and len(children) > 0 and isinstance(children[0], ListNode): self._children = children else: - raise BaseError('Children must be list of ListNodes!') + raise BaseError('ERROR Children must be list of ListNodes!') else: self._children = None - if not isinstance(rootNodeIri, str) and rootNodeIri is not None: - raise BaseError('rootNodeIri must be a str!') + if not isinstance(rootNodeIri, str) and rootNodeIri: + raise BaseError('ERROR rootNodeIri must be of type string') self._rootNodeIri = rootNodeIri - # - # Here follows a list of getters/setters - # @property def id(self) -> Optional[str]: return self._id @@ -369,10 +363,10 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: """ Internal method! Should not be used directly! - This method is used to create a ListNode instance from the JSON data returned by Knora + This method is used to create a ListNode instance from the JSON data returned by DSP :param con: Connection instance - :param json_obj: JSON data returned by Knora as python3 object + :param json_obj: JSON data returned by DSP as python3 object :return: ListNode instance """ @@ -382,7 +376,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: project = json_obj.get('projectIri') label = LangString.fromJsonObj(json_obj.get('labels')) comments = LangString.fromJsonObj(json_obj.get('comments')) - if json_obj.get('name') is not None: + if json_obj.get('name'): name = json_obj['name'] else: name = id.rsplit('/', 1)[-1] @@ -391,7 +385,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any) -> Any: child_info = json_obj.get('children') children = None - if child_info is not None: + if child_info: children = ListNode.__getChildren(con=con, parent_iri=id, project_iri=project, @@ -413,13 +407,16 @@ def toJsonObj(self, action: Actions, listIri: str = None) -> Any: """ Internal method! Should not be used directly! - Creates a JSON-object from the ListNode instance that can be used to call Knora + Creates a JSON-object from the ListNode instance that can be used to call DSP-API :param action: Action the object is used for (Action.CREATE or Action.UPDATE) + :param listIri: The IRI of the list node, only used for update action :return: JSON-object + """ tmp = {} + if action == Actions.Create: if self._project is None: raise BaseError("There must be a project id given!") @@ -427,14 +424,13 @@ def toJsonObj(self, action: Actions, listIri: str = None) -> Any: if self._label.isEmpty(): raise BaseError("There must be a valid ListNode label!") tmp['labels'] = self._label.toJsonObj() - if not self._comments.isEmpty(): + if self._comments: tmp['comments'] = self._comments.toJsonObj() - else: - tmp['comments'] = [] - if self._name is not None: + if self._name: tmp['name'] = self._name - if self._parent is not None: + if self._parent: tmp['parentNodeIri'] = self._parent + elif action == Actions.Update: if self.id is None: raise BaseError("There must be a node id given!") @@ -446,31 +442,21 @@ def toJsonObj(self, action: Actions, listIri: str = None) -> Any: tmp['labels'] = self._label.toJsonObj() if not self._comments.isEmpty() and 'comments' in self._changed: tmp['comments'] = self._comments.toJsonObj() - if self._name is not None and 'name' in self._changed: + if self._name and 'name' in self._changed: tmp['name'] = self._name - # - # temporary fix for bug in dsp-api which prevents labels from having - # escaped double-quotes in the string, e.g. "this \"label\" not works"! - # The double quotes will be replaced by single quotes... - # - if tmp.get('labels'): - print(tmp['labels']) - tmp['labels'] = [{'language': ele['language'], 'value': ele['value'].replace('"', "'")} for ele in - tmp['labels']] - # tmp['labels'] = {k: v.replace('"', "'") for k, v in tmp['labels'].items()} - # End of FIX + return tmp def create(self) -> 'ListNode': """ - Create a new List in Knora + Create a new List - :return: JSON-object from Knora + :return: JSON-object from DSP-API """ jsonobj = self.toJsonObj(Actions.Create) jsondata = json.dumps(jsonobj, cls=SetEncoder) - if self._parent is not None: + if self._parent: result = self._con.post('/admin/lists/' + quote_plus(self._parent), jsondata) return ListNode.fromJsonObj(self._con, result['nodeinfo']) else: @@ -479,9 +465,9 @@ def create(self) -> 'ListNode': def read(self) -> Any: """ - Read a project from Knora + Read a project from DSP-API - :return: JSON-object from Knora + :return: JSON-object from DSP-API """ result = self._con.get('/admin/lists/nodes/' + quote_plus(self._id)) @@ -494,9 +480,9 @@ def read(self) -> Any: def update(self) -> Union[Any, None]: """ - Udate the ListNode info in Knora with the modified data in this ListNode instance + Update the ListNode info in DSP with the modified data in this ListNode instance - :return: JSON-object from Knora refecting the update + :return: JSON-object from DSP-API reflecting the update """ jsonobj = self.toJsonObj(Actions.Update, self.id) @@ -512,9 +498,9 @@ def delete(self) -> None: """ Delete the given ListNode - :return: Knora response + :return: DSP-API response """ - raise BaseError("NOT YET IMPLEMENTED BY KNORA BACKEND!") + raise BaseError("NOT YET IMPLEMENTED") result = self._con.delete('/admin/lists/' + quote_plus(self._id)) return result # return Project.fromJsonObj(self.con, result['project']) diff --git a/knora/dsplib/models/project.py b/knora/dsplib/models/project.py index decd5eac6..fd6539a69 100644 --- a/knora/dsplib/models/project.py +++ b/knora/dsplib/models/project.py @@ -5,19 +5,13 @@ from pystrict import strict +from knora.dsplib.utils.set_encoder import SetEncoder from .connection import Connection from .helpers import Actions, BaseError from .langstring import Languages, LangStringParam, LangString from .model import Model -class SetEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, set): - return list(obj) - return json.JSONEncoder.default(self, obj) - - """ This module implements the handling (CRUD) of Knora projects. diff --git a/knora/dsplib/models/propertyclass.py b/knora/dsplib/models/propertyclass.py index fdd6a229d..e2907097f 100644 --- a/knora/dsplib/models/propertyclass.py +++ b/knora/dsplib/models/propertyclass.py @@ -10,13 +10,7 @@ from .langstring import Languages, LangString from .listnode import ListNode from .model import Model - - -class SetEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, set): - return list(obj) - return json.JSONEncoder.default(self, obj) +from ..utils.set_encoder import SetEncoder @strict diff --git a/knora/dsplib/models/resourceclass.py b/knora/dsplib/models/resourceclass.py index 6e63a080c..58a407669 100644 --- a/knora/dsplib/models/resourceclass.py +++ b/knora/dsplib/models/resourceclass.py @@ -10,14 +10,7 @@ from .helpers import Actions, BaseError, Context, Cardinality, LastModificationDate from .langstring import Languages, LangString from .model import Model - - -class SetEncoder(json.JSONEncoder): - def default(self, obj): - if isinstance(obj, set): - return list(obj) - return json.JSONEncoder.default(self, obj) - +from ..utils.set_encoder import SetEncoder """ This model implements the handling of resource classes. It contains two classes that work closely together: diff --git a/knora/dsplib/utils/BUILD.bazel b/knora/dsplib/utils/BUILD.bazel index e057a2abe..3cf5f706c 100644 --- a/knora/dsplib/utils/BUILD.bazel +++ b/knora/dsplib/utils/BUILD.bazel @@ -102,6 +102,12 @@ py_library( imports = [".", ".."], ) +py_library( + name = "set_encoder", + visibility = ["//visibility:public"], + srcs = ["set_encoder.py"] +) + py_library( name = "xml_upload", visibility = ["//visibility:public"], diff --git a/knora/dsplib/utils/onto_create_ontology.py b/knora/dsplib/utils/onto_create_ontology.py index 458fa155b..1768cbc88 100644 --- a/knora/dsplib/utils/onto_create_ontology.py +++ b/knora/dsplib/utils/onto_create_ontology.py @@ -321,7 +321,7 @@ def create_ontology(input_file: str, print("Creating resource class failed:", err.message) exit(105) newresclasses[newresclass.id] = newresclass - if verbose is not None: + if verbose: print("New resource class:") newresclass.print() diff --git a/knora/dsplib/utils/set_encoder.py b/knora/dsplib/utils/set_encoder.py new file mode 100644 index 000000000..0a36cf5da --- /dev/null +++ b/knora/dsplib/utils/set_encoder.py @@ -0,0 +1,8 @@ +import json + + +class SetEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return list(obj) + return json.JSONEncoder.default(self, obj) diff --git a/knora/dsplib/utils/xml_upload.py b/knora/dsplib/utils/xml_upload.py index eae78765a..257471958 100644 --- a/knora/dsplib/utils/xml_upload.py +++ b/knora/dsplib/utils/xml_upload.py @@ -10,7 +10,7 @@ from knora.dsplib.models.group import Group from knora.dsplib.models.permission import Permissions from knora.dsplib.models.project import Project -from knora.dsplib.models.resource import ResourceInstanceFactory +from knora.dsplib.models.resource import ResourceInstanceFactory, ResourceInstance from knora.dsplib.models.sipi import Sipi from knora.dsplib.models.value import KnoraStandoffXml @@ -613,10 +613,11 @@ def xml_upload(input_file: str, server: str, user: str, password: str, imgdir: s bitstream = None # create the resource on the server - instance = res_classes[resource.restype](con=con, label=resource.label, - permissions=permissions_lookup.get(resource.permissions), - bitstream=bitstream, - values=resource.get_propvals(res_iri_lookup, - permissions_lookup)).create() + instance: ResourceInstance = res_classes[resource.restype](con=con, label=resource.label, + permissions=permissions_lookup.get( + resource.permissions), + bitstream=bitstream, + values=resource.get_propvals(res_iri_lookup, + permissions_lookup)).create() res_iri_lookup[resource.id] = instance.iri - print("Created resource: ", instance.label, " (", resource.id, ") with IRI ", instance.iri) + print("Created resource:", instance.label, "(", resource.id, ") with IRI", instance.iri) diff --git a/test/e2e/test_tools.py b/test/e2e/test_tools.py index 4d3c191f7..1697b1e16 100644 --- a/test/e2e/test_tools.py +++ b/test/e2e/test_tools.py @@ -37,7 +37,7 @@ def test_get(self) -> None: server=self.server, user=self.user, password='test', - verbose=True) + verbose=False) with open('_anything-onto.json') as f: onto_json_str = f.read() @@ -107,7 +107,7 @@ def test_create_ontology(self) -> None: server=self.server, user=self.user, password='test', - verbose=True, + verbose=False, dump=True) def test_xml_upload(self) -> None: @@ -117,7 +117,7 @@ def test_xml_upload(self) -> None: password='test', imgdir='testdata/bitstreams', sipi='http://0.0.0.0:1024', - verbose=True, + verbose=False, validate_only=False) diff --git a/testdata/test-onto.json b/testdata/test-onto.json index c0fdd6999..97853c2a3 100644 --- a/testdata/test-onto.json +++ b/testdata/test-onto.json @@ -1,526 +1,539 @@ { - "prefixes": { - "foaf": "http://xmlns.com/foaf/0.1/", - "dcterms": "http://purl.org/dc/terms/" - }, - "$schema": "../knora/dsplib/schemas/ontology.json", - "project": { - "shortcode": "4123", - "shortname": "tp", - "longname": "test project", - "descriptions": { - "en": "A systematic test project", - "de": "Ein systematisches Testprojekt" + "prefixes": { + "foaf": "http://xmlns.com/foaf/0.1/", + "dcterms": "http://purl.org/dc/terms/" }, - "keywords": [ - "test", - "testing" - ], - "lists": [ - { - "name": "testlist", - "labels": { - "en": "Testlist" + "$schema": "../knora/dsplib/schemas/ontology.json", + "project": { + "shortcode": "4123", + "shortname": "tp", + "longname": "test project", + "descriptions": { + "en": "A systematic test project", + "de": "Ein systematisches Testprojekt" }, - "comments": {"en": "no comment"}, - "nodes": [ - { - "name": "a", - "labels": { - "en": "a_label" - } - }, - { - "name": "b", - "labels": { - "en": "b_label" - }, - "nodes": [ - { - "name": "b1", + "keywords": [ + "test", + "testing" + ], + "lists": [ + { + "name": "testlist", "labels": { - "en": "b1_label" - } - }, - { - "name": "b2", + "en": "Testlist" + }, + "comments": { + "en": "no comment", + "de": "kein Kommentar" + }, + "nodes": [ + { + "name": "a", + "labels": { + "en": "a_label with a\"post'rophes" + }, + "comments": { + "en": "no comment" + } + }, + { + "name": "b", + "labels": { + "en": "b_label" + }, + "comments": { + "en": "no comment" + }, + "nodes": [ + { + "name": "b1", + "labels": { + "en": "b1_label" + } + }, + { + "name": "b2", + "labels": { + "en": "b2_label" + } + } + ] + }, + { + "name": "c", + "labels": { + "en": "c_label" + }, + "comments": { + "en": "no comment" + } + } + ] + }, + { + "name": "my-list-from-excel", "labels": { - "en": "b2_label" + "en": "My list from Excel" + }, + "comments": { + "en": "a comment", + "de": "ein Kommentar", + "fr": "un commentaire" + }, + "nodes": { + "folder": "testdata/lists" } - } - ] - }, - { - "name": "c", - "labels": { - "en": "c_label" } - } - ] - }, - { - "name": "my-list-from-excel", - "labels": { - "en": "My list from Excel" - }, - "comments": { - "en": "no comment", - "de": "ein Kommentar", - "fr": "un commentaire" - }, - "nodes": { - "folder": "testdata/lists" - } - } - ], - "groups": [ - { - "name": "testgroup", - "descriptions": { - "en": "Test group", - "de": "Testgruppe"}, - "selfjoin": false, - "status": true - } - ], - "users": [ - { - "username": "tester", - "email": "tester@test.org", - "givenName": "Testing", - "familyName": "tester", - "password": "test0815", - "lang": "en", - "groups": [ - ":testgroup" ], - "projects": [ - ] - } - ], - "ontologies": [ - { - "name": "testonto", - "label": "Test ontology", - "properties": [ - { - "name": "hasText", - "super": [ - "hasValue" - ], - "object": "TextValue", - "labels": { - "en": "Text" - }, - "gui_element": "SimpleText", - "gui_attributes": { - "maxlength": 255, - "size": 80 - } - }, - { - "name": "hasRichtext", - "super": [ - "hasValue" - ], - "object": "TextValue", - "labels": { - "en": "Text" - }, - "gui_element": "Richtext" - }, - { - "name": "hasUri", - "super": [ - "hasValue" - ], - "object": "UriValue", - "labels": { - "en": "URI" - }, - "gui_element": "SimpleText", - "gui_attributes": { - "maxlength": 255, - "size": 80 - } - }, - { - "name": "hasBoolean", - "super": [ - "hasValue" - ], - "object": "BooleanValue", - "labels": { - "en": "Boolean value" - }, - "gui_element": "Checkbox" - }, - { - "name": "hasDate", - "super": [ - "hasValue" - ], - "object": "DateValue", - "labels": { - "en": "Date" - }, - "gui_element": "Date" - }, - { - "name": "hasInteger", - "super": [ - "hasValue" - ], - "object": "IntValue", - "labels": { - "en": "Integer" - }, - "gui_element": "Spinbox", - "gui_attributes": { - "max": -1.0, - "min": 0.0 - } - }, - { - "name": "hasDecimal", - "super": [ - "hasValue" - ], - "object": "DecimalValue", - "labels": { - "en": "Decimal number" - }, - "gui_element": "SimpleText", - "gui_attributes": { - "maxlength": 255, - "size": 80 + "groups": [ + { + "name": "testgroup", + "descriptions": { + "en": "Test group", + "de": "Testgruppe" + }, + "selfjoin": false, + "status": true } - }, - { - "name": "hasGeometry", - "super": [ - "hasValue" - ], - "object": "GeomValue", - "labels": { - "en": "Geometry" - }, - "gui_element": "Geometry" - }, - { - "name": "hasGeoname", - "super": [ - "hasValue" - ], - "object": "GeonameValue", - "labels": { - "en": "Geoname" - }, - "gui_element": "Geonames" - }, - { - "name": "hasInterval", - "super": [ - "hasValue" - ], - "object": "IntervalValue", - "labels": { - "en": "Time interval" - }, - "gui_element": "Interval" - }, - { - "name": "hasColor", - "super": [ - "hasValue" - ], - "object": "ColorValue", - "labels": { - "en": "Color" - }, - "gui_element": "Colorpicker" - }, - { - "name": "hasListItem", - "super": [ - "hasValue" - ], - "object": "ListValue", - "labels": { - "en": "List element" - }, - "gui_element": "List", - "gui_attributes": { - "hlist": "testlist" + ], + "users": [ + { + "username": "tester", + "email": "tester@test.org", + "givenName": "Testing", + "familyName": "tester", + "password": "test0815", + "lang": "en", + "groups": [ + ":testgroup" + ], + "projects": [ + ] } - }, - { - "name": "hasTestRegion", - "super": [ - "hasLinkTo" - ], - "object": "Region", - "labels": { - "en": "has region" - }, - "gui_element": "Searchbox" - }, - { - "name": "hasTestThing2", - "super": [ - "hasLinkTo" - ], - "object": ":TestThing2", - "labels": { - "en": "Another thing" - }, - "gui_element": "Searchbox" - } ], - "resources": [ - { - "name": "TestThing", - "super": "Resource", - "labels": { - "en": "TestThing" - }, - "comments": { - "en": "A thing to test things", - "de": "Ein Ding um allerlei Dinge zu testen." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1-n" - }, - { - "propname": ":hasRichtext", - "gui_order": 2, - "cardinality": "0-n" - }, - { - "propname": ":hasUri", - "gui_order": 3, - "cardinality": "0-n" - }, - { - "propname": ":hasBoolean", - "gui_order": 4, - "cardinality": "1" - }, - { - "propname": ":hasDate", - "gui_order": 5, - "cardinality": "0-n" - }, - { - "propname": ":hasInteger", - "gui_order": 6, - "cardinality": "0-n" - }, - { - "propname": ":hasDecimal", - "gui_order": 7, - "cardinality": "0-n" - }, - { - "propname": ":hasGeometry", - "gui_order": 8, - "cardinality": "0-n" - }, - { - "propname": ":hasGeoname", - "gui_order": 9, - "cardinality": "0-n" - }, - { - "propname": ":hasInterval", - "gui_order": 10, - "cardinality": "0-n" - }, - { - "propname": ":hasColor", - "gui_order": 11, - "cardinality": "0-n" - }, - { - "propname": ":hasListItem", - "gui_order": 12, - "cardinality": "0-n" - }, - { - "propname": ":hasTestRegion", - "gui_order": 13, - "cardinality": "0-n" - }, - { - "propname": ":hasTestThing2", - "gui_order": 14, - "cardinality": "0-n" - } - ] - }, - { - "name": "TestThing2", - "super": "Resource", - "labels": { - "en": "Another Test Thing" - }, - "comments": { - "en": "Another thing for testing things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "CompoundThing", - "super": "Resource", - "labels": { - "en": "A Compound Thing" - }, - "comments": { - "en": "A thing for testing compound things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "ImageThing", - "super": "StillImageRepresentation", - "labels": { - "en": "An Image Thing" - }, - "comments": { - "en": "An image thing for testing image things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "AudioThing", - "super": "AudioRepresentation", - "labels": { - "en": "An Audio Thing" - }, - "comments": { - "en": "An audio thing for testing audio things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "MovieThing", - "super": "MovingImageRepresentation", - "labels": { - "en": "An Movie Thing" - }, - "comments": { - "en": "An movie thing for testing moving image things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "DocumentThing", - "super": "DocumentRepresentation", - "labels": { - "en": "A Document Thing" - }, - "comments": { - "en": "A second things for testing different things." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "ZipThing", - "super": "DocumentRepresentation", - "labels": { - "en": "A ZIP Thing" - }, - "comments": { - "en": "A things for testing ZIPS." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "TextThing", - "super": "TextRepresentation", - "labels": { - "en": "A Text Thing" - }, - "comments": { - "en": "A things for testing TEXTS." - }, - "cardinalities": [ - { - "propname": ":hasText", - "gui_order": 1, - "cardinality": "1" - } - ] - }, - { - "name": "PartOfThing", - "super": "StillImageRepresentation", - "labels": { - "en": "A Thing having a partOf and seqnum property" - }, - "comments": { - "en": "A thing for testing partOf and seqnum properties." - }, - "cardinalities": [ - { - "propname": "isPartOf", - "gui_order": 1, - "cardinality": "1" - }, - { - "propname": "seqnum", - "gui_order": 2, - "cardinality": "1" - } - ] - } + "ontologies": [ + { + "name": "testonto", + "label": "Test ontology", + "properties": [ + { + "name": "hasText", + "super": [ + "hasValue" + ], + "object": "TextValue", + "labels": { + "en": "Text" + }, + "gui_element": "SimpleText", + "gui_attributes": { + "maxlength": 255, + "size": 80 + } + }, + { + "name": "hasRichtext", + "super": [ + "hasValue" + ], + "object": "TextValue", + "labels": { + "en": "Text" + }, + "gui_element": "Richtext" + }, + { + "name": "hasUri", + "super": [ + "hasValue" + ], + "object": "UriValue", + "labels": { + "en": "URI" + }, + "gui_element": "SimpleText", + "gui_attributes": { + "maxlength": 255, + "size": 80 + } + }, + { + "name": "hasBoolean", + "super": [ + "hasValue" + ], + "object": "BooleanValue", + "labels": { + "en": "Boolean value" + }, + "gui_element": "Checkbox" + }, + { + "name": "hasDate", + "super": [ + "hasValue" + ], + "object": "DateValue", + "labels": { + "en": "Date" + }, + "gui_element": "Date" + }, + { + "name": "hasInteger", + "super": [ + "hasValue" + ], + "object": "IntValue", + "labels": { + "en": "Integer" + }, + "gui_element": "Spinbox", + "gui_attributes": { + "max": -1.0, + "min": 0.0 + } + }, + { + "name": "hasDecimal", + "super": [ + "hasValue" + ], + "object": "DecimalValue", + "labels": { + "en": "Decimal number" + }, + "gui_element": "SimpleText", + "gui_attributes": { + "maxlength": 255, + "size": 80 + } + }, + { + "name": "hasGeometry", + "super": [ + "hasValue" + ], + "object": "GeomValue", + "labels": { + "en": "Geometry" + }, + "gui_element": "Geometry" + }, + { + "name": "hasGeoname", + "super": [ + "hasValue" + ], + "object": "GeonameValue", + "labels": { + "en": "Geoname" + }, + "gui_element": "Geonames" + }, + { + "name": "hasInterval", + "super": [ + "hasValue" + ], + "object": "IntervalValue", + "labels": { + "en": "Time interval" + }, + "gui_element": "Interval" + }, + { + "name": "hasColor", + "super": [ + "hasValue" + ], + "object": "ColorValue", + "labels": { + "en": "Color" + }, + "gui_element": "Colorpicker" + }, + { + "name": "hasListItem", + "super": [ + "hasValue" + ], + "object": "ListValue", + "labels": { + "en": "List element" + }, + "gui_element": "List", + "gui_attributes": { + "hlist": "testlist" + } + }, + { + "name": "hasTestRegion", + "super": [ + "hasLinkTo" + ], + "object": "Region", + "labels": { + "en": "has region" + }, + "gui_element": "Searchbox" + }, + { + "name": "hasTestThing2", + "super": [ + "hasLinkTo" + ], + "object": ":TestThing2", + "labels": { + "en": "Another thing" + }, + "gui_element": "Searchbox" + } + ], + "resources": [ + { + "name": "TestThing", + "super": "Resource", + "labels": { + "en": "TestThing" + }, + "comments": { + "en": "A thing to test things", + "de": "Ein Ding um allerlei Dinge zu testen." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1-n" + }, + { + "propname": ":hasRichtext", + "gui_order": 2, + "cardinality": "0-n" + }, + { + "propname": ":hasUri", + "gui_order": 3, + "cardinality": "0-n" + }, + { + "propname": ":hasBoolean", + "gui_order": 4, + "cardinality": "1" + }, + { + "propname": ":hasDate", + "gui_order": 5, + "cardinality": "0-n" + }, + { + "propname": ":hasInteger", + "gui_order": 6, + "cardinality": "0-n" + }, + { + "propname": ":hasDecimal", + "gui_order": 7, + "cardinality": "0-n" + }, + { + "propname": ":hasGeometry", + "gui_order": 8, + "cardinality": "0-n" + }, + { + "propname": ":hasGeoname", + "gui_order": 9, + "cardinality": "0-n" + }, + { + "propname": ":hasInterval", + "gui_order": 10, + "cardinality": "0-n" + }, + { + "propname": ":hasColor", + "gui_order": 11, + "cardinality": "0-n" + }, + { + "propname": ":hasListItem", + "gui_order": 12, + "cardinality": "0-n" + }, + { + "propname": ":hasTestRegion", + "gui_order": 13, + "cardinality": "0-n" + }, + { + "propname": ":hasTestThing2", + "gui_order": 14, + "cardinality": "0-n" + } + ] + }, + { + "name": "TestThing2", + "super": "Resource", + "labels": { + "en": "Another Test Thing" + }, + "comments": { + "en": "Another thing for testing things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "CompoundThing", + "super": "Resource", + "labels": { + "en": "A Compound Thing" + }, + "comments": { + "en": "A thing for testing compound things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "ImageThing", + "super": "StillImageRepresentation", + "labels": { + "en": "An Image Thing" + }, + "comments": { + "en": "An image thing for testing image things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "AudioThing", + "super": "AudioRepresentation", + "labels": { + "en": "An Audio Thing" + }, + "comments": { + "en": "An audio thing for testing audio things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "MovieThing", + "super": "MovingImageRepresentation", + "labels": { + "en": "An Movie Thing" + }, + "comments": { + "en": "An movie thing for testing moving image things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "DocumentThing", + "super": "DocumentRepresentation", + "labels": { + "en": "A Document Thing" + }, + "comments": { + "en": "A second things for testing different things." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "ZipThing", + "super": "DocumentRepresentation", + "labels": { + "en": "A ZIP Thing" + }, + "comments": { + "en": "A things for testing ZIPS." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "TextThing", + "super": "TextRepresentation", + "labels": { + "en": "A Text Thing" + }, + "comments": { + "en": "A things for testing TEXTS." + }, + "cardinalities": [ + { + "propname": ":hasText", + "gui_order": 1, + "cardinality": "1" + } + ] + }, + { + "name": "PartOfThing", + "super": "StillImageRepresentation", + "labels": { + "en": "A Thing having a partOf and seqnum property" + }, + "comments": { + "en": "A thing for testing partOf and seqnum properties." + }, + "cardinalities": [ + { + "propname": "isPartOf", + "gui_order": 1, + "cardinality": "1" + }, + { + "propname": "seqnum", + "gui_order": 2, + "cardinality": "1" + } + ] + } + ] + } ] - } - ] - } + } }