Esempio n. 1
0
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)
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
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)
Esempio n. 8
0
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
        })