Ejemplo n.º 1
0
    def index(self, **kwargs):
        """ Output stats. """

        backends = int(
            BaseSearcher.sql_get("SELECT count (*) from pg_stat_activity"))
        active_backends = int(
            BaseSearcher.sql_get(
                "SELECT count (*) - 1 from pg_stat_activity where current_query !~ '^<IDLE>'"
            ))

        ipsessions = list(cherrypy.tools.rate_limiter.cache.values())  # pylint: disable=E1101

        adns = asyncdns.AsyncDNS()

        # blocked IPs
        blocked = sorted([s for s in ipsessions if s.get('blocked', 0) >= 2],
                         key=lambda s: s.ips.sort_key())
        if 'resolve' in kwargs:
            for d in blocked:
                if d.ips.ipinfo is None:
                    d.ips.ipinfo = ipinfo.IPInfo(adns, d.ips.get_ip_to_block())

        # active IPs
        active = sorted([s for s in ipsessions if s.get('active', False)],
                        key=lambda s: s.ips.sort_key())

        # busiest IPs
        busiest = sorted([s for s in active if s.get('blocked', 0) < 2],
                         key=lambda x: -x.get('rhits'))[:10]
        if 'resolve' in kwargs:
            for d in busiest:
                if d.ips.ipinfo is None:
                    d.ips.ipinfo = ipinfo.IPInfo(adns, d.ips.get_ip_to_block())

        # IPs with most sessions
        most_sessions = sorted([
            s for s in active if not s.ips.whitelisted and len(s.sessions) > 1
        ],
                               key=lambda s: -len(s.sessions))[:10]
        if 'resolve' in kwargs:
            for d in most_sessions:
                if d.ips.ipinfo is None:
                    d.ips.ipinfo = ipinfo.IPInfo(adns, d.ips.get_ip_to_block())

        adns.wait()
        adns.cancel()

        return self.output(
            'stats',
            active=active,
            blocked=blocked,
            busiest=busiest,
            most_sessions=most_sessions,
            resolve='resolve' in kwargs,
            rl=cherrypy.tools.rate_limiter,  # pylint: disable=E1101
            backends=backends,
            active_backends=active_backends)
Ejemplo n.º 2
0
    def index(self, **dummy_kwargs):
        """ Output the suggestions page. """

        cherrypy.request.params['format'] = 'json'  # override user

        os = BaseSearcher.OpenSearch()
        os.sort_order = 'nentry'
        os.start_index = 1
        os.items_per_page = 5

        if os.format != 'json':
            raise cherrypy.HTTPError(400, 'Bad Request. Unknown format.')

        if len(os.query) == 0:
            raise cherrypy.HTTPError(400, 'Bad Request. No query.')

        last_word = os.query.split()[-1]
        if len(last_word) < 4:
            raise cherrypy.HTTPError(400, 'Bad Request. Query too short.')

        # ok. request looks sane. process it

        os.log_request('suggestions')

        os.f_format_title = os.format_suggestion
        os.f_format_subtitle = os.format_none
        os.f_format_extra = os.format_none
        os.f_format_url = os.format_none
        os.f_format_thumb_url = os.format_none
        os.f_format_icon = os.format_none

        sql = BaseSearcher.SQLStatement()

        # prepare inner query
        sql.query = 'SELECT tsvec'
        sql.from_ = ('books', )
        sql.fulltext('books.tsvec', os.query)
        inner_sql_query = self.sql_searcher.mogrify(os, sql)

        sql.query = "SELECT substr (word, 2) AS title FROM ts_stat ( %(inner)s )"
        sql.from_ = ()
        sql.params['inner'] = inner_sql_query
        sql.where = ["word ~* %(re_word)s"]
        sql.params['re_word'] = '^0' + last_word

        try:
            os = self.sql_searcher.search(os, sql)
        except DatabaseError as what:
            cherrypy.log("SQL Error: " + str(what),
                         context='REQUEST',
                         severity=logging.ERROR)
            raise cherrypy.HTTPError(500, 'Internal Server Error.')

        os.template = os.page = 'results'
        os.finalize()

        return self.format(os)
Ejemplo n.º 3
0
    def index(self, **dummy_kwargs):
        """ Output the start page. """

        os = BaseSearcher.OpenSearch()

        os.log_request('start')

        os.search_terms = ''
        os.title = {
            'mobile': _('PG Mobile'),
            'opds': _('Project Gutenberg'),
            'stanza': _('Project Gutenberg')
        }.get(os.format, _('Search Project Gutenberg'))

        cat = BaseSearcher.Cat()
        cat.header = _(
            'Welcome to Project Gutenberg. Use the search box to find your book or pick a link.'
        )
        cat.title = _('Popular')
        cat.subtitle = _('Our most popular books.')
        cat.url = os.url('search', sort_order='downloads')
        cat.class_ += 'navlink'
        cat.icon = 'popular'
        cat.order = 2
        os.entries.append(cat)

        cat = BaseSearcher.Cat()
        cat.title = _('Latest')
        cat.subtitle = _('Our latest releases.')
        cat.url = os.url('search', sort_order='release_date')
        cat.class_ += 'navlink'
        cat.icon = 'date'
        cat.order = 3
        os.entries.append(cat)

        cat = BaseSearcher.Cat()
        cat.title = _('Random')
        cat.subtitle = _('Random books.')
        cat.url = os.url('search', sort_order='random')
        cat.class_ += 'navlink'
        cat.icon = 'random'
        cat.order = 4
        os.entries.append(cat)

        os.total_results = 0
        os.template = 'results'
        os.page = 'start'

        os.url_share = os.url('/', host=os.file_host)
        os.twit = os.tagline

        os.finalize()

        return self.format(os)
Ejemplo n.º 4
0
    def index(self, **kwargs):
        """ Check with google. """

        cherrypy.lib.caching.expires(0, True)

        os = BaseSearcher.OpenSearch()

        # Remove Session cookie.
        name = cherrypy.serving.request.config.get('tools.sessions.name',
                                                   'session_id')
        del cherrypy.serving.response.cookie[name]

        if 'recaptcha_challenge_field' in kwargs:
            response = submit(kwargs['recaptcha_challenge_field'],
                              kwargs['recaptcha_response_field'],
                              cherrypy.config['recaptcha_private_key'],
                              cherrypy.request.remote.ip)

            cherrypy.ipsession.captcha_answer(response)

            if not response.is_valid:
                raise cherrypy.HTTPRedirect(
                    os.url('captcha.question', error='incorrect-captcha-sol'))

        for req in reversed(cherrypy.ipsession['requests']):
            if 'captcha' not in req:
                raise cherrypy.HTTPRedirect(req)

        raise cherrypy.HTTPRedirect(os.url('start'))
Ejemplo n.º 5
0
    def setup(self, os, sql):
        os.f_format_url = BaseSearcher.SearchUrlFormatter('bookshelf')
        os.f_format_thumb_url = os.format_none
        os.sort_orders = ('downloads', 'quantity', 'alpha', 'release_date',
                          'authors')
        os.icon = 'bookshelf'
        os.class_ += 'navlink'
        os.title = _('All Bookshelves')

        sql.query = """
                    SELECT
                       bookshelves.bookshelf as title,
                       bookshelves.pk as pk,
                       max (books.release_date) as release_date,
                       sum (books.downloads) as downloads,
                       count (books.pk) as quantity"""

        sql.from_ = ('bookshelves', 'mn_books_bookshelves as mn', 'books')
        sql.groupby += ('bookshelves.bookshelf', 'bookshelves.pk')
        sql.where.append('bookshelves.pk = mn.fk_bookshelves')
        sql.where.append('books.pk = mn.fk_books')

        if len(os.query):
            sql.fulltext('bookshelves.tsvec', os.query)
            os.title = _("Bookshelves: {bookshelf}").format(bookshelf=os.query)
Ejemplo n.º 6
0
    def fix_dc(self, dc, os):
        """ Add some info to dc for easier templating.

        Also make sure that dc `walks like a cat´. """

        super(MobileFormatter, self).fix_dc(dc, os)

        for file_ in dc.files + dc.generated_files:
            if len(file_.mediatypes) == 1:
                type_ = six.text_type(file_.mediatypes[0])
                m = type_.partition(';')[0]
                if m in MOBILE_TYPES:
                    cat = BaseSearcher.Cat()
                    cat.type = file_.mediatypes[0]
                    cat.header = _('Download')
                    cat.title = file_.hr_filetype
                    cat.extra = file_.hr_extent

                    cat.charset = file_.encoding
                    cat.url = file_.url
                    cat.icon = dc.icon
                    cat.icon2 = 'download'
                    cat.class_ += 'filelink'
                    cat.order = 20
                    os.entries.append(cat)
Ejemplo n.º 7
0
    def setup(self, os, sql):
        os.f_format_subtitle = os.format_subtitle
        os.f_format_url = BaseSearcher.SearchUrlFormatter('author')
        os.f_format_thumb_url = os.format_none
        os.sort_orders = ('downloads', 'quantity', 'alpha', 'release_date')
        os.icon = 'author'
        os.class_ += 'navlink'
        os.title = _('All Authors')

        sql.query = """
                    SELECT
                       authors.author as title,
                       coalesce (authors.born_floor || '', '') || '-' ||
                          coalesce (authors.died_floor || '', '') as subtitle,
                       authors.pk as pk,
                       max (books.release_date) as release_date,
                       sum (books.downloads) as downloads,
                       count (books.pk) as quantity"""

        sql.from_ = ('authors', 'mn_books_authors as mn', 'books')
        sql.groupby += ('authors.author', 'subtitle', 'authors.pk')
        sql.where.append('authors.pk = mn.fk_authors')
        sql.where.append('books.pk = mn.fk_books')

        if len(os.query):
            sql.fulltext('authors.tsvec', os.query)
            os.title = _("Authors: {author}").format(author=os.query)
        else:
            sql.where.append(
                "authors.author not in ('Various', 'Anonymous', 'Unknown')")
Ejemplo n.º 8
0
    def fixup (self, os):

        if (os.start_index == 1 and len (os.entries) > 0):

            # browse-by-author page for maintainers
            if 'is-catalog-maintainer' in cherrypy.request.cookie:
                cat = BaseSearcher.Cat ()
                cat.type = mt.html
                cat.rel = 'related'
                cat.title = _('Browse by Author')
                cat.url = "/browse/authors/%s#a%d" % (os.author[:1].lower (), os.id)
                cat.class_ += 'navlink grayed'
                cat.icon = 'internal'
                cat.order = 9
                os.entries.insert (0, cat)

            # wikipedia links etc.
            rows = BaseSearcher.SQLSearcher.execute (
                """SELECT url, description AS title FROM author_urls
                   WHERE fk_authors = %(fk_authors)s""",
                { 'fk_authors': os.id } )
            for row in rows:
                cat = BaseSearcher.Cat ()
                cat.type = mt.html
                cat.rel = 'related'
                cat.title = _('See also: {title}').format (title = row.title)
                cat.url = row.url
                cat.class_ += 'navlink grayed'
                cat.icon = 'external'
                cat.order = 8
                os.entries.insert (0, cat)

            # author aliases
            if os.format  == 'html':
                rows = BaseSearcher.SQLSearcher.execute (
                    """SELECT alias AS title FROM aliases
                       WHERE fk_authors = %(fk_authors)s AND alias_heading = 1""",
                    { 'fk_authors': os.id }
                    )

                for row in rows:
                    cat = BaseSearcher.Cat ()
                    cat.title = _('Alias {alias}').format (alias = row.title)
                    cat.class_ += 'grayed'
                    cat.icon = 'alias'
                    cat.order = 7
                    os.entries.insert (0, cat)
Ejemplo n.º 9
0
    def tick(self):
        """ Do things here. """

        try:
            BaseSearcher.books_in_archive = BaseSearcher.sql_get(
                'select count (*) from books')
        except:
            pass
Ejemplo n.º 10
0
    def sort_by_release_date(os):
        """ Append the sort by release date link. """

        cat = BaseSearcher.Cat()
        cat.rel = 'new'
        cat.title = _('Sort by Release Date')
        cat.url = os.url_carry(sort_order='release_date')
        cat.class_ += 'navlink grayed'
        cat.icon = 'date'
        cat.order = 4.3
        os.entries.insert(0, cat)
Ejemplo n.º 11
0
    def did_you_mean(os, corr, corrected_query):
        """ Message. """

        cat = BaseSearcher.Cat()
        cat.rel = '__didyoumean__'
        cat.title = _('Did you mean: {correction}').format(correction=corr)
        cat.url = os.url('search', query=corrected_query)
        cat.class_ += 'navlink'
        cat.icon = 'suggestion'
        cat.order = 12
        return cat
Ejemplo n.º 12
0
    def sort_by_quantity(os):
        """ Append the sort by quantity link. """

        cat = BaseSearcher.Cat()
        cat.rel = 'numerous'
        cat.title = _('Sort by Quantity')
        cat.url = os.url_carry(sort_order='quantity')
        cat.class_ += 'navlink grayed'
        cat.icon = 'quantity'
        cat.order = 4.2
        os.entries.insert(0, cat)
Ejemplo n.º 13
0
    def no_records_found(os):
        """ Message. """

        cat = BaseSearcher.Cat()
        cat.rel = '__notfound__'
        cat.title = _('No records found.')
        cat.url = os.url('start')
        cat.class_ += 'navlink grayed'
        cat.icon = 'bibrec'
        cat.order = 11
        return cat
Ejemplo n.º 14
0
    def sort_by_title(os):
        """ Append the sort alphabetically link. """

        cat = BaseSearcher.Cat()
        cat.rel = 'alphabethical'
        cat.title = _('Sort Alphabetically')
        cat.url = os.url_carry(sort_order='title')
        cat.class_ += 'navlink grayed'
        cat.icon = 'alpha'
        cat.order = 4.1
        os.entries.insert(0, cat)
Ejemplo n.º 15
0
    def sort_by_downloads(os):
        """ Append the sort by downloads link. """

        cat = BaseSearcher.Cat()
        cat.rel = 'popular'
        cat.title = _('Sort by Popularity')
        cat.url = os.url_carry(sort_order='downloads')
        cat.class_ += 'navlink grayed'
        cat.icon = 'popular'
        cat.order = 4.0
        os.entries.insert(0, cat)
Ejemplo n.º 16
0
    def status_line(os):
        """ Placeholder for status line. """

        cat = BaseSearcher.Cat()
        cat.rel = '__statusline__'
        cat.class_ += 'grayed'
        cat.icon = 'bibrec'
        cat.order = 10
        cat.header = os.title
        cat.title = _(u"Displaying results {from_}–{to}").format(
            from_=os.start_index, to=os.end_index)
        return cat
Ejemplo n.º 17
0
    def index (self, **dummy_kwargs):
        """ Output sitemap index. """

        sitemaps = []
        now = datetime.datetime.utcnow ().replace (microsecond = 0).isoformat () + 'Z'

        # 99999 is safeguard against bogus ebook numbers
        lastbook = BaseSearcher.sql_get ('select max (pk) as lastbook from books where pk < 99999')

        os = BaseSearcher.OpenSearch ()
        host = cherrypy.config['host']

        for n in range (0, lastbook // SITEMAP_SIZE + 1):
            sitemap = Struct ()
            sitemap.loc = os.url ('sitemap_index', page = n, host = host, format = None)
            sitemap.lastmod = now
            sitemaps.append (sitemap)

        data = Struct ()
        data.sitemaps = sitemaps

        return self.output ('sitemap-index', data = data)
Ejemplo n.º 18
0
    def setup(self, os, sql):
        os.sort_orders = ('downloads', 'title', 'release_date')
        os.title_icon = 'author'
        os.icon = 'book'
        os.class_ += 'booklink'
        os.f_format_icon = os.format_icon_titles
        os.author = BaseSearcher.sql_get(
            "select author from authors where pk = %(pk)s", pk=os.id)
        os.title = _('Books by {author}').format(author=os.author)

        sql.from_.append('mn_books_authors as mn')
        sql.where.append('books.pk = mn.fk_books')
        sql.where.append("mn.fk_authors = %(fk_authors)s")
        sql.params['fk_authors'] = os.id
Ejemplo n.º 19
0
    def setup(self, os, sql):
        os.sort_orders = ('downloads', 'title', 'author', 'release_date')
        os.title_icon = 'bookshelf'
        os.icon = 'book'
        os.class_ += 'booklink'
        os.f_format_icon = os.format_icon_titles
        os.bookshelf = BaseSearcher.sql_get(
            "select bookshelf from bookshelves where pk = %(pk)s", pk=os.id)
        os.title = _('Books in {bookshelf}').format(bookshelf=os.bookshelf)

        sql.from_.append('mn_books_bookshelves as mn')
        sql.where.append('books.pk = mn.fk_books')
        sql.where.append("mn.fk_bookshelves = %(fk_bookshelves)s")
        sql.params['fk_bookshelves'] = os.id
Ejemplo n.º 20
0
    def setup(self, os, sql):
        os.sort_orders = ('downloads', 'title', 'release_date')
        os.title_icon = 'subject'
        os.icon = 'book'
        os.class_ += 'booklink'
        os.f_format_icon = os.format_icon_titles
        os.subject = BaseSearcher.sql_get(
            "select subject from subjects where pk = %(pk)s", pk=os.id)
        os.title = _('Books about {subject}').format(subject=os.subject)

        sql.from_.append('mn_books_subjects as mn')
        sql.where.append('books.pk = mn.fk_books')
        sql.where.append("mn.fk_subjects = %(fk_subjects)s")
        sql.params['fk_subjects'] = os.id
Ejemplo n.º 21
0
    def index(self, **kwargs):
        """ Output captcha. """

        cherrypy.lib.caching.expires(3600, True)

        os = BaseSearcher.OpenSearch()
        os.template = 'recaptcha'
        os.recaptcha_public_key = cherrypy.config['recaptcha_public_key']
        os.error = kwargs.get('error')
        os.finalize()

        # Remove Session cookie, so that page can be cached.
        name = cherrypy.serving.request.config.get('tools.sessions.name',
                                                   'session_id')
        del cherrypy.serving.response.cookie[name]

        return self.format(os)
Ejemplo n.º 22
0
    def index (self, **kwargs):
        """ Output sitemap. """

        urls = []
        start = int (kwargs['page']) * SITEMAP_SIZE

        rows = BaseSearcher.SQLSearcher.execute (
            'select pk from books where pk >= %(start)s and pk <  %(end)s order by pk',
            { 'start': str (start), 'end': str (start + SITEMAP_SIZE) })

        os = BaseSearcher.OpenSearch ()
        host = cherrypy.config['host']

        for row in rows:
            url = Struct ()
            url.loc = os.url ('bibrec', id = row[0], host = host, format = None)
            urls.append (url)

        data = Struct ()
        data.urls = urls

        return self.output ('sitemap', data = data)
Ejemplo n.º 23
0
    def output_suggestions(self, os, max_suggestions_per_word=3):
        """ Make suggestions. """

        # similarity == matching_trigrams / (len1 + len2 - matching_trigrams)

        sql_query = """
            SELECT
               word,
               nentry,
               similarity (word, %(word)s) AS sml
            FROM terms
            WHERE word %% %(word)s
            ORDER BY sml DESC, nentry DESC LIMIT %(suggestions)s;"""

        q = os.query.lower()
        sugg = []
        for word in q.split():
            if len(word) > 3:
                try:
                    rows = BaseSearcher.SQLSearcher().execute(
                        sql_query, {
                            'word': word,
                            'suggestions': max_suggestions_per_word + 1
                        })
                    for i, row in enumerate(rows):
                        if i >= max_suggestions_per_word:
                            break
                        corr = row.word
                        if corr != word:
                            sugg.append((word, corr))
                except DatabaseError:
                    pass

        for word, corr in reversed(sugg):
            os.entries.insert(
                0, self.did_you_mean(os, corr, q.replace(word, corr)))
Ejemplo n.º 24
0
 def get_dc (self):
     """ Get a DublinCore struct for the ebook. """
     dc = BaseSearcher.DC (cherrypy.engine.pool)
     dc.load_from_database (self.id)
     # dc.translate ()
     return dc
Ejemplo n.º 25
0
 def index(self, **kwargs):
     os = BaseSearcher.OpenSearch()
     raise cherrypy.HTTPRedirect(os.url('start'))
Ejemplo n.º 26
0
    def fixup(self, os):
        """ strip marc subfields, add social media hints and facet links """

        for e in os.entries:
            if '$' in e.title:
                e.title = DublinCore.strip_marc_subfields(e.title)

        if (os.sort_order == 'release_date' and os.total_results > 0
                and os.start_index == 1):
            cat = BaseSearcher.Cat()
            cat.title = _('Follow new books on Twitter')
            cat.subtitle = _("Follow our new books on Twitter.")
            cat.url = 'https://twitter.com/gutenberg_new'
            cat.class_ += 'navlink grayed'
            cat.icon = 'twitter'
            cat.order = 5
            os.entries.insert(0, cat)

            cat = BaseSearcher.Cat()
            cat.title = _('Follow new books on Facebook')
            cat.subtitle = _(
                "Follow the link and like the page to have us post new books to your wall."
            )
            cat.url = 'https://www.facebook.com/gutenberg.new'
            cat.class_ += 'navlink grayed'
            cat.icon = 'facebook'
            cat.order = 5
            os.entries.insert(0, cat)

        if (len(os.query) and os.start_index == 1):
            sql2 = BaseSearcher.SQLStatement()
            sql2.query = "select count (*) from bookshelves"
            sql2.fulltext('bookshelves.tsvec', os.query)
            rows = BaseSearcher.SQLSearcher.execute(*sql2.build())
            if rows[0][0] > 0:
                cat = BaseSearcher.Cat()
                cat.rel = 'related'
                cat.title = _('Bookshelves')
                cat.subtitle = __('One bookshelf matches your query.',
                                  '{count} bookshelves match your search.',
                                  rows[0][0]).format(count=rows[0][0])
                cat.url = os.url('bookshelf_search', query=os.query)
                cat.class_ += 'navlink grayed'
                cat.icon = 'bookshelf'
                cat.order = 3
                os.entries.insert(0, cat)

            sql2 = BaseSearcher.SQLStatement()
            sql2.query = "select count (*) from subjects"
            sql2.fulltext('subjects.tsvec', os.query)
            rows = BaseSearcher.SQLSearcher.execute(*sql2.build())
            if rows[0][0] > 0:
                cat = BaseSearcher.Cat()
                cat.rel = 'related'
                cat.title = _('Subjects')
                cat.subtitle = __(
                    'One subject heading matches your search.',
                    '{count} subject headings match your search.',
                    rows[0][0]).format(count=rows[0][0])
                cat.url = os.url('subject_search', query=os.query)
                cat.class_ += 'navlink grayed'
                cat.icon = 'subject'
                cat.order = 3
                os.entries.insert(0, cat)

            sql2 = BaseSearcher.SQLStatement()
            sql2.query = "select count (*) from authors"
            sql2.fulltext('authors.tsvec', os.query)
            rows = BaseSearcher.SQLSearcher.execute(*sql2.build())
            if rows[0][0] > 0:
                cat = BaseSearcher.Cat()
                cat.rel = 'related'
                cat.title = _('Authors')
                cat.subtitle = __('One author name matches your search.',
                                  '{count} author names match your search.',
                                  rows[0][0]).format(count=rows[0][0])
                cat.url = os.url('author_search', query=os.query)
                cat.class_ += 'navlink grayed'
                cat.icon = 'author'
                cat.order = 3
                os.entries.insert(0, cat)
Ejemplo n.º 27
0
    def index(self, **dummy_kwargs):
        """ A bibrec page. """

        os = BaseSearcher.OpenSearch()

        os.log_request('bibrec')

        dc = BaseSearcher.DC(cherrypy.engine.pool)

        # the bulk of the work is done here
        dc.load_from_database(os.id)
        if not dc.files:
            # NOTE: Error message
            cherrypy.tools.rate_limiter.e404()
            raise cherrypy.HTTPError(404, _('No ebook by that number.'))

        # add these fields so we won't have to test for their existence later
        dc.extra_info = None
        dc.url = None

        dc.translate()
        dc.header = gg.cut_at_newline(dc.title)
        os.title = dc.make_pretty_title()
        dc.extra_info = ''
        dc.class_ = BaseSearcher.ClassAttr()
        dc.order = 10
        dc.icon = 'book'
        if 'Sound' in dc.categories:
            dc.icon = 'audiobook'
        os.title_icon = dc.icon
        os.twit = os.title
        os.qrcode_url = '//%s/cache/epub/%d/pg%d.qrcode.png' % (os.file_host,
                                                                os.id, os.id)

        os.entries.append(dc)

        s = cherrypy.session
        last_visited = s.get('last_visited', [])
        last_visited.append(os.id)
        s['last_visited'] = last_visited

        # can we find some meaningful breadcrumbs ?
        for a in dc.authors:
            if a.marcrel in ('aut', 'cre'):
                book_cnt = BaseSearcher.sql_get(
                    "select count (*) from mn_books_authors where fk_authors = %(aid)s",
                    aid=a.id)
                if book_cnt > 1:
                    os.breadcrumbs.append(
                        (__('One by {author}', '{count} by {author}',
                            book_cnt).format(count=book_cnt,
                                             author=dc.make_pretty_name(
                                                 a.name)),
                         _('Find more ebooks by the same author.'),
                         os.url('author', id=a.id)))

        if os.format in ('html', 'mobile'):
            cat = BaseSearcher.Cat()
            cat.header = _('Similar Books')
            cat.title = _('Readers also downloaded…')
            cat.rel = 'related'
            cat.url = os.url('also', id=os.id)
            cat.class_ += 'navlink grayed noprint'
            cat.icon = 'suggestion'
            cat.order = 30
            os.entries.append(cat)

            for bookshelf in dc.bookshelves:
                cat = BaseSearcher.Cat()
                cat.title = _('In {bookshelf}').format(
                    bookshelf=bookshelf.bookshelf)
                cat.rel = 'related'
                cat.url = os.url('bookshelf', id=bookshelf.id)
                cat.class_ += 'navlink grayed'
                cat.icon = 'bookshelf'
                cat.order = 33
                os.entries.append(cat)

        if os.format in ('mobile', ):
            for author in dc.authors:
                cat = BaseSearcher.Cat()
                cat.title = _('By {author}').format(
                    author=author.name_and_dates)
                cat.rel = 'related'
                cat.url = os.url('author', id=author.id)
                cat.class_ += 'navlink grayed'
                cat.icon = 'author'
                cat.order = 31
                os.entries.append(cat)

            for subject in dc.subjects:
                cat = BaseSearcher.Cat()
                cat.title = _('On {subject}').format(subject=subject.subject)
                cat.rel = 'related'
                cat.url = os.url('subject', id=subject.id)
                cat.class_ += 'navlink grayed'
                cat.icon = 'subject'
                cat.order = 32
                os.entries.append(cat)

        os.total_results = 1

        os.template = 'results' if os.format == 'mobile' else 'bibrec'
        os.page = 'bibrec'
        os.og_type = 'book'
        os.finalize()

        return self.format(os)
Ejemplo n.º 28
0
    def index(self, **kwargs):
        """ Output a search result page. """

        os = BaseSearcher.OpenSearch()
        os.log_request('search')

        if 'default_prefix' in kwargs:
            raise cherrypy.HTTPError(
                400, 'Bad Request. Unknown parameter: default_prefix')

        if os.start_index > BaseSearcher.MAX_RESULTS:
            raise cherrypy.HTTPError(
                400, 'Bad Request. Parameter start_index too high')

        sql = BaseSearcher.SQLStatement()
        sql.query = 'SELECT *'
        sql.from_ = ['v_appserver_books_4 as books']

        # let derived classes prepare the query
        try:
            self.setup(os, sql)
        except ValueError as what:
            raise cherrypy.HTTPError(400, 'Bad Request. ' + str(what))

        os.fix_sortorder()

        # execute the query
        try:
            BaseSearcher.SQLSearcher().search(os, sql)
        except DatabaseError as what:
            cherrypy.log("SQL Error: " + str(what),
                         context='REQUEST',
                         severity=logging.ERROR)
            raise cherrypy.HTTPError(400, 'Bad Request. Check your query.')

        # sync os.title and first entry header
        if os.entries:
            entry = os.entries[0]
            if os.title and not entry.header:
                entry.header = os.title
            elif entry.header and not os.title:
                os.title = entry.header

        os.template = os.page = 'results'

        # give derived class a chance to tweak result set
        self.fixup(os)

        # warn user about no records found
        if os.total_results == 0:
            self.nothing_found(os)

        # suggest alternate queries
        if os.total_results < 5:
            self.output_suggestions(os)

        # add sort by links
        if os.start_index == 1 and os.total_results > 1:
            if 'downloads' in os.alternate_sort_orders:
                self.sort_by_downloads(os)
            if 'release_date' in os.alternate_sort_orders:
                self.sort_by_release_date(os)
            if 'title' in os.alternate_sort_orders:
                self.sort_by_title(os)
            if 'alpha' in os.alternate_sort_orders:
                self.sort_alphabetically(os)
            if 'quantity' in os.alternate_sort_orders:
                self.sort_by_quantity(os)

        os.finalize()
        self.finalize(os)

        if os.total_results > 0:
            # call this after finalize ()
            os.entries.insert(0, self.status_line(os))

        return self.format(os)