Example #1
0
def _acquire_entry_lock(entry, user):
    """
Acquire the lock. The caller must make sure that there is no lock yet
on the entry before calling this function.

:param entry: The entry for which to acquire the lock.
:type entry: :class:`.Entry`
:param user: The user who is acquiring the lock.
:type user: The value of :attr:`settings.AUTH_USER_MODEL` determines the class.
:returns: The lock if the lock was acquired, or ``None`` if not.
:rtype: :class:`.EntryLock`
"""
    if not transaction.is_managed():
        raise Exception("_acquire_entry_lock requires transactions to be "
                        "managed")

    lock = EntryLock()
    lock.entry = entry
    now = util.utcnow()
    lock.owner = user
    lock.datetime = now
    lock.save()

    _report(lock, "acquired")
    return lock
Example #2
0
    def update(self, user, session_key, chunk, lemma, ctype, subtype,
               note=""):
        if self.id is None and ctype != ChangeRecord.CREATE:
            raise ValueError("The Entry has no id but the ctype is not CREATE")

        self.lemma = lemma
        # save() first. So that if we have an integrity error, there is no
        # stale ChangeRecord to remove.
        self.save()

        cr = ChangeRecord(
            entry=self,
            lemma=lemma,
            user=user,
            datetime=util.utcnow(),
            session=session_key,
            ctype=ctype,
            csubtype=subtype,
            c_hash=chunk,
            note=note)

        cr.save()

        # We can't set latest before we've saved cr.
        self.latest = cr
        self.save()
Example #3
0
def _refresh_entry_lock(lock):
    """
Refresh the entry lock.

:param lock: The lock to update.
:type lock: :class:`.EntryLock`
"""
    lock.datetime = util.utcnow()
    lock.save()
    _report(lock, "refreshed")
Example #4
0
def _refresh_entry_lock(lock):
    """
Refresh the entry lock.

:param lock: The lock to update.
:type lock: :class:`.EntryLock`
"""
    lock.datetime = util.utcnow()
    lock.save()
    _report(lock, "refreshed")
Example #5
0
 def undelete(self, user):
     dr = DeletionChange(entry=self,
                         user=user,
                         ctype=DeletionChange.UNDELETE,
                         datetime=util.utcnow())
     dr.save()
     was_deleted = self.deleted
     self.deleted = False
     self.save()
     if was_deleted:
         self._send(signals.entry_available)
Example #6
0
 def mark_deleted(self, user):
     dr = DeletionChange(entry=self,
                         user=user,
                         ctype=DeletionChange.DELETE,
                         datetime=util.utcnow())
     dr.save()
     was_deleted = self.deleted
     self.deleted = True
     self.save()
     if not was_deleted:
         self._send(signals.entry_unavailable)
Example #7
0
def create_valid_article():
    data = get_valid_document_data()

    now = util.utcnow()

    client = Client()
    add_raw_url = reverse("full-admin:lexicography_entry_rawnew")
    assert client.login(username='******', password='******')
    response = client.post(add_raw_url, {"data": data})
    assert response.status_code == 302,\
        "response was " + str(response.status_code)
    return Entry.objects.get(latest__datetime__gte=now)
Example #8
0
def create_valid_article():
    data = get_valid_document_data()

    now = util.utcnow()

    client = Client()
    add_raw_url = reverse("full-admin:lexicography_entry_rawnew")
    assert client.login(username='******', password='******')
    response = client.post(add_raw_url, {"data": data})
    assert response.status_code == 302,\
        "response was " + str(response.status_code)
    return Entry.objects.get(latest__datetime__gte=now)
Example #9
0
 def mark_deleted(self, user):
     dr = DeletionChange(
         entry=self,
         user=user,
         ctype=DeletionChange.DELETE,
         datetime=util.utcnow()
     )
     dr.save()
     was_deleted = self.deleted
     self.deleted = True
     self.save()
     if not was_deleted:
         self._send(signals.entry_unavailable)
Example #10
0
def update_entry(request, entry, chunk, xmltree, ctype, subtype):
    cr = ChangeRecord()
    cr.entry = entry
    entry.copy_to(cr)
    entry.headword = xmltree.extract_headword()
    entry.user = request.user
    entry.datetime = util.utcnow()
    entry.session = request.session.session_key
    entry.ctype = ctype
    entry.csubtype = subtype
    entry.c_hash = chunk
    cr.save()
    entry.save()
Example #11
0
 def undelete(self, user):
     dr = DeletionChange(
         entry=self,
         user=user,
         ctype=DeletionChange.UNDELETE,
         datetime=util.utcnow()
     )
     dr.save()
     was_deleted = self.deleted
     self.deleted = False
     self.save()
     if was_deleted:
         self._send(signals.entry_available)
Example #12
0
def _refresh_entry_lock(lock):
    """
Refresh the entry lock. This function requires manual transaction to
be enabled.

:param lock: The lock to update.
:type lock: :class:`.EntryLock`
"""
    if not transaction.is_managed():
        raise Exception("refresh_entry_lock requires transactions to be "
                        "managed")
    lock.datetime = util.utcnow()
    lock.save()
    _report(lock, "refreshed")
Example #13
0
    def test_now_works(self):
        """
        ``now`` evaluates to something useful and does not change once
        evaluated.
        """
        cleaner = Cleaner()
        then = cleaner.now
        time.sleep(1)

        # We can perform date arithmetics with it.
        self.assertTrue(then - utcnow() < datetime.timedelta(minutes=1))

        # It does not change.
        self.assertEqual(then, cleaner.now)
Example #14
0
    def test_now_works(self):
        """
        ``now`` evaluates to something useful and does not change once
        evaluated.
        """
        cleaner = Cleaner()
        then = cleaner.now
        time.sleep(1)

        # We can perform date arithmetics with it.
        self.assertTrue(then - utcnow() < datetime.timedelta(minutes=1))

        # It does not change.
        self.assertEqual(then, cleaner.now)
Example #15
0
    def unpublish(self, user):
        if self.published:
            if not self.can_publish(user):
                raise PermissionDenied

            self.published = False
            self.save()
            pc = PublicationChange(changerecord=self,
                                   ctype=PublicationChange.UNPUBLISH,
                                   user=user,
                                   datetime=util.utcnow())
            pc.save()
            # pylint: disable=protected-access
            self.entry._update_latest_published()
            return True
        return False
Example #16
0
    def unpublish(self, user):
        if self.published:
            if not self.can_publish(user):
                raise PermissionDenied

            self.published = False
            self.save()
            pc = PublicationChange(changerecord=self,
                                   ctype=PublicationChange.UNPUBLISH,
                                   user=user,
                                   datetime=util.utcnow())
            pc.save()
            # pylint: disable=protected-access
            self.entry._update_latest_published()
            return True
        return False
Example #17
0
    def test_fetch_items(self):
        """
        Tests that the task populates the Item table and that FETCH_KEY
        and FETCH_KEY are set appropriately.
        """
        self.assertIsNone(cache.get(tasks.FETCH_KEY))
        self.assertIsNone(cache.get(tasks.FETCH_DATE_KEY))
        items = Item.objects.all()
        self.assertEqual(items.count(), 0)

        tasks.fetch_items.delay().get()
        self.assertIsNone(cache.get(tasks.FETCH_KEY))
        last_fetch = cache.get(tasks.FETCH_DATE_KEY)
        self.assertTrue(utcnow() - last_fetch < datetime.timedelta(seconds=5))

        items = Item.objects.all()
        self.assertEqual(items.count(), 47)
Example #18
0
    def test_fetch_items(self):
        """
        Tests that the task populates the Item table and that FETCH_KEY
        and FETCH_KEY are set appropriately.
        """
        self.assertIsNone(cache.get(tasks.FETCH_KEY))
        self.assertIsNone(cache.get(tasks.FETCH_DATE_KEY))
        items = Item.objects.all()
        self.assertEqual(items.count(), 0)

        tasks.fetch_items.delay().get()
        self.assertIsNone(cache.get(tasks.FETCH_KEY))
        last_fetch = cache.get(tasks.FETCH_DATE_KEY)
        self.assertTrue(utcnow() - last_fetch < datetime.timedelta(seconds=5))

        items = Item.objects.all()
        self.assertEqual(items.count(), 47)
Example #19
0
 def test_unpublish_creates_publication_change(self):
     """
     Unpublishing a change record creates a new PublicationChange.
     """
     entry = self.valid
     latest = entry.latest
     self.assertTrue(latest.publish(self.foo))
     old_count = PublicationChange.objects.filter(
         changerecord=latest).count()
     self.assertTrue(latest.unpublish(self.foo))
     self.assertEqual(
         PublicationChange.objects.filter(changerecord=latest).count(),
         old_count + 1)
     latest_pc = PublicationChange.objects.latest('datetime')
     self.assertEqual(latest_pc.changerecord, latest)
     self.assertEqual(latest_pc.ctype, PublicationChange.UNPUBLISH)
     self.assertEqual(latest_pc.user, self.foo)
     # The timedelta is arbitrary.
     self.assertTrue(util.utcnow() -
                     latest_pc.datetime <= datetime.timedelta(seconds=5))
Example #20
0
 def test_unpublish_creates_publication_change(self):
     """
     Unpublishing a change record creates a new PublicationChange.
     """
     entry = self.valid
     latest = entry.latest
     self.assertTrue(latest.publish(self.foo))
     old_count = PublicationChange.objects.filter(
         changerecord=latest).count()
     self.assertTrue(latest.unpublish(self.foo))
     self.assertEqual(
         PublicationChange.objects.filter(changerecord=latest).count(),
         old_count + 1)
     latest_pc = PublicationChange.objects.latest('datetime')
     self.assertEqual(latest_pc.changerecord, latest)
     self.assertEqual(latest_pc.ctype, PublicationChange.UNPUBLISH)
     self.assertEqual(latest_pc.user, self.foo)
     # The timedelta is arbitrary.
     self.assertTrue(util.utcnow() -
                     latest_pc.datetime <= datetime.timedelta(seconds=5))
Example #21
0
def _acquire_entry_lock(entry, user):
    """
Acquire the lock. The caller must make sure that there is no lock yet
on the entry before calling this function.

:param entry: The entry for which to acquire the lock.
:type entry: :class:`.Entry`
:param user: The user who is acquiring the lock.
:type user: The value of :attr:`settings.AUTH_USER_MODEL` determines the class.
:returns: The lock if the lock was acquired, or ``None`` if not.
:rtype: :class:`.EntryLock`
"""
    lock = EntryLock()
    lock.entry = entry
    now = util.utcnow()
    lock.owner = user
    lock.datetime = now
    lock.save()

    _report(lock, "acquired")
    return lock
Example #22
0
    def test_edit(self):
        """
        Tests that a user with editing rights can edit an entry obtained
        by searching.
        """
        response, old_entry = self.open_abcd('foo')

        nr_changes = ChangeRecord.objects.filter(entry=old_entry).count()

        messages, data = self.save(response, 'foo')

        self.assertEqual(len(messages), 1)
        self.assertIn("save_successful", messages)

        self.assertEqual(ChangeRecord.objects.filter(entry=old_entry).count(),
                         nr_changes + 1,
                         "there is one and only one additional record change")

        # Check that we recorded the right thing.
        entry = Entry.objects.get(pk=old_entry.pk)
        self.assertEqual(entry.user, self.foo)
        # The delay used here is arbitrary
        self.assertTrue(util.utcnow() -
                        entry.datetime <= datetime.timedelta(minutes=1))
        self.assertEqual(entry.session, self.app.session.session_key)
        self.assertEqual(entry.ctype, entry.UPDATE)
        self.assertEqual(entry.csubtype, entry.MANUAL)

        # Check the chunk
        self.assertEqual(entry.c_hash.data, data)
        self.assertTrue(entry.c_hash.is_normal)

        # Check that the lastest ChangeRecord corresponds to the old_entry
        change = ChangeRecord.objects.filter(entry=old_entry) \
                                     .order_by('-datetime')[0]

        # pylint: disable=W0212
        for i in ChangeInfo._meta.get_all_field_names():
            self.assertEqual(getattr(old_entry, i), getattr(change, i))
Example #23
0
def try_updating_entry(request, entry, chunk, xmltree, ctype, subtype):
    if not transaction.is_managed():
        raise Exception("try_updating_entry requires transactions to be "
                        "managed")
    chunk.save()
    if entry.id is None:
        entry.headword = xmltree.extract_headword()
        entry.user = request.user
        entry.datetime = util.utcnow()
        entry.session = request.session.session_key
        entry.ctype = Entry.CREATE
        entry.csubtype = subtype
        entry.c_hash = chunk
        entry.save()
        if try_acquiring_lock(entry, request.user) is None:
            raise Exception("unable to acquire the lock of an entry "
                            "that was just created but not committed!")
    else:
        if try_acquiring_lock(entry, request.user) is None:
            return False
        update_entry(request, entry, chunk, xmltree, ctype, subtype)
    return True
Example #24
0
 def test_publish_creates_publication_change(self):
     """
     Publishing a change record creates a new PublicationChange.
     """
     entry = self.valid
     latest = entry.latest
     old_count = PublicationChange.objects.filter(
         changerecord=latest).count()
     self.assertFalse(latest.published,
                      "The change record we are about to use must not be "
                      "published yet.")
     self.assertTrue(latest.publish(self.foo))
     self.assertEqual(
         PublicationChange.objects.filter(changerecord=latest).count(),
         old_count + 1)
     latest_pc = PublicationChange.objects.latest('datetime')
     self.assertEqual(latest_pc.changerecord, latest)
     self.assertEqual(latest_pc.ctype, PublicationChange.PUBLISH)
     self.assertEqual(latest_pc.user, self.foo)
     # The timedelta is arbitrary.
     self.assertTrue(util.utcnow() -
                     latest_pc.datetime <= datetime.timedelta(seconds=5))
Example #25
0
 def test_publish_creates_publication_change(self):
     """
     Publishing a change record creates a new PublicationChange.
     """
     entry = self.valid
     latest = entry.latest
     old_count = PublicationChange.objects.filter(
         changerecord=latest).count()
     self.assertFalse(
         latest.published,
         "The change record we are about to use must not be "
         "published yet.")
     self.assertTrue(latest.publish(self.foo))
     self.assertEqual(
         PublicationChange.objects.filter(changerecord=latest).count(),
         old_count + 1)
     latest_pc = PublicationChange.objects.latest('datetime')
     self.assertEqual(latest_pc.changerecord, latest)
     self.assertEqual(latest_pc.ctype, PublicationChange.PUBLISH)
     self.assertEqual(latest_pc.user, self.foo)
     # The timedelta is arbitrary.
     self.assertTrue(util.utcnow() -
                     latest_pc.datetime <= datetime.timedelta(seconds=5))
Example #26
0
def fetch_the_items(task, test=None):
    """
    Fetch the bibliographical items from the Zotero database.
    """

    if test is None:
        test = {}

    # There's another task running.
    if task.request.id is not None and \
       not acquire_mutex(cache, FETCH_KEY, task.request.id, logger):
        return

    # Simulate a task that mysteriously stops working after it has
    # claimed the key.
    if test.get("vanish"):
        return

    # Simulate a task that fails due to an exception.
    if test.get("fail"):
        raise Exception("failing")

    logger.info("fetching all bibliographical items")
    search_results = btw_zotero.get_all()
    for result in search_results:
        key = result["data"]["key"]
        try:
            item = Item.objects.get(item_key=key)
            item.refresh(result)
        except Item.DoesNotExist:
            item = Item(item_key=key, uid=btw_zotero.full_uid)
            item.refresh(result)

    # We're done
    cache.set(FETCH_DATE_KEY, utcnow())
    cache.delete(FETCH_KEY)
Example #27
0
def fetch_the_items(task, test=None):
    """
    Fetch the bibliographical items from the Zotero database.
    """

    if test is None:
        test = {}

    # There's another task running.
    if task.request.id is not None and \
       not acquire_mutex(cache, FETCH_KEY, task.request.id, logger):
        return

    # Simulate a task that mysteriously stops working after it has
    # claimed the key.
    if test.get("vanish"):
        return

    # Simulate a task that fails due to an exception.
    if test.get("fail"):
        raise Exception("failing")

    logger.info("fetching all bibliographical items")
    search_results = btw_zotero.get_all()
    for result in search_results:
        key = result["data"]["key"]
        try:
            item = Item.objects.get(item_key=key)
            item.refresh(result)
        except Item.DoesNotExist:
            item = Item(item_key=key, uid=btw_zotero.full_uid)
            item.refresh(result)

    # We're done
    cache.set(FETCH_DATE_KEY, utcnow())
    cache.delete(FETCH_KEY)
Example #28
0
    def update(self, user, session_key, chunk, lemma, ctype, subtype, note=""):
        if self.id is None and ctype != ChangeRecord.CREATE:
            raise ValueError("The Entry has no id but the ctype is not CREATE")

        self.lemma = lemma
        # save() first. So that if we have an integrity error, there is no
        # stale ChangeRecord to remove.
        self.save()

        cr = ChangeRecord(entry=self,
                          lemma=lemma,
                          user=user,
                          datetime=util.utcnow(),
                          session=session_key,
                          ctype=ctype,
                          csubtype=subtype,
                          c_hash=chunk,
                          note=note)

        cr.save()

        # We can't set latest before we've saved cr.
        self.latest = cr
        self.save()
Example #29
0
    def make_records(self):
        to_clean = []
        to_keep = []

        #
        # entry1: Generic cases...
        #
        entry1 = Entry()

        # Old and unpublished...
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        # ... but not right type.
        to_keep.append(entry1.latest)

        # Old, unpublished, not of a proscribed type: will be cleaned
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.RECOVERY)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        to_clean.append(entry1.latest)

        # Old, unpublished, not of a proscribed type: will be cleaned
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        to_clean.append(entry1.latest)

        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        self.assertTrue(entry1.latest.publish(self.foo))

        # Published, won't be cleaned
        to_keep.append(entry1.latest)

        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        # Too recent.
        to_keep.append(entry1.latest)

        entry1 = None  # Make sure we cannot access it again.

        #
        # entry3: We keep the latest record.

        entry3 = Entry()
        entry3.update(
            self.foo,
            "q",
            self.chunk,
            "foo3",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        # Keep, not right type, and too young.
        to_keep.append(entry3.latest)

        entry3.update(
            self.foo,
            "q",
            self.chunk,
            "foo3",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry3.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry3.latest.save()
        # Clean: meets all requirements and is not latest.
        to_clean.append(entry3.latest)

        entry3.update(
            self.foo,
            "q",
            self.chunk,
            "foo3",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry3.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry3.latest.save()
        # Keep the latest.
        to_keep.append(entry3.latest)

        entry3 = None

        #
        # entry4: Already partially hidden.
        #

        entry4 = Entry()
        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        to_keep.append(entry4.latest)

        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry4.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry4.latest.hidden = True
        entry4.latest.save()
        # This is neither to_keep nor to_clean.

        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry4.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry4.latest.save()
        to_clean.append(entry4.latest)

        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry4.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry4.latest.save()
        to_keep.append(entry4.latest)

        return to_clean, to_keep
Example #30
0
 def expired(self):
     """
     True if the invitation has expired. False if not.
     """
     return util.utcnow() - self.creation_date >= \
         Invitation.objects.expiration_delay
Example #31
0
 def expired(self):
     """
     True if the invitation has expired. False if not.
     """
     return util.utcnow() - self.creation_date >= \
         Invitation.objects.expiration_delay
Example #32
0
 def make_success_obj(self, cleaner):
     e = self.entry
     e.latest.datetime = utcnow() - datetime.timedelta(days=2)
     return e.latest
Example #33
0
    def create_document(self, what):
        add_raw_url = reverse("full-admin:lexicography_entry_rawnew")
        from lexicography.tests.util import get_valid_document_data
        data = get_valid_document_data()
        publish = True

        if what == "valid article":
            xmltree = XMLTree(data)
        elif what in ("valid article, with one author",
                      "valid article, with two authors",
                      "valid article, with three authors",
                      "valid article, with four authors"):
            total_authors = {
                "valid article, with one author": 1,
                "valid article, with two authors": 2,
                "valid article, with three authors": 3,
                "valid article, with four authors": 4
            }[what]

            publish = True
            xmltree = XMLTree(data)
            authors = xmltree.tree.xpath("//btw:credit",
                                         namespaces=default_namespace_mapping)

            assert len(authors) == 2
            if total_authors == 1:
                authors[1].getparent().remove(authors[1])
            elif total_authors == 2:
                pass
            else:
                btw_credits = authors[0].getparent()
                for number in range(len(authors) + 1, total_authors + 1):
                    btw_credits.append(
                        lxml.etree.XML("""
<btw:credit xmlns="{0}" xmlns:btw="{1}">
  <resp>Resp</resp>
    <persName><forename>Forename {2}</forename><surname>Surname {2}</surname>\
    <genName>GenName {2}</genName></persName>
</btw:credit>""".format(tei_namespace, btw_namespace, number)))

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        elif what in ("valid article, with one editor",
                      "valid article, with two editors",
                      "valid article, with three editors",
                      "valid article, with four editors"):
            total_editors = {
                "valid article, with one editor": 1,
                "valid article, with two editors": 2,
                "valid article, with three editors": 3,
                "valid article, with four editors": 4
            }[what]

            publish = True
            xmltree = XMLTree(data)
            editors = xmltree.tree.xpath("//tei:editor",
                                         namespaces=default_namespace_mapping)

            assert len(editors) == 1
            if total_editors == 1:
                pass
            else:
                btw_credits = editors[0].getparent()
                for number in range(len(editors) + 1, total_editors + 1):
                    btw_credits.append(
                        lxml.etree.XML("""
<editor xmlns="{0}">
  <persName><forename>Forename {1}</forename><surname>Surname {1}</surname>\
  <genName>GenName {1}</genName></persName>
</editor>""".format(tei_namespace, number)))

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        elif what in ("valid article, with bad semantic fields",
                      "valid article, with good semantic fields"):
            publish = False
            xmltree = XMLTree(data)
            sfs = xmltree.tree.xpath("//btw:sf",
                                     namespaces=default_namespace_mapping)
            ix = 0
            cases = invalid_sf_cases if what.endswith("bad semantic fields") \
                else valid_sf_cases
            for case in cases:
                sfs[ix].text = case
                ix += 1

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        else:
            print("Unknown document: ", what)

        from lexicography.models import Entry
        try:
            entry = Entry.objects.get(lemma=xmltree.extract_lemma())
        except Entry.DoesNotExist:
            entry = None

        if entry is None:
            User = get_user_model()
            foo = User.objects.get(username='******')

            now = util.utcnow()

            client = Client()
            assert client.login(username='******', password='******')
            response = client.post(add_raw_url, {"data": data})
            assert response.status_code == 302
            entry = Entry.objects.get(latest__datetime__gte=now)

        if publish:
            assert entry.latest.publish(foo)
        with open(self.__control_write, 'w') as out:
            out.write(entry.lemma + "\n")
Example #34
0
 def expirable(self):
     """
     :returns: ``True`` if the lock is expirable, ``False`` if not.
     :rtype: :class:`bool`
     """
     return util.utcnow() - self.datetime > LEXICOGRAPHY_LOCK_EXPIRY
Example #35
0
    def make_records(self):
        to_clean = []
        to_keep = []

        #
        # entry1: Generic cases...
        #
        entry1 = Entry()

        # Old and unpublished...
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        # ... but not right type.
        to_keep.append(entry1.latest)

        # Old, unpublished, not of a proscribed type: will be cleaned
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        to_clean.append(entry1.latest)

        # Old, unpublished, not of a proscribed type: will be cleaned
        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        to_clean.append(entry1.latest)

        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.AUTOMATIC)
        entry1.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry1.latest.save()
        self.assertTrue(entry1.latest.publish(self.foo))

        # Published
        to_keep.append(entry1.latest)

        entry1.update(
            self.foo,
            "q",
            self.chunk,
            "foo",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        # Too recent.
        to_keep.append(entry1.latest)

        entry1 = None  # Make sure we cannot access it again.

        #
        # entry2: Make sure that we favor keeping CREATE records.
        #
        entry2 = Entry()

        # Old and unpublished...
        entry2.update(
            self.foo,
            "q",
            self.chunk,
            "foo2",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        entry2.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry2.latest.save()
        # ... but not right type.
        to_keep.append(entry2.latest)

        entry2.update(
            self.foo,
            "q",
            self.chunk,
            "foo2",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        entry2.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry2.latest.save()
        # The CREATE record is favored.
        to_clean.append(entry2.latest)

        entry2 = None

        #
        # entry3: everything is eligible for collpasing. We elect the
        # newest record to keep. See the comments in the code of the
        # class. This should be an unusual case, but we test it here.
        #

        entry3 = Entry()
        entry3.update(
            self.foo,
            "q",
            self.chunk,
            "foo3",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        # We cannot call .update above with a type of UPDATE. The
        # system is *designed* to prevent doing so. (It prevents
        # creating a new record with ctype UPDATE! So we munge it.
        entry3.latest.ctype = ChangeRecord.UPDATE
        entry3.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry3.latest.save()
        # We clean the oldest record.
        to_clean.append(entry3.latest)

        entry3.update(
            self.foo,
            "q",
            self.chunk,
            "foo3",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        entry3.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry3.latest.save()
        # Keep the newest.
        to_keep.append(entry3.latest)

        entry3 = None

        #
        # entry4: Already partially hidden.
        #

        entry4 = Entry()
        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.CREATE,
            ChangeRecord.MANUAL)
        to_keep.append(entry4.latest)

        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        entry4.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry4.latest.hidden = True
        entry4.latest.save()
        # This is neither to_keep nor to_clean.

        entry4.update(
            self.foo,
            "q",
            self.chunk,
            "foo4",
            ChangeRecord.UPDATE,
            ChangeRecord.MANUAL)
        entry4.latest.datetime = utcnow() - datetime.timedelta(days=2)
        entry4.latest.save()
        to_clean.append(entry4.latest)

        return to_clean, to_keep
Example #36
0
    def create_document(self, what):
        add_raw_url = reverse("full-admin:lexicography_entry_rawnew")
        from lexicography.tests.util import get_valid_document_data
        data = get_valid_document_data()
        publish = True

        if what == "valid article":
            xmltree = XMLTree(data)
        elif what in ("valid article, with one author",
                      "valid article, with two authors",
                      "valid article, with three authors",
                      "valid article, with four authors"):
            total_authors = {
                "valid article, with one author": 1,
                "valid article, with two authors": 2,
                "valid article, with three authors": 3,
                "valid article, with four authors": 4
            }[what]

            publish = True
            xmltree = XMLTree(data)
            authors = xmltree.tree.xpath("//btw:credit",
                                         namespaces=default_namespace_mapping)

            assert len(authors) == 2
            if total_authors == 1:
                authors[1].getparent().remove(authors[1])
            elif total_authors == 2:
                pass
            else:
                btw_credits = authors[0].getparent()
                for number in xrange(len(authors) + 1, total_authors + 1):
                    btw_credits.append(lxml.etree.XML("""
<btw:credit xmlns="{0}" xmlns:btw="{1}">
  <resp>Resp</resp>
    <persName><forename>Forename {2}</forename><surname>Surname {2}</surname>\
    <genName>GenName {2}</genName></persName>
</btw:credit>""".format(tei_namespace, btw_namespace, number)))

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        elif what in ("valid article, with one editor",
                      "valid article, with two editors",
                      "valid article, with three editors",
                      "valid article, with four editors"):
            total_editors = {
                "valid article, with one editor": 1,
                "valid article, with two editors": 2,
                "valid article, with three editors": 3,
                "valid article, with four editors": 4
            }[what]

            publish = True
            xmltree = XMLTree(data)
            editors = xmltree.tree.xpath("//tei:editor",
                                         namespaces=default_namespace_mapping)

            assert len(editors) == 1
            if total_editors == 1:
                pass
            else:
                btw_credits = editors[0].getparent()
                for number in xrange(len(editors) + 1, total_editors + 1):
                    btw_credits.append(lxml.etree.XML("""
<editor xmlns="{0}">
  <persName><forename>Forename {1}</forename><surname>Surname {1}</surname>\
  <genName>GenName {1}</genName></persName>
</editor>""".format(tei_namespace, number)))

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        elif what in ("valid article, with bad semantic fields",
                      "valid article, with good semantic fields"):
            publish = False
            xmltree = XMLTree(data)
            sfs = xmltree.tree.xpath("//btw:sf",
                                     namespaces=default_namespace_mapping)
            ix = 0
            cases = invalid_sf_cases if what.endswith("bad semantic fields") \
                else valid_sf_cases
            for case in cases:
                sfs[ix].text = case
                ix += 1

            xmltree.alter_lemma(what)
            data = xmltree.serialize()
        else:
            print "Unknown document: ", what

        from lexicography.models import Entry
        try:
            entry = Entry.objects.get(lemma=xmltree.extract_lemma())
        except Entry.DoesNotExist:
            entry = None

        if entry is None:
            User = get_user_model()
            foo = User.objects.get(username='******')

            now = util.utcnow()

            client = Client()
            assert client.login(username='******', password='******')
            response = client.post(add_raw_url, {"data": data})
            assert response.status_code == 302
            entry = Entry.objects.get(latest__datetime__gte=now)

        if publish:
            assert entry.latest.publish(foo)
        with open(self.__control_write, 'w') as out:
            out.write(entry.lemma.encode('utf-8') + "\n")
Example #37
0
 def is_expirable(self):
     """
     :returns: ``True`` if the lock is expirable, ``False`` if not.
     :rtype: :class:`bool`
     """
     return util.utcnow() - self.datetime > LEXICOGRAPHY_LOCK_EXPIRY