Skip to content

Commit

Permalink
clean up ImportForm
Browse files Browse the repository at this point in the history
  • Loading branch information
jonavellecuerdo committed Nov 28, 2023
1 parent d38f8b8 commit 3235628
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 53 deletions.
63 changes: 63 additions & 0 deletions solenoid/records/forms.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,72 @@
import logging
from typing import Any


from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.http import HttpResponse

from requests.exceptions import HTTPError, Timeout

from solenoid.elements.elements import get_from_elements
from solenoid.elements.xml_handlers import parse_author_xml
from solenoid.people.models import DLC, Author
from .helpers import Fields


logger = logging.getLogger(__name__)


class ImportForm(forms.Form):
author_id = forms.CharField(label="Author ID", max_length=20)

def get_author_from_elements(self, author_id: forms.CharField) -> dict | None: # type: ignore[return]
author_url = f"{settings.ELEMENTS_ENDPOINT}users/{author_id}"
try:
author_xml = get_from_elements(author_url)
except HTTPError as e:
logger.info(e)
if "404 Client Error" in str(e):
msg = (
f"Author with ID {author_id} not found in Elements. "
"Please confirm the Elements ID and try again."
)
raise ValidationError(message=msg)
except Timeout as e:
logger.info(e)
msg = (
"Unable to connect to Symplectic "
"Elements. Please wait a few "
"minutes and try again."
)
raise ValidationError(message=msg)
else:
author_data = parse_author_xml(author_xml)
return author_data

def get_author_from_solenoid(self, author_data: dict | None) -> Author | None: # type: ignore[return]
if author_data:
try:
author = Author.get_by_mit_id(author_data[Fields.MIT_ID])
except Author.DoesNotExist:
if not Author.is_author_creatable(author_data):
logger.info(
f"Author #{author_data['ELEMENTS ID']} was missing data "
"from Elements"
)
msg = (
f"Author with ID {author_data['ELEMENTS ID']} is "
f"missing required information. Please check the "
f"author record in Elements and confirm that all of "
f"the following information is present: "
f"{', '.join(Fields.AUTHOR_DATA)}"
)
raise ValidationError(message=msg)
else:
return author

def clean(self) -> dict[str, Any]:
author_data = self.get_author_from_elements(self.data["author_id"])
author = self.get_author_from_solenoid(author_data)
return self.cleaned_data
3 changes: 0 additions & 3 deletions solenoid/records/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def task_import_papers_for_author( # type: ignore
)
total = len(pub_ids)
logger.info(f"Finished retrieving publication IDs to import for author.")

for i, paper in enumerate(pub_ids):
paper_id = paper["id"]
if not self.request.called_directly:
Expand Down Expand Up @@ -141,5 +140,3 @@ def _run_checks_on_paper(paper_data: dict, author: Author) -> str:
f'{", ".join(dupe_list)}. Please merge #{paper_id} into an '
f"existing record in Elements. It will not be imported."
)

return ""
63 changes: 13 additions & 50 deletions solenoid/records/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,66 +56,29 @@ class Import(ConditionalLoginRequiredMixin, FormView):
form_class = ImportForm
success_url = reverse_lazy("records:status")

def _get_author_data(self, form: ImportForm, author_id: int) -> dict | HttpResponse:
def _get_author_data(self, form: ImportForm, author_id: int) -> dict:
author_url = f"{settings.ELEMENTS_ENDPOINT}users/{author_id}"
try:
author_xml = get_from_elements(author_url)
except HTTPError as e:
logger.info(e)
if "404 Client Error" in str(e):
msg = (
f"Author with ID {author_id} not found in Elements. "
"Please confirm the Elements ID and try again."
)
messages.warning(self.request, msg)
return super(Import, self).form_invalid(form)
except Timeout as e:
logger.info(e)
msg = (
"Unable to connect to Symplectic "
"Elements. Please wait a few "
"minutes and try again."
)
messages.warning(self.request, msg)
return super(Import, self).form_invalid(form)
author_xml = get_from_elements(author_url)
author_data = parse_author_xml(author_xml)
author_data["ELEMENTS ID"] = author_id
return author_data

def _get_author_record_id(
self, form: ImportForm, author_data: dict | HttpResponse
) -> int | HttpResponse:
def _get_author_record_id(self, author_data: dict) -> int | HttpResponse:
try:
author = Author.get_by_mit_id(author_data[Fields.MIT_ID])
if not author.dspace_id:
author.dspace_id = author_data[Fields.MIT_ID]
author.save()
except Author.DoesNotExist:
if Author.is_author_creatable(author_data):
dlc, _ = DLC.objects.get_or_create(name=author_data[Fields.DLC])
author = Author.objects.create( # type: ignore
first_name=author_data[Fields.FIRST_NAME],
last_name=author_data[Fields.LAST_NAME],
dlc=dlc,
email=author_data[Fields.EMAIL],
mit_id=author_data[Fields.MIT_ID],
dspace_id=author_data[Fields.MIT_ID],
)
else:
logger.info(
f"Author #{author_data['ELEMENTS ID']} was missing data "
"from Elements"
)
msg = (
f"Author with ID {author_data['ELEMENTS ID']} is "
f"missing required information. Please check the "
f"author record in Elements and confirm that all of "
f"the following information is present: "
f"{', '.join(Fields.AUTHOR_DATA)}"
)
messages.warning(self.request, msg)
return super(Import, self).form_invalid(form)

dlc, _ = DLC.objects.get_or_create(name=author_data[Fields.DLC])
author = Author.objects.create( # type: ignore
first_name=author_data[Fields.FIRST_NAME],
last_name=author_data[Fields.LAST_NAME],
dlc=dlc,
email=author_data[Fields.EMAIL],
mit_id=author_data[Fields.MIT_ID],
dspace_id=author_data[Fields.MIT_ID],
)
return author.id

def form_valid( # type: ignore
Expand All @@ -124,7 +87,7 @@ def form_valid( # type: ignore
author_id = form.cleaned_data["author_id"]
author_url = f"{settings.ELEMENTS_ENDPOINT}users/{author_id}"
author_data = self._get_author_data(form, author_id)
author = self._get_author_record_id(form, author_data)
author = self._get_author_record_id(author_data)
result = task_import_papers_for_author.delay(author_url, author_data, author)
task_id = result.task_id
return redirect("records:status", task_id=task_id)
Expand Down

0 comments on commit 3235628

Please sign in to comment.