__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" import datetime import random from string import ascii_lowercase import factory import pytz from common.faker import LazyAwareDate, LazyRandEnum, fake from common.helpers import ( random_external_doi, random_external_journal_abbrev, ) from faker import Faker from funders.factories import FunderFactory, GrantFactory from journals.constants import ( CC_LICENSES, ISSUES_AND_VOLUMES, ISSUES_ONLY, JOURNAL_STRUCTURE, PUBLICATION_PUBLISHED, ) from journals.models import journal from journals.models.autogenerated_file import AutogeneratedFileContentTemplate from journals.models.deposits import DOAJDeposit, Deposit, GenericDOIDeposit from journals.models.resource import PublicationResource from journals.models.submission_template import SubmissionTemplate from journals.models.update import PublicationUpdate from ontology.factories import SpecialtyFactory from .models import Issue, Journal, Publication, Reference, Volume class ReferenceFactory(factory.django.DjangoModelFactory): publication = factory.SubFactory("journals.factories.JournalPublicationFactory") reference_number = factory.LazyAttribute( lambda o: o.publication.references.count() + 1 ) identifier = factory.lazy_attribute(lambda n: random_external_doi()) link = factory.Faker("uri") class Meta: model = Reference @factory.lazy_attribute def citation(self): faker = Faker() return "<em>{}</em> {} <b>{}</b>, {} ({})".format( faker.sentence(), random_external_journal_abbrev(), random.randint(1, 100), random.randint(1, 100), faker.year(), ) class JournalFactory(factory.django.DjangoModelFactory): college = factory.SubFactory("colleges.factories.CollegeFactory") name = factory.LazyAttributeSequence( lambda self, n: f"SciPost {self.college.name} {n}" ) name_abbrev = factory.LazyAttribute( lambda self: "SciPost" + "".join([w[:2] for w in self.name.split()[1:]]) ) doi_label = factory.SelfAttribute("name_abbrev") issn = factory.Faker("numerify", text="########") structure = LazyRandEnum(JOURNAL_STRUCTURE) list_order = factory.LazyAttribute(lambda self: self.college.journals.count() + 1) active = True submission_allowed = True oneliner = factory.Faker("sentence") description = factory.Faker("paragraph") scope = factory.Faker("paragraph") acceptance_criteria = factory.Faker("paragraph") submission_insert = factory.Faker("paragraph") template_latex_tgz = factory.django.FileField() template_docx = factory.django.FileField() cost_info = {"default": 500} class Meta: model = Journal django_get_or_create = ("name", "doi_label") @classmethod def SciPostPhysics(cls): return cls( name="SciPost Physics", doi_label="SciPostPhys", structure=ISSUES_AND_VOLUMES, ) @classmethod def SciPostPhysicsProc(cls): return cls( name="SciPost Physics Proceedings", doi_label="SciPostPhysProc", structure=ISSUES_ONLY, ) @factory.post_generation def specialties(self, create, extracted, **kwargs): if not create: return if extracted: self.specialties.add(*extracted) else: specialties = SpecialtyFactory.create_batch( 3, acad_field=self.college.acad_field ) self.specialties.add(*specialties) class VolumeFactory(factory.django.DjangoModelFactory): in_journal = factory.SubFactory(JournalFactory) number = factory.LazyAttribute(lambda self: self.in_journal.volumes.count() + 1) doi_label = factory.LazyAttribute( lambda self: f"{self.in_journal.doi_label}.{self.number}" ) start_date = LazyAwareDate("date_time_this_decade") until_date = factory.LazyAttribute( lambda self: fake.aware.date_between(start_date=self.start_date, end_date="+1y") ) class Meta: model = Volume django_get_or_create = ("in_journal", "number") class IssueFactory(factory.django.DjangoModelFactory): class Meta: model = Issue abstract = True class Params: parent = None number = factory.LazyAttribute(lambda self: self.parent.issues.count() + 1) doi_label = factory.LazyAttribute( lambda self: "%s.%i" % (self.parent.doi_label, self.number) ) slug = factory.LazyAttribute( lambda self: "issue-" + self.doi_label.replace(".", "-") ) class VolumeIssueFactory(IssueFactory): class Params: parent = factory.SubFactory(VolumeFactory) in_volume = factory.SelfAttribute("parent") start_date = factory.LazyAttribute( lambda self: Faker().date_time_between( start_date=self.parent.start_date, end_date=self.parent.until_date, tzinfo=pytz.UTC, ) ) until_date = factory.LazyAttribute( lambda self: fake.aware.date_between(start_date=self.start_date, end_date="+1y") ) path = factory.LazyAttribute( lambda self: f"JOURNALS/{self.in_volume.in_journal.doi_label}/{self.in_volume.number}/{self.number}" ) class JournalIssueFactory(IssueFactory): class Params: parent = factory.SubFactory(JournalFactory, structure=ISSUES_ONLY) in_journal = factory.SelfAttribute("parent") path = factory.LazyAttribute( lambda self: f"JOURNALS/{self.in_journal.doi_label}/{self.number}" ) class BasePublicationFactory(factory.django.DjangoModelFactory): class Meta: model = Publication abstract = True django_get_or_create = ("accepted_submission",) exclude = ("pub_container",) @factory.lazy_attribute def pub_container(self): issue = getattr(self, "in_issue", None) journal = getattr(self, "in_journal", None) return issue or journal # Publication data # TODO: This should be a PublishedSubmissionFactory accepted_submission = factory.SubFactory( "submissions.factories.SubmissionFactory" # , generate_publication=False ) status = PUBLICATION_PUBLISHED @factory.lazy_attribute def paper_nr(self): if self.pub_container: return self.pub_container.publications.count() + 1 # Core fields title = factory.SelfAttribute("accepted_submission.title") author_list = factory.SelfAttribute("accepted_submission.author_list") abstract = factory.SelfAttribute("accepted_submission.abstract") pdf_file = factory.django.FileField() # Ontology-based semantic linking acad_field = factory.SelfAttribute("accepted_submission.acad_field") approaches = factory.SelfAttribute("accepted_submission.approaches") @factory.post_generation def specialties(self, create, extracted, **kwargs): if not create: return self.specialties.add(*self.accepted_submission.specialties.all()) @factory.post_generation def topics(self, create, extracted, **kwargs): if not create: return self.topics.add(*self.accepted_submission.topics.all()) cc_license = LazyRandEnum(CC_LICENSES) # Funders @factory.post_generation def grants(self, create, extracted, **kwargs): if not create: return if extracted: self.grants.add(*extracted) grants = GrantFactory.create_batch(3) self.grants.add(*grants) @factory.post_generation def funders_generic(self, create, extracted, **kwargs): if not create: return if extracted: self.funders_generic.add(*extracted) funders_generic = FunderFactory.create_batch(3) self.funders_generic.add(*funders_generic) # Metadata metadata = {} metadata_xml = "" metadata_DOAJ = {} citedby = {} number_of_citations = 0 @factory.lazy_attribute def doi_label(self): if self.pub_container: return self.pub_container.doi_label + "." + str(self.paper_nr).rjust(3, "0") # Date fields submission_date = factory.SelfAttribute("accepted_submission.submission_date") acceptance_date = factory.SelfAttribute("accepted_submission.latest_activity") publication_date = factory.SelfAttribute("accepted_submission.latest_activity") latest_activity = factory.SelfAttribute("accepted_submission.latest_activity") latest_citedby_update = factory.SelfAttribute("accepted_submission.latest_activity") latest_metadata_update = factory.SelfAttribute( "accepted_submission.latest_activity" ) # @factory.post_generation # def generate_publication(self, create, extracted, **kwargs): # if create and extracted is not False: # return # from journals.factories import PublicationFactory # factory.RelatedFactory( # PublicationFactory, # "accepted_submission", # title=self.title, # author_list=self.author_list, # ) # @factory.post_generation # def author_relations(self, create, extracted, **kwargs): # if not create: # return # # Append references # for i in range(5): # ReferenceFactory(publication=self) # Copy author data from Submission # for author in self.accepted_submission.authors.all(): # self.authors.create(publication=self, profile=author) # self.authors_claims.add(*self.accepted_submission.authors_claims.all()) # self.authors_false_claims.add(*self.accepted_submission.authors_false_claims.all()) class JournalPublicationFactory(BasePublicationFactory): in_journal = factory.SubFactory(JournalFactory) class VolumeIssuePublicationFactory(BasePublicationFactory): in_issue = factory.SubFactory(VolumeIssueFactory) in_journal = factory.SelfAttribute("in_issue.in_volume.in_journal") class JournalIssuePublicationFactory(BasePublicationFactory): in_issue = factory.SubFactory(JournalIssueFactory) in_journal = factory.SelfAttribute("in_issue.in_journal") class AutogeneratedFileContentTemplateFactory(factory.django.DjangoModelFactory): class Meta: model = AutogeneratedFileContentTemplate journal = factory.SubFactory(JournalFactory) name = factory.Faker("word") description = factory.Faker("sentence", nb_words=3) content_template_string = factory.Faker("word") class DepositFactory(factory.django.DjangoModelFactory): class Meta: model = Deposit publication = factory.SubFactory(JournalPublicationFactory) deposition_date = factory.SelfAttribute("publication.publication_date") timestamp = factory.LazyAttribute( lambda self: self.deposition_date.strftime("%Y%m%d%H%M%S") ) deposit_successful = True response_text = "" doi_batch_id = factory.Faker("word") metadata_xml = "" metadata_xml_file = factory.django.FileField() response_text = "" class DOAJDepositFactory(factory.django.DjangoModelFactory): class Meta: model = DOAJDeposit publication = factory.SubFactory(JournalPublicationFactory) deposition_date = factory.SelfAttribute("publication.publication_date") timestamp = factory.LazyAttribute( lambda self: self.deposition_date.strftime("%Y%m%d%H%M%S") ) deposit_successful = True metadata_DOAJ = {} metadata_DOAJ_file = factory.django.FileField() response_text = "" class GenericDOIDepositFactory(factory.django.DjangoModelFactory): class Meta: model = GenericDOIDeposit abstract = True deposition_date = LazyAwareDate("date_this_year") timestamp = factory.LazyAttribute( lambda self: self.deposition_date.strftime("%Y%m%d%H%M%S") ) deposit_successful = True doi_batch_id = factory.Faker("word") metadata_xml = "" response = "" class PublicationResourceFactory(factory.django.DjangoModelFactory): class Meta: model = PublicationResource _type = LazyRandEnum(PublicationResource.TYPE_CHOICES) publication = factory.SubFactory(JournalPublicationFactory) url = factory.Faker("uri") comments = factory.Faker("sentence") deprecated = False class SubmissionTemplateFactory(factory.django.DjangoModelFactory): class Meta: model = SubmissionTemplate template_type = LazyRandEnum(SubmissionTemplate.TYPE_CHOICES) template_file = factory.django.FileField() journal = factory.SubFactory(JournalFactory) date = LazyAwareDate("date_this_year") instructions = factory.Faker("paragraph") class PublicationUpdateFactory(factory.django.DjangoModelFactory): class Meta: model = PublicationUpdate publication = factory.SubFactory(JournalPublicationFactory) number = factory.LazyAttribute(lambda self: self.publication.updates.count() + 1) update_type = LazyRandEnum(PublicationUpdate.TYPE_CHOICES) text = factory.Faker("paragraph") publication_date = factory.LazyAttribute( lambda self: fake.aware.date_between( start_date=self.publication.publication_date, end_date="+1y" ) ) doideposit_needs_updating = False doi_label = factory.LazyAttribute( lambda self: f"{self.publication.doi_label}.Upd.{self.number}" )