def nearby(self, location, live=True):
     qu = Library.nearby(self._db, location, production=live)
     qu = qu.limit(5)
     if live:
         nearby_controller = 'nearby'
     else:
         nearby_controller = 'nearby_qa'
     this_url = self.app.url_for(nearby_controller)
     catalog = OPDSCatalog(self._db,
                           unicode(_("Libraries near you")),
                           this_url,
                           qu,
                           annotator=self.annotator,
                           live=live)
     return catalog_response(catalog)
    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)