-
Notifications
You must be signed in to change notification settings - Fork 6
/
CoverPages.py
117 lines (87 loc) · 3.67 KB
/
CoverPages.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# -*- mode: python; indent-tabs-mode: nil; -*- coding: utf-8 -*-
"""
CoverPages.py
Copyright 2009-2021 by Project Gutenberg
Distributable under the GNU General Public License Version 3 or newer.
Serve cover images of most popular and latest ebooks.
"""
from __future__ import unicode_literals
import cherrypy
import six
from sqlalchemy import select
from libgutenberg import GutenbergGlobals as gg
from libgutenberg import DublinCore, DublinCoreMapping, Models
class CoverPages(object):
""" Output a gallery of cover pages. """
@staticmethod
def serve(books, size, session):
""" Output a gallery of coverpages. """
def escape(_string):
_string = gg.xmlspecialchars(_string) # handles <,>,&
_string = _string.replace('"', '"')
_string = _string.replace("'", ''')
return _string
def author_name(author):
return escape(DublinCore.DublinCore.make_pretty_name(author.name))
cherrypy.response.headers['Content-Type'] = 'text/html; charset=utf-8'
cherrypy.response.headers['Content-Language'] = 'en'
s = ''
for book_id in books:
dc = DublinCoreMapping.DublinCoreObject(session=session, pooled=True)
dc.load_from_database(book_id)
cover = session.execute(select(Models.File.archive_path).where(
Models.File.fk_books == book_id,
Models.File.fk_filetypes == size)).scalars().first()
if not cover:
continue
url = '/' + cover
href = '/ebooks/%d' % book_id
if dc.title:
title = escape(dc.title)
else:
title = '!! missing title !!'
short_title = escape(dc.make_pretty_title())
author_name_list = map(author_name, dc.authors)
authors = ', '.join(author_name_list)
s += f"""
<a href="{href}" title="{title}" authors="{authors}" target="_top">
<div class="cover_image">
<div class="cover_img">
<img src="{url}" alt="{title}, {authors}" title="{title}"
authors="{authors}" draggable="false">
</div>
<div class="cover_title">
<h5>{short_title}</h5>
</div>
</div>
</a>
"""
return s.encode('utf-8')
def index(self, count, size, order, **kwargs):
""" Internal help function. """
session = cherrypy.engine.pool.Session()
try:
count = int(count)
if count < 1:
raise ValueError('count < 0')
if size not in ('small', 'medium'):
raise ValueError('bogus size')
size = 'cover.%s' % size
if order == 'popular':
order_by = Models.Book.downloads.desc()
else:
order_by = Models.Book.release_date.desc()
rows = session.execute(select(Models.Book.pk).where(
Models.Book.pk == Models.File.fk_books,
Models.File.fk_filetypes == size
).order_by(order_by).limit(count)).scalars().all()
if rows:
return self.serve(rows, size, session)
except (ValueError, KeyError) as what:
raise cherrypy.HTTPError (400, 'Bad Request. %s' % six.text_type(what))
except IOError:
pass
finally:
session.close()
raise cherrypy.HTTPError(500, 'Internal Server Error.')