diff --git a/requirements.txt b/requirements.txt index 1998b0de2cad7bd0cd959c426b09031a3e01b503..a10c22acc9e89a1bfb87895cc995b240488479f8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,7 +43,7 @@ Whoosh==2.7.4 # Directly related to Haystack. # Python Utils -ithenticate-api-python==0.4.2 +ithenticate-api-python==0.6 mailchimp3==2.0.15 python-dateutil==2.6.0 # Doesn't Django have this functionality built-in? -- JdW Pillow==3.4.2 # Latest version is v4.2.1; need to know about usage before upgrade. -- JdW diff --git a/submissions/exceptions.py b/submissions/exceptions.py index 474d3b343b4eff03158cc7456bd2c57dbcab2d8d..d52fa4fa099696c1eaaf8c59d104e3607018ad1a 100644 --- a/submissions/exceptions.py +++ b/submissions/exceptions.py @@ -16,3 +16,7 @@ class InvalidReportVettingValue(BaseCustomException): class ArxivPDFNotFound(Exception): pass + + +class InvalidDocumentError(Exception): + pass diff --git a/submissions/forms.py b/submissions/forms.py index 33d4ebb5d3c04b06344932f6cf85f5f44e94b7a6..a76a6ccb5796fc61c63b6867d5577e5ce8e0f669 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -722,35 +722,14 @@ class iThenticateReportForm(forms.ModelForm): return None def upload_document(self): - client = self.client - - # Get first folder available - # TODO: Fix this ugly piece of crap - if settings.ITHENTICATE_DEFAULT_FOLDER_ID: - folder_id = settings.ITHENTICATE_DEFAULT_FOLDER_ID - else: - folders = client.folders.all() - if folders['status'] == 200: - folder_id = folders['data'][0]['id'] - else: - self.add_error(None, "Uploading failed. iThenticate didn't return valid data [2]") - self.add_error(None, client.messages[0]) - - # Finally, upload the file - author = self.submission.authors.first() - response = client.documents.add( - self.document, - folder_id, - author.user.first_name, - author.user.last_name, - self.submission.title, - ) - - if response['status'] == 200: - self.submission.add_general_event(('The document has been submitted ' - 'for a plagiarism check.')) - return response - - self.add_error(None, "Updating failed. iThenticate didn't return valid data [3]") - self.add_error(None, client.messages[0]) - return None + from .plagiarism import iThenticate + plagiarism = iThenticate() + response = plagiarism.upload_submission(self.document, self.submission) + + # Give feedback to the user + if not response: + self.add_error(None, "Updating failed. iThenticate didn't return valid data [3]") + for msg in plagiarism.get_messages(): + self.add_error(None, msg) + return None + return response diff --git a/submissions/plagiarism.py b/submissions/plagiarism.py new file mode 100644 index 0000000000000000000000000000000000000000..28d4454579d7baddb3c92d349392bbfbd7782390 --- /dev/null +++ b/submissions/plagiarism.py @@ -0,0 +1,95 @@ +from django.conf import settings + +from .exceptions import InvalidDocumentError + +import iThenticate as iThenticateAPI + + +class iThenticate: + def __init__(self): + self.client = self.get_client() + + def get_client(self): + client = iThenticateAPI.API.Client(settings.ITHENTICATE_USERNAME, + settings.ITHENTICATE_PASSWORD) + if client.login(): + return client + self.add_error(None, "Failed to login to iThenticate.") + return None + + def determine_folder_group(self, group_re): + groups = self.client.groups.all() + if groups['status'] != 200: + raise InvalidDocumentError("Uploading failed. iThenticate didn't return" + " valid data [4]: %s" % self.client.messages[0]) + + for group in groups['data']: + # Found the group + if group['name'] == group_re: + return group['id'] + + # Create a new group + response = self.client.groups.add(group_re) + + if response['status'] != 200: + raise InvalidDocumentError("Failed creating a new Folder Group [5].") + + return response['data'][0]['id'] + + def determine_folder_id(self, submission): + """ + Return the folder id to which the system should upload a new document to. + + Generates a new folder and id if needed. + """ + group_re = '{journal}_submissions'.format(journal=submission.submitted_to_journal) + folder_re = '{year}_{month}'.format( + year=submission.submission_date.year, + month=submission.submission_date.month + ) + all_folders = self.client.folders.all() + if all_folders['status'] != 200: + raise InvalidDocumentError("Uploading failed. iThenticate didn't return" + " valid data [2]: %s" % self.client.messages[0]) + + # Iterate folders as the api doesn't allow for a search + for folder in all_folders['data']: + # Found right folder! + if folder['name'] == folder_re and folder['group']['name']: + return folder['id'] + + group_id = self.determine_folder_group(group_re) + + # Create new folder + data = self.client.folders.add(group_id, folder_re) + if data['status'] != 200: + raise InvalidDocumentError("Failed to create a new folder [3].") + + return data['data'][0]['id'] + + def upload_submission(self, document, submission): + """ + Upload a document related to a submission + + :document: The document to upload + :submission: submission which should be uploaded + """ + folder_id = self.determine_folder_id(submission) + + # Finally, upload the file + author = submission.authors.first() + response = self.client.documents.add( + document, + folder_id, + author.user.first_name, + author.user.last_name, + submission.title, + ) + + if response['status'] == 200: + submission.add_general_event('The document has been submitted for a plagiarism check.') + return response + return None + + def get_messages(self): + return self.client.messages