Exemplo n.º 1
0
 def order(facet, work, edition, ascending=None):
     f = Facets(
         collection=Facets.COLLECTION_FULL,
         availability=Facets.AVAILABLE_ALL,
         order=facet,
         order_ascending=ascending,
     )
     return f.order_by(work, edition)[0]
    def test_refusal_to_create_expensive_feed(self):

        facets = Facets.default()
        pagination = Pagination.default()
        lane = Lane(self._db, "My Lane", languages=['eng', 'chi'])

        args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None)

        # If we ask for a group feed that will be cached forever, and it's
        # not around, we'll get a page feed instead.
        feed, fresh = CachedFeed.fetch(*args,
                                       max_age=Configuration.CACHE_FOREVER)
        eq_(CachedFeed.PAGE_TYPE, feed.type)

        # If we ask for the same feed, but we don't say it must be cached
        # forever, it'll be created.
        feed, fresh = CachedFeed.fetch(*args, max_age=0)

        # Or if we explicitly demand that the feed be created, it will
        # be created.
        feed, fresh = CachedFeed.fetch(*args,
                                       force_refresh=True,
                                       max_age=Configuration.CACHE_FOREVER)
        feed.update("Cache this forever!")

        # Once the feed has content associated with it, we can ask for
        # it in cached-forever mode and no longer get the exception.
        feed, fresh = CachedFeed.fetch(*args,
                                       max_age=Configuration.CACHE_FOREVER)
        eq_("Cache this forever!", feed.content)
    def test_lifecycle(self):
        facets = Facets.default()
        pagination = Pagination.default()
        lane = Lane(self._db, "My Lane", languages=['eng', 'chi'])

        # Fetch a cached feed from the database--it's empty.
        args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None)
        feed, fresh = CachedFeed.fetch(*args, max_age=0)

        eq_(False, fresh)
        eq_(None, feed.content)

        eq_(pagination.query_string, feed.pagination)
        eq_(facets.query_string, feed.facets)
        eq_(lane.name, feed.lane_name)
        eq_('eng,chi', feed.languages)

        # Update the content
        feed.update("The content")
        self._db.commit()

        # Fetch it again.
        feed, fresh = CachedFeed.fetch(*args, max_age=0)

        # Now it's cached! But not fresh, because max_age is zero
        eq_("The content", feed.content)
        eq_(False, fresh)

        # Lower our standards, and it's fresh!
        feed, fresh = CachedFeed.fetch(*args, max_age=1000)
        eq_("The content", feed.content)
        eq_(True, fresh)
Exemplo n.º 4
0
    def test_fetch_ignores_feeds_without_content(self):
        facets = Facets.default(self._default_library)
        pagination = Pagination.default()
        lane = self._lane(u"My Lane", languages=['eng', 'chi'])

        # Create a feed without content (i.e. don't update it)
        contentless_feed = get_one_or_create(
            self._db,
            CachedFeed,
            lane_id=lane.id,
            type=CachedFeed.PAGE_TYPE,
            facets=unicode(facets.query_string),
            pagination=unicode(pagination.query_string))[0]

        # It's not returned because it hasn't been updated.
        args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None)
        feed, fresh = CachedFeed.fetch(*args)
        eq_(True, feed != contentless_feed)
        eq_(False, fresh)

        # But if the feed is updated, we get it back.
        feed.update(self._db, u"Just feedy things")
        result, fresh = CachedFeed.fetch(*args)
        eq_(True, fresh)
        eq_(feed, result)
Exemplo n.º 5
0
    def test_lifecycle_with_worklist(self):
        facets = Facets.default(self._default_library)
        pagination = Pagination.default()
        lane = WorkList()
        lane.initialize(self._default_library)

        # Fetch a cached feed from the database--it's empty.
        args = (self._db, lane, CachedFeed.PAGE_TYPE, facets, pagination, None)
        feed, fresh = CachedFeed.fetch(*args, max_age=0)

        eq_(False, fresh)
        eq_(None, feed.content)

        eq_(pagination.query_string, feed.pagination)
        eq_(facets.query_string, feed.facets)
        eq_(None, feed.lane_id)

        # Update the content
        feed.update(self._db, u"The content")
        self._db.commit()

        # Fetch it again.
        feed, fresh = CachedFeed.fetch(*args, max_age=0)

        # Now it's cached! But not fresh, because max_age is zero
        eq_("The content", feed.content)
        eq_(False, fresh)

        # Lower our standards, and it's fresh!
        feed, fresh = CachedFeed.fetch(*args, max_age=1000)
        eq_("The content", feed.content)
        eq_(True, fresh)
Exemplo n.º 6
0
def load_facets(order, availability, collection, config=Configuration):
    """Turn user input into a Facets object."""
    order_facets = config.enabled_facets(Facets.ORDER_FACET_GROUP_NAME)
    if order and not order in order_facets:
        return INVALID_INPUT.detailed(
            _("I don't know how to order a feed by '%(order)s'", order=order),
            400)
    availability_facets = config.enabled_facets(
        Facets.AVAILABILITY_FACET_GROUP_NAME)
    if availability and not availability in availability_facets:
        return INVALID_INPUT.detailed(
            _("I don't understand the availability term '%(availability)s'",
              availability=availability), 400)

    collection_facets = config.enabled_facets(
        Facets.COLLECTION_FACET_GROUP_NAME)
    if collection and not collection in collection_facets:
        return INVALID_INPUT.detailed(
            _("I don't understand which collection '%(collection)s' refers to.",
              collection=collection), 400)

    enabled_facets = {
        Facets.ORDER_FACET_GROUP_NAME: order_facets,
        Facets.AVAILABILITY_FACET_GROUP_NAME: availability_facets,
        Facets.COLLECTION_FACET_GROUP_NAME: collection_facets,
    }

    return Facets(collection=collection,
                  availability=availability,
                  order=order,
                  enabled_facets=enabled_facets)
Exemplo n.º 7
0
    def test_facet_groups(self):

        facets = Facets(
            Facets.COLLECTION_MAIN, Facets.AVAILABLE_ALL, Facets.ORDER_TITLE
        )
        all_groups = list(facets.facet_groups)

        # By default, there are a 9 facet transitions: three groups of three.
        eq_(9, len(all_groups))

        # available=all, collection=main, and order=title are the selected
        # facets.
        selected = sorted([x[:2] for x in all_groups if x[-1] == True])
        eq_(
            [('available', 'all'), ('collection', 'main'), ('order', 'title')],
            selected
        )

        test_facet_policy = {
            "enabled" : {
                Facets.ORDER_FACET_GROUP_NAME : [
                    Facets.ORDER_WORK_ID, Facets.ORDER_TITLE
                ],
                Facets.COLLECTION_FACET_GROUP_NAME : [Facets.COLLECTION_FULL],
                Facets.AVAILABILITY_FACET_GROUP_NAME : [Facets.AVAILABLE_ALL],
            },
            "default" : {
                Facets.ORDER_FACET_GROUP_NAME : Facets.ORDER_TITLE,
                Facets.COLLECTION_FACET_GROUP_NAME : Facets.COLLECTION_FULL,
                Facets.AVAILABILITY_FACET_GROUP_NAME : Facets.AVAILABLE_ALL,
            }
        }
        with temp_config() as config:
            config['policies'] = {
                Configuration.FACET_POLICY : test_facet_policy
            }
            facets = Facets(None, None, Facets.ORDER_TITLE)
            all_groups = list(facets.facet_groups)

            # We have disabled almost all the facets, so the list of
            # facet transitions includes only two items.
            #
            # 'Sort by title' was selected, and it shows up as the selected
            # item in this facet group.
            expect = [['order', 'title', True], ['order', 'work_id', False]]
            eq_(expect, sorted([list(x[:2]) + [x[-1]] for x in all_groups]))
Exemplo n.º 8
0
    def test_facets_can_be_enabled_at_initialization(self):
        enabled_facets = {
            Facets.ORDER_FACET_GROUP_NAME: [
                Facets.ORDER_TITLE,
                Facets.ORDER_AUTHOR,
            ],
            Facets.COLLECTION_FACET_GROUP_NAME: [Facets.COLLECTION_MAIN],
            Facets.AVAILABILITY_FACET_GROUP_NAME:
            [Facets.AVAILABLE_OPEN_ACCESS]
        }

        # Create a new Facets object with these facets enabled,
        # no matter the Configuration.
        facets = Facets(Facets.COLLECTION_MAIN,
                        Facets.AVAILABLE_OPEN_ACCESS,
                        Facets.ORDER_TITLE,
                        enabled_facets=enabled_facets)
        all_groups = list(facets.facet_groups)
        expect = [['order', 'author', False], ['order', 'title', True]]
        eq_(expect, sorted([list(x[:2]) + [x[-1]] for x in all_groups]))
Exemplo n.º 9
0
 def facetify(collection=Facets.COLLECTION_FULL,
              available=Facets.AVAILABLE_ALL,
              order=Facets.ORDER_TITLE):
     f = Facets(collection, available, order)
     return f.apply(self._db, qu)
Exemplo n.º 10
0
 def fields(facet):
     return [
         Facets.order_facet_to_database_field(facet, w, e)
         for w, e in ((Work, Edition), (mw, mw), (mwg, mwg))
     ]
Exemplo n.º 11
0
    def page(cls, _db, title, url, lane, annotator=None,
             facets=None, pagination=None,
             cache_type=None, force_refresh=False,
             use_materialized_works=True
    ):
        """Create a feed representing one page of works from a given lane."""
        facets = facets or Facets.default()
        pagination = pagination or Pagination.default()
        cache_type = cache_type or CachedFeed.PAGE_TYPE

        # Find or create a CachedFeed.
        cached, usable = CachedFeed.fetch(
            _db,
            lane=lane,
            type=cache_type,
            facets=facets,
            pagination=pagination,
            annotator=annotator,
            force_refresh=force_refresh
        )
        if usable:
            return cached

        if use_materialized_works:
            works_q = lane.materialized_works(facets, pagination)
        else:
            works_q = lane.works(facets, pagination)

        if not works_q:
            works = []
        else:
            works = works_q.all()
        feed = cls(_db, title, url, works, annotator)

        # Add URLs to change faceted views of the collection.
        for args in cls.facet_links(annotator, facets):
            OPDSFeed.add_link_to_feed(feed=feed.feed, **args)

        if len(works) > 0:
            # There are works in this list. Add a 'next' link.
            OPDSFeed.add_link_to_feed(feed=feed.feed, rel="next", href=annotator.feed_url(lane, facets, pagination.next_page))

        if pagination.offset > 0:
            OPDSFeed.add_link_to_feed(feed=feed.feed, rel="first", href=annotator.feed_url(lane, facets, pagination.first_page))

        previous_page = pagination.previous_page
        if previous_page:
            OPDSFeed.add_link_to_feed(feed=feed.feed, rel="previous", href=annotator.feed_url(lane, facets, previous_page))

        # Add "up" link and breadcrumbs
        top_level_title = annotator.top_level_title() or "Collection Home"
        visible_parent = lane.visible_parent()
        if isinstance(visible_parent, Lane):
            title = visible_parent.display_name
        else:
            title = top_level_title
        if visible_parent:
            up_uri = annotator.lane_url(visible_parent)
            OPDSFeed.add_link_to_feed(feed=feed.feed, href=up_uri, rel="up", title=title)
            feed.add_breadcrumbs(lane, annotator)

        OPDSFeed.add_link_to_feed(feed=feed.feed, rel='start', href=annotator.default_lane_url(), title=top_level_title)
        
        annotator.annotate_feed(feed, lane)

        content = unicode(feed)
        cached.update(content)
        return cached