3 # Part of Objavi2, which turns html manuals into books. This emulates
4 # the Booki-epub-Espri interface for old TWiki books.
6 # Copyright (C) 2009 Douglas Bagnall
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along
19 # with this program; if not, write to the Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 import re
, time
, traceback
24 from pprint
import pformat
26 from objavi
.twiki_wrapper
import TWikiBook
, get_chapter_html
, get_book_list
27 from objavi
.cgi_utils
import parse_args
, optionise
, shift_file
, output_blob_and_exit
, log
, make_book_name
28 from objavi
import config
30 from booki
.xhtml_utils
import EpubChapter
31 from booki
.bookizip
import BookiZip
34 def make_booki_package(server
, bookid
, clean
=False, use_cache
=False):
35 """Extract all chapters from the specified book, as well as
36 associated images and metadata, and zip it all up for conversion
39 If clean is True, the chapters will be cleaned up and converted to
40 XHTML 1.1. If cache is true, images that have been fetched on
41 previous runs will be reused.
44 bookname
= make_book_name(bookid
, server
, '-clean.zip')
46 bookname
= make_book_name(bookid
, server
, '.zip')
48 book
= TWikiBook(bookid
, server
, bookname
)
49 zfn
= book
.filepath(bookname
)
50 md
= book
.get_twiki_metadata()
52 bz
= BookiZip(zfn
, md
)
55 for chapter
in bz
.info
['spine']:
56 contents
= get_chapter_html(server
, bookid
, chapter
, wrapped
=True)
57 c
= EpubChapter(server
, bookid
, chapter
, contents
,
59 images
= c
.localise_links()
60 all_images
.update(images
)
63 bz
.add_to_package(chapter
, chapter
+ '.xhtml', c
.as_xhtml())
65 bz
.add_to_package(chapter
, chapter
+ '.html', c
.as_html())
67 # Add images afterwards, to sift out duplicates
68 for image
in all_images
:
69 imgdata
= c
.image_cache
.read_local_url(image
)
70 bz
.add_to_package(image
, image
, imgdata
)
76 # ARG_VALIDATORS is a mapping between the expected cgi arguments and
77 # functions to validate their values. (None means no validation).
79 "book": re
.compile(r
'^(\w+/?)*\w+$').match
, # can be: BlahBlah/Blah_Blah
80 "server": config
.SERVER_DEFAULTS
.__contains
__,
83 'mode': ('zip', 'html').__contains
__,
84 "all": ['all', 'skip-existing'].__contains
__,
87 if __name__
== '__main__':
89 args
= parse_args(ARG_VALIDATORS
)
90 clean
= bool(args
.get('clean', False))
91 use_cache
= args
.get('use-cache')
93 use_cache
= (os
.environ
.get('HTTP_HOST') in config
.USE_IMG_CACHE_ALWAYS_HOSTS
)
95 make_all
= args
.get('all')
96 if 'server' in args
and 'book' in args
:
97 zfn
= make_booki_package(args
['server'], args
['book'], clean
, use_cache
)
98 fn
= shift_file(zfn
, config
.BOOKI_BOOK_DIR
)
99 ziplink
= '<p><a href="%s">%s zip file.</a></p>' % (fn
, args
['book'])
101 mode
= args
.get('mode', 'html')
106 output_blob_and_exit(data
, 'application/x-booki+zip', args
['book'] + '.zip')
108 elif 'server' in args
and make_all
is not None:
110 for book
in get_book_list(args
['server']):
111 if make_all
== 'skip-existing' and book
+ '.zip' in os
.listdir(config
.BOOKI_BOOK_DIR
):
112 log("skipping %s" % book
)
115 zfn
= make_booki_package(args
['server'], book
, use_cache
=use_cache
)
116 fn
= shift_file(zfn
, config
.BOOKI_BOOK_DIR
)
117 links
.append('<a href="%s">%s</a> ' % (fn
, book
))
119 log('FAILED to make book "%s"' % book
)
120 traceback
.print_exc()
121 ziplink
= ''.join(links
)
125 print "Content-type: text/html; charset=utf-8\n"
126 f
= open('templates/booki-twiki-gateway.html')
130 print template
% {'ziplink': ziplink
,
131 'server-list': optionise(sorted(config
.SERVER_DEFAULTS
.keys()))}