#!/usr/bin/env python # # Copyright (c) 2012 Ciro Mattia Gonano # # Permission to use, copy, modify, and/or distribute this software for # any purpose with or without fee is hereby granted, provided that the # above copyright notice and this permission notice appear in all # copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA # OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # # Changelog # 1.00 - Initial version # 1.10 - Added support for CBZ/CBR files # 1.11 - Added support for ZIP/RAR extensions # 1.20 - Comic optimizations! Split pages not target-oriented (landscape # with portrait target or portrait with landscape target), add palette # and other image optimizations from Mangle. # WARNING: PIL is required for all image mangling! # # Todo: # - Add gracefully exit for CBR if no rarfile.py and no unrar # executable are found # - Improve error reporting # - recurse into dirtree for multiple comics __version__ = '1.20' import os import sys import cbxarchive class HTMLbuilder: def getResult(self): return getImageFileName(self.file) def __init__(self, dstdir, file): self.file = file filename = getImageFileName(file) if (filename != None): htmlfile = dstdir + '/' + filename[0] + '.html' f = open(htmlfile, "w"); f.writelines(["\n", "\n", "\n", "",filename[0],"\n", "\n", "\n", "\n", "
\n", "\n", "" ]) f.close() return None class NCXbuilder: def __init__(self, dstdir, title): ncxfile = dstdir + '/content.ncx' f = open(ncxfile, "w"); f.writelines(["\n", "\n", "\n", "\n\n", "",title,"\n", "\n" ]) f.close() return class OPFBuilder: def __init__(self, dstdir, title, filelist): opffile = dstdir + '/content.opf' # read the first file resolution try: from PIL import Image im = Image.open(dstdir + "/" + filelist[0][0] + filelist[0][1]) width, height = im.size imgres = str(width) + "x" + str(height) except ImportError: print "Could not load PIL, falling back on default HD" imgres = "758x1024" f = open(opffile, "w"); f.writelines(["\n", "\n", "\n", "",title,"\n", "en-US\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n"]) for filename in filelist: f.write("\n") for filename in filelist: if ('.png' == filename[1]): mt = 'image/png'; else: mt = 'image/jpeg'; f.write("\n") f.write("\n\n") for filename in filelist: f.write("\n") f.write("\n\n\n\n") f.close() return def getImageFileName(file): filename = os.path.splitext(file) if (filename[0].startswith('.') or (filename[1].lower() != '.png' and filename[1].lower() != '.jpg' and filename[1].lower() != '.jpeg')): return None return filename def isInFilelist(file,list): filename = os.path.splitext(file) seen = False for item in list: if filename[0] == item[0]: seen = True return seen if __name__ == "__main__": print ('comic2ebook v%(__version__)s. ' 'Written 2012 by Ciro Mattia Gonano.' % globals()) if len(sys.argv)<3 or len(sys.argv)>4: print "Generates HTML, NCX and OPF for a Comic ebook from a bunch of images" print "Optimized for creating Mobipockets to be read into Kindle Paperwhite" print "Usage:" print " %s " % sys.argv[0] print " <title> is optional" sys.exit(1) else: profile = sys.argv[1] dir = sys.argv[2] cbx = cbxarchive.CBxArchive(dir) if cbx.isCbxFile(): cbx.extract() dir = cbx.getPath() if len(sys.argv)==4: title = sys.argv[3] else: title = "comic" filelist = [] try: import image print "Splitting double pages..." for file in os.listdir(dir): if (getImageFileName(file) != None): img = image.ComicPage(dir+'/'+file, profile) img.splitPage(dir) for file in os.listdir(dir): if (getImageFileName(file) != None): print "Optimizing " + file + " for " + profile img = image.ComicPage(dir+'/'+file, profile) img.resizeImage() #img.frameImage() img.quantizeImage() img.saveToDir(dir) except ImportError: print "Could not load PIL, not optimizing image" for file in os.listdir(dir): if (getImageFileName(file) != None and isInFilelist(file,filelist) == False): # put credits at the end if "credits" in file.lower(): os.rename(dir+'/'+file, dir+'/ZZZ999_'+file) file = 'ZZZ999_'+file filename = HTMLbuilder(dir,file).getResult() if (filename != None): filelist.append(filename) NCXbuilder(dir,title) # ensure we're sorting files alphabetically filelist = sorted(filelist, key=lambda name: name[0]) OPFBuilder(dir,title,filelist) sys.exit(0)