def check_feed_parameters(request, project_name="", version_number="", model_name=""): # try to get the requested project... try: project = MetadataProject.objects.get(name__iexact=project_name) except ObjectDoesNotExist: msg = "Cannot find the project '%s'. Has it been registered?" % project_name return dcf_error(request, msg) # try to get the requested version... if version_number: try: version = MetadataVersion.objects.get(name__iexact=METADATA_NAME, number=version_number) except ObjectDoesNotExist: msg = "Cannot find version '%s_%s'. Has it been registered?" % ( METADATA_NAME, version_number) return dcf_error(request, msg) else: version = project.getDefaultVersion() if not version: msg = "please specify a version; the '%s' project has no default one." % project.getName( ) return dcf_error(request, msg) # try to get the requested model... model_class = version.getModelClass(model_name) return (project, version, model_class)
def serialize(request, project_name="", version_number="", model_name="", model_id=""): (project, version, model_class) = check_feed_parameters(request, project_name, version_number, model_name) # try to get the requested model... try: model_instance = model_class.objects.get(pk=model_id) except ObjectDoesNotExist: msg = "Cannot find the specified model. Please try again." return dcf_error(request, msg) if not model_instance.isDocument(): msg = "The model type '%s' is not an editable metadata document" % ( model_class.getTitle()) return dcf_error(request, msg) if not model_instance.isPublished(): msg = "This model has not yet been published." return dcf_error(request, msg) # CIM templates are stored as static files of the version # in order for this to work, the static location must be added to TEMPLATE_DIRS in settings.py cim_template_path = "%s/xml/%s.xml" % (version.getAppName(), model_class.getName().lower()) rendered_instance = django.template.loader.render_to_string( cim_template_path, {"model": model_instance}) return HttpResponse(rendered_instance, mimetype="text/xml")
def edit_new(request, version_number="", project_name="", model_name=""): msg = "" (project,version,customizer,categorization,vocabularies,model_class,msg) = \ check_parameters(version_number,project_name,model_name,msg) if not all([ project, version, customizer, categorization, vocabularies, model_class ]): return dcf_error(request, msg) # check authentication... # (not using @login_required b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): return redirect('/dcf/login/?next=%s' % (request.path)) if not (request.user.is_superuser or request.user.metadata_user.is_user_of(project)): msg = "User '%s' does not have permission to edit customizations for project '%s'." % ( request.user, project_name) return dcf_error(request, msg) model_filter_parameters = { "metadata_project": project, } if request.method == "GET": # check if the user added any parameters to the request for (key, value) in request.GET.iteritems(): value = re.sub('[\"\']', '', value) # strip out any quotes field_type = type(model_class.getField(key)) if issubclass(field_type, MetadataField): field_model_class = field_type.getModelClass() if field_model_class == django.db.models.fields.BooleanField: if value.lower() == "true" or value == "1": model_filter_parameters[key] = True elif value.lower() == "false" or value == "0": model_filter_parameters[key] = False else: model_filter_parameters[key] = value elif field_model_class == django.db.models.fields.CharField or field_model_class == django.db.models.fields.TextField: # this ensures that the filter is case-insenstive for strings key = key + "__iexact" # bear in mind that if I ever change to using get_or_create, the filter will have to be case-sensitive # see https://code.djangoproject.com/ticket/7789 for more info model_filter_parameters[key] = value else: model_filter_parameters[key] = value if len(model_filter_parameters) > 1: # if there were (extra) filter parameters passed # then try to get the customizer w/ those parameters try: existing_model_instance = model_class.objects.get( **model_filter_parameters) edit_existing_url = reverse("edit_existing", kwargs={ "version_number": version.number, "project_name": project.name, "model_name": model_name, "model_id": existing_model_instance.pk, }) return HttpResponseRedirect(edit_existing_url) except FieldError, TypeError: # raise an error if some of the filter parameters were invalid msg = "Unable to access a '%s' with the following parameters: %s" % ( model_class.getTitle(), (", ").join([ u'%s=%s' % (key, value) for (key, value) in model_filter_parameters.iteritems() ])) return dcf_error(request, msg) except MultipleObjectsReturned: # raise an error if those filter params weren't enough to uniquely identify a customizer msg = "Unable to find a <i>single</i> '%s' with the following parameters: %s" % ( model_class.getTitle(), (", ").join([ u'%s=%s' % (key, value) for (key, value) in model_filter_parameters.iteritems() ])) return dcf_error(request, msg) except model_class.DoesNotExist: # raise an error if there was no matching query msg = "Unable to find any '%s' with the following parameters: %s" % ( model_class.getTitle(), (", ").join([ u'%s=%s' % (key, value) for (key, value) in model_filter_parameters.iteritems() ])) return dcf_error(request, msg)
def edit_existing(request, version_number="", project_name="", model_name="", model_id=""): msg = "" (project,version,customizer,categorization,vocabularies,model_class,msg) = \ check_parameters(version_number,project_name,model_name) if not all([ project, version, customizer, categorization, vocabularies, model_class ]): return dcf_error(request, msg) # check authentication... # (not using @login_required b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): return redirect('/dcf/login/?next=%s' % (request.path)) if not (request.user.is_superuser or request.user.metadata_user.is_user_of(project)): msg = "User '%s' does not have permission to edit customizations for project '%s'." % ( request.user, project_name) return dcf_error(request, msg) # try to get the requested model... try: model_instance = model_class.objects.get(pk=model_id) except ObjectDoesNotExist: msg = "Cannot find the specified model. Please try again." return dcf_error(request, msg) if not model_instance.isDocument(): msg = "The model type '%s' is not an editable metadata document" % ( model_class.getTitle()) return dcf_error(request, msg) model_instances = {} model_forms = {} scientific_property_formsets = {} model_instances[model_instance.component_name] = model_instance for model in model_instance.getAllChildren(): model_instances[model.component_name] = model form_class = MetadataFormFactory(model_class, customizer) component_list = [] component_tree = {} if customizer.model_root_component: component_list.append(customizer.model_root_component) component_tree[customizer.model_root_component] = [] for vocabulary in vocabularies: try: component_list += vocabulary.getComponentList() if customizer.model_root_component: component_tree[customizer.model_root_component].append( vocabulary.getComponentTree()) else: component_tree.update(vocabulary.getComponentTree()) if not any( component_list ): # don't need to check component_tree; if it has one it will have the other msg = "There is no component hierarchy defined in vocabulary '%s'. Has it been registered?" % vocabulary return dcf_error(request, msg) except: msg = "There is no component hierarchy defined in vocabulary '%s'. Has it been registered?" % vocabulary return dcf_error(request, msg) standard_categories = customizer.getStandardCategories() scientific_categories = project.categories.all().order_by("order") for vocabulary in vocabularies: scientific_categories = scientific_categories | vocabulary.categories.all( ).order_by("order") if request.method == "POST": for component in component_list: component_key = component.lower() model_forms[component_key] = form_class( request.POST, instance=model_instances[component_key], component_name=component_key, prefix=component_key, request=request, ) scientific_properties = model_instances[ component_key].getScientificProperties() if scientific_properties: scientific_property_formsets[component_key] = \ MetadataScientificPropertyFormSetFactory( queryset = scientific_properties, prefix = component_key + "_scientific_property", request = request, ) validity = [] for (component_name, model_form) in model_forms.iteritems(): if model_form.is_valid(): validity.append(True) #print "%s is valid" % component_name else: validity.append(False) #print "%s is invalid" % component_name #print model_form.errors #print model_form.non_field_errors() for (component_name, scientific_property_formset ) in scientific_property_formsets.iteritems(): if scientific_property_formset.is_valid(): validity.append(True) #print "%s has valid scientific properties" % component_name else: validity.append(False) #print "%s has invalid scientific properties" % component_name #print scientific_property_formset.errors #print scientific_property_formset.non_form_errors() if all(validity): root_component = component_list[0].lower() for (component_name, model_form) in model_forms.iteritems(): model_instances[component_name] = model_form.save(commit=False) if ("publish_button" in request.POST) and (component_name.lower() == root_component): model_instances[component_name].published = True model_instances[component_name].save() model_form.save_m2m() for (component_name, scientific_property_formset ) in scientific_property_formsets.iteritems(): # TODO: DON'T THINK I NEED TO SAVE FORMSETS & THEN SAVE INSTANCES AS ABOVE scientific_property_formset.save() edit_existing_url = reverse( "edit_existing", kwargs={ "version_number": version.number, "project_name": project, "model_name": model_name, "model_id": model_instances[root_component].pk, }) + "?success=true" return HttpResponseRedirect(edit_existing_url) else: msg = "Unable to save the model. Please review the form and try again." else: # request.method == "GET" if request.GET.get("success", False): msg = "Successfully saved the model: '%s'." % model_instance.shortName for component in component_list: component_key = component.lower() model_forms[component_key] = form_class( instance=model_instances[component_key], component_name=component_key, prefix=component_key, request=request) scientific_properties = model_instances[ component_key].getScientificProperties() if scientific_properties: scientific_property_formsets[component_key] = \ MetadataScientificPropertyFormSetFactory( queryset = scientific_properties, prefix = component_key + "_scientific_property", request = request, ) # gather all the extra information required by the template dict = { "site": get_current_site(request), "msg": msg, "forms": model_forms, "scientific_property_formsets": scientific_property_formsets, "standard_categories": standard_categories, "scientific_categories": scientific_categories, "customizer": customizer, "project": project, "version": version, "vocabularies": vocabularies, "model_class": model_class, "component_list": component_list, "component_tree": dict_to_html(component_tree), } return render_to_response('dcf/dcf_edit.html', dict, context_instance=RequestContext(request))
except model_class.DoesNotExist: # raise an error if there was no matching query msg = "Unable to find any '%s' with the following parameters: %s" % ( model_class.getTitle(), (", ").join([ u'%s=%s' % (key, value) for (key, value) in model_filter_parameters.iteritems() ])) return dcf_error(request, msg) # if I'm here then I will be working w/ a new model... model_instance = model_class(**model_filter_parameters) if not model_instance.isDocument(): msg = "The model type '%s' is not an editable metadata document" % ( model_class.getTitle()) return dcf_error(request, msg) model_instances = {} scientific_property_instances = {} model_forms = {} scientific_property_formsets = {} form_class = MetadataFormFactory(model_class, customizer) component_list = [] component_tree = {} if customizer.model_root_component: component_list.append(customizer.model_root_component) component_tree[customizer.model_root_component] = [] # TODO: THIS WILL BREAK IF THE SAME KEY IS IN DIFFERENT VOCABS for vocabulary in vocabularies:
def view_existing(request, version_number="", project_name="", model_name="", model_id=""): msg = "" (project,version,customizer,categorization,vocabularies,model_class,msg) = \ check_parameters(version_number,project_name,model_name) if not all([ project, version, customizer, categorization, vocabularies, model_class ]): return dcf_error(request, msg) # try to get the requested model... try: model_instance = model_class.objects.get(pk=model_id) except ObjectDoesNotExist: msg = "Cannot find the specified model. Please try again." return dcf_error(request, msg) if not model_instance.isDocument(): msg = "The model type '%s' is not an editable metadata document" % ( model_class.getTitle()) return dcf_error(request, msg) model_instances = {} model_forms = {} scientific_property_formsets = {} model_instances[model_instance.component_name] = model_instance for model in model_instance.getAllChildren(): model_instances[model.component_name] = model form_class = MetadataFormFactory(model_class, customizer) component_list = [] component_tree = {} if customizer.model_root_component: component_list.append(customizer.model_root_component) component_tree[customizer.model_root_component] = [] for vocabulary in vocabularies: try: component_list += vocabulary.getComponentList() if customizer.model_root_component: component_tree[customizer.model_root_component].append( vocabulary.getComponentTree()) else: component_tree.update(vocabulary.getComponentTree()) if not any( component_list ): # don't need to check component_tree; if it has one it will have the other msg = "There is no component hierarchy defined in vocabulary '%s'. Has it been registered?" % vocabulary return dcf_error(request, msg) except: msg = "There is no component hierarchy defined in vocabulary '%s'. Has it been registered?" % vocabulary return dcf_error(request, msg) root_component = component_list[0].lower() standard_categories = customizer.getStandardCategories() scientific_categories = project.categories.all().order_by("order") for vocabulary in vocabularies: scientific_categories = scientific_categories | vocabulary.categories.all( ).order_by("order") if request.method == "POST": # POST just means they clicked "edit" edit_existing_url = reverse("edit_existing", kwargs={ "version_number": version.number, "project_name": project, "model_name": model_name, "model_id": model_instances[root_component].pk, }) return HttpResponseRedirect(edit_existing_url) else: # request.method == "GET" for component in component_list: component_key = component.lower() model_forms[component_key] = form_class( instance=model_instances[component_key], component_name=component_key, prefix=component_key, request=request) scientific_properties = model_instances[ component_key].getScientificProperties() if scientific_properties: scientific_property_formsets[component_key] = \ MetadataScientificPropertyFormSetFactory( queryset = scientific_properties, prefix = component_key + "_scientific_property", request = request, ) # gather all the extra information required by the template dict = { "msg": msg, "forms": model_forms, "scientific_property_formsets": scientific_property_formsets, "standard_categories": standard_categories, "scientific_categories": scientific_categories, "customizer": customizer, "project": project, "version": version, "vocabularies": vocabularies, "model_class": model_class, "component_list": component_list, "component_tree": dict_to_html(component_tree), } return render_to_response('dcf/dcf_view.html', dict, context_instance=RequestContext(request))
def customize_existing(request, version_number="", project_name="", model_name="", customizer_id="", **kwargs): msg = "" # try to get the requested customizer... try: model_customizer_instance = MetadataModelCustomizer.objects.get( pk=customizer_id) except ObjectDoesNotExist: msg = "Cannot find the specified Customizer. Please try again." return dcf_error(request, msg) # standard_properties = model_customizer_instance.getStandardPropertyCustomizers() # scientific_properties = model_customizer_instance.getScientificPropertyCustomizers() project = model_customizer_instance.getProject() version = model_customizer_instance.getVersion() model_class = model_customizer_instance.getModel() # check authentication... # (not using @login_required b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): return redirect('/dcf/login/?next=%s' % (request.path)) if not (request.user.is_superuser or request.user.metadata_user.is_admin_of(project)): msg = "User '%s' does not have permission to edit customizations for project '%s'." % ( request.user, project_name) return dcf_error(request, msg) # get the default categorization and vocabulary... categorizations = version.categorizations.all() vocabularies = project.vocabularies.all().filter( document_type__iexact=model_name) categorization = categorizations[0] if categorizations else None if not categorization: msg = "There is no default categorization associated with version %s." % version return dcf_error(request, msg) if not vocabularies: msg = "There are no default vocabularies associated with project %s (for model %s)." % ( project, model_name) return dcf_error(request, msg) component_list = [] for vocabulary in vocabularies: try: component_list += vocabulary.getComponentList() if not any(component_list): msg = "There is no component hierarchy defined in this vocabulary. Has it been registered?" return dcf_error(request, msg) except: msg = "There is no component hierarchy defined in this vocabulary. Has it been registered?" return dcf_error(request, msg) standard_categories = categorization.categories.all().order_by("order") scientific_categories = project.categories.all().order_by("order") for vocabulary in vocabularies: scientific_categories = scientific_categories | vocabulary.categories.all( ).order_by("order") # # check that the user has permission for this view # if not request.user.is_authenticated(): # return HttpResponseRedirect('%s/?next=%s' % (settings.LOGIN_URL,request.path)) # else: # if not user_has_permission(request.user,project.restriction_customize): # msg = "You do not have permission to access this resource." # return dcf_error(request,msg) if request.method == "POST": validity = [] model_customizer_form = MetadataModelCustomizerForm( \ request.POST, instance=model_customizer_instance, component_list = component_list, initial = { "categorization" : categorization, # "vocabularies" : vocabularies, "standard_categories_content" : JSON_SERIALIZER.serialize(standard_categories), "scientific_categories_content" : JSON_SERIALIZER.serialize(scientific_categories), } ) standard_property_customizer_formset = MetadataStandardPropertyCustomizerInlineFormSetFactory( instance=model_customizer_instance, prefix="standard_property", request=request) scientific_property_customizer_formset = MetadataScientificPropertyCustomizerInlineFormSetFactory( instance=model_customizer_instance, prefix="scientific_property", request=request) validity += [model_customizer_form.is_valid()] validity += [standard_property_customizer_formset.is_valid()] validity += [scientific_property_customizer_formset.is_valid()] if all(validity): # TODO: REMOVE LOOPS HERE model_customizer_instance = model_customizer_form.save() standard_property_customizer_instances = standard_property_customizer_formset.save( commit=False) for standard_property_customizer_instance in standard_property_customizer_instances: standard_property_customizer_instance.save() scientific_property_customizer_instances = scientific_property_customizer_formset.save( commit=False) for scientific_property_customizer_instance in scientific_property_customizer_instances: scientific_property_customizer_instance.save() customize_existing_url = reverse( "customize_existing", kwargs={ "version_number": version.number, "project_name": project, "model_name": model_name, "customizer_id": model_customizer_instance.pk, }) + "?success=true" return HttpResponseRedirect(customize_existing_url) else: # request.method == "GET" if request.GET.get("success", False): msg = "Successfully saved the customization: '%s'." % model_customizer_instance.name model_customizer_form = MetadataModelCustomizerForm( \ instance=model_customizer_instance, component_list = component_list, initial = { "categorization" : categorization, # "vocabularies" : vocabularies, "standard_categories_content" : JSON_SERIALIZER.serialize(standard_categories), "scientific_categories_content" : JSON_SERIALIZER.serialize(scientific_categories), } ) standard_property_customizer_formset = MetadataStandardPropertyCustomizerInlineFormSetFactory( instance=model_customizer_instance, prefix="standard_property", request=request) scientific_property_customizer_formset = MetadataScientificPropertyCustomizerInlineFormSetFactory( instance=model_customizer_instance, prefix="scientific_property", request=request) # gather all the extra information required by the template dict = { "msg": msg, "model_customizer_form": model_customizer_form, "standard_property_customizer_formset": standard_property_customizer_formset, "scientific_property_customizer_formset": scientific_property_customizer_formset, "project": project, "version": version, "categorization": categorization, "vocabularies": vocabularies, "model_class": model_class, "component_list": component_list, } return render_to_response('dcf/dcf_customize.html', dict, context_instance=RequestContext(request))
def customize_new(request, version_number="", project_name="", model_name=""): msg = "" # try to get the requested project... try: project = MetadataProject.objects.get(name__iexact=project_name) except ObjectDoesNotExist: msg = "Cannot find the project '%s'. Has it been registered?" % project_name return dcf_error(request, msg) # try to get the requested version... if version_number: try: version = MetadataVersion.objects.get(name__iexact=METADATA_NAME, number=version_number) except ObjectDoesNotExist: msg = "Cannot find version '%s_%s'. Has it been registered?" % ( METADATA_NAME, version_number) return dcf_error(request, msg) else: version = project.getDefaultVersion() if not version: msg = "please specify a version; the '%s' project has no default one." % project.getName( ) return dcf_error(request, msg) # try to get the requested model (class)... model_class = version.getModelClass(model_name) if not model_class: msg = "Cannot find the model type '%s' in version '%s'. Have all model types been registered?" % ( model_name, version) return dcf_error(request, msg) # check authentication... # (not using @login_required b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): return redirect('/dcf/login/?next=%s' % (request.path)) if not (request.user.is_superuser or request.user.metadata_user.is_admin_of(project)): msg = "User '%s' does not have permission to edit customizations for project '%s'." % ( request.user, project_name) return dcf_error(request, msg) # get the default categorization and vocabulary... categorizations = version.categorizations.all() vocabularies = project.vocabularies.all().filter( document_type__iexact=model_name) # TODO: THIS IS CLEARLY DUMB, # BUT THE RELATEDOBJECTMANAGER IS BEING USED FOR THE TIME WHEN # THIS CODE CAN SUPPORT MULTPLE CATEGORIZATIONS categorization = categorizations[0] if categorizations else None if not categorization: msg = "There is no default categorization associated with version %s." % version return dcf_error(request, msg) if not vocabularies: msg = "There are no default vocabularies associated with '%s' within the project '%s'." % ( model_class.getTitle(), project) return dcf_error(request, msg) component_list = [] for vocabulary in vocabularies: try: component_list += vocabulary.getComponentList() if not any(component_list): msg = "There is no component hierarchy defined in this vocabulary. Has it been registered?" return dcf_error(request, msg) except: msg = "There is no component hierarchy defined in this vocabulary. Has it been registered?" return dcf_error(request, msg) standard_categories = categorization.categories.all().order_by("order") scientific_categories = project.categories.all().order_by("order") for vocabulary in vocabularies: scientific_categories = scientific_categories | vocabulary.categories.all( ).order_by("order") # at this point I know the project, model, version, categorization, vocabularies, and categories customizer_filter_parameters = { "project": project, "version": version, "model": model_name, } if request.method == "GET": # check if the user added any parameters to the request for (key, value) in request.GET.iteritems(): value = re.sub('[\"\']', '', value) # strip out any quotes field_type = type(MetadataModelCustomizer.getField(key)) if field_type == BooleanField: # special case for boolean fields if value.lower() == "true" or value == "1": customizer_filter_parameters[key] = True elif value.lower() == "false" or value == "0": customizer_filter_parameters[key] = False else: customizer_filter_parameters[key] = value elif field_type == CharField or field_type == TextField: # this ensures that the filter is case-insenstive for strings key = key + "__iexact" # bear in mind that if I ever change to using get_or_create, the filter will have to be case-sensitive # see https://code.djangoproject.com/ticket/7789 for more info customizer_filter_parameters[key] = value else: customizer_filter_parameters[key] = value if len(customizer_filter_parameters) > 3: # if there were (extra) filter parameters passed # then try to get the customizer w/ those parameters try: existing_model_customizer_instance = MetadataModelCustomizer.objects.get( **customizer_filter_parameters) customize_existing_url = reverse( "customize_existing", kwargs={ "version_number": version.number, "project_name": project.name, "model_name": model_name, "customizer_id": existing_model_customizer_instance.pk, }) return HttpResponseRedirect(customize_existing_url) except FieldError, TypeError: # raise an error if some of the filter parameters were invalid msg = "Unable to access a Customizer with the following parameters: %s" % ( ", ").join([ u'%s=%s' % (key, value) for (key, value ) in customizer_filter_parameters.iteritems() ]) return dcf_error(request, msg) except MultipleObjectsReturned: # raise an error if those filter params weren't enough to uniquely identify a customizer msg = "Unable to find a <i>single</i> Customizer with the following parameters: %s" % ( ", ").join([ u'%s=%s' % (key, value) for (key, value ) in customizer_filter_parameters.iteritems() ]) return dcf_error(request, msg) except MetadataModelCustomizer.DoesNotExist: # raise an error if there was no matching query msg = "Unable to find any Customizer with the following parameters: %s" % ( ", ").join([ u'%s=%s' % (key, value) for (key, value ) in customizer_filter_parameters.iteritems() ]) return dcf_error(request, msg)