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
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
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_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 _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
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)
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))
def id_from_field_choice(fc): type_id, entity_id = split_type_entity_id(fc.id) return entity_id
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)
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)
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)
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