Beispiel #1
0
def index(request, experiment_id):
    url = 'monash_ands/form.html'

    try:
        e = Experiment.objects.get(id=experiment_id)

        import sys
        allowed_protocol = sys.modules['%s.%s.settings' %
                    (settings.TARDIS_APP_ROOT, 'monash_ands')].ALLOWED_PROTOCOL

        if not request.user.is_authenticated():
            # todo: de-duplicate
            from django.template import Context
            c = Context()
            c['disallowed_protocol'] = True

            return HttpResponse(render_response_index(request, url, c))

        ua = UserAuthentication.objects.get(username=request.user.username)
        if not ua.authenticationMethod == allowed_protocol:
            from django.template import Context
            c = Context()
            c['is_owner'] = authz.has_experiment_ownership(request,
                experiment_id)
            c['disallowed_protocol'] = True

            return HttpResponse(render_response_index(request, url, c))

        if not request.POST:
            monashandsService = MonashANDSService(experiment_id)
            c = monashandsService.get_context(request)
            if request.user.is_authenticated():
                c['is_owner'] = authz.has_experiment_ownership(request,
                    experiment_id)

            c['experiment'] = e

            cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)
            c['has_cc_license'] = cch.has_cc_license()

            return HttpResponse(render_response_index(request, url, c))
        else:
            monashandsService = MonashANDSService(experiment_id)
            c = monashandsService.register(request)
            if request.user.is_authenticated():
                c['is_owner'] = authz.has_experiment_ownership(request,
                    experiment_id)

            c['experiment'] = e

            return HttpResponse(render_response_index(request, url, c))
    except Exception, e:
        # todo: check with web services for adequate responses..
        message = '<b>An error occured:</b> ' + str(e)
        return HttpResponse(content=message)
Beispiel #2
0
def show_cc_license(value):
    """
    Shows creative commons license information for the experiment richly
    :param value: The experiment ID
    :type value: string
    :return: An html-formatted string of the creative commons license
    :rtype: string
    """
    experiment = Experiment.objects.get(id=value)
    cch = CreativeCommonsHandler(experiment_id=experiment.id, create=False)

    if not cch.has_cc_license():
        return "No license."
    else:
        psm = cch.get_or_create_cc_parameterset()

        image = ""
        try:
            image = psm.get_param('license_image', True)
        except ExperimentParameter.DoesNotExist:
            pass

        name = ""
        try:
            name = psm.get_param('license_name', True)
        except ExperimentParameter.DoesNotExist:
            pass

        uri = ""
        try:
            uri = psm.get_param('license_uri', True)
        except ExperimentParameter.DoesNotExist:
            pass

        if name == "":
            html = "No License."
        else:
            html = '<a href="' + uri + '"'\
            'rel="license" class="cc_js_a"><img width="88" height="31"'\
            ' border="0" class="cc_js_cc-button"'\
            'src="' + image + '"'\
            'alt="Creative Commons License"></a><br/>'\
            'This work is licensed under a <a rel="license"'\
            'href="' + uri + '">'\
            '' + name + '</a>.'

        return html
Beispiel #3
0
def show_cc_license(value):
    """
    Shows creative commons license information for the experiment richly
    :param value: The experiment ID
    :type value: string
    :return: An html-formatted string of the creative commons license
    :rtype: string
    """
    experiment = Experiment.objects.get(id=value)
    cch = CreativeCommonsHandler(experiment_id=experiment.id, create=False)

    if not cch.has_cc_license():
        return "No license."
    else:
        psm = cch.get_or_create_cc_parameterset()

        image = ""
        try:
            image = psm.get_param('license_image', True)
        except ExperimentParameter.DoesNotExist:
            pass

        name = ""
        try:
            name = psm.get_param('license_name', True)
        except ExperimentParameter.DoesNotExist:
            pass

        uri = ""
        try:
            uri = psm.get_param('license_uri', True)
        except ExperimentParameter.DoesNotExist:
            pass

        if name == "":
            html = "No License."
        else:
            html = '<a href="' + uri + '"'\
            'rel="license" class="cc_js_a"><img width="88" height="31"'\
            ' border="0" class="cc_js_cc-button"'\
            'src="' + image + '"'\
            'alt="Creative Commons License"></a><br/>'\
            'This work is licensed under a <a rel="license"'\
            'href="' + uri + '">'\
            '' + name + '</a>.'

        return html
Beispiel #4
0
def index(request, experiment_id):
    url = 'ands_register/index.html'

    e = Experiment.objects.get(pk=experiment_id)
    cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)
    has_licence = cch.has_cc_license()
    is_owner = authz.has_experiment_ownership(request, experiment_id)

    if request.POST:
        if not is_owner:
            return return_response_error(request)

        publish_handler = publishing.PublishHandler(experiment_id, True)
        form = forms.PublishingForm(has_licence, request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            publish_handler.update(cleaned_data)
            return HttpResponse('{"success": true}', mimetype='application/json')
    else:
        publish_handler = publishing.PublishHandler(experiment_id)
        form = forms.PublishingForm(has_licence, initial=publish_handler.form_data())

    c = Context()
    c['is_owner'] = is_owner
    c['has_licence'] = has_licence
    c['experiment'] = e
    c['form'] = form

    c['custom_description'] = publish_handler.custom_description()

    authors = [a.author for a in e.author_experiment_set.all()]
    c['authors_csv'] = ', '.join(authors)

    custom_authors = publish_handler.custom_authors()
    if custom_authors:
        c['custom_authors_csv'] = ', '.join(custom_authors)

    c['access_type'] = publish_handler.access_type()

    return HttpResponse(render_response_index(request, url, c))
Beispiel #5
0
def publish_experiment(request, experiment_id):
    """
    Make the experiment open to public access.
    Sets off a chain of PublishProvider modules for
    extra publish functionality.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be published
    :type experiment_id: string

    """
    import os

    logger.debug("started publish for hpctardis")
    experiment = Experiment.objects.get(id=experiment_id)
    #username = str(request.user).partition('_')[2]
    username = request.user.username
            
        
    logger.debug("request=%s" % request)
    logger.debug("exp=%s" % experiment_id)
    logger.debug("requestmethod=%s" % request.method)
    publishService = RMITANDSService(experiment.id)
    logger.debug("made service")
    
    if publishService.is_under_review():
        logger.debug("under review")
        context_dict = {}
        context_dict['legal'] = True
        context_dict['status'] = False
        context_dict['success'] = False
        context_dict['publish_result'] = [{'status':True,                                          
                                          'message':'Experiment is under review'}]
      
        c = Context(context_dict)
        return HttpResponse(render_response_index(request,
                        'tardis_portal/publish_experiment.html', c))

    if experiment.public:
        context_dict = {}
        logger.debug("Already published")
        context_dict['legal'] = True
        context_dict['success'] = False
        context_dict['publish_result'] = [{'status':True,
                                          
                                          'message':'Experiment is already published'}]
        c = Context(context_dict)
        return HttpResponse(render_response_index(request,
                        'tardis_portal/publish_experiment.html', c))
        
    if request.method == 'POST':  # If the form has been submitted...
        logger.debug("posted")
        legal = True
        success = True            
        context_dict = {}
        #fix this slightly dodgy logic
        context_dict['publish_result'] = "submitted"
        if 'legal' in request.POST:                    
            # only make public when all providers signal okay
            # experiment.public = True
            # experiment.save()
            logger.debug("legal set")
            context_dict['publish_result'] = \
            publishService.execute_publishers(request)

            for result in context_dict['publish_result']:
                if not result['status']:
                    success = False

        else:
            logger.debug('Legal agreement for exp: ' + experiment_id +
            ' not accepted.')
            legal = False

        # set dictionary to legal status and publish success result
        context_dict['legal'] = legal
        context_dict['success'] = success
    else:
        logger.debug("unposted")
      
        TARDIS_ROOT = os.path.abspath(\
        os.path.join(os.path.dirname(__file__)))

        legalpath = os.path.join(TARDIS_ROOT,
                      "publish/legal.txt")

        # if legal file isn't found then we can't proceed
        try:
            legalfile = open(legalpath, 'r')
        except IOError:
            logger.error('legal.txt not found. Publication halted.')
            return return_response_error(request)

        legaltext = legalfile.read()
        legalfile.close()
        logger.debug("templatepaths=%s" % publishService.get_template_paths())
       
        from tardis.tardis_portal.creativecommonshandler import CreativeCommonsHandler
 
        cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)

        context_dict = \
        {'username': username,
        'experiment': experiment,
        'legaltext': legaltext,  
        'publish_forms': publishService.get_template_paths(),
        'has_cc_license': cch.has_cc_license(),
        'has_ands_registered': True,
        }
        #context_dict = \
        #{'username': username,
        #'publish_forms': publishService.get_template_paths(),
        #'experiment': experiment,
        #'legaltext': legaltext,
        #}

        context_dict = dict(context_dict, \
        **publishService.get_contexts(request))
    logger.debug("context_dict=%s" % context_dict   )
    c = Context(context_dict)
    # FIXME: make own versionso publish_experiment template
    return HttpResponse(render_response_index(request,
                        'tardis_portal/publish_experiment.html', c))
    def register(self, request):
        """
        Use the EIF038 web services to gather and store party/activity
        ids for the linkages required by ANDS Research Data Australia.

        :param request: a HTTP Request instance
        :type request: :class:`django.http.HttpRequest`

        """
        username = request.user.username
        pais = PartyActivityInformationService()
        pai = pais.get_pai()

        monash_id_list = []

        experiment = Experiment.objects.get(id=self.experiment_id)

        self.clear_existing_parameters(request)

        if not('ldap_existing_party' in request.POST or\
            'ldap_party' in request.POST):
            return {'status': False,
            'message': 'Error: Must have at least' +
            ' one Monash party nominated'}

        if 'ldap_existing_party' in request.POST:
            for email in request.POST.getlist('ldap_existing_party'):
                relation_name = 'exists-' + email + '-relation'
                if relation_name in request.POST:
                    monash_id_list.append(\
                        {'party_param': email,
                        'relation_param': request.POST[relation_name]})

                # write new party info for existing party
                if settings.OAI_DOCS_PATH:
                    party_rif_cs = pai.get_party_rifcs(email)

                    XMLWriter.write_xml_to_file(
                        'rif',
                        'party',
                        email,
                        party_rif_cs
                        )

        message = ""
        if 'ldap_party' in request.POST:
            fail = False

            for email in request.POST.getlist('ldap_party'):
                if str(email):

                    monash_id = ""
                    try:

                        l = LDAPUserQuery()

                        authcate = []
                        authcate.append([LDAPUserQuery.get_user_attr(u, 'uid')\
                            for u in \
                            l.get_authcate_exact(email)])

                        monash_id = pai.get_unique_party_id(authcate[0][0])
                        relation_name = 'new-' + email + '-relation'
                        if relation_name in request.POST:
                            monash_id_list.append(\
                                {'party_param': monash_id,
                                'relation_param': request.POST[relation_name]})

                    except urllib2.URLError:
                        fail = True
                        logger.error("Can't contact research" +
                            " master web service")

                        message = message + \
                        'Error: Cannot contact Activity' + \
                        ' / Party Service. Please try again later.' \
                        + "<br/>"
                    except IndexError:
                        logger.error("Can't contact ldap for " +
                            email)
                        fail = True
                        error = "Can't get authcate for email address: " + email\
                        + "<br/>"

                        message = message + "<br/>" + error
                    except KeyError:
                        logger.error("Couldn't find authcate for " +
                            email)
                        fail = True
                        error = "Can't get authcate for email address: " + email\
                        + "<br/>"

                        message = message + "<br/>" + error

            if fail:
                return {'status': False,
                'message': message}

        for monash_id in monash_id_list:

            self.save_party_parameter(experiment,
                monash_id['party_param'], monash_id['relation_param'])

            if settings.OAI_DOCS_PATH:
                party_rif_cs = pai.get_party_rifcs(monash_id['party_param'])

                XMLWriter.write_xml_to_file(
                    'rif',
                    'party',
                    monash_id['party_param'],
                    party_rif_cs
                    )

        for activity_id in request.POST.getlist('activity'):

            if activity_id in self.get_existing_activity_keys():
                pass
            else:
                self.save_activity_parameter(experiment, activity_id)

                if settings.OAI_DOCS_PATH:
                    activity_rif_cs = pai.get_activity_rifcs(activity_id)

                    XMLWriter.write_xml_to_file(
                        'rif',
                        'activity',
                        activity_id,
                        activity_rif_cs
                        )

        cch = CreativeCommonsHandler(experiment_id=experiment.id, create=False)

        license_name = ""
        if cch.has_cc_license():
            psm = cch.get_or_create_cc_parameterset()

            license_name = ""
            try:
                license_name = psm.get_param('license_name', True)
            except ExperimentParameter.DoesNotExist:
                pass

        c = Context(dict({
                    'now': datetime.datetime.now(),
                    'experiment': experiment,
                    'party_keys': monash_id_list,
                    'activity_keys': request.POST.getlist('activity'),
                    'site_domain': Site.objects.get_current().domain,
                    'license_name': license_name,
                    }))

        custom_description = None
        if 'custom_description' in request.POST:
            custom_description = request.POST['custom_description']

            if custom_description:
                schema = 'http://localhost/pilot/collection/1.0/'

                psm = \
                    self.get_or_create_parameterset(schema)

                psm.set_param("custom_description", custom_description,
                    "Custom Description For ANDS Research Data Australia")

        c['custom_description'] = custom_description

        selected_profile = self.get_profile()
        if not selected_profile:
            selected_profile = "default.xml"

        profile_template = "monash_ands/profiles/" + selected_profile

        import sys
        mas_settings = sys.modules['%s.%s.settings' %
                    (settings.TARDIS_APP_ROOT, 'monash_ands')]

        if mas_settings.HANDLE_ENABLE:
            if not experiment.handle:
                try:
                    from HandleService import HandleService

                    hdlsrv = HandleService()

                    response = hdlsrv.mint(
                        mas_settings.AUTHTYPE, mas_settings.IDENTIFIER,
                        mas_settings.AUTHDOMAIN, mas_settings.APPID,
                        mas_settings.MINTURL, \
                            Site.objects.get_current().domain +\
                            "/experiment/view/" + str(experiment.id))
                    from xml.dom import minidom
                    xmldoc = minidom.parseString(response)

                    handle = xmldoc.firstChild.childNodes[1].attributes["handle"].value

                    if handle:
                        experiment.handle = handle
                        experiment.save()

                except KeyError:
                    logger.error(response)
                    logger.error("Persistent handle minting failed")

        if settings.OAI_DOCS_PATH:
            XMLWriter.write_template_to_file(
                'rif',
                'collection',
                experiment.id,
                profile_template,
                c,
                )

        if request.POST['profile']:

            profile = request.POST['profile']
            self.save_rif_cs_profile(experiment, profile)

        else:
            return {'status': True,
            'message': 'No profiles exist to choose from'}

        schema = "http://localhost/pilot/registration_record/1.0/"

        psm = ParameterSetManager(schema=schema,
                parentObject=experiment)

        now = datetime.datetime.now().strftime("%d %B %Y %Y %I:%M%p")
        psm.set_param("registration_date", now,
            "Registration Date")
        psm.set_param("registered_by", request.user.username,
            "Registered By")

        return {'status': True, 'message': 'Successfully registered experiment.'}
Beispiel #7
0
def publish_experiment(request, experiment_id):
    """
    Make the experiment open to public access.
    Sets off a chain of PublishProvider modules for
    extra publish functionality.

    :param request: a HTTP Request instance
    :type request: :class:`django.http.HttpRequest`
    :param experiment_id: the ID of the experiment to be published
    :type experiment_id: string

    """
    import os

    logger.debug("started publish for hpctardis")
    experiment = Experiment.objects.get(id=experiment_id)
    #username = str(request.user).partition('_')[2]
    username = request.user.username

    logger.debug("request=%s" % request)
    logger.debug("exp=%s" % experiment_id)
    logger.debug("requestmethod=%s" % request.method)
    publishService = RMITANDSService(experiment.id)
    logger.debug("made service")

    if publishService.is_under_review():
        logger.debug("under review")
        context_dict = {}
        context_dict['legal'] = True
        context_dict['status'] = False
        context_dict['success'] = False
        context_dict['publish_result'] = [{
            'status':
            True,
            'message':
            'Experiment is under review'
        }]

        c = Context(context_dict)
        return HttpResponse(
            render_response_index(request,
                                  'tardis_portal/publish_experiment.html', c))

    if experiment.public:
        context_dict = {}
        logger.debug("Already published")
        context_dict['legal'] = True
        context_dict['success'] = False
        context_dict['publish_result'] = [{
            'status':
            True,
            'message':
            'Experiment is already published'
        }]
        c = Context(context_dict)
        return HttpResponse(
            render_response_index(request,
                                  'tardis_portal/publish_experiment.html', c))

    if request.method == 'POST':  # If the form has been submitted...
        logger.debug("posted")
        legal = True
        success = True
        context_dict = {}
        #fix this slightly dodgy logic
        context_dict['publish_result'] = "submitted"
        if 'legal' in request.POST:
            # only make public when all providers signal okay
            # experiment.public = True
            # experiment.save()
            logger.debug("legal set")
            context_dict['publish_result'] = \
            publishService.execute_publishers(request)

            for result in context_dict['publish_result']:
                if not result['status']:
                    success = False

        else:
            logger.debug('Legal agreement for exp: ' + experiment_id +
                         ' not accepted.')
            legal = False

        # set dictionary to legal status and publish success result
        context_dict['legal'] = legal
        context_dict['success'] = success
    else:
        logger.debug("unposted")

        TARDIS_ROOT = os.path.abspath(\
        os.path.join(os.path.dirname(__file__)))

        legalpath = os.path.join(TARDIS_ROOT, "publish/legal.txt")

        # if legal file isn't found then we can't proceed
        try:
            legalfile = open(legalpath, 'r')
        except IOError:
            logger.error('legal.txt not found. Publication halted.')
            return return_response_error(request)

        legaltext = legalfile.read()
        legalfile.close()
        logger.debug("templatepaths=%s" % publishService.get_template_paths())

        from tardis.tardis_portal.creativecommonshandler import CreativeCommonsHandler

        cch = CreativeCommonsHandler(experiment_id=experiment_id, create=False)

        context_dict = \
        {'username': username,
        'experiment': experiment,
        'legaltext': legaltext,
        'publish_forms': publishService.get_template_paths(),
        'has_cc_license': cch.has_cc_license(),
        'has_ands_registered': True,
        }
        #context_dict = \
        #{'username': username,
        #'publish_forms': publishService.get_template_paths(),
        #'experiment': experiment,
        #'legaltext': legaltext,
        #}

        context_dict = dict(context_dict, \
        **publishService.get_contexts(request))
    logger.debug("context_dict=%s" % context_dict)
    c = Context(context_dict)
    # FIXME: make own versionso publish_experiment template
    return HttpResponse(
        render_response_index(request, 'tardis_portal/publish_experiment.html',
                              c))
    def register(self, request):
        """
        Use the EIF038 web services to gather and store party/activity
        ids for the linkages required by ANDS Research Data Australia.

        :param request: a HTTP Request instance
        :type request: :class:`django.http.HttpRequest`

        """
        username = request.user.username
        pais = PartyActivityInformationService()
        pai = pais.get_pai()

        monash_id_list = []

        experiment = Experiment.objects.get(id=self.experiment_id)

        self.clear_existing_parameters(request)

        if not('ldap_existing_party' in request.POST or\
            'ldap_party' in request.POST):
            return {'status': False,
            'message': 'Error: Must have at least' +
            ' one Monash party nominated'}

        if 'ldap_existing_party' in request.POST:
            for email in request.POST.getlist('ldap_existing_party'):
                relation_name = 'exists-' + email + '-relation'
                if relation_name in request.POST:
                    monash_id_list.append(\
                        {'party_param': email,
                        'relation_param': request.POST[relation_name]})

                # write new party info for existing party
                if settings.OAI_DOCS_PATH:
                    party_rif_cs = pai.get_party_rifcs(email)

                    XMLWriter.write_xml_to_file(
                        '',
                        'party',
                        email.replace('MON:',''),
                        party_rif_cs
                        )

        message = ""
        if 'ldap_party' in request.POST:
            fail = False

            for email in request.POST.getlist('ldap_party'):
                if str(email):

                    import sys
                    mas_settings = sys.modules['%s.%s.settings' %
                                (settings.TARDIS_APP_ROOT, 'monash_ands')]

                    if mas_settings.ALLOWED_PROTOCOL == "ldap":
                        monash_id = ""
                        try:

                            l = LDAPUserQuery()

                            authcate = []
                            authcate.append([LDAPUserQuery.get_user_attr(u, 'uid')\
                                for u in \
                                l.get_authcate_exact(email)])

                            monash_id = pai.get_unique_party_id(authcate[0][0])
                            relation_name = 'new-' + email + '-relation'
                            if relation_name in request.POST:
                                monash_id_list.append(\
                                    {'party_param': monash_id,
                                    'relation_param': request.POST[relation_name]})

                        except urllib2.URLError:
                            fail = True
                            logger.error("Can't contact research" +
                                " master web service")

                            message = message + \
                            'Error: Cannot contact Activity' + \
                            ' / Party Service. Please try again later.' \
                            + "<br/>"
                        except IndexError:
                            logger.error("Can't contact ldap for " +
                                email)
                            fail = True
                            error = "Can't get authcate for email address: " + email\
                            + "<br/>"

                            message = message + "<br/>" + error
                        except KeyError:
                            logger.error("Couldn't find authcate for " +
                                email)
                            fail = True
                            error = "Can't get authcate for email address: " + email\
                            + "<br/>"

                            message = message + "<br/>" + error
                    else:
                        # if not hooked up to ldap
                        relation_name = 'new-' + email + '-relation'
                        if relation_name in request.POST:
                            monash_id_list.append(\
                                {'party_param': email,
                                'relation_param': request.POST[relation_name]})

            if fail:
                return {'status': False,
                'message': message}

        for monash_id in monash_id_list:

            self.save_party_parameter(experiment,
                monash_id['party_param'], monash_id['relation_param'])

            if settings.OAI_DOCS_PATH:
                party_rif_cs = pai.get_party_rifcs(monash_id['party_param'])

                XMLWriter.write_xml_to_file(
                    '',
                    'party',
                    monash_id['party_param'].replace('MON:',''),
                    party_rif_cs
                    )

        for activity_id in request.POST.getlist('activity'):

            if activity_id in self.get_existing_activity_keys():
                pass
            else:
                self.save_activity_parameter(experiment, activity_id)

                if settings.OAI_DOCS_PATH:
                    activity_rif_cs = pai.get_activity_rifcs(activity_id)

                    XMLWriter.write_xml_to_file(
                        '',
                        'activity',
                        activity_id.replace('MON:',''),
                        activity_rif_cs
                        )

        cch = CreativeCommonsHandler(experiment_id=experiment.id, create=False)

        license_name = ""
        if cch.has_cc_license():
            psm = cch.get_or_create_cc_parameterset()

            license_name = ""
            try:
                license_name = psm.get_param('license_name', True)
            except ExperimentParameter.DoesNotExist:
                pass

        c = Context(dict({
                    'now': datetime.datetime.now(),
                    'experiment': experiment,
                    'party_keys': monash_id_list,
                    'activity_keys': request.POST.getlist('activity'),
                    'site_domain': Site.objects.get_current().domain,
                    'license_name': license_name,
                    }))

        custom_description = None
        if 'custom_description' in request.POST:
            custom_description = request.POST['custom_description']

            if custom_description and len(custom_description):
                schema = 'http://localhost/pilot/collection/1.0/'

                psm = \
                    self.get_or_create_parameterset(schema)

                psm.set_param("custom_description", custom_description,
                    "Custom Description For ANDS Research Data Australia")

        c['custom_description'] = custom_description

        selected_profile = self.get_profile()
        if not selected_profile:
            selected_profile = "default.xml"

        profile_template = "monash_ands/profiles/" + selected_profile

        import sys
        mas_settings = sys.modules['%s.%s.settings' %
                    (settings.TARDIS_APP_ROOT, 'monash_ands')]

        if mas_settings.DOI_ENABLE:
            if 'mint_doi' in request.POST:
                doisrv = DOIService(experiment)
                try:
                    site_url = Site.objects.get_current().domain
                    exp_url = experiment.get_absolute_url()
                    print site_url + exp_url
                    doi = doisrv.mint(site_url + exp_url)
                    self.save_doi(doi)
                except urllib2.HTTPError, e:
                    logger.error("doi minting failed")
                    logger.debug(e.read())