def details(request): """ ID Details page for a given ID """ d = {'menu_item': 'ui_manage.null'} d["testPrefixes"] = uic.testPrefixes identifier = request.path_info[len("/id/"):] r = _getLatestMetadata(identifier, request, prefixMatch=(request.GET.get( "prefix_match", "no").lower() == "yes")) if type(r) is str: django.contrib.messages.error( request, uic.formatError(r + ": " + identifier)) # ToDo: Pass details in from previous screen so we know where to send redirect back to if userauth.getUser(request) == None: return redirect("ui_search.index") else: return redirect("ui_home.index") s, id_metadata = r assert s.startswith("success:") if " in_lieu_of " in s: newid = s.split()[1] django.contrib.messages.info( request, "Identifier %s returned in lieu of %s." % (newid, identifier)) return redirect("/id/" + urllib.quote(newid, ":/")) d['allow_update'] = policy.authorizeUpdateLegacy( userauth.getUser(request, returnAnonymous=True), id_metadata["_owner"], id_metadata["_ownergroup"]) d['identifier'] = id_metadata d['id_text'] = s.split()[1] d['id_as_url'] = util2.urlForm(d['id_text']) d['is_test_id'] = _isTestId(d['id_text'], d['testPrefixes']) d['internal_profile'] = metadata.getProfile('internal') d['target'] = id_metadata['_target'] d['current_profile'] = metadata.getProfile(id_metadata['_profile']) or\ metadata.getProfile('erc') d['recent_creation'] = identifier.startswith('doi') and \ (time.time() - float(id_metadata['_created']) < 60 * 30) d['recent_update'] = identifier.startswith('doi') and \ (time.time() - float(id_metadata['_updated']) < 60 * 30) if d['current_profile'].name == 'datacite' and 'datacite' in id_metadata: r = datacite.dcmsRecordToHtml(id_metadata["datacite"]) if r: d['datacite_html'] = r if d['current_profile'].name == 'crossref' and 'crossref' in id_metadata and \ id_metadata['crossref'].strip() != "": d['has_crossref_metadata'] = True t_stat = [x.strip() for x in id_metadata['_status'].split("|", 1)] d['pub_status'] = t_stat[0] if t_stat[0] == 'unavailable' and len(t_stat) > 1: d['stat_reason'] = t_stat[1] if t_stat[0] == 'public' and identifier.startswith("ark:/"): d['schemaDotOrgMetadata'] = _schemaDotOrgMetadata( mapping.map(id_metadata), d['id_as_url']) d['has_block_data'] = uic.identifier_has_block_data(id_metadata) d['has_resource_type'] = True if (d['current_profile'].name == 'datacite' \ and 'datacite.resourcetype' in id_metadata \ and id_metadata['datacite.resourcetype'] != '') else False return uic.render(request, "manage/details", d)
def simple_form(request, d): """ Create simple identifier code shared by 'Create ID' and 'Demo' pages. Takes request and context object, d['prefixes'] should be set before calling. Returns dictionary with d['id_gen_result'] of either 'method_not_allowed', 'bad_request', 'edit_page' or 'created_identifier: <new_id>'. If process is as expected, also includes a form object containing posted data and any related errors. """ if request.method == "GET": REQUEST = request.GET elif request.method == "POST": REQUEST = request.POST else: d['id_gen_result'] = 'method_not_allowed' return d # selects current_profile based on parameters or profile preferred for prefix type d['internal_profile'] = metadata.getProfile('internal') if 'current_profile' in REQUEST: d['current_profile'] = metadata.getProfile(REQUEST['current_profile']) if d['current_profile'] == None: d['current_profile'] = metadata.getProfile('erc') else: if len(d['prefixes']) > 0 and d['prefixes'][0]['prefix'].startswith( 'doi:'): d['current_profile'] = metadata.getProfile('datacite') else: d['current_profile'] = metadata.getProfile('erc') if "form_placeholder" not in d: d['form_placeholder'] = None if request.method == "GET": # Begin ID Creation (empty form) d['form'] = form_objects.getIdForm(d['current_profile'], d['form_placeholder'], None) d['id_gen_result'] = 'edit_page' else: if "current_profile" not in REQUEST or "shoulder" not in REQUEST: d['id_gen_result'] = 'bad_request' return d d['form'] = form_objects.getIdForm(d['current_profile'], d['form_placeholder'], REQUEST) pre_list = [pr['prefix'] for pr in d['prefixes']] if not _verifyProperShoulder(request, REQUEST, pre_list): d['id_gen_result'] = 'edit_page' return d if d['form'].is_valid(): d = _createSimpleId(d, request, REQUEST) else: django.contrib.messages.error(request, _validationErr(_("created"))) d['id_gen_result'] = 'edit_page' return d
def display_xml(request, identifier): """ Used for displaying DataCite or Crossref XML """ d = {'menu_item': 'ui_manage.null'} r = _getLatestMetadata(identifier, request) if type(r) is str: django.contrib.messages.error(request, uic.formatError(r)) return redirect("/") s, id_metadata = r assert s.startswith("success:") d['identifier'] = id_metadata d['current_profile'] = metadata.getProfile(id_metadata['_profile']) if d['current_profile'].name == 'datacite' and 'datacite' in id_metadata: content = id_metadata["datacite"] elif d['current_profile'].name == 'crossref' and 'crossref' in id_metadata: content = id_metadata["crossref"] else: return uic.staticTextResponse("No XML metadata.") # By setting the content type ourselves, we gain control over the # character encoding and can properly set the content length. ec = content.encode("UTF-8") r = django.http.HttpResponse(ec, content_type="application/xml; charset=UTF-8") r["Content-Length"] = len(ec) return r
def _engage_datacite_xml_profile(request, d, profile_name): # Hack: For now, this is the only manual profile d['current_profile'] = metadata.getProfile('datacite') d['manual_profile'] = True d['current_profile_name'] = profile_name d['manual_template'] = 'create/_' + d['current_profile_name'] + '.html' d['polygon_view'] = 'view' return d
def _updateEzid(request, d, stts, m_to_upgrade=None): """ Takes data from form fields in /manage/edit and applies them to IDs metadata If m_to_upgrade is specified, converts record to advanced datacite Returns ezid.setMetadata (successful return is the identifier string) Also removes tags related to old profile if converting to advanced datacite """ m_dict = { '_target': request.POST['target'], '_status': stts, '_export': ('yes' if (not 'export' in d) or d['export'] == 'yes' else 'no') } if m_to_upgrade: d['current_profile'] = metadata.getProfile('datacite') # datacite_xml ezid profile is defined by presence of 'datacite' assigned to the # '_profile' key and XML present in the 'datacite' key m_dict['datacite'] = datacite.formRecord(d['id_text'], m_to_upgrade, True) m_dict['_profile'] = 'datacite' # Old tag cleanup if m_to_upgrade.get("_profile", "") == "datacite": m_dict['datacite.creator'] = '' m_dict['datacite.publisher'] = '' m_dict['datacite.publicationyear'] = '' m_dict['datacite.title'] = '' m_dict['datacite.type'] = '' if m_to_upgrade.get("_profile", "") == "dc": m_dict['dc.creator'] = '' m_dict['dc.date'] = '' m_dict['dc.publisher'] = '' m_dict['dc.title'] = '' m_dict['dc.type'] = '' if m_to_upgrade.get("_profile", "") == "erc": m_dict['erc.who'] = '' m_dict['erc.what'] = '' m_dict['erc.when'] = '' # ToDo: Using current_profile here, but isn't this confusing if executing simpleToAdvanced to_write = uic.assembleUpdateDictionary(request, d['current_profile'], m_dict) return ezid.setMetadata(d['id_text'], userauth.getUser(request, returnAnonymous=True), to_write)
def adv_form(request, d): """ Like simple_form. Takes request and context object. d['prefixes'] should be set before calling. Includes addtn'l features: custom remainder - optional manual_profile - If true, use custom Datacite XML template profile_names - User can choose from different profiles """ #selects current_profile based on parameters or profile preferred for prefix type d['manual_profile'] = False choice_is_doi = False # Form will be GET request when flipping between shoulders and profiles. Otherwise it's a POST. if request.method == "GET": REQUEST = request.GET elif request.method == "POST": REQUEST = request.POST else: d['id_gen_result'] = 'method_not_allowed' return d if (('shoulder' in REQUEST and REQUEST['shoulder'].startswith("doi:")) \ or (len(d['prefixes']) > 0 and d['prefixes'][0]['prefix'].startswith('doi:'))): choice_is_doi = True if 'current_profile' in REQUEST: if REQUEST['current_profile'] in uic.manual_profiles: d = _engage_datacite_xml_profile(request, d, 'datacite_xml') else: d['current_profile'] = metadata.getProfile( REQUEST['current_profile']) if d['current_profile'] == None: d['current_profile'] = metadata.getProfile('erc') else: if choice_is_doi == True: d = _engage_datacite_xml_profile(request, d, 'datacite_xml') else: d['current_profile'] = metadata.getProfile('erc') if d['manual_profile'] == False: d['current_profile_name'] = d['current_profile'].name d['internal_profile'] = metadata.getProfile('internal') d['profiles'] = [p for p in metadata.getProfiles()[1:] if p.editable] profs = [( p.name, p.displayName, ) for p in d['profiles']] + uic.manual_profiles.items() d['profile_names'] = sorted(profs, key=lambda p: p[1].lower()) # 'datacite_xml' used for advanced profile instead of 'datacite' d['profile_names'].remove(('datacite', 'DataCite')) # [TODO: Enhance advanced DOI ERC profile to allow for elements ERC + datacite.publisher or # ERC + dc.publisher.] For now, just hide this profile. if choice_is_doi: d['profile_names'].remove(('erc', 'ERC')) # Preserve remainder from GET request if 'remainder' in REQUEST: d['remainder'] = REQUEST['remainder'] d['remainder_box_default'] = form_objects.REMAINDER_BOX_DEFAULT if request.method == "GET": # Begin ID Creation (empty form) if d['current_profile_name'] == 'datacite_xml': d['form'] = form_objects.getIdForm_datacite_xml() else: d['form'] = form_objects.getAdvancedIdForm(d['current_profile'], request) d['id_gen_result'] = 'edit_page' if 'anchor' in REQUEST: d['anchor'] = REQUEST['anchor'] else: # request.method == "POST" P = REQUEST pre_list = [p['prefix'] for p in d['prefixes'] + d['testPrefixes']] if not _verifyProperShoulder(request, P, pre_list): d['id_gen_result'] = 'edit_page' return d if d['current_profile_name'] == 'datacite_xml': d = validate_adv_form_datacite_xml(request, d) if 'id_gen_result' in d: return d d = _createAdvancedId(d, request, P) else: if "current_profile" not in P or "shoulder" not in P: d['id_gen_result'] = 'bad_request' return d d['form'] = form_objects.getAdvancedIdForm(d['current_profile'], request) if not (d['form']['form'].is_valid() and d['form']['remainder_form'].is_valid()): django.contrib.messages.error(request, _validationErr(_("created"))) d['id_gen_result'] = 'edit_page' else: d = _createAdvancedId(d, request, P) return d
def edit(request, identifier): """ Edit page for a given ID """ d = {'menu_item': 'ui_manage.null'} d["testPrefixes"] = uic.testPrefixes r = _getLatestMetadata(identifier, request) if type(r) is str: django.contrib.messages.error(request, uic.formatError(r)) return redirect("ui_manage.index") s, id_metadata = r if not policy.authorizeUpdateLegacy( userauth.getUser(request, returnAnonymous=True), id_metadata["_owner"], id_metadata["_ownergroup"], ): django.contrib.messages.error( request, _( "You are not allowed to edit this identifier. " + "If this ID belongs to you and you'd like to edit, please log in." ), ) return redirect("/id/" + urllib.quote(identifier, ":/")) d['identifier'] = id_metadata t_stat = [x.strip() for x in id_metadata['_status'].split("|", 1)] d['pub_status'] = t_stat[0] d['orig_status'] = t_stat[0] d['stat_reason'] = None if t_stat[0] == 'unavailable' and len(t_stat) > 1: d['stat_reason'] = t_stat[1] d['export'] = id_metadata['_export'] if '_export' in id_metadata else 'yes' d['id_text'] = s.split()[1] d['id_as_url'] = util2.urlForm(d['id_text']) d['internal_profile'] = metadata.getProfile('internal') d['profiles'] = metadata.getProfiles()[1:] if request.method == "GET": d['is_test_id'] = _isTestId(d['id_text'], d['testPrefixes']) if '_profile' in id_metadata: d['current_profile'] = metadata.getProfile(id_metadata['_profile']) else: d['current_profile'] = metadata.getProfile('dc') if d['current_profile'].name == 'datacite' and 'datacite' in id_metadata: d = _assignManualTemplate(d) # Testing # xml = datacite_xml.temp_mockxml() # form_coll = datacite_xml.dataciteXmlToFormElements(xml) form_coll = datacite_xml.dataciteXmlToFormElements( d['identifier']['datacite'] ) # This is the only item from internal profile that needs inclusion in django form framework form_coll.nonRepeating['target'] = id_metadata['_target'] d['form'] = form_objects.getIdForm_datacite_xml(form_coll, request) if not form_objects.isValidDataciteXmlForm(d['form']): django.contrib.messages.error(request, FORM_VALIDATION_ERROR_ON_LOAD) else: if "form_placeholder" not in d: d['form_placeholder'] = None d['form'] = form_objects.getIdForm( d['current_profile'], d['form_placeholder'], id_metadata ) if not d['form'].is_valid(): django.contrib.messages.error(request, FORM_VALIDATION_ERROR_ON_LOAD) elif request.method == "POST": P = request.POST d['pub_status'] = P['_status'] if '_status' in P else d['pub_status'] d['stat_reason'] = P['stat_reason'] if 'stat_reason' in P else d['stat_reason'] d['export'] = P['_export'] if '_export' in P else d['export'] ''' Profiles could previously be switched in edit template, thus generating posibly two differing profiles (current vs original). So we previously did a check here to confirm current_profile equals original profile before saving.''' d['current_profile'] = metadata.getProfile( P.get('original_profile', d['identifier']['_profile']) ) if P['_status'] == 'unavailable': stts = P['_status'] + " | " + P['stat_reason'] else: stts = P['_status'] if d['current_profile'].name == 'datacite' and 'datacite' in id_metadata: d = _assignManualTemplate(d) d = ui_create.validate_adv_form_datacite_xml(request, d) if 'id_gen_result' in d: return uic.render(request, 'manage/edit', d) # ID Creation page else: assert 'generated_xml' in d to_write = { "_profile": 'datacite', '_target': P['target'], "_status": stts, "_export": d['export'], "datacite": d['generated_xml'], } s = ezid.setMetadata( P['identifier'], userauth.getUser(request, returnAnonymous=True), to_write, ) if s.startswith("success:"): _alertMessageUpdateSuccess(request) return redirect("/id/" + urllib.quote(identifier, ":/")) else: _alertMessageUpdateError(request, s) else: """ Even if converting from simple to advanced, let's make sure forms validate and update identifier first, else don't upgrade. """ d['form'] = form_objects.getIdForm(d['current_profile'], None, P) if d['form'].is_valid(): result = _updateEzid(request, d, stts) if not result.startswith("success:"): d['current_profile'] = metadata.getProfile(id_metadata['_profile']) _alertMessageUpdateError(request, result) return uic.render(request, "manage/edit", d) else: if 'simpleToAdvanced' in P and P['simpleToAdvanced'] == 'True': # Convert simple ID to advanced (datacite with XML) result = _updateEzid(request, d, stts, id_metadata) r = _getLatestMetadata(identifier, request) if type(r) is str: django.contrib.messages.error(request, uic.formatError(r)) return redirect("ui_manage.index") s, id_metadata = r if not result.startswith("success:"): # if things fail, just display same simple edit page with error _alertMessageUpdateError(request, result) else: _alertMessageUpdateSuccess(request) return redirect("/id/" + urllib.quote(identifier, ":/")) else: _alertMessageUpdateSuccess(request) return redirect("/id/" + urllib.quote(identifier, ":/")) else: return uic.methodNotAllowed(request) return uic.render(request, "manage/edit", d)
def tombstone(request): """ Renders a tombstone (i.e., unavailable identifier) page. """ if request.method != "GET": return uic.methodNotAllowed(request) assert request.path_info.startswith("/tombstone/id/") id = request.path_info[14:] if "auth" in request.session: r = ezid.getMetadata(id, userauth.getUser(request, returnAnonymous=True)) else: r = ezid.getMetadata(id) if type(r) is str: messages.error(request, uic.formatError(r)) return uic.redirect("/") s, m = r assert s.startswith("success:") id = s[8:].strip() if not m["_status"].startswith("unavailable"): return uic.redirect("/id/%s" % urllib.quote(id, ":/")) status = m["_status"] reason = tombstone_text if "|" in m["_status"]: status = m["_status"].split("|", 1)[0].strip() # Translators: Output for tombstone page (unavailable IDs) reason += " " + _("Reason:") + " " + m["_status"].split("|", 1)[1].strip() htmlMode = False if m["_profile"] == "datacite" and "datacite" in m: md = datacite.dcmsRecordToHtml(m["datacite"]) if md: htmlMode = True root = lxml.etree.fromstring(md) # Tack on an additional row displaying status row = lxml.etree.Element("tr", attrib={"class": "dcms_element"}) c1 = lxml.etree.SubElement(row, "th", attrib={"class": "dcms_label"}) c1.text = _("Status:") c2 = lxml.etree.SubElement(row, "td", attrib={"class": "dcms_value"}) c2.text = status root.append(row) md = lxml.etree.tostring(root) if not htmlMode: # This echoes the Merritt hack above. if m["_profile"] == "erc" and m.get("erc", "").strip() != "": md = [{"label": "ERC", "value": m["erc"].strip()}] else: p = metadata.getProfile(m["_profile"]) if not p: p = metadata.getProfile("erc") md = [] for e in p.elements: if "." not in e.name: continue v = m.get(e.name, "").strip() md.append({ "label": e.displayName, "value": v if v != "" else "(no value)" }) # Tack on an additional row displaying status md.append({"label": _("Status"), "value": status}) return uic.render( request, "tombstone", { "identifier": id, "identifierLink": "/id/%s" % urllib.quote(id, ":/"), "reason": reason, "htmlMode": htmlMode, "metadata": md })