Repository navigation
Expand file tree
/
Copy pathHTMLFormatter.py
More file actions
181 lines (139 loc) · 5.98 KB
/
Copy pathHTMLFormatter.py
File metadata and controls
181 lines (139 loc) · 5.98 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env python
# -*- mode: python; indent-tabs-mode: nil; -*- coding: iso-8859-1 -*-
"""
HTMLFormatter.py
Copyright 2009-2014 by Marcello Perathoner
Distributable under the GNU General Public License Version 3 or newer.
Produce a HTML page.
"""
from __future__ import unicode_literals
import operator
import genshi.output
import re
import six
from libgutenberg.MediaTypes import mediatypes as mt
import BaseSearcher
import BaseFormatter
# filetypes ignored on desktop site
NO_DESKTOP_FILETYPES = {'plucker', 'qioo', 'rdf', 'rst', 'rst.gen', 'rst.master', 'tei',
'cover.medium', 'cover.small', 'pageimages', 'kindle.noimages'}
# filetypes which are usually handed over to a separate app on mobile devices
HANDOVER_TYPES = (mt.epub, mt.mobi, mt.pdf)
# self-contained files we can send to dropbox
CLOUD_TYPES = (mt.epub, mt.mobi, mt.pdf)
STD_PDF_MATCH = re.compile(r'files/\d+/\d+-pdf.pdf$')
class XMLishFormatter(BaseFormatter.BaseFormatter):
""" Produce XMLish output. """
def __init__(self):
super(XMLishFormatter, self).__init__()
def fix_dc(self, dc, os):
""" Tweak dc. """
def has_std_path(file_obj):
''' so cloudstorage links can be elided when the url is non-standard'''
if file_obj.filetype == 'pdf':
return STD_PDF_MATCH.search(file_obj.url)
return True
super(XMLishFormatter, self).fix_dc(dc, os)
dedupable = {}
for file_ in dc.files:
if file_.filetype and file_.filetype.endswith('images'):
dedupable[file_.filetype] = file_
do_dedupe = False
for ft in ['epub', 'pdf', 'html']:
if ft + '.images' in dedupable and ft + '.noimages' in dedupable:
# because of timestamps, identical files may vary by a bit or 2
if abs(dedupable[ft + '.images'].extent - dedupable[ft + '.noimages'].extent) < 3:
do_dedupe = True
if do_dedupe:
for ft in ['epub', 'pdf', 'html']:
if ft + '.images' in dedupable and ft + '.noimages' in dedupable:
dc.files.remove(dedupable[ft + '.noimages'])
for file_ in dc.files:
type_ = six.text_type(file_.mediatypes[0])
m = type_.partition(';')[0]
if m in CLOUD_TYPES and has_std_path(file_):
file_.dropbox_url = os.url(
'dropbox_send', id=dc.project_gutenberg_id, filetype=file_.filetype,
protocol='https')
file_.gdrive_url = os.url(
'gdrive_send', id=dc.project_gutenberg_id, filetype=file_.filetype,
protocol='https')
file_.msdrive_url = os.url(
'msdrive_send', id = dc.project_gutenberg_id, filetype=file_.filetype,
protocol='https')
# these are used as relative links
if file_.generated and not file_.filetype.startswith('cover.'):
file_.filename = "ebooks/%d.%s" % (dc.project_gutenberg_id, file_.filetype)
def format(self, page, os):
""" Format to HTML. """
for e in os.entries:
if isinstance(e, BaseSearcher.DC):
self.fix_dc(e, os)
# loop again because fix:dc appends things
for e in os.entries:
if isinstance(e, BaseSearcher.Cat):
if e.url:
e.icon2 = e.icon2 or 'next'
else:
e.class_ += 'grayed'
if os.title_icon:
os.class_ += 'icon_' + os.title_icon
os.entries.sort(key = operator.attrgetter('order'))
return self.render(page, os)
class HTMLFormatter(XMLishFormatter):
""" Produce HTML output. """
CONTENT_TYPE = 'text/html; charset=UTF-8'
DOCTYPE = 'html5'
def __init__(self):
super (HTMLFormatter, self).__init__()
def get_serializer(self):
return genshi.output.HTMLSerializer(doctype=self.DOCTYPE, strip_whitespace=False)
def fix_dc(self, dc, os):
""" Add some info to dc for easier templating.
Also make sure that dc `walks like a cat´. """
super(HTMLFormatter, self).fix_dc(dc, os)
if dc.new_filesystem:
dc.base_dir = "/files/%d/" % dc.project_gutenberg_id
else:
dc.base_dir = None
dc.magnetlink = None
# hide all txt files but the first one
showncount = htmlcount = 0
txt_file = None
# this is the logic for whether or not to display a file
for file_ in dc.files:
filetype = file_.filetype or ''
file_.hidden = False
if filetype == 'txt.utf-8': # should be there for all books
if txt_file != None:
# must be a filetype = 'txt', hide it
txt_file.hidden = True
showncount -= 1
txt_file = file_
elif file_.compression == 'zip':
if file_.archive_path.startswith('cache/epub'):
file_.hr_filetype = 'Download HTML (zip)'
file_.mediatypes.append('application/zip')
else:
file_.hidden = True
elif filetype == 'html.images':
if file_.compression == 'none':
if htmlcount > 0:
file_.hidden = True
else:
htmlcount += 1
elif filetype in NO_DESKTOP_FILETYPES or filetype == '':
# if no filetype is available, we shouldn't show it
file_.hidden = True
elif filetype == "txt": # rare
# only show if no "txt.utf-8"
if txt_file:
file_.hidden = True
else:
txt_file = file_
if not file_.hidden:
showncount += 1
# if we happened to hide everything, show all files
if showncount == 0:
for file_ in dc.files:
file_.hidden = False