def item_edit_copy_uri(self, coll_id, type_id, view_id, entity_id, no_entity_msg, continuation_here, continuation_url, action): # NOTE: continuation_url is the continuation URL from the current page, # and is used as part of the URL used to redisplay the current # page with an error message. # @@TODO: pass in viewinfo rather than continuation URLs if not entity_id: continuation_url_dict = {} if continuation_url: continuation_url_dict = {'continuation_url': continuation_url} return uri_with_params( self.get_request_path(), self.error_params(no_entity_msg), continuation_url_dict ) redirect_uri = ( uri_with_params( self.view_uri("AnnalistEntityEditView", action=action, coll_id=coll_id, view_id=view_id, type_id=type_id, entity_id=entity_id ), {'continuation_url': continuation_here} ) ) return redirect_uri
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
def check_value_supplied(self, val, msg, continuation_url=None, testfn=(lambda v: v)): """ Test if a supplied value is specified (not None) and passes a supplied test, 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. val value that is required to be not None and not empty or False msg message to display if the value evaluated to False continuation_url a continuation URL for the resdiplayed page. testfn is a function to test the value (if not None). If not specified, the default test checks that the value does not evaluate as false (e.g. is a non-empty string, list or collection). returns a URI string for use with HttpResponseRedirect to redisplay the current page with the supplied message, or None if the value passes the test. """ redirect_uri = None continuation_url_dict = {} if continuation_url: continuation_url_dict = {'continuation_url': continuation_url} if (val is None) or not testfn(val): redirect_uri = uri_with_params( self.get_request_path(), self.error_params(msg), continuation_url_dict ) return redirect_uri
def continuation_here(self, request_dict={}, default_cont="", base_here=None): """ Returns a URL that returns control to the current page, to be passed as a continuation_uri parameter to any subsidiary pages invoked. Such continuation URIs are cascaded, so that the return URI includes a the `continuation_url` for the current page. request_dict is a request dictionary that is expected to contain the continuation_url value to use, and other parameters to be included an any continuation back to the current page. default_cont is a default continuation URI to be used for returning from the current page if the current POST request does not specify a continuation_url query parameter. base_here if specified, overrides the current request path as the base URI to be used to return to the currently displayed page (e.g. when current request URI is non-idempotent, such as creating a new entity). """ # Note: use default if request/form parameter is present but blank: if not base_here: base_here = self.get_request_path() continuation_next = self.continuation_next(request_dict, default_cont) return uri_with_params( base_here, continuation_params({"continuation_url": continuation_next}, request_dict))
def continuation_here(self, request_dict={}, default_cont="", base_here=None): """ Returns a URL that returns control to the current page, to be passed as a continuation_uri parameter to any subsidiary pages invoked. Such continuation URIs are cascaded, so that the return URI includes a the `continuation_url` for the current page. request_dict is a request dictionary that is expected to contain the continuation_url value to use, and other parameters to be included an any continuation back to the current page. default_cont is a default continuation URI to be used for returning from the current page if the current POST request does not specify a continuation_url query parameter. base_here if specified, overrides the current request path as the base URI to be used to return to the currently displayed page (e.g. when current request URI is non-idempotent, such as creating a new entity). """ # Note: use default if request/form parameter is present but blank: if not base_here: base_here = self.get_request_path() continuation_next = self.continuation_next(request_dict, default_cont) return uri_with_params(base_here, continuation_params({"continuation_url": continuation_next}, request_dict) )
def check_value_supplied(self, val, msg, continuation_url={}, testfn=(lambda v: v)): """ Test a supplied value is specified (not None) and passes a supplied test, 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. val value that is required to be not None and not empty or False msg message to display if the value evaluated to False testfn is a function to test the value (if not None). If not specified, the default test checks that the value does not evaluate as false (e.g. is a non-empty string, list or collection). returns a URI string for use with HttpResponseRedirect to redisplay the current page with the supplied message, or None if the value passes the test. """ redirect_uri = None if (val is None) or not testfn(val): redirect_uri = uri_with_params(self.get_request_path(), self.error_params(msg), continuation_url) return redirect_uri
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
def item_new_uri(self, coll_id, type_id, view_id, continuation_here): redirect_uri = uri_with_params( self.view_uri("AnnalistEntityNewView", coll_id=coll_id, view_id=view_id, type_id=type_id, action="new"), continuation_here) return redirect_uri
def redirect_info(self, viewuri, view_params={}, info_message=None, info_head=message.ACTION_COMPLETED): """ Redirect to a specified view with an information/confirmation message for display (see templates/base_generic.html for display details) """ redirect_uri = uri_with_params(viewuri, view_params, self.info_params(info_message, info_head)) return HttpResponseRedirect(redirect_uri)
def item_new_uri(self, coll_id, type_id, view_id, continuation_here): # @@TODO: pass in viewinfo rather than continuation URL redirect_uri = uri_with_params( self.view_uri("AnnalistEntityNewView", coll_id=coll_id, view_id=view_id, type_id=type_id, action="new" ), {'continuation_url': continuation_here} ) return redirect_uri
def item_new_uri(self, coll_id, type_id, view_id, continuation_here): # @@TODO: pass in viewinfo rather than continuation URL redirect_uri = uri_with_params( self.view_uri("AnnalistEntityNewView", coll_id=coll_id, view_id=view_id, type_id=type_id, action="new"), {'continuation_url': continuation_here}) return redirect_uri
def item_edit_copy_uri(self, coll_id, type_id, view_id, entity_id, no_entity_msg, continuation_here, continuation_next, action): redirect_uri = (self.check_value_supplied( entity_id, no_entity_msg, continuation_next) or uri_with_params( self.view_uri("AnnalistEntityEditView", action=action, coll_id=coll_id, view_id=view_id, type_id=type_id, entity_id=entity_id), continuation_here)) return redirect_uri
def redirect_error(self, viewuri, view_params={}, error_message=None, error_head=message.INPUT_ERROR ): """ Redirect to a specified view with an error message for display (see templates/base_generic.html for display details) """ redirect_uri = uri_with_params( viewuri, view_params, self.error_params(error_message, error_head=error_head) ) return HttpResponseRedirect(redirect_uri)
def redirect_info(self, viewuri, view_params={}, info_message=None, info_head=message.ACTION_COMPLETED): """ Redirect to a specified view with an information/confirmation message for display (see templates/base_generic.html for display details) """ redirect_uri = uri_with_params( viewuri, view_params, self.info_params(info_message, info_head)) return HttpResponseRedirect(redirect_uri)
def redirect_error(self, viewuri, view_params={}, error_message=None, error_head=message.INPUT_ERROR): """ Redirect to a specified view with an error message for display (see templates/base_generic.html for display details) """ redirect_uri = uri_with_params( viewuri, view_params, self.error_params(error_head, error_message)) return HttpResponseRedirect(redirect_uri)
def make_data_ref(request_url, data_ref, resource_type=None): """ Returns a URL reference rel.atiove to the suppliued request_url that can be used as a reference to a data resource based on the supplied request URL, data reference and optional type. Scope-repated query parameters from the original request_url are preserved, and others are discarded. """ params = scope_params(uri_param_dict(request_url)) if resource_type: params['type'] = resource_type return uri_with_params(data_ref, params)
def make_data_ref(request_url, data_ref, resource_type=None): """ Returns a URL reference rel.atiove to the suppliued request_url that can be used as a reference to a data resource based on the supplied request URL, data reference and optional type. Scope-repated query parameters from the original request_url are preserved, and others are discarded. """ params = scope_params(uri_param_dict(request_url)) if resource_type: params['type'] = resource_type return uri_with_params(data_ref, params)
def get_continuation_url(self): """ Generate continuation URL for return back to the current request page """ chere = "" if self._extras is None: log.warning("bound_field.get_continuation_url() - no extra context provided") else: requrl = self._extras.get("request_url", "") if requrl: chere = uri_with_params(requrl, continuation_params(self._extras)) # log.debug('bound_field.get_continuation_url %s'%(chere,)) return chere
def item_edit_copy_uri(self, coll_id, type_id, view_id, entity_id, no_entity_msg, continuation_here, continuation_url, action): # NOTE: continuation_url is the continuation URL from the current page, # and is used as part of the URL used to redisplay the current # page with an error message. # @@TODO: pass in viewinfo rather than continuation URLs if not entity_id: continuation_url_dict = {} if continuation_url: continuation_url_dict = {'continuation_url': continuation_url} return uri_with_params(self.get_request_path(), self.error_params(no_entity_msg), continuation_url_dict) redirect_uri = (uri_with_params( self.view_uri("AnnalistEntityEditView", action=action, coll_id=coll_id, view_id=view_id, type_id=type_id, entity_id=entity_id), {'continuation_url': continuation_here})) return redirect_uri
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 get_continuation_url(self): """ Generate continuation URL for return back to the current request page """ chere = "" if self._extras is None: log.warning( "bound_field.get_continuation_url() - no extra context provided" ) else: requrl = self._extras.get("request_url", "") if requrl: chere = uri_with_params(requrl, continuation_params(self._extras)) # log.debug('bound_field.get_continuation_url %s'%(chere,)) return chere
def item_edit_copy_uri(self, coll_id, type_id, view_id, entity_id, no_entity_msg, continuation_here, continuation_url, action): # NOTE: continuation_url is the continuation URL from the current page, # and is used as part of the URL used to redisplay the current # page with an error message. # @@TODO: pass in viewinfo rather than continuation URLs redirect_uri = (self.check_value_supplied( entity_id, no_entity_msg, continuation_url) or uri_with_params( self.view_uri("AnnalistEntityEditView", action=action, coll_id=coll_id, view_id=view_id, type_id=type_id, entity_id=entity_id), {'continuation_url': continuation_here})) return redirect_uri
def continuation_urls(self, request_dict, default_cont, base_here=None): """ Returns a tuple of two continuation URI dictionary values: [0] { 'continuation_url': continuation_next } [1] { 'continuation_url': continuation_here } where: `continuation_next` is the URI to use after the current page has completed processing, which is either supplied as a parameter to the current page or set to an indicated default. `continuation_here` is a URI that returns control to the current page, to be passed as a contionuation_uri parameter to any subsidiary pages invoked. Such continuation URIs are cascaded, so that the return URI includes a the `continuation_url` for the current page. request_dict is a request dictionary that is expected to contain a to continuation_url value to use, other parameters to be included an any continuation back to the current page. default_cont is a default continuation URI to be used for returning from the current page if the current POST request does not specify a continuation_url query parameter. base_here if specified, overrides the current request path as the base URI to be used to return to the currently displayed page (e.g. when current request URI is non-idempotent, such as creating a new entity). """ # Note: use default if request/form parameter is present but blank: continuation_url = request_dict.get( "continuation_url") or default_cont or None if not base_here: base_here = self.get_request_path() if continuation_url: continuation_next = {"continuation_url": continuation_url} else: continuation_next = {} continuation_here = uri_with_params( base_here, continuation_params(continuation_next, request_dict.dict())) # continuation_here = uri_with_continuation_params( # base_here, continuation_next, request_dict.dict() # ) return (continuation_next, {"continuation_url": continuation_here})
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 get_list_url(self, coll_id, list_id, type_id=None, scope=None, search=None, query_params={}): """ Return a URL for accessing the current list display """ list_uri_params = ( { 'coll_id': coll_id , 'list_id': list_id }) if type_id: list_uri_params['type_id'] = type_id if scope: query_params = dict(query_params, scope=scope) if search: query_params = dict(query_params, search=search) list_url = ( uri_with_params( self.view_uri("AnnalistEntityGenericList", **list_uri_params), query_params ) ) return list_url
def get_list_url(self, coll_id, list_id, type_id=None, scope=None, search=None, query_params={}): """ Return a URL for accessing the current list display """ list_uri_params = ({'coll_id': coll_id, 'list_id': list_id}) if type_id: list_uri_params['type_id'] = type_id if scope: query_params = dict(query_params, scope=scope) if search: query_params = dict(query_params, search=search) list_url = (uri_with_params( self.view_uri("AnnalistEntityGenericList", **list_uri_params), query_params)) return list_url
def invoke_config_edit_view(self, entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, orig_entity, viewinfo, context_extra_values, messages, config_edit_url, config_edit_perm, url_params, continuation_url): """ Common logic for invoking a configuration resource edit while editing some other resource: - the entity currently being edited is saved - authorization to perform configuration edits is checked - a continuaton URL is calculated which is the URL for the current view, except that the continuation action is always "edit" - a URL for the config edit view is assembled from the supplied base URL and parameters, and the calculated continuaton URL - an HTTP redirect response to the config edit view is returned. If there is a problem with any ofthese steps, an error response is returned and displayed in the current view. """ http_response = self.save_entity(entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, viewinfo, context_extra_values, messages) if http_response: return http_response # @@TODO: get permission required mfrom typeinfo of entity to be created if viewinfo.check_authorization(config_edit_perm): return viewinfo.http_response (continuation_next, continuation_here) = self.continuation_urls( form_data, continuation_url, base_here=viewinfo.get_edit_continuation_url( entity_type_id, entity_id)) return HttpResponseRedirect( uri_with_params(config_edit_url, url_params, continuation_here))
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 entitydata_list_url_query(viewname, kwargs, query_params, more_params): """ Helper function for generatinglist URLs """ list_url = reverse(viewname, kwargs=kwargs) return uri_with_params(list_url, query_params, more_params)
def __getattr__(self, name): """ Get a bound field description attribute. If the attribute name is "field_value" then the value corresponding to the field description is retrieved from the entity, otherwise the named attribute is retrieved from thge field description. """ # log.info("self._key %s, __getattr__ %s"%(self._key, name)) # log.info("self._key %s"%self._key) # log.info("self._entity %r"%self._entity) if name in [ "entity_id", "entity_link", "entity_type_id", "entity_type_link" ]: return self._entityvals.get(name, "") elif name == "field_value_key": return self._key elif name == "context_extra_values": return self._extras elif name == "field_placeholder": return self._field_description.get( 'field_placeholder', "@@bound_field.field_placeholder@@") elif name == "continuation_url": if self._extras is None: log.warning( "bound_field.continuation_url - no extra context provided") return "" cont = self._extras.get("request_url", "") if cont: cont = uri_with_params(cont, continuation_params(self._extras)) return cont elif name == "entity_link_continuation": return self.entity_link + self.get_continuation_param() elif name == "entity_type_link_continuation": return self.entity_type_link + self.get_continuation_param() elif name == "field_value": field_val = None if self._key in self._entityvals: field_val = self._entityvals[self._key] elif self._extras and self._key in self._extras: field_val = self._extras[self._key] if field_val is None: # Return default value, or empty string. # Used to populate form field value when no value supplied, or provide per-field default field_val = self._field_description.get( 'field_default_value', None) if field_val is None: field_val = "" return field_val elif name == "field_value_link": # Used to get link corresponding to a value, if such exists return self.get_field_link() elif name == "field_value_link_continuation": # Used to get link corresponding to a value, if such exists return self.get_field_link() + self.get_continuation_param() elif name == "field_description": # Used to get link corresponding to a value, if such exists return self._field_description elif name == "options": return self.get_field_options() else: # log.info("bound_field[%s] -> %r"%(name, self._field_description[name])) return self._field_description[name]
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 post(self, request): """ Process options to add or remove a collection in an Annalist site """ log.debug("site.post: %r" % (request.POST.lists())) collections = request.POST.getlist("select", []) coll_id = collections[0] if collections else "_" coll_ids = {'ids': ", ".join(collections)} perm_req = None perm_scope = None none_msg = None many_msg = None redirect_uri = None http_response = None # Process POST option if "view" in request.POST: # Collection data is considered part of configuration, hence CONFIG_PERMISSIONS: perm_req = CONFIG_PERMISSIONS["view"] # Use Collection or Site permissions: perm_scope = "all" none_msg = message.NO_COLLECTION_VIEW many_msg = message.MANY_COLLECTIONS_VIEW target_uri = self.view_uri("AnnalistEntityEditView", coll_id=layout.SITEDATA_ID, view_id="Collection_view", type_id="_coll", entity_id=coll_id, action="view") redirect_uri = uri_with_params( target_uri, {'continuation_url': self.continuation_here()}) elif "edit" in request.POST: perm_req = CONFIG_PERMISSIONS["edit"] perm_scope = "all" none_msg = message.NO_COLLECTION_EDIT many_msg = message.MANY_COLLECTIONS_EDIT target_uri = self.view_uri("AnnalistEntityEditView", coll_id=layout.SITEDATA_ID, view_id="Collection_view", type_id="_coll", entity_id=coll_id, action="edit") redirect_uri = uri_with_params( target_uri, {'continuation_url': self.continuation_here()}) elif "remove" in request.POST: perm_req = "DELETE_COLLECTION" perm_scope = "all" # Collection or site permissions none_msg = message.NO_COLLECTIONS_REMOVE elif "new" in request.POST: perm_req = "CREATE_COLLECTION" perm_scope = "site" # Site permission required new_id = request.POST["new_id"] new_label = request.POST["new_label"] # Common checks if none_msg and not collections: http_response = self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=none_msg, info_head=message.NO_ACTION_PERFORMED) elif many_msg and len(collections) > 1: http_response = self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=many_msg % coll_ids, info_head=message.NO_ACTION_PERFORMED) elif perm_req: if perm_scope == "all": # Check collections for permissions for cid in collections: if http_response is None: site = self.site(host=self.get_request_host()) sitedata = self.site_data() coll = Collection.load(site, cid, altscope="site") http_response = ( self.authorize("ADMIN", coll) and # Either of these... self.authorize(perm_req, coll)) coll = None else: # Check site only for permissions http_response = (self.authorize("ADMIN", None) and self.authorize(perm_req, None)) if http_response is not None: return http_response # Perform selected option if redirect_uri: log.info("Redirect to %s" % redirect_uri) return HttpResponseRedirect(redirect_uri) if "remove" in request.POST: if layout.SITEDATA_ID in collections: log.warning("Attempt to delete site data collection %(ids)s" % (coll_ids)) http_response = self.error( self.error403values(scope="DELETE_SITE")) else: http_response = ConfirmView.render_form( request, action_description=message.REMOVE_COLLECTIONS % coll_ids, action_params=request.POST, confirmed_action_uri=self.view_uri( 'AnnalistSiteActionView'), cancel_action_uri=self.view_uri('AnnalistSiteView'), title=self.site_data()["title"]) return http_response if "new" in request.POST: log.info("New collection %s: %s" % (new_id, new_label)) error_message = None if not new_id: error_message = message.MISSING_COLLECTION_ID elif not util.valid_id(new_id): error_message = message.INVALID_COLLECTION_ID % { 'coll_id': new_id } if error_message: return self.redirect_error(self.view_uri("AnnalistSiteView"), error_message=error_message) coll_meta = ({RDFS.CURIE.label: new_label, RDFS.CURIE.comment: ""}) # Add collection coll = self.site().add_collection(new_id, coll_meta) coll.generate_coll_jsonld_context() user = self.request.user user_id = user.username user_uri = "mailto:" + user.email user_name = "%s %s" % (user.first_name, user.last_name) user_description = "User %s: permissions for %s in collection %s" % ( user_id, user_name, new_id) coll.create_user_permissions(user_id, user_uri, user_name, user_description, user_permissions=[ "VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN" ]) return self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=message.CREATED_COLLECTION_ID % {'coll_id': new_id}) # elif "remove" in request.POST: # collections = request.POST.getlist("select", []) # if collections: # # Check authorization # if layout.SITEDATA_ID in collections: # log.warning("Attempt to delete site data collection %r"%(collections)) # auth_required = self.error(self.error403values(scope="DELETE_SITE")) # else: # auth_required = ( # self.authorize("ADMIN", None) and # either of these.. # self.authorize("DELETE_COLLECTION", None) # ) # return ( # # Get user to confirm action before actually doing it # auth_required or # ConfirmView.render_form(request, # action_description= message.REMOVE_COLLECTIONS%{'ids': ", ".join(collections)}, # action_params= request.POST, # confirmed_action_uri= self.view_uri('AnnalistSiteActionView'), # cancel_action_uri= self.view_uri('AnnalistSiteView'), # title= self.site_data()["title"] # ) # ) # else: # return self.redirect_info( # self.view_uri("AnnalistSiteView"), # info_message=message.NO_COLLECTIONS_REMOVE, info_head=message.NO_ACTION_PERFORMED # ) # if "new" in request.POST: # # Create new collection with name and label supplied # new_id = request.POST["new_id"] # new_label = request.POST["new_label"] # log.debug("New collection %s: %s"%(new_id, new_label)) # if not new_id: # return self.redirect_error( # self.view_uri("AnnalistSiteView"), # error_message=message.MISSING_COLLECTION_ID # ) # if not util.valid_id(new_id): # return self.redirect_error( # self.view_uri("AnnalistSiteView"), # error_message=message.INVALID_COLLECTION_ID%{'coll_id': new_id} # ) # # Create new collection with name and label supplied # auth_required = ( # self.authorize("ADMIN", None) and # either of these.. # self.authorize("CREATE_COLLECTION", None) # ) # if auth_required: # return auth_required # coll_meta = ( # { RDFS.CURIE.label: new_label # , RDFS.CURIE.comment: "" # }) # coll = self.site().add_collection(new_id, coll_meta) # # Generate initial context # coll.generate_coll_jsonld_context() # # Create full permissions in new collection for creating user # user = self.request.user # user_id = user.username # user_uri = "mailto:"+user.email # user_name = "%s %s"%(user.first_name, user.last_name) # user_description = "User %s: permissions for %s in collection %s"%(user_id, user_name, new_id) # coll.create_user_permissions( # user_id, user_uri, # user_name, user_description, # user_permissions=["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] # ) # return self.redirect_info( # self.view_uri("AnnalistSiteView"), # info_message=message.CREATED_COLLECTION_ID%{'coll_id': new_id} # ) log.warning("Invalid POST request: %r" % (request.POST.lists())) return self.error(self.error400values())
def post(self, request): """ Process options to add or remove a collection in an Annalist site """ log.debug("site.post: %r"%(request.POST.lists())) collections = request.POST.getlist("select", []) coll_id = collections[0] if collections else "_" coll_ids = {'ids': ", ".join(collections)} perm_req = None perm_scope = None none_msg = None many_msg = None redirect_uri = None http_response = None # Process POST option if "view" in request.POST: # Collection data is considered part of configuration, hence CONFIG_PERMISSIONS: perm_req = CONFIG_PERMISSIONS["view"] # Use Collection or Site permissions: perm_scope = "all" none_msg = message.NO_COLLECTION_VIEW many_msg = message.MANY_COLLECTIONS_VIEW target_uri = self.view_uri("AnnalistEntityEditView", coll_id=layout.SITEDATA_ID, view_id="Collection_view", type_id="_coll", entity_id=coll_id, action="view" ) redirect_uri = uri_with_params( target_uri, {'continuation_url': self.continuation_here()} ) elif "edit" in request.POST: perm_req = CONFIG_PERMISSIONS["edit"] perm_scope = "all" none_msg = message.NO_COLLECTION_EDIT many_msg = message.MANY_COLLECTIONS_EDIT target_uri = self.view_uri("AnnalistEntityEditView", coll_id=layout.SITEDATA_ID, view_id="Collection_view", type_id="_coll", entity_id=coll_id, action="edit" ) redirect_uri = uri_with_params( target_uri, {'continuation_url': self.continuation_here()} ) elif "remove" in request.POST: perm_req = "DELETE_COLLECTION" perm_scope = "all" # Collection or site permissions none_msg = message.NO_COLLECTIONS_REMOVE elif "new" in request.POST: perm_req = "CREATE_COLLECTION" perm_scope = "site" # Site permission required new_id = request.POST["new_id"] new_label = request.POST["new_label"] # Common checks if none_msg and not collections: http_response = self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=none_msg, info_head=message.NO_ACTION_PERFORMED ) elif many_msg and len(collections) > 1: http_response = self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=many_msg%coll_ids, info_head=message.NO_ACTION_PERFORMED ) elif perm_req: if perm_scope == "all": # Check collections for permissions for cid in collections: if http_response is None: site = self.site(host=self.get_request_host()) sitedata = self.site_data() coll = Collection.load(site, cid, altscope="site") http_response = ( self.authorize("ADMIN", coll) and # Either of these... self.authorize(perm_req, coll) ) coll = None else: # Check site only for permissions http_response = ( self.authorize("ADMIN", None) and self.authorize(perm_req, None) ) if http_response is not None: return http_response # Perform selected option if redirect_uri: log.info("Redirect to %s"%redirect_uri) return HttpResponseRedirect(redirect_uri) if "remove" in request.POST: if layout.SITEDATA_ID in collections: log.warning("Attempt to delete site data collection %(ids)s"%(coll_ids)) http_response = self.error(self.error403values(scope="DELETE_SITE")) else: http_response = ConfirmView.render_form(request, action_description= message.REMOVE_COLLECTIONS%coll_ids, action_params= request.POST, confirmed_action_uri= self.view_uri('AnnalistSiteActionView'), cancel_action_uri= self.view_uri('AnnalistSiteView'), title= self.site_data()["title"] ) return http_response if "new" in request.POST: log.info("New collection %s: %s"%(new_id, new_label)) error_message = None if not new_id: error_message = message.MISSING_COLLECTION_ID elif not util.valid_id(new_id): error_message = message.INVALID_COLLECTION_ID%{'coll_id': new_id} if error_message: return self.redirect_error( self.view_uri("AnnalistSiteView"), error_message=error_message ) coll_meta = ( { RDFS.CURIE.label: new_label , RDFS.CURIE.comment: "" }) # Add collection coll = self.site().add_collection(new_id, coll_meta) coll.generate_coll_jsonld_context() user = self.request.user user_id = user.username user_uri = "mailto:"+user.email user_name = "%s %s"%(user.first_name, user.last_name) user_description = "User %s: permissions for %s in collection %s"%(user_id, user_name, new_id) coll.create_user_permissions( user_id, user_uri, user_name, user_description, user_permissions=["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] ) return self.redirect_info( self.view_uri("AnnalistSiteView"), info_message=message.CREATED_COLLECTION_ID%{'coll_id': new_id} ) # elif "remove" in request.POST: # collections = request.POST.getlist("select", []) # if collections: # # Check authorization # if layout.SITEDATA_ID in collections: # log.warning("Attempt to delete site data collection %r"%(collections)) # auth_required = self.error(self.error403values(scope="DELETE_SITE")) # else: # auth_required = ( # self.authorize("ADMIN", None) and # either of these.. # self.authorize("DELETE_COLLECTION", None) # ) # return ( # # Get user to confirm action before actually doing it # auth_required or # ConfirmView.render_form(request, # action_description= message.REMOVE_COLLECTIONS%{'ids': ", ".join(collections)}, # action_params= request.POST, # confirmed_action_uri= self.view_uri('AnnalistSiteActionView'), # cancel_action_uri= self.view_uri('AnnalistSiteView'), # title= self.site_data()["title"] # ) # ) # else: # return self.redirect_info( # self.view_uri("AnnalistSiteView"), # info_message=message.NO_COLLECTIONS_REMOVE, info_head=message.NO_ACTION_PERFORMED # ) # if "new" in request.POST: # # Create new collection with name and label supplied # new_id = request.POST["new_id"] # new_label = request.POST["new_label"] # log.debug("New collection %s: %s"%(new_id, new_label)) # if not new_id: # return self.redirect_error( # self.view_uri("AnnalistSiteView"), # error_message=message.MISSING_COLLECTION_ID # ) # if not util.valid_id(new_id): # return self.redirect_error( # self.view_uri("AnnalistSiteView"), # error_message=message.INVALID_COLLECTION_ID%{'coll_id': new_id} # ) # # Create new collection with name and label supplied # auth_required = ( # self.authorize("ADMIN", None) and # either of these.. # self.authorize("CREATE_COLLECTION", None) # ) # if auth_required: # return auth_required # coll_meta = ( # { RDFS.CURIE.label: new_label # , RDFS.CURIE.comment: "" # }) # coll = self.site().add_collection(new_id, coll_meta) # # Generate initial context # coll.generate_coll_jsonld_context() # # Create full permissions in new collection for creating user # user = self.request.user # user_id = user.username # user_uri = "mailto:"+user.email # user_name = "%s %s"%(user.first_name, user.last_name) # user_description = "User %s: permissions for %s in collection %s"%(user_id, user_name, new_id) # coll.create_user_permissions( # user_id, user_uri, # user_name, user_description, # user_permissions=["VIEW", "CREATE", "UPDATE", "DELETE", "CONFIG", "ADMIN"] # ) # return self.redirect_info( # self.view_uri("AnnalistSiteView"), # info_message=message.CREATED_COLLECTION_ID%{'coll_id': new_id} # ) log.warning("Invalid POST request: %r"%(request.POST.lists())) return self.error(self.error400values())
def form_response(self, viewinfo, entity_id, orig_entity_id, entity_type_id, orig_entity_type_id, messages, context_extra_values): """ Handle POST response from entity edit form. """ log.info( "form_response entity_id %s, orig_entity_id %s, entity_type_id %s, orig_entity_type_id %s" % (entity_id, orig_entity_id, entity_type_id, orig_entity_type_id)) form_data = self.request.POST continuation_url = context_extra_values['continuation_url'] if 'cancel' in form_data: return HttpResponseRedirect(continuation_url) typeinfo = viewinfo.entitytypeinfo orig_entity = self.get_entity(orig_entity_id, typeinfo, viewinfo.action) # log.info("orig_entity %r"%(orig_entity.get_values(),)) entityvaluemap = self.get_view_entityvaluemap(viewinfo, orig_entity) # Check response has valid id and type if not util.valid_id(entity_id): log.debug("form_response: entity_id not util.valid_id('%s')" % entity_id) return self.form_re_render( viewinfo, entityvaluemap, form_data, context_extra_values, error_head=messages['entity_heading'], error_message=messages['entity_invalid_id']) if not util.valid_id(entity_type_id): log.debug("form_response: entity_type_id not util.valid_id('%s')" % entity_type_id) return self.form_re_render( viewinfo, entityvaluemap, form_data, context_extra_values, error_head=messages['entity_type_heading'], error_message=messages['entity_type_invalid']) # Save updated details if 'save' in form_data: # log.info( # "save: entity_id %s, orig_entity_id %s, type_id %s, orig_type_id %s"% # (entity_id, orig_entity_id, entity_type_id, orig_entity_type_id) # ) http_response = self.save_entity(entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, viewinfo, context_extra_values, messages) return http_response or HttpResponseRedirect(continuation_url) # Add field from entity view (as opposed to view description view) # See below call of 'find_add_field' for adding field in view description if 'add_view_field' in form_data: view_edit_uri_base = self.view_uri("AnnalistEntityEditView", coll_id=viewinfo.coll_id, view_id="View_view", type_id="_view", entity_id=viewinfo.view_id, action="edit") return self.invoke_config_edit_view( entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, orig_entity, viewinfo, context_extra_values, messages, view_edit_uri_base, "config", {"add_field": "View_fields"}, continuation_url) # Update or define new view or type (invoked from generic entity editing view) # Save current entity and redirect to view edit with new field added, and # current page as continuation. if 'use_view' in form_data: # Save entity, then redirect to selected view http_response = self.save_entity(entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, viewinfo, context_extra_values, messages) if http_response: return http_response view_uri_params = ({ 'coll_id': viewinfo.coll_id, 'type_id': entity_type_id, 'view_id': form_data['view_choice'], 'entity_id': entity_id, 'action': "edit" }) redirect_uri = (uri_with_params( self.view_uri("AnnalistEntityEditView", **view_uri_params), {'continuation_url': continuation_url})) return HttpResponseRedirect(redirect_uri) # New entity buttons # # These may use explicit button ids per the table below, or may be part of # an enumered-value field used to create a new enumerated value instance. # # In all cases, the current entity is saved and the browser is redirected # to a new page to enter details of a new entity of the appropriate type. # new_button_map = ({ 'new_type': { 'type_id': "_type", 'view_id': "Type_view" }, 'new_view': { 'type_id': "_view", 'view_id': "View_view" }, 'new_field': { 'type_id': "_field", 'view_id': "Field_view" }, 'new_group': { 'type_id': "_group", 'view_id': "Field_group_view" } }) new_type_id = None for button_id in new_button_map.keys(): if button_id in form_data: new_type_id = new_button_map[button_id]['type_id'] new_view_id = new_button_map[button_id]['view_id'] break new_enum = self.find_new_enum(entityvaluemap, form_data) if new_enum: new_type_id = new_enum['field_options_typeref'] new_typeinfo = EntityTypeInfo(viewinfo.site, viewinfo.collection, new_type_id) new_view_id = new_typeinfo.get_default_view_id() if new_type_id is not None: new_edit_uri_base = self.view_uri("AnnalistEntityNewView", coll_id=viewinfo.coll_id, view_id=new_view_id, type_id=new_type_id, action="new") return self.invoke_config_edit_view( entityvaluemap, form_data, entity_id, entity_type_id, orig_entity_id, orig_entity_type_id, orig_entity, viewinfo, context_extra_values, messages, new_edit_uri_base, "new", {}, continuation_url) # Add new instance of repeating field, and redisplay add_field = self.find_add_field(entityvaluemap, form_data) # log.info("*** Add field: "+repr(add_field)) if add_field: entityvals = entityvaluemap.map_form_data_to_values(form_data) return self.update_view_fields(viewinfo, add_field, entityvals, entityvaluemap, **context_extra_values) # Remove Field(s), and redisplay remove_field = self.find_remove_field(entityvaluemap, form_data) if remove_field: if not remove_field['remove_fields']: log.debug( "form_response: No field(s) selected for remove_field") return self.form_re_render( viewinfo, entityvaluemap, form_data, context_extra_values, error_head=messages['remove_field_error'], error_message=messages['no_field_selected']) entityvals = entityvaluemap.map_form_data_to_values(form_data) return self.update_view_fields(viewinfo, remove_field, entityvals, entityvaluemap, **context_extra_values) # Report unexpected form data # This shouldn't happen, but just in case... # Redirect to continuation with error err_values = self.error_params( message.UNEXPECTED_FORM_DATA % (form_data), message.SYSTEM_ERROR) log.warning("Unexpected form data %s" % (err_values)) log.warning("Continue to %s" % (continuation_url)) for k, v in form_data.items(): log.info(" form[%s] = %r" % (k, v)) redirect_uri = uri_with_params(continuation_url, 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 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)
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)