1 # Part of Objavi2, which makes pdf versions of FLOSSManuals books.
2 # This python module contains or encapsulates configuration and
5 # Copyright (C) 2009 Douglas Bagnall
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along
18 # with this program; if not, write to the Free Software Foundation, Inc.,
19 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 """This module contains constant values used to produce books.
23 #XXX eventually, read in a real config file.
24 #XXX Some of these values should be editable via an admin cgi script
26 #Not really configurable (72 pt per inch / 25.4 mm per inch)
27 POINT_2_MM
= 25.4 / 72.0
28 MM_2_POINT
= 72.0 / 25.4
35 BOOKI_BOOK_DIR
= 'booki-books'
38 WKHTMLTOPDF
= '/usr/local/bin/wkhtmltopdf-static'
39 WKHTMLTOPDF_EXTRA_COMMANDS
= []
41 HTML2ODT
= './html2odt'
43 #CGITB_DOMAINS = ('203.97.236.46', '202.78.240.7')
46 #bookland is used to make isbn barcodes
47 BOOKLAND
= 'bookland/bookland'
49 # how many pages to number in one pdfedit process (which has
50 # exponential memory leak)
51 PDFEDIT_MAX_PAGES
= 40
53 #keep book lists around for this time without refetching
54 BOOK_LIST_CACHE
= 3600 * 2
55 BOOK_LIST_CACHE_DIR
= 'cache'
57 TOC_URL
= "http://%s/pub/%s/_index/TOC.txt"
58 CHAPTER_URL
= "http://%s/bin/view/%s/%s?skin=text"
59 PUBLISH_URL
= "/books/"
61 TWIKI_GATEWAY_URL
= 'http://%s/booki-twiki-gateway.cgi?server=%s&book=%s&mode=zip'
62 BOOKI_ZIP_URL
= 'http://%(server)s/export/%(book)s/export'
64 DEFAULT_SERVER
= 'en.flossmanuals.net'
65 DEFAULT_SIZE
= 'COMICBOOK'
66 DEFAULT_ENGINE
= 'webkit'
68 BOOKIZIP_MIMETYPE
= "application/x-booki+zip"
70 RTL_SCRIPTS
= ['persian', 'arabic', 'hebrew', 'urdu']
72 USE_CACHED_IMAGES
= False
74 #Normally, Book objects try to shutdown subprocesses and clean up temp
75 #files when they __exit__. This flag makes them try when they __del__
76 #too (i.e. when they are garbage collected).
77 TRY_BOOK_CLEANUP_ON_DEL
= False
79 LOCALHOST
= 'localhost'
82 'booki.flossmanuals.net': {
83 'css-book': 'static/en.flossmanuals.net.css',
84 'css-web': 'static/en.flossmanuals.net-web.css',
85 'css-newspaper': 'static/en.flossmanuals.net-newspaper.css',
86 'css-openoffice': 'static/en.flossmanuals.net-openoffice.css',
92 'toc_header': 'Table of Contents',
95 'css-book': 'static/en.flossmanuals.net.css',
96 'css-web': 'static/en.flossmanuals.net-web.css',
97 'css-newspaper': 'static/en.flossmanuals.net-newspaper.css',
98 'css-openoffice': 'static/en.flossmanuals.net-openoffice.css',
101 'toc-encoding': None,
103 'interface': 'Booki',
104 'toc_header': 'Table of Contents',
107 'css-book': 'static/en.flossmanuals.net.css',
108 'css-web': 'static/en.flossmanuals.net-web.css',
109 'css-newspaper': 'static/en.flossmanuals.net-newspaper.css',
110 'css-openoffice': 'static/en.flossmanuals.net-openoffice.css',
113 'toc-encoding': 'iso-8859-1',
115 'interface': 'local',
116 'toc_header': 'Table of Contents',
118 'en.flossmanuals.net': {
119 'css-book': 'static/en.flossmanuals.net.css',
120 'css-web': 'static/en.flossmanuals.net-web.css',
121 'css-newspaper': 'static/en.flossmanuals.net-newspaper.css',
122 'css-openoffice': 'static/en.flossmanuals.net-openoffice.css',
125 'toc-encoding': None,
127 'interface': 'TWiki',
128 'toc_header': 'Table of Contents',
130 'fr.flossmanuals.net': {
131 'css-book': 'static/fr.flossmanuals.net.css',
132 'css-web': 'static/fr.flossmanuals.net-web.css',
133 'css-newspaper': 'static/fr.flossmanuals.net-newspaper.css',
134 'css': 'static/fr.flossmanuals.net.css',
135 'css-openoffice': 'static/fr.flossmanuals.net-openoffice.css',
138 'toc-encoding': 'iso-8859-1',
140 'interface': 'TWiki',
141 'toc_header': 'Table of Contents',
143 'translate.flossmanuals.net': {
144 'css-book': 'static/translate.flossmanuals.net.css',
145 'css-web': 'static/translate.flossmanuals.net-web.css',
146 'css-newspaper': 'static/translate.flossmanuals.net-newspaper.css',
147 'css': 'static/translate.flossmanuals.net.css',
148 'css-openoffice': 'static/translate.flossmanuals.net-openoffice.css',
151 'toc-encoding': None,
153 'interface': 'TWiki',
154 'toc_header': 'Table of Contents',
156 'nl.flossmanuals.net': {
157 'css-book': 'static/nl.flossmanuals.net.css',
158 'css-web': 'static/nl.flossmanuals.net-web.css',
159 'css-newspaper': 'static/nl.flossmanuals.net-newspaper.css',
160 'css': 'static/nl.flossmanuals.net.css',
161 'css-openoffice': 'static/nl.flossmanuals.net-openoffice.css',
164 'toc-encoding': 'iso-8859-1',
166 'interface': 'TWiki',
167 'toc_header': 'Table of Contents',
169 'bn.flossmanuals.net': {
170 'css-book': 'static/bn.flossmanuals.net.css',
171 'css-web': 'static/bn.flossmanuals.net-web.css',
172 'css-newspaper': 'static/bn.flossmanuals.net-newspaper.css',
173 'css': 'static/bn.flossmanuals.net.css',
174 'css-openoffice': 'static/bn.flossmanuals.net-openoffice.css',
177 'toc-encoding': 'iso-8859-1',
179 'interface': 'TWiki',
180 'toc_header': 'Table of Contents',
182 'fa.flossmanuals.net': {
183 'css-book': 'static/fa.flossmanuals.net.css',
184 'css-web': 'static/fa.flossmanuals.net-web.css',
185 'css-newspaper': 'static/fa.flossmanuals.net-newspaper.css',
186 'css': 'static/fa.flossmanuals.net.css',
187 'css-openoffice': 'static/fa.flossmanuals.net-openoffice.css',
190 'toc-encoding': 'iso-8859-1',
192 'interface': 'TWiki',
193 'toc_header': 'Table of Contents',
199 "ar": 'RTL', # arabic (many variants)
200 "dv": 'RTL', # dhivehi, maldives islands
202 #"ha": 'RTL', # hausa, west africa, particularly niger and nigeria
203 "he": 'RTL', # hebrew
204 "ps": 'RTL', # pashto
205 "ur": 'RTL', # urdu, pakistan
206 "yi": 'RTL', # yiddish, israel
209 # uncomment a debug mode to get messages about that topic.
219 #convert all sizes to points
220 PAPER_SIZES
= [(s
, x
* MM_2_POINT
, y
* MM_2_POINT
) for s
, x
, y
in (
235 # margins are BASE_MARGIN + PROPORTIONAL_MARGIN * min(width, height)
237 PROPORTIONAL_MARGIN
= 0.04
238 # gutter is BASE_GUTTER + PROPORTIONAL_GUTTER * width
240 PROPORTIONAL_GUTTER
= 0.011
243 'page_width': (1, 1000, MM_2_POINT
),
244 'page_height': (1, 1414, MM_2_POINT
), #can't be bigger than biggest PAPER_SIZE
245 'gutter': (-1000, 1000, MM_2_POINT
),
246 'top_margin': (0, 1500, MM_2_POINT
),
247 'side_margin': (0, 1500, MM_2_POINT
),
248 'bottom_margin': (0, 1500, MM_2_POINT
),
249 "columns": (1, 12, 1),
250 "column_margin": (0, 1000, MM_2_POINT
),
253 PAGE_NUMBER_SIZE
= 11 #XXX this is not used by pdfedit! (ie, it is a guess)
256 'COMICBOOK': {'pointsize': ((6.625 * 72), (10.25 * 72)), 'class': "lulu"},
257 "POCKET": {'pointsize': (4.25 * 72, 6.875 * 72), 'class': "lulu"},
259 "USLETTER": {'pointsize': (8.5 * 72, 11 * 72), 'class': "lulu"},
260 "USTRADE": {'pointsize': (6 * 72, 9 * 72), 'class': "lulu"},
261 "LANDSCAPE9x7": {'pointsize': (9 * 72, 7 * 72), 'class': "lulu"},
262 "SQUARE7.5": {'pointsize': (7.5 * 72, 7.5 * 72), 'class': "lulu"},
263 "ROYAL": {'pointsize': (6.139 * 72, 9.21 * 72), 'class': "lulu"},
264 "CROWNQUARTO": {'pointsize': (7.444 * 72, 9.681 * 72), 'class': "lulu"},
265 "SQUARE8.5": {'pointsize': (8.5 * 72, 8.5 * 72), 'class': "lulu"},
267 "A5": {'pointsize': (148 * MM_2_POINT
, 210 * MM_2_POINT
), 'class': "lulu iso"},
268 "A4": {'pointsize': (210 * MM_2_POINT
, 297 * MM_2_POINT
), 'class': "lulu iso"},
269 "A3 (NZ Tabloid)": {'pointsize': (297 * MM_2_POINT
, 420 * MM_2_POINT
), 'class': 'iso newspaper'},
270 "A2 (NZ Broadsheet)": {'pointsize': (420 * MM_2_POINT
, 594 * MM_2_POINT
), 'class': 'iso newspaper'},
271 "A1": {'pointsize': (594 * MM_2_POINT
, 841 * MM_2_POINT
), 'class': 'iso'},
272 "B4": {'pointsize': (250 * MM_2_POINT
, 353 * MM_2_POINT
), 'class': 'iso'},
273 "B3": {'pointsize': (353 * MM_2_POINT
, 500 * MM_2_POINT
), 'class': 'iso'},
274 "B2": {'pointsize': (500 * MM_2_POINT
, 707 * MM_2_POINT
), 'class': 'iso'},
275 "B1": {'pointsize': (707 * MM_2_POINT
, 1000 * MM_2_POINT
), 'class': 'iso'},
277 "UK Tabloid": {'pointsize': (11 * INCH_2_POINT
, 17 * INCH_2_POINT
), 'class': 'newspaper'},
278 "UK Broadsheet": {'pointsize': (18 * INCH_2_POINT
, 24 * INCH_2_POINT
), 'class': 'newspaper'},
279 "US Broadsheet": {'pointsize': (15 * INCH_2_POINT
, 22.75 * INCH_2_POINT
), 'class': 'newspaper'},
280 "Berliner" : {'pointsize': (315 * MM_2_POINT
, 470 * MM_2_POINT
), 'class': 'newspaper'},
281 "Foolscap (F4)": {'pointsize': (210 * MM_2_POINT
, 330 * MM_2_POINT
)},
283 "Oamaru Broadsheet":{'pointsize': (382 * MM_2_POINT
, 540 * MM_2_POINT
), 'class': 'newspaper'},
284 "Oamaru Tabloid": {'pointsize': (265 * MM_2_POINT
, 380 * MM_2_POINT
), 'class': 'newspaper'},
286 #ODT printable 380x560
290 "custom": {'class': "custom"},
293 MIN_COLUMN_WIDTH
= (110 * MM_2_POINT
)
300 INSIDE_FRONT_COVER_TEMPLATE
= 'templates/inside-front-cover.%s.html'
301 END_MATTER_TEMPLATE
= 'templates/end_matter.%s.html'
303 FONT_LIST_INCLUDE
= 'cache/font-list.inc'
304 FONT_LIST_URL
= '/font-list.cgi.pdf'
305 FONT_EXAMPLE_SCRIPT_DIR
= 'templates/font-list'
307 # for the license field, with a view to making it a drop down.
309 'GPL': 'http://www.gnu.org/licenses/gpl.txt',
310 'GPLv2': 'http://www.gnu.org/licenses/gpl-2.0.txt',
311 'GPLv2+': 'http://www.gnu.org/licenses/gpl-2.0.txt',
312 'GPLv3': 'http://www.gnu.org/licenses/gpl-3.0.txt',
313 'GPLv3+': 'http://www.gnu.org/licenses/gpl-3.0.txt',
314 'LGPL': 'http://www.gnu.org/licenses/lgpl.txt',
315 'LGPLv2.1': 'http://www.gnu.org/licenses/lgpl-2.1.txt',
316 'LGPLv3': 'http://www.gnu.org/licenses/lgpl-3.0.txt',
317 'BSD': 'http://www.debian.org/misc/bsd.license',
318 'public domain': None,
319 'MIT': 'http://www.opensource.org/licenses/mit-license.html',
320 'Artistic': 'http://dev.perl.org/licenses/artistic.html',
321 'CC-BY': 'http://creativecommons.org/licenses/by/3.0/',
322 'CC-BY-SA': 'http://creativecommons.org/licenses/by-sa/3.0/',
325 DEFAULT_LICENSE
= 'GPLv2+'
327 CGI_MODES
= { # arguments are: (publication, )
329 'newspaper': (True,),
331 'openoffice': (True,),
332 'booklist': (False,),
339 PUBLIC_CGI_MODES
= tuple(k
for k
, v
in CGI_MODES
.items() if v
[0])
341 #PUBLISH_DESTINATIONS
342 PUBLISH_DESTINATIONS
= {
348 DEFAULT_PUBLISH_DESTINATION
= 'html'
352 # input, name, input type, contents key, CSS classes, extra text
353 ("server", "FLOSS Manuals server", "select", "server_options", "", ""),
354 ("book", "Manual", "select", "book_options", "", ""),
355 ("title", "Book title", "input[type=text]", None, "", ""),
356 ("license", "License", "select", "licenses", "", ""),
358 ("mode", "Document type", "select", "pdf_types", "advanced openoffice", ""),
359 ("isbn", "ISBN", "input[type=text]", None, "advanced", "(13 digits)"),
360 ("toc_header", "Table of Contents header", "input[type=text]", None, "advanced", ""),
362 ("booksize", "Page size", "select", "size_options", "advanced", '(Size compatibility: <span class="lulu">Lulu</span>, <span class="newspaper">newspapers</span>, <span class="iso">ISO standards</span>)'),
363 ("page_width", "Page width", "input[type=text]", None, "advanced booksize numeric-field", ""),
364 ("page_height", "Page height", "input[type=text]", None, "advanced booksize numeric-field", ""),
366 ("top_margin", "Top margin", "input[type=text]", None, "advanced margins numeric-field", ""),
367 ("side_margin", "Side margin", "input[type=text]", None, "advanced margins numeric-field", ""),
368 ("bottom_margin", "Bottom margin", "input[type=text]", None, "advanced margins numeric-field", ""),
369 ("gutter", "Gutter", "input[type=text]", None, "advanced margins numeric-field", ""),
371 ("columns", "Columns", "input[type=text]", None, "advanced columns numeric-field", ""),
372 ("column_margin", "Column margin", "input[type=text]", None, "advanced columns numeric-field", ""),
374 ("grey_scale", "Grey-scale", "input[type=checkbox]", 'yes', "advanced", "(for black and white printing)"),
376 #("css_customise", "Customise CSS", "input[type=checkbox]", None, "advanced", "Enter a URL or "),
377 ("css-url", "CSS URL", "input[type=text][disabled]", "css_url", "advanced css-url openoffice", ""),
378 ("font_list", "Available fonts", "ul", "font_list", "advanced css-custom openoffice", ""),
379 ("font_links", "Font examples", "ul", "font_links", "advanced css-custom openoffice", ""),
380 ("css", "CSS", "textarea", "css", "advanced css-custom openoffice", ""),
382 ("rotate", "Rotate pages for binding", "input[type=checkbox]", 'yes', "advanced", "(for RTL books on LTR printing presses, and vice versa)."),
383 #("engine", "Layout engine", "select", "engines", "advanced", ""),
384 #("header", "Header Text", "input[type=text]", None, "advanced", ""),
385 ("max-age", "Use cached data", "input[type=text]", None, "advanced numeric-field", "(younger than this many minutes)."),
386 #("destination", "Use cached data", "input[type=text]", None, "advanced", "(younger than this many minutes)."),
389 FORM_ELEMENT_TYPES
= {
390 'input[type=text]' : '<input type="text" id="%(id)s" name="%(id)s" value="%(val)s" />',
391 'input[type=text][disabled]' : '<input type="text" disabled="disabled" id="%(id)s" name="%(id)s" value="%(val)s" />',
392 'input[type=checkbox]' : '<input type="checkbox" id="%(id)s" name="%(id)s" value="%(val)s" />',
393 'textarea' : '<textarea id="%(id)s" name="%(id)s">%(val)s</textarea>',
394 'select': '<select id="%(id)s" name="%(id)s">%(val)s</select>',
395 'ul': '<ul id="%(id)s">%(val)s</ul>',
399 ("start", "wake up", PUBLIC_CGI_MODES
),
400 ("fetch_zip", "Load data", PUBLIC_CGI_MODES
),
401 ("__init__", "Initialise the book", PUBLIC_CGI_MODES
),
402 ("load_book", "Fetch the book", ('book', 'newspaper', 'web', 'openoffice')),
403 ("add_css", "Add css", ('book', 'newspaper', 'web', 'openoffice')),
404 ("add_section_titles", "Add section titles", ('book', 'newspaper', 'web', 'openoffice')),
405 ("make_epub", "Make the epub file", ('epub',)),
406 ("make_oo_doc", "Make the OpenOffice document", ('openoffice',)),
407 ("generate_pdf", "Generate the main pdf", ('book', 'newspaper', 'web')),
408 ("extract_pdf_outline", "Find page numbers", ('book',)),
409 ("reshape_pdf", "Cut pages to size", ('book', 'newspaper',)),
410 #('make_body_pdf', "Generate the main pdf", ('book', 'newspaper', 'web')),
411 ("number_pdf", "Number pages", ('book', 'newspaper',)),
412 ("make_contents", "Calculate Table of Contents", ('book',)),
413 ("make_preamble_pdf", "Generate preamble pdf", ('book',)),
414 ('make_end_matter_pdf', "Generate end matter pdf", ('book',)),
415 ("concatenated_pdfs", "concatenate the pdfs", ('book',)),
416 #("publish_pdf", "Publish the pdf", ('book', 'newspaper', 'web')),
417 ("finished", "Finished!", PUBLIC_CGI_MODES
),
421 DCNS
= "{http://purl.org/dc/elements/1.1/}"
422 DC
= "http://purl.org/dc/elements/1.1/"
423 FM
= "http://booki.cc/"
424 XHTMLNS
= '{http://www.w3.org/1999/xhtml}'
425 XHTML
= 'http://www.w3.org/1999/xhtml'
427 S3_SECRET
= '/home/douglas/s3.archive.org-secret'
428 S3_ACCESSKEY
= '/home/douglas/s3.archive.org-accesskey'
430 #When it is necessary to creat a navpoint ID, use this string.
431 NAVPOINT_ID_TEMPLATE
= 'chapter%s'
433 CLAIM_UNAUTHORED
= False
435 IMG_CACHE
= 'cache/images/'
437 USE_IMG_CACHE_ALWAYS_HOSTS
= ['objavi.halo.gen.nz']
438 USE_ZIP_CACHE_ALWAYS_HOSTS
= ['objavi.halo.gen.nz']
440 IGNORABLE_TWIKI_BOOKS
= ('Main', 'TWiki', 'PR', 'Trash', 'Sandbox')
442 WHITESPACE_AND_NULL
= ''.join(chr(_x
) for _x
in range(33))
444 #how big to let epub chapters get before splitting?
445 #sony reader has 100k compressed/300k uncompressed limit, but lets leave room to move.
446 EPUB_COMPRESSED_SIZE_MAX
= 70000
447 EPUB_FILE_SIZE_MAX
= 200000
449 #used to identify marker tags in html
450 MARKER_CLASS
= "espri-marker-name-clash-with-no-one"
452 if __name__
== '__main__':
453 print ', '.join(x
for x
in globals().keys() if not x
.startswith('_'))