Beispiel #1
0
 def setUp(self):
     init_annalist_test_site()
     init_annalist_test_coll()
     self.testsite = Site(TestBaseUri, TestBaseDir)
     self.testcoll = Collection(self.testsite, "testcoll")
     # Populate collection with linked record types, views and lists
     self.test_supertype_type = RecordType.create(
         self.testcoll, "test_supertype_type",
         test_supertype_type_create_values)
     self.test_subtype_type = RecordType.create(
         self.testcoll, "test_subtype_type",
         test_subtype_type_create_values)
     self.no_options = [FieldChoice('', label="(no options)")]
     # Create type and data records for testing:
     self.test_supertype_type_info = EntityTypeInfo(self.testcoll,
                                                    "test_supertype_type",
                                                    create_typedata=True)
     self.test_subtype_type_info = EntityTypeInfo(self.testcoll,
                                                  "test_subtype_type",
                                                  create_typedata=True)
     for entity_id in ("test_subtype_entity", ):
         self.test_subtype_type_info.create_entity(
             entity_id, test_subtype_entity_create_values(entity_id))
     # Login and permissions
     create_test_user(self.testcoll, "testuser", "testpassword")
     self.client = Client(HTTP_HOST=TestHost)
     loggedin = self.client.login(username="******",
                                  password="******")
     self.assertTrue(loggedin)
     return
 def setUp(self):
     init_annalist_test_site()
     init_annalist_test_coll()
     self.testsite = Site(TestBaseUri, TestBaseDir)
     self.testcoll = Collection(self.testsite, "testcoll")
     # Populate collection with linked record types, views and lists
     self.testsrc_type = RecordType.create(self.testcoll, "testsrc_type",
                                           testsrc_type_create_values)
     self.testtgt_type = RecordType.create(self.testcoll, "testtgt_type",
                                           testtgt_type_create_values)
     self.testsrc_view = RecordView.create(self.testcoll, "testsrc_view",
                                           testsrc_view_create_values)
     self.testtgt_view = RecordView.create(self.testcoll, "testtgt_view",
                                           testtgt_view_create_values)
     self.testsrc_list = RecordList.create(self.testcoll, "testsrc_list",
                                           testsrc_list_create_values)
     self.testtgt_list = RecordList.create(self.testcoll, "testtgt_list",
                                           testtgt_list_create_values)
     self.testtgtref_field = RecordField.create(
         self.testcoll, "testtgtref_field", testtgtref_field_create_values)
     self.no_options = [FieldChoice('', label="(no options)")]
     self.tgt_options = ([
         FieldChoice("testtgt_type/" + v,
                     label="testtgt_entity %s label" % v,
                     link=entity_url("testcoll", "testtgt_type", v))
         for v in ["testtgt1", "testtgt2"]
     ])
     # Create data records for testing:
     self.testtgt_type_info = EntityTypeInfo(self.testcoll,
                                             "testtgt_type",
                                             create_typedata=True)
     self.testsrc_type_info = EntityTypeInfo(self.testcoll,
                                             "testsrc_type",
                                             create_typedata=True)
     for tgt_id in ("testtgt1", "testtgt2"):
         self.testtgt_type_info.create_entity(
             tgt_id, testtgt_entity_create_values(tgt_id))
     for src_id, tgt_ref in (("testsrc1", "testtgt1"), ("testsrc2",
                                                        "testtgt2")):
         self.testsrc_type_info.create_entity(
             src_id, testsrc_entity_create_values(src_id, tgt_ref))
     # Login and permissions
     create_test_user(self.testcoll, "testuser", "testpassword")
     self.client = Client(HTTP_HOST=TestHost)
     loggedin = self.client.login(username="******",
                                  password="******")
     self.assertTrue(loggedin)
     return
Beispiel #3
0
 def test_save_subproperty_field(self):
     self.create_subproperty_field_view_entity()
     # Post edit form response
     u = entitydata_edit_url("edit",
                             "testcoll",
                             "testtype",
                             entity_id="testentity",
                             view_id="testview")
     f = ({
         'entity_id': "testentity",
         'entity_type': "testtype",
         'orig_id': "testentity",
         'orig_type': "testtype",
         'Test_sup_field': "Updated subproperty value",
         'action': "edit",
         'save': "Save"
     })
     r = self.client.post(u, f)
     self.assertEqual(r.status_code, 302)
     self.assertEqual(r.reason_phrase, "FOUND")
     # Check entity exists,and compare data with expected
     typeinfo = EntityTypeInfo(self.testcoll, "testtype")
     self.assertTrue(
         typeinfo.entityclass.exists(typeinfo.entityparent, "testentity"))
     e = typeinfo.entityclass.load(typeinfo.entityparent, "testentity")
     self.assertEqual(e.get_id(), "testentity")
     # Check superproperty value remains undefined
     self.assertEqual(e.get_values().get("test:superprop_uri", "undefined"),
                      "undefined")
     # Check subproperty has been updated
     v = self.testentity_data.get_values().copy()
     v['test:subprop_uri'] = f['Test_sup_field']
     self.assertDictionaryMatch(e.get_values(), v)
     return
Beispiel #4
0
 def setUp(self):
     self.filepath  = "%s/README.md"%TestBaseDir
     self.fileuri   = "file://"+self.filepath
     self.imagepath = "%s/test-image.jpg"%TestBaseDir
     self.imageuri  = "file://"+self.filepath
     init_annalist_test_site()
     init_annalist_test_coll()
     self.testsite    = Site(TestBaseUri, TestBaseDir)
     self.testcoll    = Collection(self.testsite, "testcoll")
     # Populate collection with record type, view and field
     self.test_ref_type = RecordType.create(
         self.testcoll, "testreftype", test_image_ref_type_create_values
         )
     self.test_ref_view = RecordView.create(
         self.testcoll, "testrefview", test_image_ref_view_create_values
         )
     self.test_ref_field = RecordField.create(
         self.testcoll, "Test_image_ref", test_image_ref_field_create_values
         )
     # Create data records for testing image references:
     self.test_ref_type_info = EntityTypeInfo(
         self.testcoll, "testreftype", create_typedata=True
         )
     self.test_ref_type_info.create_entity("test1", test_ref_entity_create_values(self.imageuri))
     # Login and permissions
     create_test_user(self.testcoll, "testuser", "testpassword")
     self.client = Client(HTTP_HOST=TestHost)
     loggedin = self.client.login(username="******", password="******")
     self.assertTrue(loggedin)
     return
 def test_save_field_alias_target(self):
     # Save BibEntry from Default_view: aliased values should be included
     u = entitydata_edit_url(
         "edit", "testcoll", "BibEntry_type", 
         entity_id="bibentity1", 
         view_id="Default_view"
         )
     f = (
         { 'entity_id':          "bibentity1"
         , 'entity_type':        "BibEntry_type"
         , 'orig_id':            "bibentity1"
         , 'orig_type':          "BibEntry_type"
         , 'Entity_label':       "Updated "+self.bibentity1_data['bib:title']
         , 'Entity_comment':     "Updated "+self.bibentity1_data['bib:note']
         , 'action':             "edit"
         , 'save':               "Save"
         })
     r = self.client.post(u, f)
     self.assertEqual(r.status_code,   302)
     self.assertEqual(r.reason_phrase, "FOUND")
     # Check entity exists,and compare data with expected
     typeinfo = EntityTypeInfo(self.testsite, self.testcoll, "BibEntry_type")
     self.assertTrue(typeinfo.entityclass.exists(typeinfo.entityparent, "bibentity1"))
     e = typeinfo.entityclass.load(typeinfo.entityparent, "bibentity1")
     self.assertEqual(e.get_id(), "bibentity1")
     v = self.bibentity1_data.copy()
     v[RDFS.CURIE.label]   = f['Entity_label']
     v[RDFS.CURIE.comment] = f['Entity_comment']
     self.assertDictionaryMatch(e.get_values(), v)
     return
    def check_collection_entity(self, entity_id, entity_type, msg):
        """
        Test a supplied entity_id is defined in the current collection,
        returning a URI to display a supplied error message if the test fails.

        NOTE: this function works with the generic base template base_generic.html, which
        is assumed to provide an underlay for the currently viewed page.

        entity_id           entity id that is required to be defined in the current collection.
        entity_type         specified type for entity to delete.
        msg                 message to display if the test fails.

        returns a URI string for use with HttpResponseRedirect to redisplay the 
        current page with the supplied message, or None if entity id is OK.
        """
        # log.info("check_collection_entity: entity_id: %s"%(entity_id))
        # log.info("check_collection_entity: entityparent: %s"%(self.entityparent.get_id()))
        # log.info("check_collection_entity: entityclass: %s"%(self.entityclass))
        redirect_uri = None
        typeinfo = self.entitytypeinfo
        if not typeinfo or typeinfo.get_type_id() != entity_type:
            typeinfo = EntityTypeInfo(self.collection, entity_type)
        if not typeinfo.entityclass.exists(typeinfo.entityparent, entity_id):
            redirect_uri = (uri_with_params(self.view.get_request_path(),
                                            self.view.error_params(msg),
                                            self.get_continuation_url_dict()))
        return redirect_uri
Beispiel #7
0
 def get_collection_subtype_ids(self, supertype_id, altscope):
     """
     Returns a iterator of type ids for all subtypes of the supplied type 
     accessible in the indicated scope from the current collection, including 
     the identified type itself.
     """
     if not valid_id(supertype_id):
         log.warning(
             "EntityFinder.get_collection_subtype_ids: invalid type_id %s" %
             (supertype_id, ))
         return
     supertype_info = EntityTypeInfo(self._coll, supertype_id)
     supertype_uri = supertype_info.get_type_uri()
     if supertype_uri is not None:
         for try_subtype_id in self.get_collection_type_ids(altscope):
             try_subtype = self._coll.cache_get_type(try_subtype_id)
             if try_subtype:
                 try_subtype_uri = try_subtype.get_uri()
                 if ((supertype_uri == try_subtype_uri) or
                     (supertype_uri in self._coll.cache_get_supertype_uris(
                         try_subtype_uri))):
                     yield try_subtype_id
     else:
         log.warning(
             "EntityFinder.get_collection_subtype_ids: no type_uri for %s" %
             (supertype_id, ))
Beispiel #8
0
def migrate_coll_data(coll):
    """
    Migrate collection data for specified collection

    Returns list of error message strings, or empty list.
    """
    log.info("Migrate Annalist collection data for %s"%(coll.get_id()))
    errs = migrate_coll_config_dirs(coll)
    if errs:
        return errs
    try:
        entityfinder = EntityFinder(coll)
        for e in entityfinder.get_entities():
            log.info("migrate_coll_data: %s/%s"%(e[ANNAL.CURIE.type_id], e[ANNAL.CURIE.id]))
            typeinfo = EntityTypeInfo(coll, e[ANNAL.CURIE.type_id])
            e[ANNAL.CURIE.type] = typeinfo.get_type_uri()
            coll.update_entity_types(e)
            e._save(post_update_flags={"nocontext"})
            if e.get_errors():
                errs.extend(e.get_errors())
    except Annalist_Error as err:
        errs.append(str(err))
    if errs:
        return errs
    # Rename _group directory
    errs = migrate_collection_dir(coll, layout.GROUP_DIR, layout.GROUP_DIR+".migrated")
    if errs:
        return errs
    coll.generate_coll_jsonld_context()    
    return errs
Beispiel #9
0
 def setUp(self):
     self.fileuri = "file://%s/README.md"%TestBaseDir
     init_annalist_test_site()
     init_annalist_test_coll()
     self.testsite    = Site(TestBaseUri, TestBaseDir)
     self.testcoll    = Collection(self.testsite, "testcoll")
     # Populate collection with linked record types, views and lists
     self.test_imp_type = RecordType.create(
         self.testcoll, "testimptype", test_import_type_create_values
         )
     self.test_imp_view = RecordView.create(
         self.testcoll, "testimpview", test_import_view_create_values
         )
     self.test_imp_field = RecordField.create(
         self.testcoll, "Test_import", test_import_field_create_values
         )
     self.test_ref_type = RecordType.create(
         self.testcoll, "testreftype", test_reference_type_create_values
         )
     self.test_ref_view = RecordView.create(
         self.testcoll, "testrefview", test_reference_view_create_values
         )
     self.test_ref_field = RecordField.create(
         self.testcoll, "Test_reference", test_reference_field_create_values
         )
     # Create data records for testing import and references:
     self.test_imp_type_info = EntityTypeInfo(
         self.testcoll, "testimptype", create_typedata=True
         )
     for entity_id in ("test1", "test2"):
         self.test_imp_type_info.create_entity(
             entity_id, test_imp_entity_create_values(entity_id)
             )
     self.test_ref_type_info = EntityTypeInfo(
         self.testcoll, "testreftype", create_typedata=True
         )
     for entity_id in ("test1", "test2"):
         self.test_ref_type_info.create_entity(
             entity_id, test_ref_entity_create_values(entity_id)
             )
     # Login and permissions
     create_test_user(self.testcoll, "testuser", "testpassword")
     self.client = Client(HTTP_HOST=TestHost)
     loggedin = self.client.login(username="******", password="******")
     self.assertTrue(loggedin)
     return
Beispiel #10
0
 def check_entity_values(self, type_id, entity_id, check_values=None):
     "Helper function checks content of entity record; returns entity"
     typeinfo = EntityTypeInfo(self.testcoll, type_id)
     self.assertTrue(typeinfo.entity_exists(entity_id))
     e = typeinfo.get_entity(entity_id)
     self.assertEqual(e.get_id(), entity_id)
     self.assertEqual(e.get_type_id(), type_id)
     self.assertDictionaryMatch(e.get_values(), check_values)
     return e
Beispiel #11
0
 def get_targetvals(self):
     """
     If field description is a reference to a target type entity or field, 
     return a copy of the referenced target entity, otherwise None.
     """
     log.debug("bound_field.get_targetvals: field_description %r" %
               (self._field_description, ))
     target_type = self._field_description.get('field_ref_type', None)
     target_key = self._field_description.get('field_ref_field', None)
     log.debug("bound_field.get_targetvals: target_type %s, target_key %s" %
               (target_type, target_key))
     if self._targetvals is None:
         if target_type:
             # Extract entity_id and type_id; default to type id from field descr
             field_val = self.get_field_value()
             log.debug("field_val: %s" % (field_val, ))
             type_id, entity_id = split_type_entity_id(
                 self.get_field_value(), target_type)
             log.debug(
                 "bound_field.get_targetvals: type_id %s, entity_id %s" %
                 (type_id, entity_id))
             # Get entity type info
             coll = self._field_description._collection
             typeinfo = EntityTypeInfo(coll, type_id)
             # Check access permission, assuming user has "VIEW" permission in collection
             # This is primarily to prevent a loophole for accessing user account details
             #@@TODO: pass actual user permissions in to bound_field or field description
             #        or extra params
             user_permissions = ["VIEW"]
             req_permissions_map = typeinfo.get_entity_permissions_map(
                 entity_id)
             req_permissions = list(
                 set(req_permissions_map[a] for a in ["view", "list"]))
             if all([p in user_permissions for p in req_permissions]):
                 if entity_id is None or entity_id == "":
                     raise TargetIdNotFound_Error(
                         value=(typeinfo.type_id,
                                self._field_description["field_name"]))
                 targetentity = typeinfo.get_entity(entity_id)
                 if targetentity is None:
                     raise TargetEntityNotFound_Error(value=(target_type,
                                                             entity_id))
                 targetentity = typeinfo.get_entity_implied_values(
                     targetentity)
                 self._targetvals = get_entity_values(
                     typeinfo, targetentity)
                 log.debug("bound_field.get_targetvals: %r" %
                           (self._targetvals, ))
             else:
                 log.warning(
                     "bound_field.get_targetvals: target value type %s requires %r permissions"
                     % (target_type, req_permissions))
     log.debug("bound_field.get_targetvals: targetvals %r" %
               (self._targetvals, ))
     return self._targetvals
 def get_collection_subtypes(self, type_id, altscope):
     """
     Returns a iterator of `entitytypeinfo` objects for all subtypes
     of the supplied type in the current collection, including the 
     identified type itself.
     """
     supertypeinfo = EntityTypeInfo(self._coll, type_id)
     supertypeuri = supertypeinfo.get_type_uri()
     if supertypeuri is None:
         log.warning(
             "EntityFinder.get_collection_uri_subtypes: no type_uri for %s"
             % (type_id, ))
     return self.get_collection_uri_subtypes(supertypeuri, altscope)
Beispiel #13
0
    def get_type_entities(self, type_id, user_permissions, scope):
        """
        Iterate over entities from collection matching the supplied type.

        'scope' is used to determine the extend of data top be included in the listing:
        a value of 'all' means that site-wide entyioties are icnluded in the listing.
        Otherwise only collection entities are included.        
        """
        entitytypeinfo = EntityTypeInfo(self._site, self._coll, type_id)
        include_sitedata = (scope == "all")
        for e in entitytypeinfo.enum_entities(user_permissions,
                                              usealtparent=include_sitedata):
            yield e
        return
Beispiel #14
0
 def test_save_subproperty_list(self):
     self.create_subproperty_field_view_entity()
     self.create_subproperty_list_field_view_entity()
     # Post edit form response
     u = entitydata_edit_url("edit",
                             "testcoll",
                             "testtype",
                             entity_id="testlistentity",
                             view_id="testlistview")
     f = ({
         'entity_id': "testlistentity",
         'entity_type': "testtype",
         'orig_id': "testlistentity",
         'orig_type': "testtype",
         'Test_sup_list__0__Test_sup_field': "Updated subprop 1",
         'Test_sup_list__1__Test_sup_field': "Updated subprop 2",
         'action': "edit",
         'save': "Save"
     })
     r = self.client.post(u, f)
     self.assertEqual(r.status_code, 302)
     self.assertEqual(r.reason_phrase, "FOUND")
     # Check entity exists,and compare data with expected
     typeinfo = EntityTypeInfo(self.testcoll, "testtype")
     self.assertTrue(
         typeinfo.entityclass.exists(typeinfo.entityparent,
                                     "testlistentity"))
     e = typeinfo.entityclass.load(typeinfo.entityparent, "testlistentity")
     # print("@@@@ e: "+repr(e.get_values()))
     self.assertEqual(e.get_id(), "testlistentity")
     # Check superproperty value remains undefined
     self.assertEqual(e.get_values().get("test:superprop_uri", "undefined"),
                      "undefined")
     # Check subproperty has been updated
     v = self.testlistentity_data.get_values().copy()
     #@@NOTE:
     #   With reference to 'test:superprop_uri' below:
     #   It is a known restriction that subproperties used within repeating field
     #   groups are not propagated.  See RepeatValuesMap.map_form_to_entity.
     #@@
     v['test:subprop_list_uri'] = ([{
         "test:superprop_uri":
         "Updated subprop 1"
     }, {
         "test:superprop_uri":
         "Updated subprop 2"
     }])
     self.assertDictionaryMatch(e.get_values(), v)
     return
Beispiel #15
0
    def check_delete_type_values(self, listinfo, entity_id, entity_type, msg):
        """
        Checks for attempt to delete type with existing values

        Returns redirect URI to display error, or None if no error
        """
        if entity_type == "_type":
            typeinfo = EntityTypeInfo(listinfo.collection, entity_id)
            if next(typeinfo.enum_entity_ids(), None) is not None:
                return (
                    # Type has values: redisplay form with error message
                    uri_with_params(listinfo.view.get_request_path(),
                                    listinfo.view.error_params(msg),
                                    listinfo.get_continuation_url_dict()))
        return None
 def _check_entity_data_values(self, 
     entity_id, type_id="testtype", update="Entity", 
     comment2="Comment field 2",
     comment3="Comment field 3"
     ):
     "Helper function checks content of form-updated record type entry with supplied entity_id"
     # log.info("_check_entity_data_values: type_id %s, entity_id %s"%(type_id, entity_id))
     typeinfo = EntityTypeInfo(self.testcoll, type_id)
     self.assertTrue(typeinfo.entityclass.exists(typeinfo.entityparent, entity_id))
     e = typeinfo.entityclass.load(typeinfo.entityparent, entity_id)
     self.assertEqual(e.get_id(), entity_id)
     v = entitydata_values(entity_id, type_id=type_id, update=update)
     v = entitydata_values_add_field(v, "rdfs:comment", 2, comment2)
     v = entitydata_values_add_field(v, "rdfs:comment_alt", 3, comment3)
     self.assertDictionaryMatch(e.get_values(), v)
     return e
 def get_collection_uri_subtypes(self, type_uri, altscope=None):
     """
     Returns a iterator of `entitytypeinfo` objects for all subtypes
     of the supplied type in the current collection, including the 
     identified type itself.
     """
     # log.info(
     #     "@@ EntityFinder.get_collection_uri_subtypes: type_uri %s, altscope=%s"%
     #     (type_uri, altscope)
     #     )
     if type_uri is not None:
         for tid in self.get_collection_type_ids(altscope):
             tinfo = EntityTypeInfo(self._coll, tid)
             if tinfo and (type_uri in tinfo.get_all_type_uris()):
                 yield tinfo
     return
Beispiel #18
0
 def _check_entity_data_values(self, entity_id, type_id="testtype", update="Entity", update_dict=None):
     "Helper function checks content of form-updated record type entry with supplied entity_id"
     # log.info("_check_entity_data_values: type_id %s, entity_id %s"%(type_id, entity_id))
     typeinfo = EntityTypeInfo(self.testsite, self.testcoll, type_id)
     self.assertTrue(typeinfo.entityclass.exists(typeinfo.entityparent, entity_id))
     e = typeinfo.entityclass.load(typeinfo.entityparent, entity_id)
     self.assertEqual(e.get_id(), entity_id)
     self.assertEqual(e.get_view_url(""), TestHostUri + entity_url("testcoll", type_id, entity_id))
     v = entitydata_values(entity_id, type_id=type_id, update=update)
     if update_dict:
         v.update(update_dict)
         for k in update_dict:
             if update_dict[k] is None:
                 v.pop(k, None)
     # log.info(e.get_values())
     self.assertDictionaryMatch(e.get_values(), v)
     return e
    def get_type_entities(self, type_id, user_permissions, altscope):
        """
        Iterate over entities from collection matching the supplied type.

        'altscope' is used to determine the extent of data to be included in the listing:
        a value of 'all' means that site-wide entyities are icnluded in the listing.
        Otherwise only collection entities are included.        
        """
        #@@
        # log.info("get_type_entities: type_id %s"%type_id)
        #@@
        entitytypeinfo = EntityTypeInfo(self._coll, type_id)
        for e in entitytypeinfo.enum_entities_with_implied_values(
                user_permissions, altscope=altscope):
            if e.get_id() != "_initial_values":
                yield e
        return
Beispiel #20
0
 def get_type_info(self, type_id):
     """
     Check type identifier, and get reference to type information object.
     """
     if not self.http_response:
         assert ((self.site and self.collection) is not None)
         if type_id:
             self.type_id = type_id
             self.entitytypeinfo = EntityTypeInfo(self.collection, type_id)
             if not self.entitytypeinfo.recordtype:
                 # log.warning("DisplayInfo.get_type_data: RecordType %s not found"%type_id)
                 self.http_response = self.view.error(
                     dict(self.view.error404values(),
                          message=message.RECORD_TYPE_NOT_EXISTS %
                          ({
                              'id': type_id,
                              'coll_id': self.coll_id
                          })))
     return self.http_response
Beispiel #21
0
def get_entity_values(displayinfo, entity, entity_id=None):
    """
    Returns an entity values dictionary for a supplied entity, suitable for
    use with a bound_field object.
    """
    if not entity_id:
        entity_id = entity.get_id()
    type_id = entity.get_type_id()
    entityvals = entity.get_values().copy()
    entityvals['entity_id'] = entity_id
    entityvals['entity_link'] = entity.get_view_url_path()
    # log.info("type_id %s"%(type_id))
    entityvals['entity_type_id'] = type_id
    typeinfo = EntityTypeInfo(displayinfo.site, displayinfo.collection,
                              type_id)
    if typeinfo.recordtype:
        entityvals['entity_type_link'] = typeinfo.recordtype.get_view_url_path(
        )
        # @@other type-related info; e.g., aliases - populate
    return entityvals
Beispiel #22
0
    def get_subtype_entities(self, type_id, user_permissions, altscope):
        """
        Iterate over entities from collection that are of the indicated type
        or any of its subtypes.

        'altscope' is used to determine the extent of data to be included in the listing:
        a value of 'all' means that site-wide entities are included in the listing.
        Otherwise only collection entities are included.        
        """
        for subtype_id in self.get_collection_subtype_ids(type_id, "all"):
            subtype_info = EntityTypeInfo(self._coll, subtype_id)
            es = subtype_info.enum_entities_with_implied_values(
                user_permissions, altscope=altscope)
            #@@
            # es = list(es) #@@ Force strict eval
            # log.info("get_subtype_entities: %r"%([e.get_id() for e in es],))
            #@@
            for e in es:
                if e.get_id() != layout.INITIAL_VALUES_ID:
                    yield e
        return
 def test_save_field_alias_source(self):
     # Save BibEntry from BibEntry_view: aliases should not be included
     u = entitydata_edit_url("edit",
                             "testcoll",
                             "BibEntry_type",
                             entity_id="bibentity1",
                             view_id="BibEntry_view")
     f = ({
         'entity_id': "bibentity1",
         'entity_type': "BibEntry_type",
         'orig_id': "bibentity1",
         'orig_type': "BibEntry_type",
         'Bib_type': "article",
         'Bib_title': "Updated " + self.bibentity1_data['bib:title'],
         'Bib_year': "2014",
         'Bib_month': "09",
         'Bib_note': "Updated " + self.bibentity1_data['bib:note'],
         'action': "edit",
         'save': "Save"
     })
     r = self.client.post(u, f)
     self.assertEqual(r.status_code, 302)
     self.assertEqual(r.reason_phrase, "FOUND")
     # Check entity exists,and compare data with expected
     typeinfo = EntityTypeInfo(self.testcoll, "BibEntry_type")
     self.assertTrue(
         typeinfo.entityclass.exists(typeinfo.entityparent, "bibentity1"))
     e = typeinfo.entityclass.load(typeinfo.entityparent, "bibentity1")
     self.assertEqual(e.get_id(), "bibentity1")
     v = self.bibentity1_data.copy()
     v['bib:title'] = f['Bib_title']
     v['bib:note'] = f['Bib_note']
     del v['bib:author']
     self.assertDictionaryMatch(e.get_values(), v)
     self.assertEqual(e.get_values().get(RDFS.CURIE.label, None), None)
     # Comment defaults from aliased label value
     self.assertEqual(e.get_values().get(RDFS.CURIE.comment, None),
                      f['Bib_title'])
     return
Beispiel #24
0
def copy_coll_data(src_coll, tgt_coll):
    """
    Copy collection data from specified source to target collection.

    returns     list of error messages; an empty list indicates success.
    """
    log.info("Copying collection '%s' to '%s'" %
             (src_coll.get_id(), tgt_coll.get_id()))
    msgs = []
    entityfinder = EntityFinder(src_coll)
    for e in entityfinder.get_entities():
        entity_id = e.get_id()
        typeinfo = EntityTypeInfo(tgt_coll,
                                  e.get_type_id(),
                                  create_typedata=True)
        new_entity = typeinfo.create_entity(entity_id, e.get_values())
        if not typeinfo.entity_exists(entity_id):
            msg = ("Collection.copy_coll_data: Failed to create entity %s/%s" %
                   (typeinfo.type_id, entity_id))
            log.warning(msg)
            msgs.append(msg)
        msgs += new_entity._copy_entity_files(e)
    return msgs
Beispiel #25
0
 def get_uri_type_info(self, type_uri):
     """
     Return typeinfo corresponding to the supplied type URI
     """
     t = self._coll.get_uri_type(type_uri)
     return t and EntityTypeInfo(self._coll, t.get_id())
Beispiel #26
0
    def test_inherited_image_edit(self):
        # This tests that editing an inherited image creartes a new copy in the
        # inheriting collection.

        # Upload image
        self.test_image_edit_field()

        # Create collection inheriting uploaded image
        testsubcoll = create_test_coll_inheriting(base_coll_id="testcoll",
                                                  coll_id="testsubcoll",
                                                  type_id="testtype")
        # create_test_user(testsubcoll, "testuser", "testpassword")
        user_permissions = ["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG"]
        user_id = "testuser"
        user_perms = testsubcoll.create_user_permissions(
            user_id, "mailto:%s@%s" % (user_id, TestHost), "Test User",
            "User %s: permissions for %s in collection %s" %
            (user_id, "Test User", testsubcoll.get_id()), user_permissions)

        # Get editing form
        u = entitydata_edit_url("edit",
                                "testsubcoll",
                                "testimgtype",
                                entity_id="test1",
                                view_id="testimgview")
        r = self.client.get(u)
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.reason_phrase, "OK")
        # log.info(r.content)     #@@
        hi1 = """<input type="hidden" name="orig_id"          value="test1" />"""
        hi2 = """<input type="hidden" name="orig_type"        value="testimgtype" />"""
        hi3 = """<input type="hidden" name="orig_coll"        value="testcoll" />"""
        hi4 = """<input type="hidden" name="action"           value="edit" />"""
        hi5 = """<input type="hidden" name="view_id"          value="testimgview" />"""
        self.assertContains(r, hi1, html=True)
        self.assertContains(r, hi2, html=True)
        self.assertContains(r, hi3, html=True)
        self.assertContains(r, hi4, html=True)
        self.assertContains(r, hi5, html=True)

        # Edit entity
        f = default_view_form_data(coll_id="testsubcoll",
                                   type_id="testimgtype",
                                   entity_id="test1",
                                   orig_coll="testcoll",
                                   action="edit",
                                   update="Updated")
        u = entitydata_edit_url("edit",
                                "testsubcoll",
                                "testimgtype",
                                entity_id="test1",
                                view_id="testimgview")
        r = self.client.post(u, f)
        self.assertEqual(r.status_code, 302)
        self.assertEqual(r.reason_phrase, "FOUND")

        # Retrieve updated form
        r = self.client.get(u)
        # Test context
        self.assertEqual(len(r.context['fields']), 4)
        f0 = context_view_field(r.context, 0, 0)
        self.assertEqual(f0.field_id, "Entity_id")
        self.assertEqual(f0.field_value, "test1")
        f1 = context_view_field(r.context, 1, 0)
        self.assertEqual(f1.field_id, "Entity_label")
        self.assertEqual(f1.field_value,
                         "Updated testsubcoll/testimgtype/test1")
        f2 = context_view_field(r.context, 2, 0)
        self.assertEqual(f2.field_id, "Entity_comment")
        f3 = context_view_field(r.context, 3, 0)
        self.assertEqual(f3.field_id, "Test_image")
        self.assertDictionaryMatch(f3.field_value, test_image_field_value())

        # Read back and compare entity resource
        inherited_test_img_type_info = EntityTypeInfo(testsubcoll,
                                                      "testimgtype",
                                                      create_typedata=True)
        siteobj = open(self.imagepath, "rb")
        testobj = inherited_test_img_type_info.get_fileobj(
            "test1", "img_field", "annal:Image", "image/jpeg", "rb")
        self.assertTrue(siteobj.read() == testobj.read(),
                        "Edited entity image != original")
    def setUp(self):
        self.filepath = "%s/testdatafile.md" % TestBaseDir
        self.fileuri = "file://" + self.filepath
        self.imagepath = "%s/test-image.jpg" % TestBaseDir
        self.imageuri = "file://" + self.imagepath
        init_annalist_test_site()
        init_annalist_test_coll()
        self.testsite = Site(TestBaseUri, TestBaseDir)
        self.testcoll = Collection(self.testsite, "testcoll")
        # Populate collection with linked record types, views and lists

        # Types
        self.test_upl_type = RecordType.create(self.testcoll, "testupltype",
                                               test_upload_type_create_values)
        self.test_ref_type = RecordType.create(
            self.testcoll, "testreftype", test_reference_type_create_values)
        self.test_image_type = RecordType.create(
            self.testcoll, "testimgtype", test_image_type_create_values)

        # Views
        self.test_upl_file_view = RecordView.create(
            self.testcoll, "testuplfileview",
            test_upload_file_view_create_values)
        self.test_upl_image_view = RecordView.create(
            self.testcoll, "testuplimageview",
            test_upload_image_view_create_values)
        self.test_ref_file_view = RecordView.create(
            self.testcoll, "testrefview", test_reference_view_create_values)
        self.test_ref_image_view = RecordView.create(
            self.testcoll, "testimgrefview", test_image_ref_view_create_values)
        self.test_image_view = RecordView.create(
            self.testcoll, "testimgview", test_image_view_create_values)

        # Fields
        self.test_upl_file_field = RecordField.create(
            self.testcoll, "Test_upload_file",
            test_upload_file_field_create_values)
        self.test_upl_image_field = RecordField.create(
            self.testcoll, "Test_upload_image",
            test_upload_image_field_create_values)
        self.test_ref_file_field = RecordField.create(
            self.testcoll, "Test_reference",
            test_reference_field_create_values)
        self.test_ref_image_field = RecordField.create(
            self.testcoll, "Test_image_ref",
            test_image_ref_field_create_values)
        self.test_image_field = RecordField.create(
            self.testcoll, "Test_image", test_image_field_create_values)

        # Create data records for testing import and references:
        test_entity_ids = ("test1", "test2")
        test_entity_ids = ("test1", )
        self.test_upl_type_info = EntityTypeInfo(self.testcoll,
                                                 "testupltype",
                                                 create_typedata=True)
        for entity_id in test_entity_ids:
            self.test_upl_type_info.create_entity(
                entity_id, test_imp_entity_create_values(entity_id))
        self.test_ref_type_info = EntityTypeInfo(self.testcoll,
                                                 "testreftype",
                                                 create_typedata=True)
        for entity_id in test_entity_ids:
            self.test_ref_type_info.create_entity(
                entity_id, test_ref_entity_create_values(entity_id))
        self.test_img_type_info = EntityTypeInfo(self.testcoll,
                                                 "testimgtype",
                                                 create_typedata=True)
        for entity_id in test_entity_ids:
            self.test_img_type_info.create_entity(
                entity_id, test_img_entity_create_values(entity_id))
        # Login and permissions
        create_test_user(self.testcoll, "testuser", "testpassword")
        self.client = Client(HTTP_HOST=TestHost)
        loggedin = self.client.login(username="******",
                                     password="******")
        self.assertTrue(loggedin)
        return
Beispiel #28
0
    def post(self, request, coll_id=None, type_id=None, list_id=None):
        """
        Handle response from dynamically generated list display form.
        """
        log.info("views.entitylist.post: coll_id %s, type_id %s, list_id %s" %
                 (coll_id, type_id, list_id))
        log.log(settings.TRACE_FIELD_VALUE, "  %s" % (self.get_request_path()))
        log.log(settings.TRACE_FIELD_VALUE, "  form data %r" % (request.POST))
        listinfo = self.list_setup(coll_id, type_id, list_id,
                                   request.POST.dict())
        if listinfo.http_response:
            return listinfo.http_response
        if 'close' in request.POST:
            return HttpResponseRedirect(listinfo.get_continuation_url()
                                        or self.collection_view_url)

        # Process requested action
        redirect_uri = None
        entity_ids = request.POST.getlist('entity_select')
        log.debug("entity_ids %r" % (entity_ids))
        if len(entity_ids) > 1:
            action = ""
            redirect_uri = self.check_value_supplied(
                None,
                message.TOO_MANY_ENTITIES_SEL,
                continuation_url=listinfo.get_continuation_url())
        else:
            entity_type = type_id or listinfo.get_list_type_id()
            entity_id = None
            if len(entity_ids) == 1:
                (entity_type,
                 entity_id) = split_type_entity_id(entity_ids[0], entity_type)
            if "new" in request.POST:
                action = "new"
                redirect_uri = uri_with_params(
                    listinfo.get_new_view_uri(coll_id, entity_type),
                    {'continuation_url': listinfo.get_continuation_here()})
            if "copy" in request.POST:
                action = "copy"
                redirect_uri = (
                    self.check_value_supplied(
                        entity_id,
                        message.NO_ENTITY_FOR_COPY,
                        continuation_url=listinfo.get_continuation_url())
                    or uri_with_params(
                        listinfo.get_edit_view_uri(coll_id, entity_type,
                                                   entity_id, action),
                        {'continuation_url': listinfo.get_continuation_here()
                         }))
            if "edit" in request.POST:
                action = "edit"
                redirect_uri = (
                    self.check_value_supplied(
                        entity_id,
                        message.NO_ENTITY_FOR_EDIT,
                        continuation_url=listinfo.get_continuation_url())
                    or uri_with_params(
                        listinfo.get_edit_view_uri(coll_id, entity_type,
                                                   entity_id, action),
                        {'continuation_url': listinfo.get_continuation_here()
                         }))
            if "delete" in request.POST:
                action = "delete"
                redirect_uri = (self.check_value_supplied(
                    entity_id,
                    message.NO_ENTITY_FOR_DELETE,
                    continuation_url=listinfo.get_continuation_url())
                                or listinfo.check_collection_entity(
                                    entity_id, entity_type,
                                    message.SITE_ENTITY_FOR_DELETE %
                                    {'id': entity_id})
                                or self.check_delete_type_values(
                                    listinfo, entity_id, entity_type,
                                    message.TYPE_VALUES_FOR_DELETE %
                                    {'type_id': entity_id}))
                if not redirect_uri:
                    # Get user to confirm action before actually doing it
                    confirmed_action_uri = self.view_uri(
                        "AnnalistEntityDataDeleteView",
                        coll_id=coll_id,
                        type_id=entity_type)
                    # log.info("coll_id %s, type_id %s, confirmed_action_uri %s"%(coll_id, entity_type, confirmed_action_uri))
                    delete_params = dict_querydict({
                        "entity_delete": ["Delete"],
                        "entity_id": [entity_id],
                        "completion_url": [listinfo.get_continuation_here()],
                        "search_for": [request.POST['search_for']]
                    })
                    curi = listinfo.get_continuation_url()
                    if curi:
                        dict_querydict["continuation_url"] = [curi]
                    message_vals = {
                        'id': entity_id,
                        'type_id': entity_type,
                        'coll_id': coll_id
                    }
                    typeinfo = listinfo.entitytypeinfo
                    if typeinfo is None:
                        typeinfo = EntityTypeInfo(listinfo.collection,
                                                  entity_type)
                    return (self.form_action_auth(
                        "delete", listinfo.collection,
                        typeinfo.permissions_map) or ConfirmView.render_form(
                            request,
                            action_description=message.REMOVE_ENTITY_DATA %
                            message_vals,
                            confirmed_action_uri=confirmed_action_uri,
                            action_params=delete_params,
                            cancel_action_uri=listinfo.get_continuation_here(),
                            title=self.site_data()["title"]))
            if "default_view" in request.POST:
                if listinfo.entitytypeinfo:
                    permissions_map = listinfo.entitytypeinfo.permissions_map
                else:
                    permissions_map = CONFIG_PERMISSIONS
                auth_check = self.form_action_auth("config",
                                                   listinfo.collection,
                                                   permissions_map)
                if auth_check:
                    return auth_check
                listinfo.collection.set_default_list(list_id)
                action = "list"
                msg = message.DEFAULT_LIST_UPDATED % {
                    'coll_id': coll_id,
                    'list_id': list_id
                }
                redirect_uri = (uri_with_params(
                    self.get_request_path(), self.info_params(msg),
                    listinfo.get_continuation_url_dict()))
            if (("list_type" in request.POST) or ("list_all" in request.POST)):
                action = "list"
                redirect_uri = self.get_list_url(
                    coll_id,
                    extract_entity_id(request.POST['list_choice']),
                    type_id=None if "list_all" in request.POST else type_id,
                    scope="all" if "list_scope_all" in request.POST else None,
                    search=request.POST['search_for'],
                    query_params=listinfo.get_continuation_url_dict())
            if "customize" in request.POST:
                action = "config"
                redirect_uri = (uri_with_params(
                    self.view_uri("AnnalistCollectionEditView",
                                  coll_id=coll_id),
                    {'continuation_url': listinfo.get_continuation_here()}))
        if redirect_uri:
            return (listinfo.check_authorization(action)
                    or HttpResponseRedirect(redirect_uri))
        # Report unexpected form data
        # This shouldn't happen, but just in case...
        # Redirect to continuation with error
        log.error("Unexpected form data posted to %s: %r" %
                  (request.get_full_path(), request.POST))
        err_values = self.error_params(
            message.UNEXPECTED_FORM_DATA % (request.POST),
            message.SYSTEM_ERROR)
        redirect_uri = uri_with_params(listinfo.get_continuation_next(),
                                       err_values)
        return HttpResponseRedirect(redirect_uri)
Beispiel #29
0
    def post(self,
             request,
             coll_id=None,
             type_id=None,
             list_id=None,
             scope=None):
        """
        Handle response from dynamically generated list display form.
        """
        log.info("views.entitylist.post: coll_id %s, type_id %s, list_id %s" %
                 (coll_id, type_id, list_id))
        # log.info("  %s"%(self.get_request_path()))
        # log.info("  form data %r"%(request.POST))
        continuation_next, continuation_here = self.continuation_urls(
            request.POST, None
            # self.view_uri("AnnalistSiteView")
            # self.view_uri("AnnalistCollectionEditView", coll_id=coll_id)
        )
        if 'close' in request.POST:
            return HttpResponseRedirect(
                continuation_next.get('continuation_url',
                                      self.view_uri("AnnalistSiteView")))

        # Not "Close": set up list parameters
        listinfo = self.list_setup(coll_id, type_id, list_id)
        if listinfo.http_response:
            return listinfo.http_response

        # Process requested action
        redirect_uri = None
        entity_ids = request.POST.getlist('entity_select')
        log.debug("entity_ids %r" % (entity_ids))
        if len(entity_ids) > 1:
            action = ""
            redirect_uri = self.check_value_supplied(
                None, message.TOO_MANY_ENTITIES_SEL)
        else:
            (entity_type, entity_id) = (entity_ids[0].split("/") if
                                        len(entity_ids) == 1 else (None, None))
            entity_type = entity_type or type_id or listinfo.get_list_type_id()
            if "new" in request.POST:
                action = "new"
                redirect_uri = uri_with_params(
                    listinfo.get_new_view_uri(coll_id, entity_type),
                    continuation_here)
            if "copy" in request.POST:
                action = "copy"
                redirect_uri = (self.check_value_supplied(
                    entity_id,
                    message.NO_ENTITY_FOR_COPY,
                    continuation_url=continuation_next) or uri_with_params(
                        listinfo.get_edit_view_uri(coll_id, entity_type,
                                                   entity_id, action),
                        continuation_here))
            if "edit" in request.POST:
                action = "edit"
                redirect_uri = (self.check_value_supplied(
                    entity_id,
                    message.NO_ENTITY_FOR_EDIT,
                    continuation_url=continuation_next) or uri_with_params(
                        listinfo.get_edit_view_uri(coll_id, entity_type,
                                                   entity_id, action),
                        continuation_here))
            if "delete" in request.POST:
                action = "delete"
                redirect_uri = (self.check_value_supplied(
                    entity_id,
                    message.NO_ENTITY_FOR_DELETE,
                    continuation_url=continuation_next)
                                or listinfo.check_collection_entity(
                                    entity_id,
                                    entity_type,
                                    message.SITE_ENTITY_FOR_DELETE %
                                    {'id': entity_id},
                                    continuation_url=continuation_next)
                                or self.check_delete_type_values(
                                    listinfo,
                                    entity_id,
                                    entity_type,
                                    message.TYPE_VALUES_FOR_DELETE %
                                    {'type_id': entity_id},
                                    continuation_url=continuation_next))
                if not redirect_uri:
                    # Get user to confirm action before actually doing it
                    confirmed_action_uri = self.view_uri(
                        "AnnalistEntityDataDeleteView",
                        coll_id=coll_id,
                        type_id=entity_type)
                    # log.info("coll_id %s, type_id %s, confirmed_action_uri %s"%(coll_id, entity_type, confirmed_action_uri))
                    delete_params = dict_querydict({
                        "entity_delete": ["Delete"],
                        "entity_id": [entity_id],
                        "completion_url":
                        [continuation_here['continuation_url']],
                        "continuation_url":
                        [continuation_next.get('continuation_url')],
                        "search_for": [request.POST['search_for']]
                    })
                    message_vals = {
                        'id': entity_id,
                        'type_id': entity_type,
                        'coll_id': coll_id
                    }
                    typeinfo = listinfo.entitytypeinfo
                    if typeinfo is None:
                        typeinfo = EntityTypeInfo(listinfo.site,
                                                  listinfo.collection,
                                                  entity_type)
                    return (self.form_action_auth(
                        "delete", listinfo.collection,
                        typeinfo.permissions_map) or ConfirmView.render_form(
                            request,
                            action_description=message.REMOVE_ENTITY_DATA %
                            message_vals,
                            confirmed_action_uri=confirmed_action_uri,
                            action_params=delete_params,
                            cancel_action_uri=self.get_request_path(),
                            title=self.site_data()["title"]))
            if "default_view" in request.POST:
                if listinfo.entitytypeinfo:
                    permissions_map = listinfo.entitytypeinfo.permissions_map
                else:
                    permissions_map = CONFIG_PERMISSIONS
                auth_check = self.form_action_auth("config",
                                                   listinfo.collection,
                                                   permissions_map)
                if auth_check:
                    return auth_check
                listinfo.collection.set_default_list(list_id)
                action = "list"
                msg = message.DEFAULT_VIEW_UPDATED % {
                    'coll_id': coll_id,
                    'list_id': list_id
                }
                redirect_uri = (uri_with_params(self.get_request_path(),
                                                self.info_params(msg),
                                                continuation_next))
            if ("view" in request.POST) or ("view_all" in request.POST):
                action = "list"
                search = request.POST['search_for']
                params = continuation_next
                if search:
                    params = dict(params, search=search)
                list_uri_params = ({
                    'coll_id': coll_id,
                    'list_id': request.POST['list_choice']
                })
                if "view_all" in request.POST:
                    list_uri_params['scope'] = "all"
                #@@
                # if type_id:
                #     list_uri_params.update({'type_id': type_id})
                #@@
                redirect_uri = (uri_with_params(
                    self.view_uri("AnnalistEntityGenericList",
                                  **list_uri_params), params))
            if "customize" in request.POST:
                action = "config"
                redirect_uri = (uri_with_params(
                    self.view_uri("AnnalistCollectionEditView",
                                  coll_id=coll_id), continuation_here))
        if redirect_uri:
            return (listinfo.check_authorization(action)
                    or HttpResponseRedirect(redirect_uri))
        # Report unexpected form data
        # This shouldn't happen, but just in case...
        # Redirect to continuation with error
        log.error("Unexpected form data posted to %s: %r" %
                  (request.get_full_path(), request.POST))
        err_values = self.error_params(
            message.UNEXPECTED_FORM_DATA % (request.POST),
            message.SYSTEM_ERROR)
        redirect_uri = uri_with_params(continuation_next['continuation_url'],
                                       err_values)
        return HttpResponseRedirect(redirect_uri)
Beispiel #30
0
 def check_entity_does_not_exist(self, type_id, entity_id):
     "Helper function checks content of entity record"
     typeinfo = EntityTypeInfo(self.testcoll, type_id)
     self.assertFalse(typeinfo.entity_exists(entity_id))
     return