Пример #1
0
 def _map_entity_field_enum_val(self, entitydata, key, type_id, old_enum_val, new_enum_val):
     """
     Map enumerated value of specified type
     """
     if key in entitydata:
         type_id_here, enum_val_here = split_type_entity_id(entitydata[key])
         if type_id_here == type_id and enum_val_here == old_enum_val:
             entitydata[key] = make_type_entity_id(type_id, new_enum_val)
     return entitydata
Пример #2
0
 def _map_entity_field_enum_val(self, entitydata, key, type_id, old_enum_val, new_enum_val):
     """
     Map enumerated value of specified type
     """
     if key in entitydata:
         type_id_here, enum_val_here = split_type_entity_id(entitydata[key])
         if type_id_here == type_id and enum_val_here == old_enum_val:
             entitydata[key] = make_type_entity_id(type_id, new_enum_val)
     return entitydata
Пример #3
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
Пример #4
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
Пример #5
0
    def _migrate_values(self, entitydata):
        """
        Field description entity format migration method.

        The specification for this method is that it returns an entitydata value
        which is a copy of the supplied entitydata with format migrations applied.

        NOTE:  implementations are free to apply migrations in-place.  The resulting 
        entitydata should be exactly as the supplied data *should* appear in storage
        to conform to the current format of the data.  The migration function should 
        be idempotent; i.e.
            x._migrate_values(x._migrate_values(e)) == x._migrate_values(e)
        """
        field_id = entitydata[ANNAL.CURIE.id]
        migration_map = (
            [ (ANNAL.CURIE.options_typeref,     ANNAL.CURIE.field_ref_type       )
            , (ANNAL.CURIE.restrict_values,     ANNAL.CURIE.field_ref_restriction)
            , (ANNAL.CURIE.target_field,        ANNAL.CURIE.field_ref_field      )
            , (ANNAL.CURIE.field_target_type,   ANNAL.CURIE.field_value_type     )
            ])
        entitydata = self._migrate_values_map_field_names(migration_map, entitydata)
        # Fix up enumerated values to use new enumeration type names
        field_enum_types = (
            [ (ANNAL.CURIE.field_render_type, "_enum_render_type")
            , (ANNAL.CURIE.field_value_mode,  "_enum_value_mode")
            ])
        for fkey, ftype in field_enum_types:
            if fkey in entitydata and entitydata[fkey]:
                entitydata[fkey] = make_type_entity_id(
                    ftype, extract_entity_id(entitydata[fkey])
                    )
        # If comment and no tooltip, create tooltip and update comment
        if (RDFS.CURIE.comment in entitydata) and (ANNAL.CURIE.tooltip not in entitydata):
            label   = entitydata.get(RDFS.CURIE.label, "Field '%s'"%field_id)
            comment = entitydata[RDFS.CURIE.comment]
            entitydata[ANNAL.CURIE.tooltip] = comment
            entitydata[RDFS.CURIE.comment]  = "# %s\r\n\r\n%s"%(label, comment)
        # If reference to field group, copy group field list inline
        if ANNAL.CURIE.group_ref in entitydata:
            group_type_id, group_id = split_type_entity_id(
                entitydata[ANNAL.CURIE.group_ref], default_type_id=layout.GROUP_TYPEID
                )
            if group_id != "":
                log.info("Migrating group reference %s in field %s"%(group_id, field_id))
                group_obj = RecordGroup_migration.load(self._parent, group_id)
                if not group_obj:
                    msg = (
                        "Failed to load group '%s' for field '%s' in collection '%s'"%
                        (group_id, field_id, self._parent.get_id())
                        )
                    log.warning(msg)
                    self.set_error(msg)
                    # raise Annalist_Error(msg)
                else:
                    field_value_type = entitydata[ANNAL.CURIE.field_value_type]
                    group_entity_type = group_obj[ANNAL.CURIE.group_entity_type]
                    if field_value_type and group_entity_type and field_value_type != group_entity_type:
                        log.warning(
                            "Group %s entity type %s differs from field %s value type %s"%
                            (group_id, group_entity_type, field_id, field_value_type)
                            )
                    entitydata[ANNAL.CURIE.field_fields] = group_obj[ANNAL.CURIE.group_fields]
            del entitydata[ANNAL.CURIE.group_ref]
        # Default render type to "Text"
        if ANNAL.CURIE.field_render_type not in entitydata:
            entitydata[ANNAL.CURIE.field_render_type] = "_enum_render_type/Text"
        # Migrate changed render type names
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "RepeatGroup", "Group_Seq"
            )
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "RepeatGroupRow", "Group_Seq_Row"
            )
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "Slug", "EntityRef"
            )
        # Calculate mode from other fields if not defined
        val_render = entitydata[ANNAL.CURIE.field_render_type]
        ref_type  = entitydata.get(ANNAL.CURIE.field_ref_type, None)
        ref_field = entitydata.get(ANNAL.CURIE.field_ref_field, None)
        if ANNAL.CURIE.field_value_mode in entitydata:
            val_mode = entitydata[ANNAL.CURIE.field_value_mode]
        else:
            val_mode  = "Value_direct"
            if ref_type and ref_field:
                val_mode = "Value_field"
            elif val_render == "RefMultifield":
                val_mode = "Value_entity"
            elif val_render == "URIImport":
                val_mode = "Value_import"
            elif val_render == "FileUpload":
                val_mode = "Value_upload"
            entitydata[ANNAL.CURIE.field_value_mode] = val_mode
        # Consistency checks
        if val_mode == "Value_field":
            if ( not (ref_type and ref_field) ):
               log.warning(
                    "RecordField %s: val_mode 'Value_field' requires values for %s and %s"%
                        (field_id, ANNAL.CURIE.field_ref_type, ANNAL.CURIE.field_ref_field)
                    )
        elif val_mode == "Value_entity":
            if not ref_type:
               log.warning(
                    "RecordField %s: val_mode 'Value_entity' requires value for %s"%
                        (field_id, ANNAL.CURIE.field_ref_type)
                    )
            if ref_field:
               log.warning(
                    "RecordField %s: val_mode 'Value_entity' should not define value for %s"%
                        (field_id, ANNAL.CURIE.field_ref_field)
                    )
        # Return result
        return entitydata
Пример #6
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)
Пример #7
0
def add_link_to_field_choice(fc, coll_id, default_type_id=None):
    type_id, entity_id = split_type_entity_id(fc.id,
                                              default_type_id=default_type_id)
    return fc.add_link(entity_url(coll_id, type_id, entity_id))
Пример #8
0
def id_from_field_choice(fc):
    type_id, entity_id = split_type_entity_id(fc.id)
    return entity_id
Пример #9
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
        action          = None
        redirect_path   = None
        redirect_cont   = listinfo.get_continuation_here()
        redirect_params = {}
        entity_ids      = request.POST.getlist('entity_select')
        log.debug("entity_ids %r"%(entity_ids))
        if len(entity_ids) > 1:
            listinfo.display_error_response(message.TOO_MANY_ENTITIES_SEL)
        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)
                log.info("EntityList.post entity_ids: entity_type %s, entity_id %s"%(entity_type, entity_id))
            if "new" in request.POST:
                action        = "new"
                redirect_path = listinfo.get_new_view_uri(coll_id, entity_type)
            if "copy" in request.POST:
                action = "copy"
                if not entity_id:
                    listinfo.display_error_response(message.NO_ENTITY_FOR_COPY)
                else:
                    redirect_path = listinfo.get_edit_view_uri(
                        coll_id, entity_type, entity_id, action
                        )
            if "edit" in request.POST:
                action = "edit"
                if not entity_id:
                    listinfo.display_error_response(message.NO_ENTITY_FOR_EDIT)
                else:
                    redirect_path = listinfo.get_edit_view_uri(
                        coll_id, entity_type, entity_id, action
                        )
            if "delete" in request.POST:
                action = "delete"
                confirmed_deletion_uri = self.view_uri(
                    "AnnalistEntityDataDeleteView", 
                    coll_id=coll_id, type_id=entity_type
                    )
                return listinfo.confirm_delete_entity_response(
                    entity_type, entity_id, 
                    confirmed_deletion_uri
                    )
            if "default_view" in request.POST:
                #@@
                # auth_check = self.form_action_auth("config", listinfo.collection, CONFIG_PERMISSIONS)
                #@@
                auth_check = listinfo.check_authorization("config")
                if auth_check:
                    return auth_check
                listinfo.collection.set_default_list(list_id)
                listinfo.add_info_message(
                    message.DEFAULT_LIST_UPDATED%{'coll_id': coll_id, 'list_id': list_id}         
                    )
                redirect_path, redirect_params = listinfo.redisplay_path_params()
                redirect_cont   = listinfo.get_continuation_next()
            if ( ("list_type" in request.POST) or ("list_all"  in request.POST) ):
                action          = "list"
                redirect_path   = 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
                    )
                redirect_params = dict(
                    scope="all" if "list_scope_all" in request.POST else None,
                    search=request.POST['search_for']
                    )
                redirect_cont   = listinfo.get_continuation_next()
                # redirect_cont   = None
            if "customize" in request.POST:
                action        = "config"
                redirect_path = self.view_uri(
                            "AnnalistCollectionEditView", 
                            coll_id=coll_id
                            )
        if redirect_path:
            if redirect_cont:
                redirect_params.update(
                    { "continuation_url": redirect_cont }
                    )
            listinfo.redirect_response(
                redirect_path, redirect_params=redirect_params, action=action
                )
            # return (
            #     listinfo.check_authorization(action) or
            #     HttpResponseRedirect(redirect_uri)
            #     )
        if listinfo.http_response:
            return listinfo.http_response


        # 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)
Пример #10
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
        action = None
        redirect_path = None
        redirect_cont = listinfo.get_continuation_here()
        redirect_params = {}
        entity_ids = request.POST.getlist('entity_select')
        log.debug("entity_ids %r" % (entity_ids))
        if len(entity_ids) > 1:
            listinfo.display_error_response(message.TOO_MANY_ENTITIES_SEL)
        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_path = listinfo.get_new_view_uri(coll_id, entity_type)
            if "copy" in request.POST:
                action = "copy"
                if not entity_id:
                    listinfo.display_error_response(message.NO_ENTITY_FOR_COPY)
                else:
                    redirect_path = listinfo.get_edit_view_uri(
                        coll_id, entity_type, entity_id, action)
            if "edit" in request.POST:
                action = "edit"
                if not entity_id:
                    listinfo.display_error_response(message.NO_ENTITY_FOR_EDIT)
                else:
                    redirect_path = listinfo.get_edit_view_uri(
                        coll_id, entity_type, entity_id, action)
            if "delete" in request.POST:
                action = "delete"
                confirmed_deletion_uri = self.view_uri(
                    "AnnalistEntityDataDeleteView",
                    coll_id=coll_id,
                    type_id=entity_type)
                return listinfo.confirm_delete_entity_response(
                    entity_type, entity_id, confirmed_deletion_uri)
            if "default_view" in request.POST:
                #@@
                # auth_check = self.form_action_auth("config", listinfo.collection, CONFIG_PERMISSIONS)
                #@@
                auth_check = listinfo.check_authorization("config")
                if auth_check:
                    return auth_check
                listinfo.collection.set_default_list(list_id)
                listinfo.add_info_message(message.DEFAULT_LIST_UPDATED % {
                    'coll_id': coll_id,
                    'list_id': list_id
                })
                redirect_path, redirect_params = listinfo.redisplay_path_params(
                )
                redirect_cont = listinfo.get_continuation_next()
            if (("list_type" in request.POST) or ("list_all" in request.POST)):
                action = "list"
                redirect_path = 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)
                redirect_params = dict(
                    scope="all" if "list_scope_all" in request.POST else None,
                    search=request.POST['search_for'])
                redirect_cont = listinfo.get_continuation_next()
                # redirect_cont   = None
            if "customize" in request.POST:
                action = "config"
                redirect_path = self.view_uri("AnnalistCollectionEditView",
                                              coll_id=coll_id)
        if redirect_path:
            if redirect_cont:
                redirect_params.update({"continuation_url": redirect_cont})
            listinfo.redirect_response(redirect_path,
                                       redirect_params=redirect_params,
                                       action=action)
            # return (
            #     listinfo.check_authorization(action) or
            #     HttpResponseRedirect(redirect_uri)
            #     )
        if listinfo.http_response:
            return listinfo.http_response

        # 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)
Пример #11
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)
Пример #12
0
    def _migrate_values(self, entitydata):
        """
        Field description entity format migration method.

        The specification for this method is that it returns an entitydata value
        which is a copy of the supplied entitydata with format migrations applied.

        NOTE:  implementations are free to apply migrations in-place.  The resulting 
        entitydata should be exactly as the supplied data *should* appear in storage
        to conform to the current format of the data.  The migration function should 
        be idempotent; i.e.
            x._migrate_values(x._migrate_values(e)) == x._migrate_values(e)
        """
        field_id = entitydata[ANNAL.CURIE.id]
        migration_map = (
            [ (ANNAL.CURIE.options_typeref,     ANNAL.CURIE.field_ref_type       )
            , (ANNAL.CURIE.restrict_values,     ANNAL.CURIE.field_ref_restriction)
            , (ANNAL.CURIE.target_field,        ANNAL.CURIE.field_ref_field      )
            , (ANNAL.CURIE.field_target_type,   ANNAL.CURIE.field_value_type     )
            ])
        entitydata = self._migrate_values_map_field_names(migration_map, entitydata)
        # Fix up enumerated values to use new enumeration type names
        field_enum_types = (
            [ (ANNAL.CURIE.field_render_type, "_enum_render_type")
            , (ANNAL.CURIE.field_value_mode,  "_enum_value_mode")
            ])
        for fkey, ftype in field_enum_types:
            if fkey in entitydata and entitydata[fkey]:
                entitydata[fkey] = make_type_entity_id(
                    ftype, extract_entity_id(entitydata[fkey])
                    )
        # If comment and no tooltip, create tooltip and update comment
        if (RDFS.CURIE.comment in entitydata) and (ANNAL.CURIE.tooltip not in entitydata):
            label   = entitydata.get(RDFS.CURIE.label, "Field '%s'"%field_id)
            comment = entitydata[RDFS.CURIE.comment]
            entitydata[ANNAL.CURIE.tooltip] = comment
            entitydata[RDFS.CURIE.comment]  = "# %s\r\n\r\n%s"%(label, comment)
        # If reference to field group, copy group field list inline
        if ANNAL.CURIE.group_ref in entitydata:
            group_type_id, group_id = split_type_entity_id(
                entitydata[ANNAL.CURIE.group_ref], default_type_id=layout.GROUP_TYPEID
                )
            if group_id != "":
                log.info("Migrating group reference %s in field %s"%(group_id, field_id))
                group_obj = RecordGroup_migration.load(self._parent, group_id)
                if not group_obj:
                    msg = (
                        "Failed to load group '%s' for field '%s' in collection '%s'"%
                        (group_id, field_id, self._parent.get_id())
                        )
                    log.warning(msg)
                    self.set_error(msg)
                    # raise Annalist_Error(msg)
                else:
                    field_value_type = entitydata[ANNAL.CURIE.field_value_type]
                    group_entity_type = group_obj[ANNAL.CURIE.group_entity_type]
                    if field_value_type and group_entity_type and field_value_type != group_entity_type:
                        log.warning(
                            "Group %s entity type %s differs from field %s value type %s"%
                            (group_id, group_entity_type, field_id, field_value_type)
                            )
                    entitydata[ANNAL.CURIE.field_fields] = group_obj[ANNAL.CURIE.group_fields]
            del entitydata[ANNAL.CURIE.group_ref]
        # Default render type to "Text"
        if ANNAL.CURIE.field_render_type not in entitydata:
            entitydata[ANNAL.CURIE.field_render_type] = "_enum_render_type/Text"
        # Migrate changed render type names
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "RepeatGroup", "Group_Seq"
            )
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "RepeatGroupRow", "Group_Seq_Row"
            )
        entitydata = self._map_entity_field_enum_val(
            entitydata, ANNAL.CURIE.field_render_type, "_enum_render_type", 
            "Slug", "EntityRef"
            )
        # Calculate mode from other fields if not defined
        val_render = entitydata[ANNAL.CURIE.field_render_type]
        ref_type  = entitydata.get(ANNAL.CURIE.field_ref_type, None)
        ref_field = entitydata.get(ANNAL.CURIE.field_ref_field, None)
        if ANNAL.CURIE.field_value_mode in entitydata:
            val_mode = entitydata[ANNAL.CURIE.field_value_mode]
        else:
            val_mode  = "Value_direct"
            if ref_type and ref_field:
                val_mode = "Value_field"
            elif val_render == "RefMultifield":
                val_mode = "Value_entity"
            elif val_render == "URIImport":
                val_mode = "Value_import"
            elif val_render == "FileUpload":
                val_mode = "Value_upload"
            entitydata[ANNAL.CURIE.field_value_mode] = val_mode
        # Consistency checks
        if val_mode == "Value_field":
            if ( not (ref_type and ref_field) ):
               log.warning(
                    "RecordField %s: val_mode 'Value_field' requires values for %s and %s"%
                        (field_id, ANNAL.CURIE.field_ref_type, ANNAL.CURIE.field_ref_field)
                    )
        elif val_mode == "Value_entity":
            if not ref_type:
               log.warning(
                    "RecordField %s: val_mode 'Value_entity' requires value for %s"%
                        (field_id, ANNAL.CURIE.field_ref_type)
                    )
            if ref_field:
               log.warning(
                    "RecordField %s: val_mode 'Value_entity' should not define value for %s"%
                        (field_id, ANNAL.CURIE.field_ref_field)
                    )
        # Return result
        return entitydata