Newer
Older
publications = Publication.objects.order_by('-publication_date')
context = {
'publications': publications
}
return render(request, 'journals/harvest_citedby_list.html', context)
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
@transaction.atomic
def harvest_citedby_links(request, doi_label):
publication = get_object_or_404(Publication, doi_label=doi_label)
update_citedby(doi_label)
return render(request, 'journals/harvest_citedby_links.html', {'publication': publication})
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
@login_required
def sign_existing_report(request, report_id):
"""
Allows the author of a Report, originally submitted anonymously,
to sign the Report.
"""
report = get_object_or_404(Report, pk=report_id)
if report.author != request.user.contributor:
errormessage = 'Only the author of this Report can change its anonymity status'
return render(request, 'scipost/error.html', context={'errormessage': errormessage})
form = ConfirmationForm(request.POST or None)
if form.is_valid():
if form.cleaned_data['confirm'] == 'True':
report.anonymous = False
report.doideposit_needs_updating = True
report.save()
messages.success(request, 'Your Report is now publicly signed.')
else:
messages.error(request, 'Report signing operation cancelled.')
return redirect(reverse('scipost:personal_page'))
context = {'report': report, 'form': form}
return render(request, 'journals/sign_existing_report.html', context)
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def manage_report_metadata(request):
"""
This page offers Editorial Administrators tools for managing
the metadata of Reports.
"""
reports = Report.objects.all()
ready_for_deposit = request.GET.get('ready_for_deposit') == '1'
if ready_for_deposit:
report_ids = [r.id for r in reports.exclude(
needs_doi=False).filter(doi_label='') if r.associated_published_doi is not None]
reports = reports.filter(id__in=report_ids, doi_label='')
needing_update = request.GET.get('needing_update') == '1'
if needing_update:
reports = reports.filter(
Q(needs_doi=None) | Q(needs_doi=True, doideposit_needs_updating=True)).filter(
submission__status=STATUS_PUBLISHED)
page = request.GET.get('page')
try:
reports = paginator.page(page)
except PageNotAnInteger:
reports = paginator.page(1)
except EmptyPage:
reports = paginator.page(paginator.num_pages)
context = {
'reports': reports,
'page_obj': reports,
'paginator': paginator,
}
return render(request, 'journals/manage_report_metadata.html', context)
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def manage_comment_metadata(request):
"""
This page offers Editorial Administrators tools for managing
the metadata of Comments.
"""
comments = Comment.objects.all()
paginator = Paginator(comments, 25)
page = request.GET.get('page')
try:
comments = paginator.page(page)
except PageNotAnInteger:
comments = paginator.page(1)
except EmptyPage:
comments = paginator.page(paginator.num_pages)
context = {
'comments': comments,
'page_obj': comments,
'paginator': paginator,
}
return render(request, 'journals/manage_comment_metadata.html', context)
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def manage_update_metadata(request):
"""
This page offers Editorial Administrators tools for managing
the metadata of PublicationUpdates.
"""
updates = PublicationUpdate.objects.all()
paginator = Paginator(updates, 25)
page = request.GET.get('page')
try:
updates = paginator.page(page)
except PageNotAnInteger:
updates = paginator.page(1)
except EmptyPage:
updates = paginator.page(paginator.num_pages)
context = {
'updates': updates,
'page_obj': updates,
'paginator': paginator,
}
return render(request, 'journals/manage_update_metadata.html', context)
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def mark_report_doi_needed(request, report_id, needed):
report = get_object_or_404(Report, pk=report_id)
if needed == '1':
report.needs_doi = True
elif needed == '0':
report.needs_doi = False
report.save()
return redirect(reverse('journals:manage_report_metadata'))
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def mark_comment_doi_needed(request, comment_id, needed):
comment = get_object_or_404(Comment, pk=comment_id)
if needed == '1':
comment.needs_doi = True
elif needed == '0':
comment.needs_doi = False
comment.save()
return redirect(reverse('journals:manage_comment_metadata'))
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
@transaction.atomic
def generic_metadata_xml_deposit(request, **kwargs):
"""
Handle generic non-Publication metadata deposits at Crossref.
Types of objects handled:
* Reports
* Comments
* PublicationUpdates
The metadata is created and immediately deposited at Crossref.
For Reports and Comments, if there exists a relation to a
SciPost-published object, the deposit uses Crossref's peer review content type.
Otherwise the deposit is done as a dataset.
For PublicationUpdates, the deposit type is `journal_article` and
the journal is used as container.
"""
type_of_object = kwargs['type_of_object']
object_id = int(kwargs['object_id'])
if type_of_object == 'report':
_object = get_object_or_404(Report, id=object_id)
elif type_of_object == 'comment':
_object = get_object_or_404(Comment, id=object_id)
elif type_of_object == 'update':
_object = get_object_or_404(PublicationUpdate, id=object_id)
_object.create_doi_label()
timestamp = timezone.now().strftime('%Y%m%d%H%M%S')
# create a doi_batch_id
salt = ""
for i in range(5):
salt = salt + random.choice(string.ascii_letters)
salt = salt.encode('utf8')
idsalt = str(_object)[:10]
idsalt = idsalt.encode('utf8')
doi_batch_id = hashlib.sha1(salt+idsalt).hexdigest()
metadata_xml = _object.xml(doi_batch_id=doi_batch_id)
relation_to_published = _object.relation_to_published # Reports and Comments have this
metadata_xml = (
'<?xml version="1.0" encoding="UTF-8"?>\n'
'<doi_batch version="4.4.1" xmlns="http://www.crossref.org/schema/4.4.1" '
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
'xsi:schemaLocation="http://www.crossref.org/schema/4.4.1 '
'http://www.crossref.org/shema/deposit/crossref4.4.1.xsd">\n'
'<head>\n'
'<doi_batch_id>' + str(doi_batch_id) + '</doi_batch_id>\n'
'<timestamp>' + timestamp + '</timestamp>\n'
'<depositor>\n'
'<depositor_name>scipost</depositor_name>\n'
'<email_address>' + settings.CROSSREF_DEPOSIT_EMAIL + '</email_address>\n'
'</depositor>\n'
'<registrant>scipost</registrant>\n'
'</head>\n'
)
if relation_to_published: # Reports and Comments have this
metadata_xml += (
'<body>\n'
'<peer_review stage="' + relation_to_published['stage'] + '">\n'
'<contributors>'
)
if _object.anonymous:
metadata_xml += (
'<anonymous sequence="first" contributor_role="'
+ relation_to_published['contributor_role'] + '"/>'
)
else:
metadata_xml += (
'<person_name sequence="first" contributor_role="'
+ relation_to_published['contributor_role'] + '">'
'<given_name>' + _object.author.user.first_name + '</given_name>'
'<surname>' + _object.author.user.last_name + '</surname>'
'</person_name>\n'
)
if isinstance(_object, Publication):
url_to_declare = 'https://scipost.org{}'.format(_object.get_absolute_url())
else:
url_to_declare = 'https://scipost.org/{}'.format(_object.doi_label)
metadata_xml += (
'</contributors>\n'
'<titles><title>' + relation_to_published['title'] + '</title></titles>\n'
'<review_date>'
'<month>' + _object.date_submitted.strftime('%m') + '</month>'
'<day>' + _object.date_submitted.strftime('%d') + '</day>'
'<year>' + _object.date_submitted.strftime('%Y') + '</year>'
'</review_date>\n'
'<program xmlns="http://www.crossref.org/relations.xsd">\n'
'<related_item>'
'<description>' + relation_to_published['title'] + '</description>\n'
'<inter_work_relation relationship-type="isReviewOf" identifier-type="doi">'
+ relation_to_published['isReviewOfDOI'] + '</inter_work_relation></related_item>\n'
'</program>'
'<doi_data><doi>' + _object.doi_string + '</doi>\n'
'<resource>' + url_to_declare +
'</resource></doi_data>\n'
'</peer_review>\n'
'</body>\n'
'</doi_batch>\n'
else: # Reports and Comments on not-yet-published objects
metadata_xml += (
'<body>\n'
'<database>\n'
'<database_metadata language="en">\n'
'<titles><title>SciPost Reports and Comments</title></titles>\n'
'</database_metadata>\n'
'<dataset dataset_type="collection">\n'
'<doi_data><doi>' + _object.doi_string + '</doi>\n'
'<resource>https://scipost.org' + _object.get_absolute_url() +
'</resource></doi_data>\n'
'</dataset></database>\n'
'</body></doi_batch>'
)
# CAUTION: Debug is False, production goes for real deposit!!!
url = 'http://doi.crossref.org/servlet/deposit'
else:
url = 'http://test.crossref.org/servlet/deposit'
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
params = {
'operation': 'doMDUpload',
'login_id': settings.CROSSREF_LOGIN_ID,
'login_passwd': settings.CROSSREF_LOGIN_PASSWORD,
}
files = {'fname': ('metadata.xml', metadata_xml, 'multipart/form-data')}
r = requests.post(url, params=params, files=files)
deposit = GenericDOIDeposit(content_type=ContentType.objects.get_for_model(_object),
object_id=object_id,
content_object=_object,
timestamp=timestamp,
doi_batch_id=doi_batch_id,
metadata_xml=metadata_xml,
deposition_date=timezone.now(),
response=r.text)
deposit.save()
context = {
'response_headers': r.headers,
'response_text': r.text,
}
return render(request, 'journals/generic_metadata_xml_deposit.html', context)
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def mark_generic_deposit_success(request, deposit_id, success):
deposit = get_object_or_404(GenericDOIDeposit, pk=deposit_id)
if success == '1':
deposit.deposit_successful = True
deposit.content_object.doideposit_needs_updating = False
deposit.content_object.save()
elif success == '0':
deposit.deposit_successful = False
deposit.save()
if deposit.content_type.name == 'report':
return redirect(reverse('journals:manage_report_metadata'))
else:
return redirect(reverse('journals:manage_comment_metadata'))
@permission_required('scipost.can_publish_accepted_submission', return_403=True)
def email_object_made_citable(request, **kwargs):
"""
This method sends an email to the author of a Report or a Comment,
to notify that the object has been made citable (doi registered).
"""
type_of_object = kwargs['type_of_object']
object_id = int(kwargs['object_id'])
if type_of_object == 'report':
_object = get_object_or_404(Report, id=object_id)
accepted_submission__thread_hash=_object.submission.thread_hash)
publication_citation = publication.citation
publication_doi = publication.doi_string
except Publication.DoesNotExist:
pass
elif type_of_object == 'comment':
_object = get_object_or_404(Comment, id=object_id)
redirect_to = reverse('journals:manage_comment_metadata')
else:
raise Http404
if not _object.doi_label:
messages.warning(request, 'This object does not have a DOI yet.')
return redirect(redirect_to)
if type_of_object == 'report':
JournalUtils.load({'report': _object,
'publication_citation': publication_citation,
'publication_doi': publication_doi})
JournalUtils.email_report_made_citable()
else:
JournalUtils.load({'comment': _object, })
JournalUtils.email_comment_made_citable()
messages.success(request, 'Email sent')
return redirect(redirect_to)
###########
# Viewing #
###########
def report_detail(request, doi_label):
report = get_object_or_404(Report.objects.accepted(), doi_label=doi_label)
return redirect(report.get_absolute_url())
def comment_detail(request, doi_label):
comment = get_object_or_404(Comment.objects.vetted().regular_comments(), doi_label=doi_label)
return redirect(comment.get_absolute_url())
def author_reply_detail(request, doi_label):
comment = get_object_or_404(Comment.objects.vetted().author_replies(), doi_label=doi_label)
return redirect(comment.get_absolute_url())
def publication_detail(request, doi_label):
"""
The actual Publication detail page. This is visible for everyone if published or
visible for Production Supervisors and Administrators if in draft.
"""
publication = get_object_or_404(Publication, doi_label=doi_label)
if not publication.is_published and not request.user.has_perm('scipost.can_draft_publication'):
raise Http404('Publication is not publicly visible')
context = {
'publication': publication,
'affiliation_indices': publication.get_author_affiliation_indices_list(),
'affiliations_list': publication.get_all_affiliations(),
'select_topic_form': SelectTopicForm(),
return render(request, 'journals/publication_detail.html', context)
def publication_detail_pdf(request, doi_label):
"""
The actual Publication pdf. This is visible for everyone if published or
visible for Production Supervisors and Administrators if in draft.
"""
publication = get_object_or_404(Publication, doi_label=doi_label)
if not publication.is_published and not request.user.has_perm('scipost.can_draft_publication'):
raise Http404('Publication is not publicly visible')
response = HttpResponse(publication.pdf_file.read(), content_type='application/pdf')
response['Content-Disposition'] = ('filename='
+ publication.doi_label.replace('.', '_') + '.pdf')
def publication_update_detail(request, doi_label, update_nr):
"""
Detail page for a PublicationUpdate.
"""
update = get_object_or_404(PublicationUpdate,
publication__doi_label=doi_label, number=update_nr)
context = {
'update': update,
'journal': update.publication.get_journal(),
}
return render(request, 'journals/publication_update_detail.html', context)
######################
# Feed DOIs to arXiv #
######################
def arxiv_doi_feed(request, doi_label):
"""
This method provides arXiv with the doi and journal ref of the 100 most recent
publications in the journal specified by doi_label.
"""
journal = get_object_or_404(Journal, doi_label=doi_label)
feedxml = ('<preprint xmlns="http://arxiv.org/doi_feed" '
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
'identifier="SciPost.org ' + doi_label + ' arXiv.org DOI feed" '
'version="DOI SnappyFeed v1.0" '
'xsi:schemaLocation="http://arxiv.org/doi_feed '
'http://arxiv.org/schemas/doi_feed.xsd">')
now = timezone.now()
feedxml += '<date year="%s" month="%s" day="%s" />' % (now.strftime('%Y'),
now.strftime('%m'), now.strftime('%d'))
publications = journal.get_publications().order_by('-publication_date')[:100]
# Determine if any of the preprints in thread were on arXiv
for sub in publication.accepted_submission.thread:
if sub.preprint.is_arXiv:
feedxml += ('\n<article preprint_id="%s" doi="%s" journal_ref="%s" />' % (
sub.preprint.identifier_w_vn_nr.rpartition('v')[0],
publication.doi_string,
publication.citation))
break # only do once for each publication
feedxml += '\n</preprint>'
return HttpResponse(feedxml, content_type='text/xml')