From 26b9d8edd21a39d0b02089c5b51a828ac999c36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Mon, 5 Dec 2022 10:43:00 +0100 Subject: [PATCH] Build facilities for EdAdmin to handle plagiarism --- scipost_django/edadmin/forms/plagiarism.py | 40 ++++- .../edadmin/_hx_plagiarism_assessment.html | 51 ++++++ .../edadmin/_hx_plagiarism_iThenticate.html | 123 ++++++++------- .../_hx_plagiarism_iThenticate_assess.html | 9 ++ .../edadmin/_hx_plagiarism_internal.html | 145 ++++++++++-------- .../_hx_plagiarism_internal_assess.html | 9 ++ .../edadmin/_hx_submission_incoming.html | 25 ++- .../edadmin/_hx_submissions_list.html | 6 +- .../edadmin/templates/edadmin/edadmin.html | 28 ++-- .../plagiarism_assessment_status_span.html | 1 + scipost_django/edadmin/urls/incoming.py | 10 ++ scipost_django/edadmin/views/incoming.py | 82 +++++++++- scipost_django/ontology/views.py | 1 - .../migrations/0128_auto_20221205_0500.py | 28 ++++ .../models/plagiarism_assessment.py | 6 +- .../submissions/submission_detail.html | 2 +- 16 files changed, 392 insertions(+), 174 deletions(-) create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_plagiarism_assessment.html create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate_assess.html create mode 100644 scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal_assess.html create mode 100644 scipost_django/edadmin/templates/edadmin/plagiarism_assessment_status_span.html create mode 100644 scipost_django/submissions/migrations/0128_auto_20221205_0500.py diff --git a/scipost_django/edadmin/forms/plagiarism.py b/scipost_django/edadmin/forms/plagiarism.py index bd23e2045..69f1c7d30 100644 --- a/scipost_django/edadmin/forms/plagiarism.py +++ b/scipost_django/edadmin/forms/plagiarism.py @@ -3,32 +3,60 @@ __license__ = "AGPL v3" from django import forms +from django.utils import timezone + +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Layout, Div, Field, ButtonHolder, Submit from submissions.models import ( + PlagiarismAssessment, InternalPlagiarismAssessment, iThenticatePlagiarismAssessment, ) -class InternalPlagiarismAssessmentForm(forms.ModelForm): +class PlagiarismAssessmentForm(forms.ModelForm): + class Meta: + model = PlagiarismAssessment + fields = [ + "status", + "comments_for_edadmin", + "comments_for_authors", + ] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = FormHelper() + self.helper.layout = Layout( + Field("status"), + Field("comments_for_edadmin"), + Field("comments_for_authors"), + ButtonHolder(Submit("submit", "Submit", css_class="btn btn-primary")), + ) + + def save(self): + assessment = super().save(commit=False) + if self.cleaned_data["status"] == self.instance.STATUS_PASSED: + assessment.date_set = timezone.now() + assessment.save() + return assessment + + +class InternalPlagiarismAssessmentForm(PlagiarismAssessmentForm): class Meta: model = InternalPlagiarismAssessment fields = [ - "submission", "status", - "passed_on", "comments_for_edadmin", "comments_for_authors", ] -class iThenticatePlagiarismAssessmentForm(forms.ModelForm): +class iThenticatePlagiarismAssessmentForm(PlagiarismAssessmentForm): class Meta: model = iThenticatePlagiarismAssessment fields = [ - "submission", "status", - "passed_on", "comments_for_edadmin", "comments_for_authors", ] diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_assessment.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_assessment.html new file mode 100644 index 000000000..dac3572c5 --- /dev/null +++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_assessment.html @@ -0,0 +1,51 @@ +{% load automarkup %} + +<h3> + Assessment + {% if assessment %} + <span class="ms-4"> + {% include "edadmin/plagiarism_assessment_status_span.html" with assessment=assessment %} + {% if assessment.date_set %} +  <span>set on {{ assessment.date_set }}</span>  + {% endif %} + </span> + {% endif %} + <button class="m-2 btn btn-primary" + hx-get="{% if method == 'internal' %}{% url 'edadmin:_hx_plagiarism_internal_assess' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}{% elif method == 'iThenticate' %}{% url 'edadmin:_hx_plagiarism_iThenticate_assess' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}{% endif %}" + hx-target="#submission-{{ submission.pk }}-plagiarism-{{ method }}-assessment" + hx-trigger="click" + hx-indicator="#indicator-{{ submission.pk }}-plagiarism-{{ method }}-assess" + > + {% if assessment %} + Edit assessment + {% else %} + Start assessment + {% endif %} + </button> +</h3> + +{% if assessment %} + <div class="row"> + {% if assessment.comments_for_edadmin %} + <div class="col col-lg-6"> + <h4>Comments for EdAdmin</h4> + {% automarkup assessment.comments_for_edadmin %} + </div> + {% endif %} + {% if assessment.comments_for_authors %} + <div class="col col-lg-6"> + <h4>Comments for Authors</h4> + {% automarkup assessment.comments_for_authors %} + </div> + {% endif %} + </div> +{% endif %} + +<div class="htmx-indicator" + id="indicator-{{ submission.pk }}-plagiarism-{{ method }}-assess" +> + <button class="btn btn-sm btn-warning" type="button" disabled> + <strong>Loading...</strong> + <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div> + </button> +</div> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html index 1ed0f83bf..d64e15803 100644 --- a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html +++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate.html @@ -1,70 +1,79 @@ {% load bootstrap %} -<div class="row"> - <div class="col"> - <h3>iThenticate report</h3> - {% if submission.iThenticate_plagiarism_report %} - <table> - <tr> - <td>Latest update</td> - <td>{{ submission.iThenticate_plagiarism_report.latest_activity }}</td> - </tr> - <tr> - <td style="min-width: 150px;">iThenticate document</td> - <td>{{ submission.iThenticate_plagiarism_report.doc_id }}</td> - </tr> - <tr> - <td>Uploaded</td> - <td>{{ submission.iThenticate_plagiarism_report.uploaded_time }}</td> - </tr> - {% if submission.iThenticate_plagiarism_report.processed %} +<details class="border border-2"> + <summary class="bg-primary bg-opacity-10 p-2"> + <h2> + iThenticate checks + {% if submission.iThenticate_plagiarism_assessment %} +  {% include "edadmin/plagiarism_assessment_status_span.html" with assessment=submission.iThenticate_plagiarism_assessment %} + {% endif %} + </h2> + </summary> + <div class="row m-2"> + <div class="col col-lg-4"> + <h3>iThenticate report</h3> + {% if submission.iThenticate_plagiarism_report %} + <table> <tr> - <td>Processed</td> - <td>{{ submission.iThenticate_plagiarism_report.processed_time }}</td> + <td>Latest update</td> + <td>{{ submission.iThenticate_plagiarism_report.latest_activity }}</td> </tr> <tr> - <td>Percent match</td> - <td>{{ submission.iThenticate_plagiarism_report.percent_match }}%</td> + <td style="min-width: 150px;">iThenticate document</td> + <td>{{ submission.iThenticate_plagiarism_report.doc_id }}</td> </tr> <tr> - <td><a href="{% url 'submissions:iThenticate_plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="btn btn-success text-white" target="_blank">Download report pdf</a></td> + <td>Uploaded</td> + <td>{{ submission.iThenticate_plagiarism_report.uploaded_time }}</td> </tr> - {% else %} - <tr> - <td>Report not yet received</td> - </tr> - {% endif %} - </table> - {% else %} - <p>No report yet</p> - {% endif %} - {% if not submission.iThenticate_plagiarism_report.processed %} - <form - class="mt-3" enctype="multipart/form-data" - hx-post="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" - hx-target="#submission-{{ submission.pk }}-iThenticate" - hx-indicator="#indicator-{{ submission.pk }}-iThenticate" + {% if submission.iThenticate_plagiarism_report.processed %} + <tr> + <td>Processed</td> + <td>{{ submission.iThenticate_plagiarism_report.processed_time }}</td> + </tr> + <tr> + <td>Percent match</td> + <td>{{ submission.iThenticate_plagiarism_report.percent_match }}%</td> + </tr> + <tr> + <td><a href="{% url 'submissions:iThenticate_plagiarism_report' submission.preprint.identifier_w_vn_nr %}" class="btn btn-success text-white" target="_blank">Download report pdf</a></td> + </tr> + {% else %} + <tr> + <td>Report not yet received</td> + </tr> + {% endif %} + </table> + {% else %} + <p>No report yet</p> + {% endif %} + </div> + <div class="col col-lg-4"> + {% if not submission.iThenticate_plagiarism_report.processed %} + <form + class="mt-3" enctype="multipart/form-data" + hx-post="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" + hx-target="#submission-{{ submission.pk }}-plagiarism-iThenticate" + hx-indicator="#indicator-{{ submission.pk }}-plagiarism-iThenticate" > - {% csrf_token %} - {{ form|bootstrap }} - <input type="submit" class="btn btn-primary" value="{% if submission.iThenticate_plagiarism_report %}Update report status{% else %}Submit document for plagiarism check{% endif %}"> - </form> - <div id="indicator-{{ submission.pk }}-iThenticate" class="htmx-indicator"> - <button class="btn btn-sm btn-warning" type="button" disabled> - <strong>Loading...</strong> - <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div> - </button> - </div> - {% endif %} + {% csrf_token %} + {{ form|bootstrap }} + <input type="submit" class="btn btn-primary" value="{% if submission.iThenticate_plagiarism_report %}Update report status{% else %}Submit document for plagiarism check{% endif %}"> + </form> + <div id="indicator-{{ submission.pk }}-plagiarism-iThenticate" class="htmx-indicator"> + <button class="btn btn-sm btn-warning" type="button" disabled> + <strong>Loading...</strong> + <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div> + </button> + </div> + {% endif %} + </div> </div> - <div class="col"> - <h3>Assessment</h3> - {% if submission.iThenticate_plagiarism_assessment %} - {{ submission.iThenticate_plagiarism_assessment }} - {% else %} - TODO: assessment form - {% endif %} + <div id="submission-{{ submission.pk }}-plagiarism-iThenticate-assessment" + class="m-2 p-2 border border-2 border-warning" + > + {% include "edadmin/_hx_plagiarism_assessment.html" with submission=submission assessment=submission.iThenticate_plagiarism_assessment method="iThenticate" %} </div> -</div> +</details> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate_assess.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate_assess.html new file mode 100644 index 000000000..da9c2b7a6 --- /dev/null +++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_iThenticate_assess.html @@ -0,0 +1,9 @@ +{% load crispy_forms_tags %} +<h3>Update assessment of iThenticate plagiarism</h3> +<form + class="mt-3" + hx-post="{% url 'edadmin:_hx_plagiarism_iThenticate_assess' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" + hx-target="#submission-{{ submission.pk }}-plagiarism-iThenticate-assessment" +> + {% crispy form %} +</form> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html index 498f23c42..65f30b06c 100644 --- a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html +++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal.html @@ -1,72 +1,89 @@ -<details open> - <summary class="m-2 p-2"> - Submission matches - {% if not "submission_matches" in submission.internal_plagiarism_matches %} - <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span> - {% endif %} +<details class="border border-2"> + <summary class="bg-primary bg-opacity-10 p-2"> + <h2> + Internal plagiarism checks + {% if submission.internal_plagiarism_assessment %} +  {% include "edadmin/plagiarism_assessment_status_span.html" with assessment=submission.internal_plagiarism_assessment %} + {% endif %} + </h2> </summary> - <table class="table"> - <thead> - <tr> - <th>Submission</th> - <th>Title match %</th> - <th>Authors match %</th> - <th>Abstract match %</th> - </tr> - </thead> - <tbody> - {% for match in submission_matches %} + <details open> + <summary class="m-2 p-2"> + Submission matches + {% if not "submission_matches" in submission.internal_plagiarism_matches %} + <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span> + {% endif %} + </summary> + <table class="table m-2"> + <thead> <tr> - <td> - {{ match.submission.preprint.identifier_w_vn_nr }} -  <small class="text-muted">Thread hash: {{ match.submission.thread_hash }}</small> - <br> - <a href="{{ match.submission.get_absolute_url }}" target="_blank">{{ match.submission.title }}</a><br> - {{ match.submission.author_list }} - </td> - <td>{{ match.ratio_title|floatformat:2 }}</td> - <td>{{ match.ratio_authors|floatformat:2 }}</td> - <td>{{ match.ratio_abstract|floatformat:2 }}</td> + <th>Submission</th> + <th>Title match %</th> + <th>Authors match %</th> + <th>Abstract match %</th> </tr> - {% empty %} - <tr><td>No matching Submissions</td></tr> - {% endfor %} - </tbody> - </table> -</details> + </thead> + <tbody> + {% for match in submission_matches %} + <tr> + <td> + {{ match.submission.preprint.identifier_w_vn_nr }} +  <small class="text-muted">Thread hash: {{ match.submission.thread_hash }}</small> + <br> + <a href="{{ match.submission.get_absolute_url }}" target="_blank">{{ match.submission.title }}</a><br> + {{ match.submission.author_list }} + </td> + <td>{{ match.ratio_title|floatformat:2 }}</td> + <td>{{ match.ratio_authors|floatformat:2 }}</td> + <td>{{ match.ratio_abstract|floatformat:2 }}</td> + </tr> + {% empty %} + <tr><td>No matching Submissions</td></tr> + {% endfor %} + </tbody> + </table> + </details> -<details open> - <summary class="m-2 p-2"> - Publication matches - {% if not "publication_matches" in submission.internal_plagiarism_matches %} - <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span> - {% endif %} - </summary> - <table class="table"> - <thead> - <tr> - <th>Publication</th> - <th>Title match %</th> - <th>Authors match %</th> - <th>Abstract match %</th> - </tr> - </thead> - <tbody> - {% for match in publication_matches %} + <details open> + <summary class="m-2 p-2"> + Publication matches + {% if not "publication_matches" in submission.internal_plagiarism_matches %} + <span class="text-danger border border-danger m-2 p-2">This automated internal plagiarism check has not finished running yet; please come back later!</span> + {% endif %} + </summary> + <table class="table m-2"> + <thead> <tr> - <td> - {{ match.publication.doi_label }}<br> - <a href="{{ match.publication.get_absolute_url }}" target="_blank">{{ match.publication.title }}</a><br> - {{ match.publication.author_list }} - </td> - <td>{{ match.ratio_title|floatformat:2 }}</td> - <td>{{ match.ratio_authors|floatformat:2 }}</td> - <td>{{ match.ratio_abstract|floatformat:2 }}</td> + <th>Publication</th> + <th>Title match %</th> + <th>Authors match %</th> + <th>Abstract match %</th> </tr> - {% empty %} - <tr><td>No matching Publications</td></tr> - {% endfor %} - </tbody> - </table> + </thead> + <tbody> + {% for match in publication_matches %} + <tr> + <td> + {{ match.publication.doi_label }}<br> + <a href="{{ match.publication.get_absolute_url }}" target="_blank">{{ match.publication.title }}</a><br> + {{ match.publication.author_list }} + </td> + <td>{{ match.ratio_title|floatformat:2 }}</td> + <td>{{ match.ratio_authors|floatformat:2 }}</td> + <td>{{ match.ratio_abstract|floatformat:2 }}</td> + </tr> + {% empty %} + <tr><td>No matching Publications</td></tr> + {% endfor %} + </tbody> + </table> + </details> + + <div id="submission-{{ submission.pk }}-plagiarism-internal-assessment" + class="m-2 p-2 border border-2 border-warning" + > + {% include "edadmin/_hx_plagiarism_assessment.html" with submission=submission assessment=submission.internal_plagiarism_assessment method="internal" %} + </div> + </details> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal_assess.html b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal_assess.html new file mode 100644 index 000000000..3eab60f15 --- /dev/null +++ b/scipost_django/edadmin/templates/edadmin/_hx_plagiarism_internal_assess.html @@ -0,0 +1,9 @@ +{% load crispy_forms_tags %} +<h3>Update assessment of internal plagiarism</h3> +<form + class="mt-3" + hx-post="{% url 'edadmin:_hx_plagiarism_internal_assess' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" + hx-target="#submission-{{ submission.pk }}-plagiarism-internal-assessment" +> + {% crispy form %} +</form> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_submission_incoming.html b/scipost_django/edadmin/templates/edadmin/_hx_submission_incoming.html index 4f3ef8e7d..7d8475628 100644 --- a/scipost_django/edadmin/templates/edadmin/_hx_submission_incoming.html +++ b/scipost_django/edadmin/templates/edadmin/_hx_submission_incoming.html @@ -1,20 +1,17 @@ <h1>Plagiarism</h1> <div class="p-2"> - <h2>Internal plagiarism checks</h2> - <button class="m-2 btn btn-primary" - id="submission-{{ submission.preprint.identifier_w_vn_nr }}" - hx-get="{% url 'edadmin:_hx_plagiarism_internal' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" - hx-swap="outerHTML" - hx-trigger="revealed" - >load internal plagiarism info</button> + <div id="submission-{{ submission.pk }}-plagiarism-internal" + class="m-2" + hx-get="{% url 'edadmin:_hx_plagiarism_internal' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" + hx-trigger="revealed, {{ submission.pk }}-plagiarism-internal-updated" + > + </div> </div> <div class="p-2"> - <h2>iThenticate checks {% if submission.iThenticate_plagiarism_assessment %}{% if submission.iThenticate_plagiarism_assessment.passed %}[passed]{% elif submission.iThenticate_plagiarism_assessment.ongoing %}[ongoing]{% elif submission.iThenticate_plagiarism_assessment.failed %}[failed]{% else %}[STATUS ERROR] {{ submission.iThenticate_plagiarism_assessment.get_status_display }}{% endif %}{% else %}[not assessed yet]{% endif %}</h2> - <div id="submission-{{ submission.pk }}-iThenticate"> - <button class="m-2 btn btn-primary" - hx-get="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" - hx-swap="outerHTML" - hx-trigger="revealed" - >load iThenticate plagiarism info</button> + <div id="submission-{{ submission.pk }}-plagiarism-iThenticate" + class="m-2" + hx-get="{% url 'edadmin:_hx_plagiarism_iThenticate' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" + hx-trigger="revealed, {{ submission.pk }}-plagiarism-iThenticate-updated" + > </div> </div> diff --git a/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html b/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html index 757f87afa..6524664d3 100644 --- a/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html +++ b/scipost_django/edadmin/templates/edadmin/_hx_submissions_list.html @@ -1,7 +1,7 @@ {% for submission in submissions %} <details class="border border-2 my-2"> - <summary class="px-4 py-2"> + <summary class="px-4 py-2 bg-primary bg-opacity-10"> <table> <tbody> <tr> @@ -16,7 +16,7 @@ </tbody> </table> </summary> - <div class="p-2"> + <div class="p-4"> <h1>Summary</h1> {% include 'submissions/_submission_summary.html' with submission=submission hide_title=1 show_abstract=1 %} @@ -26,7 +26,7 @@ <h1>Workflow diagram</h1> <button class="m-2 btn btn-primary workflowDiagram" - id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram" + id="submission-{{ submission.pk }}-workflow-diagram" hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" hx-swap="outerHTML" >Load Submission processing workflow graphs</button> diff --git a/scipost_django/edadmin/templates/edadmin/edadmin.html b/scipost_django/edadmin/templates/edadmin/edadmin.html index 36d1eb8bf..ef28f63b6 100644 --- a/scipost_django/edadmin/templates/edadmin/edadmin.html +++ b/scipost_django/edadmin/templates/edadmin/edadmin.html @@ -21,30 +21,20 @@ <summary class="bg-info px-4 py-2"> <h1>Incoming</h1> </summary> - <div class="p-2"> + <span class="p-2"> <button class="m-2 btn btn-primary" id="incoming" hx-get="{% url 'edadmin:_hx_incoming_list' %}" hx-swap="outerHTML" + hx-indicator="#indicator-submissions-incoming" >Load incoming Submissions</button> - </div> - </details> - - <details> - <summary>Preassignment</summary> - {% for submission in preassignment %} - - {% include 'submissions/_submission_events.html' with events=submission.events.for_edadmin %} - - <details> - <summary>{{ submission }}</summary> - <button class="m-2 btn btn-primary workflowDiagram" - id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram" - hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" - hx-swap="outerHTML" - >Load Submission processing workflow graphs</button> - </details> - {% endfor %} + </span> + <span id="indicator-submissions-incoming" class="htmx-indicator"> + <button class="btn btn-sm btn-warning" type="button" disabled> + <strong>Loading...</strong> + <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div> + </button> + </span> </details> {% endblock content %} diff --git a/scipost_django/edadmin/templates/edadmin/plagiarism_assessment_status_span.html b/scipost_django/edadmin/templates/edadmin/plagiarism_assessment_status_span.html new file mode 100644 index 000000000..0acf012c5 --- /dev/null +++ b/scipost_django/edadmin/templates/edadmin/plagiarism_assessment_status_span.html @@ -0,0 +1 @@ +<span class="px-2 py-1 bg-{% if assessment.ongoing %}warning{% elif assessment.passed %}success{% else %}danger{% endif %} text-white">{{ assessment.get_status_display }}</span> diff --git a/scipost_django/edadmin/urls/incoming.py b/scipost_django/edadmin/urls/incoming.py index d7815dc60..b3cae05f4 100644 --- a/scipost_django/edadmin/urls/incoming.py +++ b/scipost_django/edadmin/urls/incoming.py @@ -21,11 +21,21 @@ urlpatterns = [ incoming._hx_plagiarism_internal, name="_hx_plagiarism_internal", ), + path( + "_hx_plagiarism_internal_assess", + incoming._hx_plagiarism_internal_assess, + name="_hx_plagiarism_internal_assess", + ), path( "_hx_plagiarism_iThenticate", incoming._hx_plagiarism_iThenticate, name="_hx_plagiarism_iThenticate", ), + path( + "_hx_plagiarism_iThenticate_assess", + incoming._hx_plagiarism_iThenticate_assess, + name="_hx_plagiarism_iThenticate_assess", + ), ]) ), ] diff --git a/scipost_django/edadmin/views/incoming.py b/scipost_django/edadmin/views/incoming.py index b9dd0f279..a7038c5bb 100644 --- a/scipost_django/edadmin/views/incoming.py +++ b/scipost_django/edadmin/views/incoming.py @@ -3,14 +3,25 @@ __license__ = "AGPL v3" from django.contrib.auth.decorators import login_required, user_passes_test -from django.shortcuts import get_object_or_404, render +from django.http import HttpResponse +from django.shortcuts import get_object_or_404, redirect, render +from django.urls import reverse from guardian.shortcuts import get_objects_for_user from colleges.permissions import is_edadmin -from submissions.models import Submission +from submissions.models import ( + Submission, + InternalPlagiarismAssessment, + iThenticatePlagiarismAssessment, +) from submissions.forms import iThenticateReportForm +from edadmin.forms.plagiarism import ( + InternalPlagiarismAssessmentForm, + iThenticatePlagiarismAssessmentForm, +) + @login_required @user_passes_test(is_edadmin) @@ -26,13 +37,21 @@ def _hx_incoming_list(request): return render(request, "edadmin/_hx_submissions_list.html", context) +######################## +# Plagiarism: internal # +######################## + @login_required @user_passes_test(is_edadmin) def _hx_plagiarism_internal(request, identifier_w_vn_nr): submission = get_object_or_404( Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr ) - context = {"submission_matches": [], "publication_matches": []} + context = { + "submission": submission, + "submission_matches": [], + "publication_matches": [], + } if "submission_matches" in submission.internal_plagiarism_matches: for sub_match in submission.internal_plagiarism_matches["submission_matches"]: context["submission_matches"].append( @@ -64,10 +83,32 @@ def _hx_plagiarism_internal_assess(request, identifier_w_vn_nr): submission = get_object_or_404( Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr ) - form = InternalPlagiarismAssessmentForm(request.POST or None) - if form.is_valid(): - form.save() + # if Submission has no assessment yet, create one: + try: + submission.internal_plagiarism_assessment + except InternalPlagiarismAssessment.DoesNotExist: + assessment = InternalPlagiarismAssessment(submission=submission) + assessment.save() + submission.refresh_from_db() + form = InternalPlagiarismAssessmentForm( + request.POST or None, + instance=submission.internal_plagiarism_assessment, + ) + if form.is_valid(): # just trigger re-rendering of iThenticate div + assessment = form.save() + response = HttpResponse() + response["HX-Trigger"] = f"{submission.pk}-plagiarism-internal-updated" + return response + context = { + "submission": submission, + "form": form, + } + return render(request, "edadmin/_hx_plagiarism_internal_assess.html", context) + +########################### +# Plagiarism: iThenticate # +########################### @login_required @user_passes_test(is_edadmin) @@ -84,3 +125,32 @@ def _hx_plagiarism_iThenticate(request, identifier_w_vn_nr): "form": form, } return render(request, "edadmin/_hx_plagiarism_iThenticate.html", context) + + +@login_required +@user_passes_test(is_edadmin) +def _hx_plagiarism_iThenticate_assess(request, identifier_w_vn_nr): + submission = get_object_or_404( + Submission, preprint__identifier_w_vn_nr=identifier_w_vn_nr + ) + # if Submission has no assessment yet, create one: + try: + submission.iThenticate_plagiarism_assessment + except iThenticatePlagiarismAssessment.DoesNotExist: + assessment = iThenticatePlagiarismAssessment(submission=submission) + assessment.save() + submission.refresh_from_db() + form = iThenticatePlagiarismAssessmentForm( + request.POST or None, + instance=submission.iThenticate_plagiarism_assessment, + ) + if form.is_valid(): # just trigger re-rendering of iThenticate div + assessment = form.save() + response = HttpResponse() + response["HX-Trigger"] = f"{submission.pk}-plagiarism-iThenticate-updated" + return response + context = { + "submission": submission, + "form": form, + } + return render(request, "edadmin/_hx_plagiarism_iThenticate_assess.html", context) diff --git a/scipost_django/ontology/views.py b/scipost_django/ontology/views.py index 9dc67cc56..8dcc3dd71 100644 --- a/scipost_django/ontology/views.py +++ b/scipost_django/ontology/views.py @@ -3,7 +3,6 @@ __license__ = "AGPL v3" from django.contrib import messages -from django.http import HttpResponse from django.urls import reverse, reverse_lazy from django.db.models import Q from django.shortcuts import get_object_or_404, redirect, render diff --git a/scipost_django/submissions/migrations/0128_auto_20221205_0500.py b/scipost_django/submissions/migrations/0128_auto_20221205_0500.py new file mode 100644 index 000000000..9de4772ce --- /dev/null +++ b/scipost_django/submissions/migrations/0128_auto_20221205_0500.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.16 on 2022-12-05 04:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0127_auto_20221204_1439'), + ] + + operations = [ + migrations.RenameField( + model_name='plagiarismassessment', + old_name='passed_on', + new_name='date_set', + ), + migrations.AlterField( + model_name='plagiarismassessment', + name='comments_for_authors', + field=models.TextField(blank=True), + ), + migrations.AlterField( + model_name='plagiarismassessment', + name='comments_for_edadmin', + field=models.TextField(blank=True), + ), + ] diff --git a/scipost_django/submissions/models/plagiarism_assessment.py b/scipost_django/submissions/models/plagiarism_assessment.py index c4b3b89cb..8766e6545 100644 --- a/scipost_django/submissions/models/plagiarism_assessment.py +++ b/scipost_django/submissions/models/plagiarism_assessment.py @@ -21,9 +21,9 @@ class PlagiarismAssessment(models.Model): choices=STATUS_CHOICES, default=STATUS_ONGOING, ) - passed_on = models.DateTimeField(blank=True, null=True) - comments_for_edadmin = models.TextField() - comments_for_authors = models.TextField() + date_set = models.DateTimeField(blank=True, null=True) + comments_for_edadmin = models.TextField(blank=True) + comments_for_authors = models.TextField(blank=True) @property def ongoing(self): diff --git a/scipost_django/submissions/templates/submissions/submission_detail.html b/scipost_django/submissions/templates/submissions/submission_detail.html index 64abe82fb..1d0476e66 100644 --- a/scipost_django/submissions/templates/submissions/submission_detail.html +++ b/scipost_django/submissions/templates/submissions/submission_detail.html @@ -163,7 +163,7 @@ {% if is_ed_admin %} <button class="m-2 btn btn-primary workflowDiagram" - id="submission-{{ submission.preprint.identifier_w_vn_nr }}-workflow-diagram" + id="submission-{{ submission.pk }}-workflow-diagram" hx-get="{% url 'submissions:_hx_submission_workflow_diagram' identifier_w_vn_nr=submission.preprint.identifier_w_vn_nr %}" hx-swap="outerHTML" >Load Submission processing workflow graphs</button> -- GitLab