From 1edbe389ba59d1cbe6686cd83b1a4e5a55394502 Mon Sep 17 00:00:00 2001 From: Ciro Mattia Gonano Date: Fri, 1 Mar 2013 16:21:54 +0100 Subject: [PATCH] Mainly adhere to PEP 8 code style (http://www.python.org/dev/peps/pep-0008/) Add some commented code for working on Panel view enhancement and natural sorting. --- kcc/comic2ebook.py | 256 +++++++++++++++++++++++++++------------------ 1 file changed, 153 insertions(+), 103 deletions(-) diff --git a/kcc/comic2ebook.py b/kcc/comic2ebook.py index 68797e3..e3f3150 100755 --- a/kcc/comic2ebook.py +++ b/kcc/comic2ebook.py @@ -17,17 +17,33 @@ # PERFORMANCE OF THIS SOFTWARE. # __version__ = '2.5' -__license__ = 'ISC' +__license__ = 'ISC' __copyright__ = '2012-2013, Ciro Mattia Gonano ' __docformat__ = 'restructuredtext en' -import os, sys, tempfile -from shutil import move,copyfile,copytree,rmtree,make_archive +import os +import sys +import tempfile +import re +from shutil import move +from shutil import copyfile +from shutil import copytree +from shutil import rmtree +from shutil import make_archive from optparse import OptionParser -import image, cbxarchive, pdfjpgextract +import image +import cbxarchive +import pdfjpgextract -def buildHTML(path,file): - filename = getImageFileName(file) + +def sort_nicely(l): + convert = lambda text: int(text) if text.isdigit() else text + alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] + l.sort(key=alphanum_key) + + +def buildHTML(path, imgfile): + filename = getImageFileName(imgfile) if filename is not None: htmlpath = '' postfix = '' @@ -36,55 +52,70 @@ def buildHTML(path,file): while True: head, tail = os.path.split(head) if tail == 'Images': - htmlpath = os.path.join(head,'Text',postfix) + htmlpath = os.path.join(head, 'Text', postfix) break postfix = tail + "/" + postfix backref += 1 if not os.path.exists(htmlpath): os.makedirs(htmlpath) - htmlfile = os.path.join(htmlpath,filename[0] + '.html') + htmlfile = os.path.join(htmlpath, filename[0] + '.html') f = open(htmlfile, "w") - f.writelines(["\n", + f.writelines(["\n", "\n", "\n", - "",filename[0],"\n", + "", filename[0], "\n", "\n", "\n", "\n", - "
\"",file,"\"
\n", + "
\"",
\n", + #"
\n", + #"\n", + #"
\n", + #"
\n", + #"
\n", + #"
\n", + #"
\n", + #"\"",\n", + #"
\n", "\n", "" ]) f.close() - return path,file + return path, imgfile + def buildNCX(dstdir, title, chapters): - ncxfile = os.path.join(dstdir,'OEBPS','toc.ncx') + ncxfile = os.path.join(dstdir, 'OEBPS', 'toc.ncx') f = open(ncxfile, "w") f.writelines(["\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "",title,"\n", - "" - ]) + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "", title, "\n", + "" + ]) for chapter in chapters: - folder = chapter[0].replace(os.path.join(dstdir,'OEBPS'),'').lstrip('/').lstrip('\\\\') + folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\') title = os.path.basename(folder) - filename = getImageFileName(os.path.join(folder,chapter[1])) - f.write("" + title + filename = getImageFileName(os.path.join(folder, chapter[1])) + f.write("" + title + "\n") f.write("\n") f.close() return + def buildOPF(profile, dstdir, title, filelist, cover=None, righttoleft=False): - opffile = os.path.join(dstdir,'OEBPS','content.opf') + opffile = os.path.join(dstdir, 'OEBPS', 'content.opf') # read the first file resolution profilelabel, deviceres, palette = image.ProfileData.Profiles[profile] imgres = str(deviceres[0]) + "x" + str(deviceres[1]) @@ -94,24 +125,28 @@ def buildOPF(profile, dstdir, title, filelist, cover=None, righttoleft=False): writingmode = "horizontal-lr" f = open(opffile, "w") f.writelines(["\n", - "\n", - "\n", - "",title,"\n", - "en-US\n", - "015ffaec-9340-42f8-b163-a0c5ab7d0611\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n\n\n" - ]) + "\n", + "\n", + "", title, "\n", + "en-US\n", + "", + "015ffaec-9340-42f8-b163-a0c5ab7d0611\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n\n\n" + ]) # set cover if cover is not None: - filename = getImageFileName(cover.replace(os.path.join(dstdir,'OEBPS'),'').lstrip('/').lstrip('\\\\')) + filename = getImageFileName(cover.replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\')) if '.png' == filename[1]: mt = 'image/png' else: @@ -119,57 +154,65 @@ def buildOPF(profile, dstdir, title, filelist, cover=None, righttoleft=False): f.write("\n") reflist = [] for path in filelist: - folder = path[0].replace(os.path.join(dstdir,'OEBPS'),'').lstrip('/').lstrip('\\\\') + folder = path[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\') filename = getImageFileName(path[1]) - uniqueid = os.path.join(folder,filename[0]).replace('/','_') + uniqueid = os.path.join(folder, filename[0]).replace('/', '_') reflist.append(uniqueid) - f.write("\n") if '.png' == filename[1]: mt = 'image/png' else: mt = 'image/jpeg' - f.write("\n") + f.write("\n") f.write("\n\n") for entry in reflist: f.write("\n") f.write("\n\n\n\n") f.close() # finish with standard ePub folders - os.mkdir(os.path.join(dstdir,'META-INF')) - f = open(os.path.join(dstdir,'mimetype'), 'w') + os.mkdir(os.path.join(dstdir, 'META-INF')) + f = open(os.path.join(dstdir, 'mimetype'), 'w') f.write('application/epub+zip') f.close() - f = open(os.path.join(dstdir,'META-INF','container.xml'), 'w') + f = open(os.path.join(dstdir, 'META-INF', 'container.xml'), 'w') f.writelines(["\n", - "\n", - "\n", - "\n", - "\n", - ""]) + "\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'): + +def getImageFileName(imgfile): + filename = os.path.splitext(imgfile) + 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) + +def isInFilelist(filename, filelist): + filename = os.path.splitext(filename) seen = False - for item in list: + for item in filelist: if filename[0] == item[0]: seen = True return seen + def applyImgOptimization(img): img.optimizeImage() img.cropWhiteSpace(10.0) if options.cutpagenumbers: img.cutPageNumber() - img.resizeImage(options.upscale,options.stretch,options.black_borders) + img.resizeImage(options.upscale, options.stretch, options.black_borders) img.quantizeImage() @@ -177,91 +220,96 @@ def dirImgProcess(path): global options for (dirpath, dirnames, filenames) in os.walk(path): - for file in filenames: - if getImageFileName(file) is not None: + for afile in filenames: + if getImageFileName(afile) is not None: if options.verbose: - print "Optimizing " + file + " for " + options.profile + print "Optimizing " + afile + " for " + options.profile else: print ".", - img = image.ComicPage(os.path.join(dirpath,file), options.profile) + img = image.ComicPage(os.path.join(dirpath, afile), options.profile) split = img.splitPage(dirpath, options.righttoleft) if split is not None: if options.verbose: - print "Splitted " + file - img0 = image.ComicPage(split[0],options.profile) + print "Splitted " + afile + img0 = image.ComicPage(split[0], options.profile) applyImgOptimization(img0) img0.saveToDir(dirpath) - img1 = image.ComicPage(split[1],options.profile) + img1 = image.ComicPage(split[1], options.profile) applyImgOptimization(img1) img1.saveToDir(dirpath) else: applyImgOptimization(img) img.saveToDir(dirpath) + def genEpubStruct(path): global options filelist = [] chapterlist = [] cover = None - os.mkdir(os.path.join(path,'OEBPS','Text')) - for (dirpath, dirnames, filenames) in os.walk(os.path.join(path,'OEBPS','Images')): + os.mkdir(os.path.join(path, 'OEBPS', 'Text')) + for (dirpath, dirnames, filenames) in os.walk(os.path.join(path, 'OEBPS', 'Images')): chapter = False - for file in filenames: - filename = getImageFileName(file) + for afile in filenames: + filename = getImageFileName(afile) if filename is not None: # put credits at the end - if "credit" in file.lower(): - os.rename(os.path.join(dirpath,file), os.path.join(dirpath,'ZZZ999_'+file)) - file = 'ZZZ999_'+file - if "+" in file.lower() or "#" in file.lower(): - newfilename = file.replace('+','_').replace('#','_') - os.rename(os.path.join(dirpath,file), os.path.join(dirpath,newfilename)) - file = newfilename - filelist.append(buildHTML(dirpath,file)) + if "credit" in afile.lower(): + os.rename(os.path.join(dirpath, afile), os.path.join(dirpath, 'ZZZ999_' + afile)) + afile = 'ZZZ999_' + afile + if "+" in afile.lower() or "#" in afile.lower(): + newfilename = afile.replace('+', '_').replace('#', '_') + os.rename(os.path.join(dirpath, afile), os.path.join(dirpath, newfilename)) + afile = newfilename + filelist.append(buildHTML(dirpath, afile)) if not chapter: - chapterlist.append((dirpath.replace('Images','Text'),filelist[-1][1])) + chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1])) chapter = True if cover is None: - cover = os.path.join(filelist[-1][0],'cover' + getImageFileName(filelist[-1][1])[1]) - copyfile(os.path.join(filelist[-1][0],filelist[-1][1]), cover) - buildNCX(path,options.title,chapterlist) + cover = os.path.join(filelist[-1][0], 'cover' + getImageFileName(filelist[-1][1])[1]) + copyfile(os.path.join(filelist[-1][0], filelist[-1][1]), cover) + buildNCX(path, options.title, chapterlist) # ensure we're sorting files alphabetically filelist = sorted(filelist, key=lambda name: (name[0].lower(), name[1].lower())) - buildOPF(options.profile,path,options.title,filelist,cover,options.righttoleft) + buildOPF(options.profile, path, options.title, filelist, cover, options.righttoleft) -def getWorkFolder(file): + +def getWorkFolder(afile): workdir = tempfile.mkdtemp() - fname = os.path.splitext(file) - if os.path.isdir(file): + fname = os.path.splitext(afile) + if os.path.isdir(afile): try: import shutil os.rmdir(workdir) # needed for copytree() fails if dst already exists - copytree(file, workdir) + copytree(afile, workdir) path = workdir except OSError: raise elif fname[1].lower() == '.pdf': - pdf = pdfjpgextract.PdfJpgExtract(file) - path = pdf.extract(workdir) + pdf = pdfjpgextract.PdfJpgExtract(afile) + path = pdf.extract() else: - cbx = cbxarchive.CBxArchive(file) + cbx = cbxarchive.CBxArchive(afile) if cbx.isCbxFile(): path = cbx.extract(workdir) else: raise TypeError - move(path,path + "_temp") - move(path + "_temp",os.path.join(path,'OEBPS','Images')) + move(path, path + "_temp") + move(path + "_temp", os.path.join(path, 'OEBPS', 'Images')) return path + def Copyright(): print ('comic2ebook v%(__version__)s. ' - 'Written 2012 by Ciro Mattia Gonano.' % globals()) + 'Written 2012 by Ciro Mattia Gonano.' % globals()) + def Usage(): 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" parser.print_help() + def main(argv=None): global parser, options, epub_path usage = "Usage: %prog [options] comic_file|comic_folder" @@ -275,15 +323,16 @@ def main(argv=None): parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="Verbose output [default=False]") parser.add_option("--no-image-processing", action="store_false", dest="imgproc", default=True, - help="Do not apply image preprocessing (page splitting and optimizations) [default=True]") + help="Do not apply image preprocessing (page splitting and optimizations) [default=True]") parser.add_option("--upscale-images", action="store_true", dest="upscale", default=False, - help="Resize images smaller than device's resolution [default=False]") + help="Resize images smaller than device's resolution [default=False]") parser.add_option("--stretch-images", action="store_true", dest="stretch", default=False, - help="Stretch images to device's resolution [default=False]") + help="Stretch images to device's resolution [default=False]") parser.add_option("--black-borders", action="store_true", dest="black_borders", default=False, - help="Use black borders (instead of white ones) when not stretching and ratio is not like the device's one [default=False]") + help="Use black borders (instead of white ones) when not stretching and ratio " + + "is not like the device's one [default=False]") parser.add_option("--no-cut-page-numbers", action="store_false", dest="cutpagenumbers", default=True, - help="Do not try to cut page numbering on images [default=True]") + help="Do not try to cut page numbering on images [default=True]") options, args = parser.parse_args(argv) if len(args) != 1: parser.print_help() @@ -301,11 +350,12 @@ def main(argv=None): epubpath = args[0] + '.epub' else: epubpath = os.path.splitext(args[0])[0] + '.epub' - make_archive(path + '_comic','zip',path) + make_archive(path + '_comic', 'zip', path) move(path + '_comic.zip', epubpath) rmtree(path) return epubpath + def getEpubPath(): global epub_path return epub_path