Example #1
0
    def all_libraries(self):
        """Find an iterator over all libraries, whatever
        'all libraries' means in the context of this script.

        By default, 'all libraries' means all libraries in the
        production or testing stages.
        """
        return self._db.query(Library).filter(
            Library._feed_restriction(production=False)
        )
    def libraries_opds(self, live=True, location=None):
        """Return all the libraries in OPDS format

        :param live: If this is True, then only production libraries are shown.
        :param location: If this is set, then libraries near this point will be
           promoted out of the alphabetical list.
        """
        alphabetical = self._db.query(Library).order_by(Library.name)

        # We always want to filter out cancelled libraries.  If live, we also filter out
        # libraries that are in the testing stage, i.e. only show production libraries.
        alphabetical = alphabetical.filter(
            Library._feed_restriction(production=live))

        # Pick up each library's hyperlinks and validation
        # information; this will save database queries when building
        # the feed.
        alphabetical = alphabetical.options(
            joinedload('hyperlinks'),
            joinedload('hyperlinks', 'resource'),
            joinedload('hyperlinks', 'resource', 'validation'),
        )
        alphabetical = alphabetical.options(defer('logo'))
        if location is None:
            # No location data is available. Use the alphabetical list as
            # the list of libraries.
            a = time.time()
            libraries = alphabetical.all()
            b = time.time()
            self.log.info(
                "Built alphabetical list of all libraries in %.2fsec" %
                (b - a))
        else:
            # Location data is available. Get the list of nearby libraries, then get
            # the rest of the list in alphabetical order.

            # We can't easily do the joindeload() thing for this
            # query, because it doesn't simply return Library objects,
            # but it won't return more than five results.
            a = time.time()
            nearby_libraries = Library.nearby(self._db,
                                              location,
                                              production=live).limit(5).all()
            b = time.time()
            self.log.info("Fetched libraries near %s in %.2fsec" %
                          (location, b - a))

            # Exclude nearby libraries from the alphabetical query
            # to get a list of faraway libraries.
            faraway_libraries = alphabetical.filter(
                ~Library.id.in_([x.id for x, distance in nearby_libraries]))
            c = time.time()
            libraries = nearby_libraries + faraway_libraries.all()
            self.log.info("Fetched libraries far from %s in %.2fsec" %
                          (location, c - b))

        url = self.app.url_for("libraries_opds")
        a = time.time()
        catalog = OPDSCatalog(self._db,
                              'Libraries',
                              url,
                              libraries,
                              annotator=self.annotator,
                              live=live)
        b = time.time()
        self.log.info("Built library catalog in %.2fsec" % (b - a))
        return catalog_response(catalog)