示例#1
0
    def test_fix_buggy_romeo_ids(self):
        """
        A long time ago, the SHERPA API returned "DOAJ" or "journal" as publisher id for
        some journals… so we need to update them appropriately.
        """
        publisher = Publisher(romeo_id='DOAJ',
                              preprint='can',
                              postprint='can',
                              pdfversion='can')
        publisher.save()
        journal = Journal(issn='0013-9696',
                          title='Greek Review of Social Research',
                          publisher=publisher)
        journal.save()

        # mocked separately as a different endpoint is used
        with requests_mock.mock() as http_mocker:
            http_mocker.get(
                'http://www.sherpa.ac.uk/downloads/journal-title-issns.php?format=tsv',
                content=self.journals_dump_response)

            with patch.object(Journal,
                              'change_publisher') as mock_change_publisher:
                self.api.fetch_all_journals()

                new_publisher = Journal.objects.get(issn='0013-9696').publisher

                mock_change_publisher.assert_not_called()

                self.assertEqual(new_publisher.pk, publisher.pk)
                self.assertEqual(new_publisher.romeo_id, '2201')
示例#2
0
    def test_publisher_change(self):
        """
        If the publisher associated with a journal changes, we need to change it too,
        but also update the associated papers!
        """
        journal = self.api.fetch_journal({'issn': '0013-9696'})
        original_publisher = journal.publisher

        new_publisher = Publisher(romeo_id='12345',
                                  preprint='cannot',
                                  postprint='cannot',
                                  pdfversion='cannot')
        new_publisher.save()
        journal.publisher = new_publisher
        journal.save()

        # Fetching the updates from romeo should revert to the original (true) publisher
        with requests_mock.mock() as http_mocker:
            http_mocker.get(
                'http://www.sherpa.ac.uk/downloads/journal-title-issns.php?format=tsv',
                content=self.journals_dump_response)

            with patch.object(Journal,
                              'change_publisher') as mock_change_publisher:
                self.api.fetch_all_journals()
                mock_change_publisher.assert_called_once_with(
                    original_publisher)
示例#3
0
    def test_delete(self):
        publisher, created = Publisher.from_dict({"name": "Publishing House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        deleted = publisher.delete()
        self.assertIsNone(publisher.id)
        self.assertEquals((1, {"publishers.Publisher": 1}), deleted)

        publisher, created = Publisher.from_dict({
            "name":
            "Publishing House",
            "links": [{
                "url": "https://publishing.house"
            }]
        })
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        deleted = publisher.delete()
        self.assertIsNone(publisher.id)
        self.assertEquals(
            (
                3,
                {
                    "publishers.Publisher": 1,
                    "publishers.Publisher_links": 1,
                    "links.Link": 1,
                },
            ),
            deleted,
        )
示例#4
0
    def test_fetch_journal_updates_publisher(self):
        # First we have an old version of a publisher record
        p = Publisher(name='Harvard University Press', romeo_id='3243',
                      preprint='can', postprint='can', pdfversion='can', last_updated=None)
        p.classify_oa_status()
        p.save()

        # Then we fetch one of its journals
        journal = self.api.fetch_journal({'issn':'0073-0688'})

        # That updates the publisher object
        publisher = Publisher.objects.get(id=journal.publisher.id)
        self.assertEqual(publisher.id, p.id)
        self.assertEqual(publisher.preprint, 'unclear')
        self.assertEqual(publisher.last_updated, dateutil.parser.parse('2018-05-10T10:48:27Z'))
示例#5
0
 def test_get_publisher_by_name(self, monkeypatch):
     """
     Must return publisher object
     """
     publisher = Publisher()
     monkeypatch.setattr(Publisher, 'find', lambda x: publisher)
     assert self.test_class._get_publisher('p_name', None) == publisher
示例#6
0
 def test_get_publisher_by_journal(self):
     """
     Must return Publisher object
     """
     publisher = Publisher()
     journal = Journal(publisher=publisher)
     assert self.test_class._get_publisher('p_name', journal) == publisher
示例#7
0
    def test_get(self):
        publisher, created = Publisher.from_dict({"name": "Publishing House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        publisher2 = Publisher.get("Publishing House")
        self.assertIsNotNone(publisher2)
        self.assertEquals(publisher, publisher2)

        publisher2 = Publisher.get("house")
        self.assertIsNotNone(publisher2)
        self.assertEquals(publisher, publisher2)

        publisher2 = Publisher.get(str(publisher.id))
        self.assertIsNotNone(publisher2)
        self.assertEquals(publisher, publisher2)
示例#8
0
    def test_search(self):
        publisher, created = Publisher.from_dict({"name": "Publishing House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        publisher, created = Publisher.from_dict({"name": "Old House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        publisher, created = Publisher.from_dict({"name": "Publishing Press"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        self.assertEquals(3, Publisher.objects.all().count())
        self.assertEquals(2, Publisher.search("pub").count())
        self.assertEquals(2, Publisher.search("House").count())
示例#9
0
    def test_from_to_dict(self):
        link, created = Link.objects.get_or_create(link="https://press.org")
        self.assertTrue(created)
        self.assertIsNotNone(link.id)

        publisher, created = Publisher.objects.get_or_create(name="Test Press")
        publisher.links.add(link)
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)
        self.assertEquals(
            {
                "name": "Test Press",
                "links": [{
                    "url": "https://press.org"
                }]
            },
            publisher.to_dict(),
        )
        self.assertEquals(
            (publisher, False),
            Publisher.from_dict({
                "name": "Test Press",
                "links": [{
                    "url": "https://press.org"
                }]
            }),
        )
        self.assertEquals((publisher, False),
                          Publisher.from_dict({"name": "Test Press"}))

        publisher, created = Publisher.objects.get_or_create(
            name="Random Press")
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)
        self.assertEquals({
            "name": "Random Press",
            "links": None
        }, publisher.to_dict())
        self.assertEquals(
            (publisher, False),
            Publisher.from_dict({
                "name": "Random Press",
                "links": None
            }),
        )
        self.assertEquals((publisher, False),
                          Publisher.from_dict({"name": "Random Press"}))
示例#10
0
def create_publisher(request):
    form_publisher = PublisherForm()
    context = {'form_publisher': form_publisher}

    if request.method == 'POST':
        form_publisher = PublisherForm(request.POST)

        if form_publisher.is_valid():
            name = request.POST.get('name', )
            publisher_object = Publisher(name=name)
            publisher_object.save()
            all_publishers = Publisher.objects.all()
            context = {
                'all_publishers': all_publishers,
            }
        return render(request, 'publishers/index.html', context)
    return render(request, 'publishers/create_publisher.html', context)
示例#11
0
    def test_save(self):
        publisher = Publisher(name="Publishing House")
        publisher.save()
        self.assertIsNotNone(publisher.id)
        self.assertEquals("publishing-house", publisher.slug)

        publisher = Publisher(name="Random")
        publisher.save()
        self.assertIsNotNone(publisher.id)
        self.assertEquals("random", publisher.slug)
示例#12
0
    def edit(self: T, field: str, value: str, *args, **kwargs):
        """Change field by given value."""
        assert field in [
            "alternate_title",
            "alternate-title",
            "binding",
            "cover",
            "isbn",
            "person",
            "publishing_date",
            "publishing-date",
            "publisher",
            "language",
            "link",
            "file",
        ]

        if field == "alternate_title" or field == "alternate-title":
            self.alternate_title = value
        elif field == "binding":
            self.binding = Binding.get_or_create(value)
        elif field == "cover":
            self.cover_image.save(os.path.basename(str(value)),
                                  DJFile(open(str(value), "rb")))
        elif field == "isbn":
            self.isbn = value
        elif field == "person":
            person = Person.get_or_create(value)
            if self.persons.filter(pk=person.pk).exists():
                self.persons.remove(person)
            else:
                self.persons.add(person)
        elif field == "publishing_date" or field == "publishing-date":
            self.publishing_date = value
        elif field == "publisher":
            self.publisher = Publisher.get_or_create(value)
        elif field == "language":
            language = Language.get_or_create(value)
            if self.languages.filter(pk=language.pk).exists():
                self.languages.remove(language)
            else:
                self.languages.add(language)
        elif field == "link":
            link = Link.get_or_create(value)
            if self.links.filter(pk=link.pk).exists():
                self.links.remove(link)
            else:
                self.links.add(link)
        elif field == "file":
            file, created = File.from_dict({"path": value})
            if self.files.filter(pk=file.pk).exists():
                self.files.remove(file)
                file.delete()
            else:
                self.files.add(file)
        self.save(*args, **kwargs)
示例#13
0
    def from_dict(cls: Type[T], data: Dict, book: Book) -> Tuple[T, bool]:
        """Create from dict.

        Returns True if was crated, i. e. was not found in the DB.
        """
        defaults: Dict = {}
        if "alternate_title" in data and data["alternate_title"]:
            defaults["alternate_title"] = data["alternate_title"]
        if "isbn" in data and data["isbn"]:
            defaults["isbn"] = data["isbn"]
        if "publishing_date" in data and data["publishing_date"]:
            defaults["publishing_date"] = datetime.datetime.strptime(
                data["publishing_date"], "%Y-%m-%d").date()
        if "publisher" in data and data["publisher"]:
            defaults["publisher"] = Publisher.from_dict(data["publisher"])[0]
        if "binding" in data and data["binding"]:
            defaults["binding"] = Binding.from_dict(data["binding"])[0]
        if "bibtex" in data and data["bibtex"]:
            defaults["bibtex"] = data["bibtex"]

        edition, created = cls.objects.get_or_create(
            book=book,
            alternate_title=data["alternate_title"]
            if "alternate_title" in data else None,
            isbn=data["isbn"] if "isbn" in data else None,
            publishing_date=data["publishing_date"]
            if "publishing_date" in data else None,
            defaults=defaults,
        )

        if "cover_image" in data and data["cover_image"]:
            edition.cover_image.save(
                os.path.basename(data["cover_image"]),
                DJFile(open(data["cover_image"], "rb")),
            )
        if "languages" in data and data["languages"]:
            for i in data["languages"]:
                edition.languages.add(Language.from_dict(i)[0])
        if "links" in data and data["links"]:
            for i in data["links"]:
                edition.links.add(Link.from_dict(i)[0])
        if "persons" in data and data["persons"]:
            for i in data["persons"]:
                edition.persons.add(Person.from_dict(i)[0])

        if "acquisitions" in data and data["acquisitions"]:
            for i in data["acquisitions"]:
                Acquisition.from_dict(i, edition)
        if "files" in data and data["files"]:
            for i in data["files"]:
                File.from_dict(i, edition)
        if "reads" in data and data["reads"]:
            for i in data["reads"]:
                Read.from_dict(i, edition)
        edition.save()
        return edition, created
示例#14
0
    def test_get_or_create(self):
        publisher, created = Publisher.from_dict({"name": "Publishing House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)
        self.assertEquals(1, Publisher.objects.count())

        publisher2 = Publisher.get_or_create("Publishing House")
        self.assertIsNotNone(publisher2)
        self.assertEquals(publisher, publisher2)
        self.assertEquals(1, Publisher.objects.count())

        publisher2 = Publisher.get_or_create(str(publisher.id))
        self.assertIsNotNone(publisher2)
        self.assertEquals(publisher, publisher2)
        self.assertEquals(1, Publisher.objects.count())

        publisher2 = Publisher.get_or_create("Old House")
        self.assertIsNotNone(publisher2)
        self.assertNotEquals(publisher, publisher2)
        self.assertEquals(2, Publisher.objects.count())
示例#15
0
    def test_publisher_change(self):
        """
        If the publisher associated with a journal changes, we need to change it too,
        but also update the associated papers!
        """
        journal = self.api.fetch_journal({'issn':'0013-9696'})
        original_publisher = journal.publisher

        new_publisher = Publisher(romeo_id='12345', preprint='cannot', postprint='cannot', pdfversion='cannot')
        new_publisher.save()
        journal.publisher = new_publisher
        journal.save()

        # Fetching the updates from romeo should revert to the original (true) publisher
        with requests_mock.mock() as http_mocker:
            http_mocker.get('http://www.sherpa.ac.uk/downloads/journal-title-issns.php?format=tsv',
                content=self.journals_dump_response)

            with patch.object(Journal, 'change_publisher') as mock_change_publisher:
                self.api.fetch_all_journals()
                mock_change_publisher.assert_called_once_with(original_publisher)
示例#16
0
 def _get_publisher(name, journal):
     """
     Tries to find a publisher PK, based on journal or name
     :param name: Name of the publisher
     :param journal: Journal object
     """
     if journal is not None:
         publisher = journal.publisher
         AliasPublisher.increment(name, publisher)
     else:
         publisher = Publisher.find(name)
     return publisher
示例#17
0
 def test_change_publisher(self):
     """
     Changing the publisher of a journal should update the 
     associated papers.
     """
     journal = RomeoAPIStub().fetch_journal({'issn':'0892-7537'})
     paper = Paper.create_by_doi('10.1007/bf02221836')
     self.assertEqual(paper.oairecords[0].journal, journal)
     self.assertEqual(paper.oairecords[0].publisher.oa_status, 'OK')
     self.assertEqual(paper.oa_status, 'OK')
     
     closed_publisher = Publisher(romeo_id='249384', preprint='cannot', postprint='cannot', pdfversion='cannot')
     closed_publisher.save()
     
     journal.change_publisher(closed_publisher)
     paper = Paper.objects.get(id=paper.id)
     journal = Journal.objects.get(id=journal.id)
     self.assertEqual(paper.oa_status, 'UNK')
     self.assertEqual(paper.publisher(), closed_publisher)
     self.assertEqual(journal.publisher, closed_publisher)
     
     
示例#18
0
    def test_change_publisher(self):
        """
        Changing the publisher of a journal should update the 
        associated papers.
        """
        journal = RomeoAPIStub().fetch_journal({'issn': '0892-7537'})
        paper = Paper.create_by_doi('10.1007/bf02221836')
        self.assertEqual(paper.oairecords[0].journal, journal)
        self.assertEqual(paper.oairecords[0].publisher.oa_status, 'OK')
        self.assertEqual(paper.oa_status, 'OK')

        closed_publisher = Publisher(romeo_id='249384',
                                     preprint='cannot',
                                     postprint='cannot',
                                     pdfversion='cannot')
        closed_publisher.save()

        journal.change_publisher(closed_publisher)
        paper = Paper.objects.get(id=paper.id)
        journal = Journal.objects.get(id=journal.id)
        self.assertEqual(paper.oa_status, 'UNK')
        self.assertEqual(paper.publisher(), closed_publisher)
        self.assertEqual(journal.publisher, closed_publisher)
示例#19
0
    def test_fix_buggy_romeo_ids(self):
        """
        A long time ago, the SHERPA API returned "DOAJ" or "journal" as publisher id for
        some journals… so we need to update them appropriately.
        """
        publisher = Publisher(romeo_id='DOAJ', preprint='can', postprint='can', pdfversion='can')
        publisher.save()
        journal = Journal(issn='0013-9696', title='Greek Review of Social Research', publisher=publisher)
        journal.save()

        # mocked separately as a different endpoint is used
        with requests_mock.mock() as http_mocker:
            http_mocker.get('http://www.sherpa.ac.uk/downloads/journal-title-issns.php?format=tsv',
                content=self.journals_dump_response)

            with patch.object(Journal, 'change_publisher') as mock_change_publisher:
                self.api.fetch_all_journals()

                new_publisher = Journal.objects.get(issn='0013-9696').publisher

                mock_change_publisher.assert_not_called()

                self.assertEqual(new_publisher.pk, publisher.pk)
                self.assertEqual(new_publisher.romeo_id, '2201')
示例#20
0
    def test_print(self):
        publisher, created = Publisher.from_dict({"name": "Publishing House"})
        self.assertTrue(created)
        self.assertIsNotNone(publisher.id)

        with StringIO() as cout:
            publisher.print(cout)
            self.assertEquals(
                "Field                            Value                              "
                +
                "                                \n=================================="
                +
                "==================================================================\n"
                +
                "Id                               1                                  "
                +
                "                                \n__________________________________"
                +
                "__________________________________________________________________\n"
                +
                "Name                             Publishing House                   "
                +
                "                                \n__________________________________"
                +
                "__________________________________________________________________\n"
                +
                "Links                                                               "
                +
                "                                \n__________________________________"
                +
                "__________________________________________________________________\n"
                +
                "Editions                                                            "
                +
                "                                \n__________________________________"
                +
                "__________________________________________________________________\n",
                cout.getvalue(),
            )
示例#21
0
    def test_fetch_journal_updates_publisher(self):
        # First we have an old version of a publisher record
        p = Publisher(name='Harvard University Press',
                      romeo_id='3243',
                      preprint='can',
                      postprint='can',
                      pdfversion='can',
                      last_updated=None)
        p.classify_oa_status()
        p.save()

        # Then we fetch one of its journals
        journal = self.api.fetch_journal({'issn': '0073-0688'})

        # That updates the publisher object
        publisher = Publisher.objects.get(id=journal.publisher.id)
        self.assertEqual(publisher.id, p.id)
        self.assertEqual(publisher.preprint, 'unclear')
        self.assertEqual(publisher.last_updated,
                         dateutil.parser.parse('2018-05-10T10:48:27Z'))
示例#22
0
def _publisher(args: Namespace, file: TextIO = sys.stdout):
    publisher: Optional[Publisher] = None
    if args.subparser == "add":
        publisher, created = Publisher.from_dict({
            "name":
            args.name,
            "links":
            [Link.get_or_create(link).to_dict() for link in args.link],
        })
        if created:
            stdout.write(
                _('Successfully added publisher "%(name)s" with id "%(pk)d".')
                % {
                    "name": publisher.name,
                    "pk": publisher.pk
                },
                "=",
                file=file,
            )
            publisher.print(file)
        else:
            stdout.write(
                _('The publisher "%(name)s" already exists with id "%(pk)d", '
                  + "aborting...") % {
                      "name": publisher.name,
                      "pk": publisher.pk
                  },
                "",
                file=file,
            )
    elif args.subparser == "delete":
        publisher = Publisher.get(args.publisher)
        if publisher:
            publisher.delete()
            stdout.write(
                _('Successfully deleted publisher with id "%(pk)d".') %
                {"pk": publisher.pk},
                "",
                file=file,
            )
        else:
            stdout.write(_("No publisher found."), "", file=file)
    elif args.subparser == "edit":
        publisher = Publisher.get(args.publisher)
        if publisher:
            publisher.edit(args.field, args.value)
            stdout.write(
                _('Successfully edited publisher "%(name)s" with id "%(pk)d".')
                % {
                    "name": publisher.name,
                    "pk": publisher.pk
                },
                "",
                file=file,
            )
            publisher.print(file)
        else:
            stdout.write(_("No publisher found."), "", file=file)
    elif args.subparser == "info":
        publisher = Publisher.get(args.publisher)
        if publisher:
            publisher.print(file)
        else:
            stdout.write(_("No publisher found."), "", file=file)
    elif args.subparser == "list":
        if args.search:
            publishers = Publisher.search(args.search)
        else:
            publishers = Publisher.objects.all()
        stdout.write(
            [_("Id"), _("Name"), _("Number of editions")],
            "=", [0.05, 0.8],
            file=file)
        for i, has_next in lookahead(publishers):
            stdout.write(
                [i.id, i.name, i.editions.count()],
                "_" if has_next else "=",
                [0.05, 0.8],
                file=file,
            )
示例#23
0
class TestCiteproc():
    """
    This class groups tests about the Citeproc class
    """

    test_class = Citeproc

    @pytest.mark.parametrize('url, expected', is_oai_license_params)
    def test_is_oa_license(self, url, expected):
        assert self.test_class.is_oa_license(url) == expected

    @pytest.mark.usefixtures('db')
    def test_to_paper(self, container_title, title, citeproc):
        p = self.test_class.to_paper(citeproc)
        # Ensure that paper is in database (i.e. created)
        assert p.pk >= 1
        # Check paper fields
        for author_p, author_c in zip(p.authors_list, citeproc['author']):
            assert author_p['name']['first'] == author_c['given']
            assert author_p['name']['last'] == author_c['family']
            assert author_p['affiliation'] == author_c['affiliation'][0][
                'name']
            assert author_p['orcid'] == author_c['ORCID']
        assert p.pubdate == date(*citeproc['issued']['date-parts'][0])
        assert p.title == title
        # Ensure that oairecord is in database (i.e. created)
        r = OaiRecord.objects.get(about=p)
        # Check oairecord fields
        assert r.doi == citeproc['DOI']
        assert r.identifier == doi_to_crossref_identifier(citeproc['DOI'])
        assert r.issue == citeproc['issue']
        assert r.journal_title == container_title
        assert r.pages == citeproc['page']
        assert r.pubdate == date(*citeproc['issued']['date-parts'][0])
        assert r.publisher_name == citeproc['publisher']
        assert r.source == OaiSource.objects.get(identifier='crossref')
        assert r.splash_url == doi_to_url(citeproc['DOI'])
        assert r.volume == citeproc['volume']

    @pytest.mark.parametrize('mock_function',
                             ['_get_oairecord_data', '_get_paper_data'])
    def test_to_paper_invalid_data(self, monkeypatch, mock_function, citeproc):
        """
        If data is invalid, i.e. metadata is corrupted, somethings missing or so, must raise exception
        """
        def raise_citeproc_error(*args, **kwargs):
            raise CiteprocError

        monkeypatch.setattr(self.test_class, mock_function,
                            raise_citeproc_error)
        with pytest.raises(CiteprocError):
            self.test_class.to_paper(citeproc)

    def test_to_paper_no_data(self):
        """
        If no data, must raise CiteprocError
        """
        with pytest.raises(CiteprocError):
            self.test_class.to_paper(None)

    @pytest.mark.parametrize('name, expected', convert_to_name_pair_list)
    def test_convert_to_name_pair(self, name, expected):
        """
        Test if name pairing works
        """
        assert self.test_class._convert_to_name_pair(name) == expected

    @pytest.mark.parametrize('author_elem, expected',
                             [(dict(), None),
                              ({
                                  'affiliation': [{
                                      'name': 'Porto'
                                  }]
                              }, 'Porto'),
                              ({
                                  'affiliation': [{
                                      'name': 'Porto'
                                  }, {
                                      'name': 'Lissabon'
                                  }]
                              }, 'Porto')])
    def test_get_affiliation(self, author_elem, expected):
        """
        Must return the first affiliation if any
        """
        assert self.test_class._get_affiliation(author_elem) == expected

    def test_get_abstract(self, citeproc):
        """
        Abstract must be set
        """
        assert self.test_class._get_abstract(citeproc) == citeproc['abstract']

    def test_get_abstact_missing(self, citeproc):
        """
        If no abstract, assert blank
        """
        del citeproc['abstract']
        assert self.test_class._get_abstract(citeproc) == ''

    def test_get_abstract_escaping(self, citeproc):
        """
        Must do some escaping, e.g. we sometimes get some jats tags
        """
        # We wrap the current abstract into some jats
        expected = citeproc['abstract']
        citeproc['abstract'] = r'<jats:p>{}<\/jats:p>'.format(expected)
        assert self.test_class._get_abstract(citeproc) == expected

    def test_get_affiliations(self, affiliations, citeproc):
        """
        Must have the same length as citeproc['author'] and identical to list of affiliations
        """
        r = self.test_class._get_affiliations(citeproc)
        assert len(r) == len(citeproc.get('author'))
        assert r == affiliations

    def test_get_affiliations_no_authors(self, citeproc):
        """
        Must rais exception
        """
        del citeproc['author']
        with pytest.raises(CiteprocAuthorError):
            self.test_class._get_affiliations(citeproc)

    def test_get_authors(self, citeproc):
        """
        The list of authors shall be a list of BareNames
        """
        r = self.test_class._get_authors(citeproc)
        assert isinstance(r, list)
        for barename in r:
            assert isinstance(barename, BareName)

    def test_get_authors_empty_list(self, citeproc):
        """
        The list of authors must not be empty
        """
        citeproc['author'] = []
        with pytest.raises(CiteprocAuthorError):
            self.test_class._get_authors(citeproc)

    def test_get_authors_no_list(self, citeproc):
        """
        author in citeproc must be a list
        """
        del citeproc['author']
        with pytest.raises(CiteprocAuthorError):
            self.test_class._get_authors(citeproc)

    def test_get_authors_invalid_author(self, monkeypatch, citeproc):
        """
        If 'None' is an entry, raise exception
        """
        # We mock the function and let it return None, so that name_pairs is a list of None
        monkeypatch.setattr(self.test_class, '_convert_to_name_pair',
                            lambda x: None)
        with pytest.raises(CiteprocAuthorError):
            self.test_class._get_authors(citeproc)

    def test_get_container(self, container_title, citeproc):
        """
        Must return container title
        """
        assert self.test_class._get_container(citeproc) == container_title

    def test_get_container_missing(self):
        """
        Must return exception
        """
        with pytest.raises(CiteprocContainerTitleError):
            self.test_class._get_container(dict())

    def test_get_doi(self, citeproc):
        """
        Must return the DOI
        """
        assert self.test_class._get_doi(citeproc) == citeproc['DOI']

    def test_get_doi_invalid(self):
        """
        Must raise exception
        """
        with pytest.raises(CiteprocDOIError):
            self.test_class._get_doi({'DOI': 'spanish inquisition'})

    def test_get_doi_missing(self):
        """
        Must raise exception
        """
        with pytest.raises(CiteprocDOIError):
            self.test_class._get_doi(dict())

    @pytest.mark.parametrize('issn, expected', [('1234-5675', '1234-5675'),
                                                ([
                                                    '1234-5675',
                                                ], '1234-5675'), ([], '')])
    def test_get_issn(self, citeproc, issn, expected):
        """
        Must return the issn or ''
        """
        citeproc['ISSN'] = issn
        assert self.test_class._get_issn(citeproc) == expected

    def test_get_issn_missing(self, citeproc):
        """
        Must return ''
        """
        del citeproc['ISSN']
        assert self.test_class._get_issn(citeproc) == ''

    @pytest.mark.usefixtures('mock_alias_publisher_increment',
                             'mock_journal_find', 'mock_publisher_find')
    @pytest.mark.parametrize('journal', [Journal(publisher=Publisher()), None])
    def test_get_oairecord_data(self, db, monkeypatch, container_title, issn,
                                citeproc, journal):
        """
        We do some assertions on the results, but relatively lax, as we test the called functions, too
        """
        monkeypatch.setattr(Journal, 'find', lambda issn, title: journal)
        r = self.test_class._get_oairecord_data(citeproc)
        assert r['doi'] == citeproc['DOI']
        assert r['description'] == citeproc['abstract']
        assert r['identifier'] == doi_to_crossref_identifier(citeproc['DOI'])
        assert r['issn'] == issn
        assert r['issue'] == citeproc['issue']
        assert r['journal'] == journal
        assert r['journal_title'] == container_title
        assert r['pages'] == citeproc['page']
        assert r['pdf_url'] == ''  # Is not OA
        assert r['pubdate'] == date(*citeproc['issued']['date-parts'][0])
        assert r['publisher_name'] == citeproc['publisher']
        assert r['pubtype'] == citeproc['type']
        assert r['source'] == OaiSource.objects.get(identifier='crossref')
        assert r['splash_url'] == doi_to_url(citeproc['DOI'])
        assert r['volume'] == citeproc['volume']

    @pytest.mark.usefixtures('mock_journal_find', 'mock_publisher_find')
    def test_get_oairecord_data_missing(self, monkeypatch, container_title,
                                        issn, citeproc):
        """
        Some fields may be empty, namely those with a direct get call
        """
        keys = ['abstract', 'issue', 'publisher', 'page', 'volume']
        for k in keys:
            del citeproc[k]
        r = self.test_class._get_oairecord_data(citeproc)
        keys = ['description', 'issue', 'publisher_name', 'pages', 'volume']
        for k in keys:
            assert r[k] == ''

    @pytest.mark.parametrize('orcid, expected',
                             [({
                                 'ORCID': '0000-0001-8187-9704'
                             }, '0000-0001-8187-9704'),
                              ({
                                  'ORCID': '0000-0001-8187-9705'
                              }, None), ({}, None)])
    def test_get_orcid(self, orcid, expected):
        """
        Must be valid or None
        """
        assert self.test_class._get_orcid(orcid) == expected

    def test_get_orcids(self, orcids, citeproc):
        """
        Must have the same length as citeproc['author'] and identical to list of  orcid
        """
        r = self.test_class._get_orcids(citeproc)
        assert len(r) == len(citeproc.get('author'))
        assert r == orcids

    def test_get_orcid_no_authors(self, citeproc):
        """
        Must rais exception
        """
        del citeproc['author']
        with pytest.raises(CiteprocAuthorError):
            self.test_class._get_orcids(citeproc)

    def test_get_paper_data(self, affiliations, orcids, title, citeproc):
        """
        We do some assertions on the results, but relatively lax, as we test the called functions, too
        """
        r = self.test_class._get_paper_data(citeproc)
        assert r['affiliations'] == affiliations
        for a in r['author_names']:
            assert isinstance(a, BareName)
        assert r['orcids'] == orcids
        assert r['pubdate'] == date(*citeproc['issued']['date-parts'][0])
        assert r['title'] == title

    @pytest.mark.parametrize('doi', [True, False])
    @pytest.mark.parametrize('license', [True, False])
    def test_get_pdf_url(self, monkeypatch, doi, license):
        """
        Must return true or false
        """
        monkeypatch.setattr(self.test_class, '_is_oa_by_doi', lambda x: doi)
        monkeypatch.setattr(self.test_class, '_is_oa_by_license',
                            lambda x: license)
        url = 'https://repository.dissem.in/entry/3242/document.pdf'
        r = self.test_class._get_pdf_url(doi, license, url)
        if doi or license:
            assert r == url
        else:
            assert r == ''

    def test_get_pubdate_issued(self, citeproc):
        """
        If contains issued, take this
        """
        citeproc['created'] = {'date-parts': [[2019, 10, 11]]}
        citeproc['deposited'] = {'date-parts': [[2019, 10, 12]]}
        assert self.test_class._get_pubdate(citeproc) == date(
            *citeproc['issued']['date-parts'][0])

    def test_get_pubdate_created(self, citeproc):
        """
        If contains no issued, take created
        """
        del citeproc['issued']
        citeproc['created'] = {'date-parts': [[2019, 10, 11]]}
        citeproc['deposited'] = {'date-parts': [[2019, 10, 12]]}
        assert self.test_class._get_pubdate(citeproc) == date(
            *citeproc['created']['date-parts'][0])

    def test_get_pubdate_deposited(self, citeproc):
        """
        If contains no issued and created, take deposited
        """
        del citeproc['issued']
        citeproc['deposited'] = {'date-parts': [[2019, 10, 12]]}
        assert self.test_class._get_pubdate(citeproc) == date(
            *citeproc['deposited']['date-parts'][0])

    def test_get_pubdate_no_date(self, citeproc):
        """
        If contains no date, raise exception
        """
        del citeproc['issued']
        with pytest.raises(CiteprocDateError):
            self.test_class._get_pubdate(citeproc)

    def test_get_pubdate_received_none(self, monkeypatch):
        """
        If no valid date is found, raise exception
        """
        monkeypatch.setattr(self.test_class, '_parse_date', lambda x: None)
        with pytest.raises(CiteprocDateError):
            self.test_class._get_pubdate(dict())

    @pytest.mark.usefixtures('mock_alias_publisher_increment')
    def test_get_publisher_by_journal(self):
        """
        Must return Publisher object
        """
        publisher = Publisher()
        journal = Journal(publisher=publisher)
        assert self.test_class._get_publisher('p_name', journal) == publisher

    def test_get_publisher_by_name(self, monkeypatch):
        """
        Must return publisher object
        """
        publisher = Publisher()
        monkeypatch.setattr(Publisher, 'find', lambda x: publisher)
        assert self.test_class._get_publisher('p_name', None) == publisher

    def test_get_pubtype(self):
        """
        Must return something from PAPER_TYPES
        """
        pubtype = 'book'
        assert self.test_class._get_pubtype({'type': pubtype}) == pubtype

    def test_get_pubtype_strange(self):
        """
        Must return other
        """
        assert self.test_class._get_pubtype({'type':
                                             'spanish inquisition'}) == 'other'

    def test_get_pubtype_missing(self):
        """
        Must raise exception
        """
        with pytest.raises(CiteprocPubtypeError):
            self.test_class._get_pubtype(dict())

    def test_get_title(self, citeproc):
        r = self.test_class._get_title(citeproc)
        assert r == citeproc['title'][:1024]
        assert len(r) <= 1024

    def test_get_title_length(self, citeproc):
        """
        Title must no be longer than 1024 chars
        """
        citeproc['title'] = 'x' * 2000
        r = self.test_class._get_title(citeproc)
        assert r == citeproc['title'][:1024]
        assert len(r) <= 1024

    def test_get_title_length_with_unicode(self, citeproc):
        citeproc['title'] = '–' * 1024
        r = self.test_class._get_title(citeproc)
        assert r == citeproc['title'][:341]
        assert len(r) <= 1024

    def test_get_title_no_title(self, citeproc):
        """
        Title is mandatory
        """
        del citeproc['title']
        with pytest.raises(CiteprocTitleError):
            self.test_class._get_title(citeproc)

    def test_get_title_emtpy_string(self, citeproc):
        """
        If no title is found, expect CiteprocTitleError
        """
        citeproc['title'] = ''
        with pytest.raises(CiteprocTitleError):
            self.test_class._get_title(citeproc)

    @pytest.mark.parametrize('doi, expected', [('10.2195/spam', True),
                                               ('10.15122/spam', False)])
    def test_is_oa_by_doi(self, doi, expected):
        """
        Must be true or false
        """
        assert self.test_class._is_oa_by_doi(doi) == expected

    @pytest.mark.parametrize('licenses, expected',
                             [([{
                                 'URL': 'creativecommons.org/licenses/'
                             }], True),
                              ([{
                                  'URL': 'https://dissem.in/not_free'
                              }], False), ([{}], False), ([], False)])
    def test_is_oa_by_license(self, licenses, expected):
        """
        Must be true or false
        """
        assert self.test_class._is_oa_by_license(licenses) == expected

    @pytest.mark.parametrize('data, expected', [({
        'date-parts': [[2019, 10, 10]]
    }, date(2019, 10, 10)), ({
        'raw': '2019-10-10'
    }, date(2019, 10, 10)), (None, None), ({
        'spam': 'ham'
    }, None)])
    def test_parse_date(self, data, expected):
        """
        Must return a valid date or None
        """
        assert self.test_class._parse_date(data) == expected

    @pytest.mark.parametrize('date_parts, expected', [([
        2019,
    ], date(2019, 1, 1)), ([
        2019,
        10,
    ], date(2019, 10, 1)), ([2019, 10, 10], date(2019, 10, 10))])
    def test_parse_date_parts(self, date_parts, expected):
        """
        Must parse the date list
        """
        assert self.test_class._parse_date_parts(date_parts) == expected
示例#24
0
def run():
    author1 = Author(name="J. K. Rowling", birth_date="1965-07-31", author_pic="authors/2020/05/jkrowling.jpg", bio="Es una escritora, productora de cine y guionista británica, conocida por ser la autora de la serie de libros Harry Potter, que han superado los quinientos millones de ejemplares vendidos.")
    author2 = Author(name="Rick Riordan", birth_date='1964-06-05', author_pic="authors/2020/06/rriordan.jpg", bio="Richard Russell Riordan es un escritor estadounidense. Es más conocido por ser el autor de la saga Percy Jackson y los dioses del Olimpo.")
    author3 = Author(name="Suzanne Collins", birth_date='1962-08-10', author_pic="authors/2020/06/scollins.jpg", bio="Escritora estadounidense, sus revolucionarias novelas juveniles, Los Juegos del Hambre, En llamas y Sinsajo fueron superventas de The New York Times. Recibieron reconocimiento en todo el mundo.")
    publisher1 = Publisher(name="Bloomsbury", city="Londres", country="Reino Unido", about="Bloomsbury Publishing es una casa editorial independiente, asentada en Londres en el Reino Unido, conocida por sus novelas literarias. Fue nombrada \"editorial del año\" en 1999 y 2000.", website="www.bloomsbury.com", publisher_pic="publishers/2020/06/bblogo.png")
    publisher2 = Publisher(name="Salamandra", city="Barcelona", country="España", about="Ediciones Salamandra, también llamada simplemente Salamandra, es una editorial fundada en 1989 en Barcelona como filial española de la editorial argentina Emecé Editores.", website="www.megustaleer.com/editoriales/salamandra/SD/", publisher_pic="publishers/2020/06/sallogo.jpg")
    publisher3 = Publisher(name="Scholastic", city="Nueva York", country="Estados Unidos", about="Scholastic es una empresa editora de libros estadounidense conocida por publicar materiales educativos para escuelas, además de libros comerciales.", website="www.scholastic.com", publisher_pic="publishers/2020/06/schlogo.png")
    tag1 = Tag(title="Fantasy")
    tag2 = Tag(title="Mystery")
    tag3 = Tag(title="Novel")
    tag4 = Tag(title="Adventure")
    book1 = Book(title="Harry Potter y la Piedra Filosofal", author=author1, pub_date="1997-06-26", publisher=publisher1, description="Harry Potter crece en la casa de sus tíos, los Dursley, quienes le ocultan su verdadera historia familiar; al cumplir Harry once años de edad, empiezan a llegarle cartas de remitente desconocido, que van aumentando en número a medida que sus tíos no dejan que las abra. Las mismas traen la noticia de que el niño ha sido admitido en el Colegio Hogwarts de Magia y Hechicería, ya que, al igual que sus padres, tiene poderes mágicos. \\n\\nSe descubre entonces que los Potter no murieron en un accidente de coche como se le había dicho a Harry, sino que habían sido asesinados en la noche de Halloween por un hechicero tenebroso conocido como lord Voldemort, quien había aterrorizado a la comunidad mágica británica años atrás. Sin embargo, algo ocurrió esa noche: Voldemort consiguió matar al matrimonio Potter pero no pudo asesinar al bebé, perdió su cuerpo y le dejó al niño una cicatriz permanente en forma de rayo en su frente. \\n\\nRubeus Hagrid aparece para llevarse a Harry una noche, cuando los Dursley intentan impedir que parta rumbo al colegio. Más tarde, el hombre ayuda a Harry a comprar sus materiales escolares en el callejón Diagon y allí éste descubre que es famoso entre los magos por haber sobrevivido al intento de homicidio. Posteriormente, el muchacho toma el tren que lo lleva a Hogwarts y allí conoce a Ron Weasley, un chico pelirrojo hijo de magos, y a Hermione Granger, una jovencita de origen muggle con altas aspiraciones académicas. Los tres se hacen amigos y más tarde, durante su año escolar, se ven envueltos en una serie de episodios relacionados con un objeto escondido en las profundidades del edificio: la piedra filosofal, un artefacto con el poder de transmutar los metales en oro y producir el elixir de la vida eterna. Diferentes hechos les hacen suponer que uno de sus profesores, Severus Snape, desea conseguir la piedra para entregársela a Voldemort, con quien el docente estaría confabulado.", price="199.99", cover_pic="covers/2020/05/hpylpf.jpg", book_content="contents/hpylpf.pdf")
    book2 = Book(title="Harry Potter y la Cámara Secreta", author=author1, pub_date="1998-07-08", publisher=publisher1, description="Tras derrotar una vez más a lord Voldemort, su siniestro enemigo  en Harry  Potter y la piedra filosofal, Harry espera impaciente en casa de sus insoportables tíos el inicio del segundo curso del Colegio Hogwarts de Magia y hechicería. Sin embargo, la espera dura poco, pues un elfo aparece en su habitación y le advierte que una amenaza mortal se cierne sobre la escuela. Así pues, Harry no se lo piensa dos veces y, acompañado de  Ron, su mejor amigo, se dirige a Hogwarts en un coche volador. Pero ¿puede un aprendiz de mago defender la escuela de los malvados que pretenden destruirla? Sin saber que alguien ha abierto la Cámara de los Secretos, dejando escapar una serie de monstruos peligrosos, Harry y sus amigos Ron y Hermione tendrán que enfrentarse con arañas gigantes, serpientes encantadas, fantasmas enfurecidos y, sobre todo, con la mismísima reencarnación de su más temible adversario.", price="199.99", cover_pic="covers/2020/05/hpylca.jpg", book_content="contents/hpylca.pdf")
    book3 = Book(title="Harry Potter y el Prisionero de Azkaban", author=author1, pub_date="1999-07-08", publisher=publisher1, description="Por la cicatriz que lleva en la frente, sabemos que Harry Potter no es un niño como los demás, sino el héroe que venció a lord Voldemort, el mago más temible y maligno de todos los tiempos y culpable de la muerte de los  padres  de  Harry.  Desde  entonces,  Harry  no  tiene  más  remedio  que  vivir  con  sus  pesados  tíos  y  su  insoportable  primo  Dudley,  todos  ellos  muggles, o sea, personas no magas, que desprecian a su sobrino debido a sus poderes. Igual que en las dos primeras partes de la serie —La piedra filosofal y La cámara  secreta—  Harry  aguarda  con  impaciencia  el  inicio  del  tercer  curso  en  el  Colegio  Hogwarts  de  Magia  y  Hechicería.  Tras  haber  cumplido los trece años, solo y lejos de sus amigos de Hogwarts, Harry se pelea con su bigotuda tía Marge, a la que convierte en globo, y debe huir en un autobús mágico. Mientras tanto, de la prisión de Azkaban se ha  escapado  un  terrible  villano,  Sirius  Black,  un  asesino  en  serie  con  poderes  mágicos  que  fue  cómplice  de  lord  Voldemort  y  que  parece  dispuesto  a  eliminar  a  Harry  del  mapa.  Y  por  si  esto  fuera  poco,  Harry  deberá enfrentarse también a unos terribles monstruos, los dementores, seres  abominables  capaces  de  robarles  la  felicidad  a  los  magos  y  de  borrar  todo  recuerdo  hermoso  de  aquellos  que  osan  mirarlos.  Lo  que  ninguno de estos malvados personajes sabe es que Harry, con la ayuda de sus fieles amigos Ron y Hermione, es capaz de todo y mucho más.", price="199.99", cover_pic="covers/2020/05/hpyepda.jpg", book_content="contents/hpyepda.pdf")
    book4 = Book(title="Harry Potter y el Cáliz de Fuego", author=author1, pub_date='2000-07-08', publisher=publisher1, description="Tras otro abominable verano con los Dursley, Harry se dispone a  iniciar el cuarto curso en Hogwarts, la famosa escuela de magia y  hechicería. A sus catorce años, a Harry le gustaría ser un joven  mago como los demás y dedicarse a aprender nuevos sortilegios, encontrarse con sus amigos Ron y Hermione y asistir con ellos a los Mundiales de quidditch. Sin embargo, al llegar al colegio le espera una gran sorpresa que lo obligará a  enfrentarse a los desafíos más temibles de toda su vida. Si logra superarlos, habrá demostrado que ya no es un niño y que está preparado para vivir las nuevas y emocionantes experiencias que el futuro le depara.",  price="199.99", cover_pic="covers/2020/06/hpyecdf.jpg", book_content="contents/hpyecdf.pdf")
    book5 = Book(title="Percy Jackson y el Ladrón del Rayo", author=author2, pub_date='2005-06-28', publisher=publisher2, description="¿Qué pasaría si un día descubrieras que, en realidad, eres hijo de un dios griego que debe cumplir una misión secreta? Pues eso es lo que le sucede a Percy Jackson, que a partir de ese momento se dispone a vivir los acontecimientos más emocionantes de su vida. Expulsado de seis colegios, Percy padece dislexia y dificultades para concentrarse, o al menos ésa es la versión oficial. Objeto de burlas por inventarse historias fantásticas, ni siquiera él mismo acaba de creérselas hasta el día que los dioses del Olimpo le revelan la verdad: Percy es nada menos que un semidiós, es decir, el hijo de un dios y una mortal. Y como tal ha de descubrir quién ha robado el rayo de Zeus y así evitar que estalle una guerra entre los dioses. Para cumplir la misión contará con la ayuda de sus amigos Grover, un joven sátiro, y Annabeth, hija de Atenea. El ladrón del rayo da comienzo a la apasionante serie Percy Jackson y los Dioses del Olimpo, un mundo secreto que los antiguos dioses griegos han recreado a nuestro alrededor en pleno siglo XXI.", price="159.99", cover_pic="covers/2020/06/pjyeldr.jpg", book_content="contents/pjyeldr.pdf")
    book6 = Book(title="Percy Jackson y el Mar de los Monstruos", author=author2, pub_date='2006-04-01', publisher=publisher2, description="Desde que sabe que es hijo de un dios del Olimpo, Percy Jackson espera que el destino le depare continuas aventuras. Y sus expectativas se cumplen con creces. Aunque el nuevo curso en la Escuela Meriwether transcurre con inusual nor- malidad, un simple partido de balón prisionero acaba en batalla campal contra una banda de feroces gigantes. A partir de ahí los acontecimientos se precipitan: el perímetro mágico que protege el Campamento Mestizo es destruido por un misterioso enemigo y la única seguridad con que contaban los semidioses desaparece. Así, para impedir este daño irreparable, Percy y sus amigos inician la travesía del temible Mar de los Monstruos en busca de lo único que puede salvar el campamento: el Vellocino de Oro.", price="159.99", cover_pic="covers/2020/06/pjyemdlm.jpg", book_content="contents/pjyemdlm.pdf")
    book7 = Book(title="Percy Jackson y la Maldición del Titán", author=author2, pub_date="2007-04-15", publisher=publisher2, description="Ante la llamada de socorro de su amigo el sátiro Grover, Percy acude inmediatamente en su auxilio. Y aunque va acompañado de Annabeth y Thalia, las dos semidiosas que son sus aliadas, ninguno imagina la sorpresa  que  los  aguarda:  una  terrible  mantícora  pretende secuestrarlos  y  llevarlos  ante  el  general  enviado  por  Cronos,  el diabólico señor de los titanes. Sin embargo, gracias a la ayuda de las cazadoras de Artemisa, Percy y sus aliadas logran escapar y volver al campamento  mestizo.  Una  vez  allí,  emprenderán  la  búsqueda  del monstruo que puede provocar la destrucción del Olimpo, a pesar de que, según la profecía del Oráculo, sólo uno de ellos logrará resistir la maldición del titán.", price="159.99", cover_pic="covers/2020/06/pjylmdt.jpg", book_content="contents/pjylmdt.pdf")
    book8 = Book(title="The Hunger Games", author=author3, pub_date="2008-09-14", publisher=publisher3, description="Ganar significa fama y fortuna. Perder significa muerte segura. Los juegos del hambre han comenzado. . . . En las ruinas de un lugar una vez conocido como América del Norte se encuentra la nación de Panem, un brillante Capitolio rodeado de doce distritos periféricos. El Capitolio es duro y cruel y mantiene a los distritos en línea al obligarlos a enviar a un niño y una niña entre las edades de doce y dieciocho años a participar en los Juegos Anuales del Hambre, una pelea a muerte en la televisión en vivo.Katniss Everdeen, de 16 años, lo considera una sentencia de muerte cuando se adelanta para ocupar el lugar de su hermana en los Juegos. Pero Katniss ha estado cerca de la muerte antes, y la supervivencia, para ella, es una segunda naturaleza. Sin querer realmente, se convierte en una contendiente. Pero si quiere ganar, tendrá que comenzar a tomar decisiones que sopesen la supervivencia contra la humanidad y la vida contra el amor.", price="149.99", cover_pic="covers/2020/06/thg.jpg", book_content="contents/thg.pdf")
    book9 = Book(title="Catching Fire", author=author3, pub_date="2009-09-01", publisher=publisher3, description="Suzanne Collins continúa la increíble historia de Katniss Everdeen en la fenomenal trilogía de los Juegos del Hambre. Contra viento y marea, Katniss Everdeen ha ganado los Juegos del Hambre anuales con su colega tributo del distrito, Peeta Mellark. Pero fue una victoria ganada por el desafío del Capitolio y sus duras reglas. Katniss y Peeta deberían estar felices. Después de todo, acaban de ganar para ellos y sus familias una vida segura y abundante. Pero hay rumores de rebelión entre los sujetos, y Katniss y Peeta, para su horror, son los rostros de esa rebelión. El capitolio está enojado. El Capitolio quiere venganza.", price="149.99", cover_pic="covers/2020/06/thgcf.jpg", book_content="contents/thgcf.pdf")
    book10 = Book(title="Mockingjay", author=author3, pub_date="2010-08-24", publisher=publisher3, description="Katniss Everdeen, niña en llamas, ha sobrevivido, a pesar de que su casa ha sido destruida. Hay rebeldes. Hay nuevos líderes. Se está desarrollando una revolución. El Distrito 13 salió de las sombras y está planeando derrocar al Capitolio. Aunque ha sido parte de la revolución durante mucho tiempo, Katniss no lo ha sabido. Ahora parece que todos han intervenido en los planes cuidadosamente elaborados menos ella. El éxito de la rebelión depende de la voluntad de Katniss de ser un peón, de aceptar la responsabilidad de innumerables vidas y de cambiar el curso del futuro de Panem. Para hacer esto, debe dejar de lado sus sentimientos de ira y desconfianza. Ella debe convertirse en el Sinsajo de los rebeldes, sin importar el costo.", price="149.99", cover_pic="covers/2020/06/thgmj.jpg", book_content="contents/thgmj.pdf")
    author1.save()
    author2.save()
    author3.save()
    publisher1.save()
    publisher2.save()
    publisher3.save()
    tag1.save()
    tag2.save()
    tag3.save()
    tag4.save()
    book1.save()
    book2.save()
    book3.save()
    book4.save()
    book5.save()
    book6.save()
    book7.save()
    book8.save()
    book9.save()
    book10.save()
    book1.tags.set([tag1])
    book2.tags.set([tag1, tag2])
    book3.tags.set([tag1])
    book4.tags.set([tag1, tag2])
    book5.tags.set([tag1, tag4])
    book6.tags.set([tag1, tag4])
    book7.tags.set([tag1, tag4])
    book8.tags.set([tag3])
    book9.tags.set([tag3])
    book10.tags.set([tag3])
示例#25
0
        last_name=fake.last_name(),
        about=fake.paragraphs(nb=2),
    )
    author.save()

# Add Genre
genre_list = ['Action', 'Literary', 'Romance', 'Humor', 'Science', 'History',
              'Cooking', 'Graphic Novel']

for word in genre_list:
    genre = Genre(name=word, about=fake.paragraphs(nb=1))
    genre.save()

# Add Publisher
for x in range(0, 11):
    publisher = Publisher(name=fake.company(),
                          about=fake.paragraphs(nb=2))
    publisher.save()

# Add Books
for x in range(0, 101):
    rand_auth = randint(1, 20)
    author_query = Author.objects.get(id=rand_auth)

    rand_pub = randint(1, 10)
    publish_query = Publisher.objects.get(id=rand_pub)

    rand_genre = randint(1, 8)
    genre_query = Genre.objects.get(id=rand_genre)

    book = Book(
        name=fake.text(max_nb_chars=40),
示例#26
0
    def get_or_create_publisher(self, romeo_xml_description):
        """
        Retrieves from the model, or creates into the model,
        the publisher corresponding to the <publisher> description
        from RoMEO.

        If the data from RoMEO is more fresh than what we have
        in cache, we update our model.
        """
        xml = romeo_xml_description
        romeo_id = None
        try:
            romeo_id = xml.attrib['id']
        except KeyError:
            raise MetadataSourceException('RoMEO did not provide a publisher id.')

        romeo_parent_id = None
        try:
            romeo_parent_id = xml.attrib['parentid']
        except KeyError:
            pass

        name = None
        try:
            raw_name = xml.findall('./name')[0].text.strip()
            name = fromstring(kill_html(sanitize_html(raw_name))).text
        except (KeyError, IndexError, AttributeError):
            raise MetadataSourceException(
                'RoMEO did not provide the publisher\'s name.')

        alias = None
        try:
            alias = nstrip(xml.findall('./alias')[0].text)
            if alias:
                alias = fromstring(kill_html(sanitize_html(alias))).text
        except (KeyError, IndexError):
            pass

        last_update = self._get_romeo_date(xml, './dateupdated')

        # Check if we already have it.
        # Sadly the romeo_id is not unique (as publishers imported from doaj
        # all get the same id, so we have to use the name too).
        matches = None
        if re.match(r'\d+', romeo_id): # numeric ids are unambiguous
            matches = Publisher.objects.filter(romeo_id=romeo_id)
        elif alias:
            matches = Publisher.objects.filter(
                romeo_id=romeo_id, name__iexact=name, alias__iexact=alias)
        else:
            matches = Publisher.objects.filter(
                romeo_id=romeo_id, name__iexact=name, alias__isnull=True)
        if matches:
            first_match = matches[0]
            if first_match.last_updated is not None and first_match.last_updated >= last_update:
                return matches[0]

        # Otherwise, create it
        url = None
        try:
            url = nstrip(xml.findall('./homeurl')[0].text)
        except (KeyError, IndexError):
            pass

        preprint = None
        try:
            preprint = xml.findall('./preprints/prearchiving')[0].text.strip()
        except (KeyError, IndexError, AttributeError):
            raise MetadataSourceException(
                'RoMEO did not provide the preprint policy.')

        postprint = None
        try:
            postprint = xml.findall('./postprints/postarchiving')[0].text.strip()
        except (KeyError, IndexError, AttributeError):
            raise MetadataSourceException(
                'RoMEO did not provide the postprint policy.')

        pdfversion = None
        try:
            pdfversion = xml.findall('./pdfversion/pdfarchiving')[0].text.strip()
        except (KeyError, IndexError, AttributeError):
            raise MetadataSourceException(
                'RoMEO did not provide the pdf archiving policy.')

        # Compute OA status of the publisher
        status = 'UNK'

        if not matches:
            publisher = Publisher()
        else:
            publisher = matches[0]

        publisher.name = name
        publisher.alias = alias
        publisher.url = url
        publisher.preprint = preprint
        publisher.postprint = postprint
        publisher.pdfversion = pdfversion
        publisher.romeo_id = romeo_id
        publisher.romeo_parent_id = romeo_parent_id
        publisher.oa_status = status
        publisher.last_updated = last_update
        publisher.save()

        if matches:
            publisher.publishercopyrightlink_set.all().delete()
            publisher.publisherrestrictiondetail_set.all().delete()
            publisher.publishercondition_set.all().delete()

        # Add the conditions, restrictions, and copyright
        for restriction in xml.findall('./preprints/prerestrictions/prerestriction'):
            self.add_restriction(restriction, 'preprint', publisher)

        for restriction in xml.findall('./postprints/postrestrictions/postrestriction'):
            self.add_restriction(restriction, 'postprint', publisher)

        for restriction in xml.findall('./pdfversion/pdfrestrictions/pdfrestriction'):
            self.add_restriction(restriction, 'pdfversion', publisher)

        for condition in xml.findall('./conditions/condition'):
            if condition.text:
                c = PublisherCondition(publisher=publisher,
                                       text=condition.text.strip())
                c.save()

        # Update the publisher status
        publisher.oa_status = publisher.classify_oa_status()
        publisher.save(update_fields=['oa_status'])

        # TODO: if the OA status has changed, then we should update the journals and papers accordingly with the
        # adequate task

        for link in xml.findall('./copyrightlinks/copyrightlink'):
            text = None
            url = None
            texts = link.findall('./copyrightlinktext')
            if texts:
                text = nstrip(texts[0].text)
            urls = link.findall('./copyrightlinkurl')
            if urls:
                url = nstrip(urls[0].text)
            if url and text:
                cplink = PublisherCopyrightLink(
                    text=text, url=url[:1024], publisher=publisher)
                cplink.save()

        return publisher
示例#27
0
def _book(args: Namespace, file: TextIO = sys.stdout):
    book: Optional[Book] = None
    if args.subparser == "add":
        book, created = Book.from_dict({
            "title":
            args.title,
            "authors":
            [Person.get_or_create(author).to_dict() for author in args.author],
            "series":
            Series.get_or_create(args.series).to_dict()
            if args.series else None,
            "volume":
            args.volume,
            "genres":
            [Genre.get_or_create(genre).to_dict() for genre in args.genre],
            "links":
            [Link.get_or_create(link).to_dict() for link in args.link],
        })

        if created:
            stdout.write(
                _('Successfully added book "%(title)s" with id "%(pk)d".') % {
                    "title": book.title,
                    "pk": book.pk
                },
                "=",
                file=file,
            )
            book.print(file)
        else:
            stdout.write(
                _('The book "%(title)s" already exists with id "%(pk)d", aborting...'
                  ) % {
                      "title": book.title,
                      "pk": book.pk
                  },
                "",
                file=file,
            )
    elif args.subparser == "delete":
        book = Book.get(args.book)
        if book:
            book.delete()
            stdout.write(
                _('Successfully deleted book "%(title)s" with id "%(pk)d".') %
                {
                    "title": book.title,
                    "pk": book.pk
                },
                "",
                file=file,
            )
        else:
            stdout.write(_("No book found."), "", file=file)
    elif args.subparser == "edit":
        book = Book.get(args.book)
        if book:
            book.edit(args.edit_subparser, args.value)
            stdout.write(
                _('Successfully edited book "%(title)s" with id "%(pk)d".') % {
                    "title": book.title,
                    "pk": book.pk
                },
                "=",
                file=file,
            )
            book.print(file)
        else:
            stdout.write(_("No book found."), "", file=file)
    elif args.subparser == "edition":
        book = Book.get(args.book)
        if book:
            if args.edition_subparser == "acquisition" and book:
                edition = Edition.get(args.edition, book)
                acquisition: Optional[Acquisition] = None
                if args.acquisition_subparser == "add" and edition:
                    acquisition, created = Acquisition.from_dict(
                        {
                            "date": args.date,
                            "price": args.price
                        }, edition)
                    if created:
                        stdout.write(
                            _('Successfully added acquisition with id "%(pk)d".'
                              ) % {"pk": acquisition.pk},
                            "=",
                            file=file,
                        )
                    else:
                        stdout.write(
                            _('The acquisition already exists with id "%(pk)d".'
                              ) % {"pk": acquisition.pk},
                            "",
                            file=file,
                        )
                    acquisition.print(file)
                elif args.acquisition_subparser == "delete" and edition:
                    acquisition = Acquisition.get(args.acquisition,
                                                  editions=edition)
                    if acquisition:
                        acquisition.delete(acquisition)
                        stdout.write(
                            _('Successfully deleted acquisition with id "%(pk)d".'
                              ) % {"pk": acquisition.pk},
                            "",
                            file=file,
                        )
                    else:
                        stdout.write(_("No acquisition found."), "", file=file)
                elif args.acquisition_subparser == "edit" and edition:
                    acquisition = Acquisition.get(args.acquisition,
                                                  editions=edition)
                    if acquisition:
                        acquisition.edit(args.field, args.value)
                        stdout.write(
                            _('Successfully edited acquisition with id "%(pk)d".'
                              ) % {"pk": acquisition.pk},
                            "=",
                            file=file,
                        )
                        acquisition.print(file)
                    else:
                        stdout.write(_("No acquisition found."), "", file=file)
                else:
                    stdout.write([_("No edition found.")], "", file=file)
            elif args.edition_subparser == "add" and book:
                edition, created = Edition.from_dict(
                    {
                        "alternate_title":
                        args.alternate_title,
                        "isbn":
                        args.isbn,
                        "publishing_date":
                        args.publishing_date,
                        "cover":
                        args.cover,
                        "binding":
                        Binding.get_or_create(args.binding).to_dict()
                        if args.binding else None,
                        "publisher":
                        Publisher.get_or_create(args.publisher).to_dict()
                        if args.publisher else None,
                        "persons": [
                            Person.get_or_create(person).to_dict()
                            for person in args.person
                        ],
                        "languages": [
                            Language.get_or_create(language).to_dict()
                            for language in args.language
                        ],
                        "links": [
                            Link.get_or_create(link).to_dict()
                            for link in args.link
                        ],
                        "files": [{
                            "path": file
                        } for file in args.file],
                    },
                    book,
                )
                if created:
                    stdout.write(
                        _('Successfully added edition "%(edition)s" with id "%(pk)d".'
                          ) % {
                              "edition": edition,
                              "pk": edition.pk
                          },
                        "=",
                        file=file,
                    )
                    edition.print(file)
                else:
                    stdout.write(
                        _('The edition "%(edition)s" already exists with id "%(pk)d",'
                          + " aborting...") % {
                              "edition": edition,
                              "pk": edition.pk
                          },
                        "",
                        file=file,
                    )
            elif args.edition_subparser == "edit" and book:
                edition = Edition.get(args.edition, book)
                if edition:
                    edition.edit(args.edit_subparser, args.value)
                    stdout.write(
                        _('Successfully edited edition "%(edition)s" with id "%(pk)d".'
                          ) % {
                              "edition": edition,
                              "pk": edition.pk
                          },
                        "=",
                        file=file,
                    )
                    edition.print(file)
                else:
                    stdout.write(_("No edition found."), "", file=file)
            elif args.edition_subparser == "info" and book:
                edition = Edition.get(args.edition, book)
                if edition:
                    edition.print(file)
                else:
                    stdout.write(_("No edition found."), "", file=file)
            elif args.edition_subparser == "list" and book:
                if args.shelf:
                    editions = Edition.list.by_shelf(args.shelf, book)
                elif args.search:
                    editions = Edition.list.by_term(args.search, book)
                else:
                    editions = Edition.objects.filter(book=book)
                stdout.write(
                    [
                        _("Id"),
                        _("Title"),
                        _("Binding"),
                        _("ISBN"),
                        _("Publishing date"),
                    ],
                    "=",
                    [0.05, 0.55, 0.7, 0.85],
                    file=file,
                )
                for i, has_next in lookahead(editions):
                    stdout.write(
                        [
                            i.pk,
                            i.get_title(), i.binding, i.isbn, i.publishing_date
                        ],
                        "_" if has_next else "=",
                        [0.05, 0.55, 0.7, 0.85],
                        file=file,
                    )
            elif args.edition_subparser == "open" and book:
                edition = Edition.get(args.edition, book)
                if edition:
                    edition_file = edition.files.get(pk=args.file)
                    path = settings.MEDIA_ROOT / edition_file.file.path
                    if sys.platform == "linux":
                        os.system(f'xdg-open "{path}"')
                    else:
                        os.system(f'open "{path}"')
                else:
                    stdout.write(_("No edition found."), "", file=file)
            elif args.edition_subparser == "read" and book:
                edition = Edition.get(args.edition, book)
                read: Optional[Read] = None
                if args.read_subparser == "add" and edition:
                    read, created = Read.from_dict(
                        {
                            "started": args.started,
                            "finished": args.finished
                        }, edition)
                    if created:
                        stdout.write(
                            _('Successfully added read with id "%(pk)d".') %
                            {"pk": read.pk},
                            "=",
                            file=file,
                        )
                    else:
                        stdout.write(
                            _('The read already exists with id "%(pk)d".') %
                            {"pk": read.pk},
                            "",
                            file=file,
                        )
                    read.print(file)
                elif args.read_subparser == "delete" and edition:
                    read = Read.get(args.read, editions=edition)
                    if read:
                        read.delete()
                        stdout.write(
                            _('Successfully deleted read with id "%(pk)d".') %
                            {"pk": read.pk},
                            "",
                            file=file,
                        )
                    else:
                        stdout.write(_("No read found."), "", file=file)
                elif args.read_subparser == "edit" and edition:
                    read = Read.get(args.read, editions=edition)
                    if read:
                        read.edit(args.field, args.value)
                        stdout.write(
                            _('Successfully edited read with id "%(pk)d".') %
                            {"pk": read.pk},
                            "=",
                            file=file,
                        )
                        read.info(file)
                    else:
                        stdout.write(_("No read found."), "", file=file)
                else:
                    stdout.write(_("No edition found."), "", file=file)
        else:
            stdout.write(_("No book found."), "", file=file)
    elif args.subparser == "info":
        book = Book.get(args.book)
        if book:
            book.print(file)
        else:
            stdout.write(_("No book found."), "", file=file)
    elif args.subparser == "list":
        if args.search:
            books = Book.search(args.search)
        elif args.shelf:
            books = Book.by_shelf(args.shelf)
        else:
            books = Book.objects.all()
        stdout.write(
            [_("Id"), ("Title"),
             _("Authors"),
             _("Series"),
             _("Volume")],
            "=",
            [0.05, 0.5, 0.75, 0.9],
            file=file,
        )
        for i, has_next in lookahead(books):
            stdout.write(
                [
                    i.pk,
                    i.title,
                    " ,".join(f"{a}" for a in i.authors.all()),
                    i.series.name if i.series else "",
                    i.volume,
                ],
                "_" if has_next else "=",
                [0.05, 0.5, 0.75, 0.9],
                file=file,
            )
示例#28
0
def _create_publication(paper, metadata):
    if not metadata:
        return
    if not metadata.get('container-title'):
        return
    doi = to_doi(metadata.get('DOI', None))

    title = metadata['container-title']
    if isinstance(title, list):
        title = title[0]
    title = title[:512]

    issn = metadata.get('ISSN', None)
    if issn and isinstance(issn, list):
        issn = issn[0]  # TODO pass all the ISSN to the RoMEO interface
    volume = metadata.get('volume', None)
    pages = metadata.get('page', None)
    issue = metadata.get('issue', None)
    date_dict = metadata.get('issued', dict())
    pubdate = None
    if 'date-parts' in date_dict:
        dateparts = date_dict.get('date-parts')[0]
        pubdate = date_from_dateparts(dateparts)
    # for instance it outputs dates like 2014-2-3
    publisher_name = metadata.get('publisher', None)
    if publisher_name:
        publisher_name = publisher_name[:512]

    pubtype = metadata.get('type', 'unknown')
    pubtype = CROSSREF_PUBTYPE_ALIASES.get(pubtype, pubtype)
    splash_url = doi_to_url(doi)

    # PDF availability
    pdf_url = None
    licenses = set([(license or {}).get('URL')
                    for license in metadata.get('license', [])])
    doi_prefix = doi.split('/')[0]
    if doi_prefix in free_doi_prefixes or any(map(is_oa_license, licenses)):
        pdf_url = splash_url

    # Lookup journal
    journal = Journal.find(issn=issn, title=title)

    publisher = None
    if journal:
        publisher = journal.publisher
        AliasPublisher.increment(publisher_name, journal.publisher)
    else:
        publisher = Publisher.find(publisher_name)

    barepub = BareOaiRecord(
            paper=paper,
            journal_title=title,
            issue=issue,
            volume=volume,
            pubdate=pubdate,
            pages=pages,
            doi=doi,
            pubtype=pubtype,
            publisher_name=publisher_name,
            journal=journal,
            publisher=publisher,
            pdf_url=pdf_url,
            splash_url=splash_url,
            source=OaiSource.objects.get(identifier='crossref'),
            identifier=doi_to_crossref_identifier(doi))
    rec = paper.add_oairecord(barepub)
    paper.update_availability()
    return paper, rec
示例#29
0
def _create_publication(paper, metadata):
    if not metadata:
        return
    if not metadata.get('container-title'):
        return
    doi = to_doi(metadata.get('DOI', None))

    title = metadata['container-title']
    if isinstance(title, list):
        title = title[0]
    title = title[:512]

    issn = metadata.get('ISSN', None)
    if issn and isinstance(issn, list):
        issn = issn[0]  # TODO pass all the ISSN to the RoMEO interface
    volume = metadata.get('volume', None)
    pages = metadata.get('page', None)
    issue = metadata.get('issue', None)
    date_dict = metadata.get('issued', dict())
    pubdate = None
    if 'date-parts' in date_dict:
        dateparts = date_dict.get('date-parts')[0]
        pubdate = date_from_dateparts(dateparts)
    # for instance it outputs dates like 2014-2-3
    publisher_name = metadata.get('publisher', None)
    if publisher_name:
        publisher_name = publisher_name[:512]

    pubtype = metadata.get('type', 'unknown')
    pubtype = CROSSREF_PUBTYPE_ALIASES.get(pubtype, pubtype)
    splash_url = doi_to_url(doi)

    # PDF availability
    pdf_url = None
    licenses = set([(license or {}).get('URL')
                    for license in metadata.get('license', [])])
    doi_prefix = doi.split('/')[0]
    if doi_prefix in free_doi_prefixes or any(map(is_oa_license, licenses)):
        pdf_url = splash_url

    # Lookup journal
    journal = Journal.find(issn=issn, title=title)

    publisher = None
    if journal:
        publisher = journal.publisher
        AliasPublisher.increment(publisher_name, journal.publisher)
    else:
        publisher = Publisher.find(publisher_name)

    barepub = BareOaiRecord(
        paper=paper,
        journal_title=title,
        issue=issue,
        volume=volume,
        pubdate=pubdate,
        pages=pages,
        doi=doi,
        pubtype=pubtype,
        publisher_name=publisher_name,
        journal=journal,
        publisher=publisher,
        pdf_url=pdf_url,
        splash_url=splash_url,
        source=OaiSource.objects.get(identifier='crossref'),
        identifier=doi_to_crossref_identifier(doi))
    rec = paper.add_oairecord(barepub)
    paper.update_availability()
    return paper, rec
示例#30
0
            'RoMEO did not provide the postprint policy.')

    pdfversion = None
    try:
        pdfversion = xml.findall('./pdfversion/pdfarchiving')[0].text.strip()
    except (KeyError, IndexError, AttributeError):
        raise MetadataSourceException(
            'RoMEO did not provide the pdf archiving policy.')

    # Compute OA status of the publisher
    status = 'UNK'

    publisher = Publisher(name=name,
                          alias=alias,
                          url=url,
                          preprint=preprint,
                          postprint=postprint,
                          pdfversion=pdfversion,
                          romeo_id=romeo_id,
                          oa_status=status)

    publisher.save()

    # Add the conditions, restrictions, and copyright
    for restriction in xml.findall(
            './preprints/prerestrictions/prerestriction'):
        addRestriction(restriction, 'preprint', publisher)

    for restriction in xml.findall(
            './postprints/postrestrictions/postrestriction'):
        addRestriction(restriction, 'postprint', publisher)