Source code for arxiv.submission.services.classic.patch

"""Methods for updating :class:`.Submission` with state outside event scope."""

from typing import List, Dict, Any
from ... import domain
from . import models


[docs]def patch_hold(submission: domain.Submission, row: models.Submission) -> domain.Submission: """Patch hold-related data from this database row.""" if not row.is_new_version(): raise ValueError('Only applies to new and replacement rows') if row.status == row.ON_HOLD: created = row.get_updated() creator = domain.agent.System(__name__) event_id = domain.Event.get_id(created, 'AddHold', creator) hold = domain.Hold(event_id=event_id, creator=creator, created=created, hold_type=domain.Hold.Type.PATCH) submission.holds[event_id] = hold return submission
[docs]def patch_jref(submission: domain.Submission, row: models.Submission) -> domain.Submission: """ Patch a :class:`.domain.submission.Submission` with JREF data outside the event scope. Parameters ---------- submission : :class:`.domain.submission.Submission` The submission object to patch. Returns ------- :class:`.domain.submission.Submission` The same submission that was passed; now patched with JREF data outside the scope of the event model. """ submission.metadata.doi = row.doi submission.metadata.journal_ref = row.journal_ref submission.metadata.report_num = row.report_num return submission
# This should update the reason_for_withdrawal (if applied), # and add a WithdrawalRequest to user_requests.
[docs]def patch_withdrawal(submission: domain.Submission, row: models.Submission, request_number: int = -1) -> domain.Submission: req_type = domain.WithdrawalRequest data = {'reason_for_withdrawal': row.get_withdrawal_reason()} return _patch_request(req_type, data, submission, row, request_number)
[docs]def patch_cross(submission: domain.Submission, row: models.Submission, request_number: int = -1) -> domain.Submission: req_type = domain.CrossListClassificationRequest clsns = [domain.Classification(dbc.category) for dbc in row.categories if not dbc.is_primary and dbc.category not in submission.secondary_categories] data = {'classifications': clsns} return _patch_request(req_type, data, submission, row, request_number)
def _patch_request(req_type: type, data: Dict[str, Any], submission: domain.Submission, row: models.Submission, request_number: int = -1) -> domain.Submission: status = req_type.WORKING if row.is_announced(): status = req_type.APPLIED elif row.is_deleted(): status = req_type.CANCELLED elif row.is_rejected(): status = req_type.REJECTED elif not row.is_working(): status = req_type.PENDING # Includes hold state. data.update({'status': status}) request_id = req_type.generate_request_id(submission, request_number) if request_number < 0: creator = domain.User(native_id=row.submitter_id, email=row.submitter_email) user_request = req_type(creator=creator, created=row.get_created(), updated=row.get_updated(), request_id=request_id, **data) else: user_request = submission.user_requests[request_id] if any([setattr_changed(user_request, field, value) for field, value in data.items()]): user_request.updated = row.get_updated() submission.user_requests[request_id] = user_request if status == req_type.APPLIED: submission = user_request.apply(submission) return submission
[docs]def setattr_changed(obj: Any, field: str, value: Any) -> bool: """ Set an attribute on an object only if the value does not match provided. Parameters ---------- obj : object field : str The name of the attribute on ``obj`` to set. value : object Returns ------- bool True if the attribute was set; otherwise False. """ if getattr(obj, field) != value: setattr(obj, field, value) return True return False