From bd52d0eee7dcc10a9e7bbcfdc508f0893357f754 Mon Sep 17 00:00:00 2001 From: darodi <4682830+darodi@users.noreply.github.com> Date: Sat, 13 May 2023 17:36:50 +0200 Subject: [PATCH] OptionParser to ArgumentParser --- README.md | 132 +++++++++---------- kcc-c2e.py | 5 +- kcc-c2p.py | 5 +- kcc.py | 5 +- kindlecomicconverter/KCC_gui.py | 2 +- kindlecomicconverter/comic2ebook.py | 181 +++++++++++++-------------- kindlecomicconverter/comic2panel.py | 181 ++++++++++++++------------- kindlecomicconverter/comicarchive.py | 2 +- 8 files changed, 255 insertions(+), 258 deletions(-) diff --git a/README.md b/README.md index 83c72edc..edfa464d 100644 --- a/README.md +++ b/README.md @@ -136,89 +136,81 @@ sudo apt-get install python3 p7zip-full python3-pil python3-psutil python3-slugi ### Standalone `kcc-c2e.py` usage: ``` -Usage: kcc-c2e [options] comic_file|comic_folder - -Options: - MAIN: - -p PROFILE, --profile=PROFILE - Device profile (Available options: K1, K2, K34, K578, - KDX, KPW, KPW5, KV, KO, K11, KS, KoMT, KoG, KoGHD, - KoA, KoAHD, KoAH2O, KoAO, KoN, KoC, KoL, KoF, KoS, - KoE) [Default=KV] - -m, --manga-style Manga style (right-to-left reading and splitting) - -q, --hq Try to increase the quality of magnification - -2, --two-panel Display two not four panels in Panel View mode - -w, --webtoon Webtoon processing mode - --targetsize=TARGETSIZE - the maximal size of output file in MB. [Default=100MB - for webtoon and 400MB for others] - - OUTPUT SETTINGS: - -o OUTPUT, --output=OUTPUT - Output generated file to specified directory or file - -t TITLE, --title=TITLE - Comic title [Default=filename or directory name] - -f FORMAT, --format=FORMAT - Output format (Available options: Auto, MOBI, EPUB, - CBZ, KFX, MOBI+EPUB) [Default=Auto] - -b BATCHSPLIT, --batchsplit=BATCHSPLIT - Split output into multiple files. 0: Don't split 1: - Automatic mode 2: Consider every subdirectory as - separate volume [Default=0] - - PROCESSING: - -n, --noprocessing Do not modify image and ignore any profil or - processing option - -u, --upscale Resize images smaller than device's resolution - -s, --stretch Stretch images to device's resolution - -r SPLITTER, --splitter=SPLITTER - Double page parsing mode. 0: Split 1: Rotate 2: Both - [Default=0] - -g GAMMA, --gamma=GAMMA - Apply gamma correction to linearize the image - [Default=Auto] - -c CROPPING, --cropping=CROPPING - Set cropping mode. 0: Disabled 1: Margins 2: Margins + - page numbers [Default=2] - --cp=CROPPINGP, --croppingpower=CROPPINGP +usage: kcc-c2e [options] [input] + +MANDATORY: + input Full path to comic folder or file(s) to be processed. + +MAIN: + -p PROFILE, --profile PROFILE + Device profile (Available options: K1, K2, K34, K578, KDX, KPW, KPW5, KV, KO, K11, KS, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O, KoAO, KoN, KoC, KoL, KoF, KoS, KoE) [Default=KV] + -m, --manga-style Manga style (right-to-left reading and splitting) + -q, --hq Try to increase the quality of magnification + -2, --two-panel Display two not four panels in Panel View mode + -w, --webtoon Webtoon processing mode + --ts TARGETSIZE, --targetsize TARGETSIZE + the maximal size of output file in MB. [Default=100MB for webtoon and 400MB for others] + +PROCESSING: + -n, --noprocessing Do not modify image and ignore any profil or processing option + -u, --upscale Resize images smaller than device's resolution + -s, --stretch Stretch images to device's resolution + -r SPLITTER, --splitter SPLITTER + Double page parsing mode. 0: Split 1: Rotate 2: Both [Default=0] + -g GAMMA, --gamma GAMMA + Apply gamma correction to linearize the image [Default=Auto] + -c CROPPING, --cropping CROPPING + Set cropping mode. 0: Disabled 1: Margins 2: Margins + page numbers [Default=2] + --cp CROPPINGP, --croppingpower CROPPINGP Set cropping power [Default=1.0] - --cm=CROPPINGM, --croppingminimum=CROPPINGM + --cm CROPPINGM, --croppingminimum CROPPINGM Set cropping minimum area ratio [Default=0.0] - --blackborders Disable autodetection and force black borders - --whiteborders Disable autodetection and force white borders - --forcecolor Don't convert images to grayscale - --forcepng Create PNG files instead JPEG - --mozjpeg Create JPEG files using mozJpeg - --maximizestrips Turn 1x4 strips to 2x2 strips - -d, --delete Delete source file(s) or a directory. It's not - recoverable. - - CUSTOM PROFILE: - --customwidth=CUSTOMWIDTH + --blackborders Disable autodetection and force black borders + --whiteborders Disable autodetection and force white borders + --forcecolor Don't convert images to grayscale + --forcepng Create PNG files instead JPEG + --mozjpeg Create JPEG files using mozJpeg + --maximizestrips Turn 1x4 strips to 2x2 strips + -d, --delete Delete source file(s) or a directory. It's not recoverable. + +OUTPUT SETTINGS: + -o OUTPUT, --output OUTPUT + Output generated file to specified directory or file + -t TITLE, --title TITLE + Comic title [Default=filename or directory name] + -f FORMAT, --format FORMAT + Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX, MOBI+EPUB) [Default=Auto] + -b BATCHSPLIT, --batchsplit BATCHSPLIT + Split output into multiple files. 0: Don't split 1: Automatic mode 2: Consider every subdirectory as separate volume [Default=0] + +CUSTOM PROFILE: + --customwidth CUSTOMWIDTH Replace screen width provided by device profile - --customheight=CUSTOMHEIGHT + --customheight CUSTOMHEIGHT Replace screen height provided by device profile - OTHER: - -h, --help Show this help message and exit +OTHER: + -h, --help Show this help message and exit + ``` ### Standalone `kcc-c2p.py` usage: ``` -Usage: kcc-c2p [options] comic_folder +usage: kcc-c2p [options] [input] + +MANDATORY: + input Full path to comic folder(s) to be processed. Separate multiple inputs with spaces. -Options: - MANDATORY: - -y HEIGHT, --height=HEIGHT +MAIN: + -y HEIGHT, --height HEIGHT Height of the target device screen - -i, --in-place Overwrite source directory - -m, --merge Combine every directory into a single image before - splitting + -i, --in-place Overwrite source directory + -m, --merge Combine every directory into a single image before splitting - OTHER: - -d, --debug Create debug file for every split image - -h, --help Show this help message and exit +OTHER: + -d, --debug Create debug file for every split image + -h, --help Show this help message and exit ``` ## CREDITS diff --git a/kcc-c2e.py b/kcc-c2e.py index 72606d5d..bb38740b 100755 --- a/kcc-c2e.py +++ b/kcc-c2e.py @@ -19,8 +19,9 @@ # PERFORMANCE OF THIS SOFTWARE. import sys -if sys.version_info[0] != 3: - print('ERROR: This is Python 3 script!') + +if sys.version_info < (3, 8, 0): + print('ERROR: This is a Python 3.8+ script!') exit(1) from multiprocessing import freeze_support, set_start_method diff --git a/kcc-c2p.py b/kcc-c2p.py index 08e39524..353776d5 100755 --- a/kcc-c2p.py +++ b/kcc-c2p.py @@ -19,8 +19,9 @@ # PERFORMANCE OF THIS SOFTWARE. import sys -if sys.version_info[0] != 3: - print('ERROR: This is Python 3 script!') + +if sys.version_info < (3, 8, 0): + print('ERROR: This is a Python 3.8+ script!') exit(1) from multiprocessing import freeze_support, set_start_method diff --git a/kcc.py b/kcc.py index 8d9e93a9..8e12cfd9 100755 --- a/kcc.py +++ b/kcc.py @@ -19,8 +19,9 @@ # PERFORMANCE OF THIS SOFTWARE. import sys -if sys.version_info[0] != 3: - print('ERROR: This is Python 3 script!') + +if sys.version_info < (3, 8, 0): + print('ERROR: This is a Python 3.8+ script!') exit(1) # OS specific workarounds diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index ba4f4af3..464daee3 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -255,7 +255,7 @@ def run(self): MW.modeConvert.emit(0) parser = comic2ebook.makeParser() - options, _ = parser.parse_args() + options = parser.parse_args() argv = '' currentJobs = [] diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 85f933bb..398bf217 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -20,6 +20,7 @@ import os import sys +from argparse import ArgumentParser from time import strftime, gmtime from copy import copy from glob import glob, escape @@ -28,10 +29,9 @@ from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED from tempfile import mkdtemp, gettempdir, TemporaryFile from shutil import move, copytree, rmtree, copyfile -from optparse import OptionParser, OptionGroup from multiprocessing import Pool from uuid import uuid4 -from slugify import slugify as slugifyExt +from slugify import slugify as slugify_ext from PIL import Image from subprocess import STDOUT, PIPE from psutil import Popen, virtual_memory, disk_usage @@ -54,23 +54,23 @@ def main(argv=None): global options parser = makeParser() - optionstemplate, args = parser.parse_args(argv) - if len(args) == 0: + args = parser.parse_args(argv) + options = copy(args) + if not argv or options.input == []: parser.print_help() return 0 if sys.platform.startswith('win'): - sources = set([source for arg in args for source in glob(escape(arg))]) + sources = set([source for option in options.input for source in glob(escape(option))]) else: - sources = set(args) + sources = set(options.input) if len(sources) == 0: print('No matching files found.') return 1 for source in sources: source = source.rstrip('\\').rstrip('/') - options = copy(optionstemplate) + options = copy(args) options = checkOptions(options) - if len(sources) > 1: - print('Working on ' + source + '...') + print('Working on ' + source + '...') makeBook(source) return 0 @@ -546,7 +546,7 @@ def imgDirectoryProcessing(path): GUI.progressBarTick.emit(str(pagenumber)) if len(work) > 0: for i in work: - workerPool.apply_async(func=imgFileProcessing, args=(i, ), callback=imgFileProcessingTick) + workerPool.apply_async(func=imgFileProcessing, args=(i,), callback=imgFileProcessingTick) workerPool.close() workerPool.join() if GUI and not GUI.conversionAlive: @@ -910,9 +910,9 @@ def createNewTome(): def slugify(value, isdir): if isdir: - value = slugifyExt(value, regex_pattern=r'[^-a-z0-9_\.]+').strip('.') + value = slugify_ext(value, regex_pattern=r'[^-a-z0-9_\.]+').strip('.') else: - value = slugifyExt(value).strip('.') + value = slugify_ext(value).strip('.') value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value, count=2)) return value @@ -933,85 +933,84 @@ def makeZIP(zipfilename, basedir, isepub=False): def makeParser(): - psr = OptionParser(usage="Usage: kcc-c2e [options] comic_file|comic_folder", add_help_option=False) - - mainOptions = OptionGroup(psr, "MAIN") - processingOptions = OptionGroup(psr, "PROCESSING") - outputOptions = OptionGroup(psr, "OUTPUT SETTINGS") - customProfileOptions = OptionGroup(psr, "CUSTOM PROFILE") - otherOptions = OptionGroup(psr, "OTHER") - - mainOptions.add_option("-p", "--profile", action="store", dest="profile", default="KV", - help="Device profile (Available options: K1, K2, K34, K578, KDX, KPW, KPW5, KV, KO, " - "K11, KS, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O, KoAO, KoN, KoC, KoL, KoF, KoS, KoE)" - " [Default=KV]") - mainOptions.add_option("-m", "--manga-style", action="store_true", dest="righttoleft", default=False, - help="Manga style (right-to-left reading and splitting)") - mainOptions.add_option("-q", "--hq", action="store_true", dest="hq", default=False, - help="Try to increase the quality of magnification") - mainOptions.add_option("-2", "--two-panel", action="store_true", dest="autoscale", default=False, - help="Display two not four panels in Panel View mode") - mainOptions.add_option("-w", "--webtoon", action="store_true", dest="webtoon", default=False, - help="Webtoon processing mode"), - mainOptions.add_option("--targetsize", type="int", dest="targetsize", default=None, - help="the maximal size of output file in MB." - " [Default=100MB for webtoon and 400MB for others]") - - outputOptions.add_option("-o", "--output", action="store", dest="output", default=None, - help="Output generated file to specified directory or file") - outputOptions.add_option("-t", "--title", action="store", dest="title", default="defaulttitle", - help="Comic title [Default=filename or directory name]") - outputOptions.add_option("-f", "--format", action="store", dest="format", default="Auto", - help="Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX, MOBI+EPUB) " - "[Default=Auto]") - outputOptions.add_option("-b", "--batchsplit", type="int", dest="batchsplit", default="0", - help="Split output into multiple files. 0: Don't split 1: Automatic mode " - "2: Consider every subdirectory as separate volume [Default=0]") - - processingOptions.add_option("-n", "--noprocessing", action="store_true", dest="noprocessing", default=False, - help="Do not modify image and ignore any profil or processing option") - processingOptions.add_option("-u", "--upscale", action="store_true", dest="upscale", default=False, - help="Resize images smaller than device's resolution") - processingOptions.add_option("-s", "--stretch", action="store_true", dest="stretch", default=False, - help="Stretch images to device's resolution") - processingOptions.add_option("-r", "--splitter", type="int", dest="splitter", default="0", - help="Double page parsing mode. 0: Split 1: Rotate 2: Both [Default=0]") - processingOptions.add_option("-g", "--gamma", type="float", dest="gamma", default="0.0", - help="Apply gamma correction to linearize the image [Default=Auto]") - processingOptions.add_option("-c", "--cropping", type="int", dest="cropping", default="2", - help="Set cropping mode. 0: Disabled 1: Margins 2: Margins + page numbers [Default=2]") - processingOptions.add_option("--cp", "--croppingpower", type="float", dest="croppingp", default="1.0", - help="Set cropping power [Default=1.0]") - processingOptions.add_option("--cm", "--croppingminimum", type="float", dest="croppingm", default="0.0", - help="Set cropping minimum area ratio [Default=0.0]") - processingOptions.add_option("--blackborders", action="store_true", dest="black_borders", default=False, - help="Disable autodetection and force black borders") - processingOptions.add_option("--whiteborders", action="store_true", dest="white_borders", default=False, - help="Disable autodetection and force white borders") - processingOptions.add_option("--forcecolor", action="store_true", dest="forcecolor", default=False, - help="Don't convert images to grayscale") - processingOptions.add_option("--forcepng", action="store_true", dest="forcepng", default=False, - help="Create PNG files instead JPEG") - processingOptions.add_option("--mozjpeg", action="store_true", dest="mozjpeg", default=False, - help="Create JPEG files using mozJpeg") - processingOptions.add_option("--maximizestrips", action="store_true", dest="maximizestrips", default=False, - help="Turn 1x4 strips to 2x2 strips") - processingOptions.add_option("-d", "--delete", action="store_true", dest="delete", default=False, - help="Delete source file(s) or a directory. It's not recoverable.") - - customProfileOptions.add_option("--customwidth", type="int", dest="customwidth", default=0, - help="Replace screen width provided by device profile") - customProfileOptions.add_option("--customheight", type="int", dest="customheight", default=0, - help="Replace screen height provided by device profile") - - otherOptions.add_option("-h", "--help", action="help", - help="Show this help message and exit") - - psr.add_option_group(mainOptions) - psr.add_option_group(outputOptions) - psr.add_option_group(processingOptions) - psr.add_option_group(customProfileOptions) - psr.add_option_group(otherOptions) + psr = ArgumentParser(prog="kcc-c2e", usage="kcc-c2e [options] [input]", add_help=False) + + mandatory_options = psr.add_argument_group("MANDATORY") + main_options = psr.add_argument_group("MAIN") + processing_options = psr.add_argument_group("PROCESSING") + output_options = psr.add_argument_group("OUTPUT SETTINGS") + custom_profile_options = psr.add_argument_group("CUSTOM PROFILE") + other_options = psr.add_argument_group("OTHER") + + mandatory_options.add_argument("input", action="extend", nargs="*", default=None, + help="Full path to comic folder or file(s) to be processed.") + + main_options.add_argument("-p", "--profile", action="store", dest="profile", default="KV", + help="Device profile (Available options: K1, K2, K34, K578, KDX, KPW, KPW5, KV, KO, " + "K11, KS, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O, KoAO, KoN, KoC, KoL, KoF, KoS, KoE)" + " [Default=KV]") + main_options.add_argument("-m", "--manga-style", action="store_true", dest="righttoleft", default=False, + help="Manga style (right-to-left reading and splitting)") + main_options.add_argument("-q", "--hq", action="store_true", dest="hq", default=False, + help="Try to increase the quality of magnification") + main_options.add_argument("-2", "--two-panel", action="store_true", dest="autoscale", default=False, + help="Display two not four panels in Panel View mode") + main_options.add_argument("-w", "--webtoon", action="store_true", dest="webtoon", default=False, + help="Webtoon processing mode"), + main_options.add_argument("--ts", "--targetsize", type=int, dest="targetsize", default=None, + help="the maximal size of output file in MB." + " [Default=100MB for webtoon and 400MB for others]") + + output_options.add_argument("-o", "--output", action="store", dest="output", default=None, + help="Output generated file to specified directory or file") + output_options.add_argument("-t", "--title", action="store", dest="title", default="defaulttitle", + help="Comic title [Default=filename or directory name]") + output_options.add_argument("-f", "--format", action="store", dest="format", default="Auto", + help="Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX, MOBI+EPUB) " + "[Default=Auto]") + output_options.add_argument("-b", "--batchsplit", type=int, dest="batchsplit", default="0", + help="Split output into multiple files. 0: Don't split 1: Automatic mode " + "2: Consider every subdirectory as separate volume [Default=0]") + + processing_options.add_argument("-n", "--noprocessing", action="store_true", dest="noprocessing", default=False, + help="Do not modify image and ignore any profil or processing option") + processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False, + help="Resize images smaller than device's resolution") + processing_options.add_argument("-s", "--stretch", action="store_true", dest="stretch", default=False, + help="Stretch images to device's resolution") + processing_options.add_argument("-r", "--splitter", type=int, dest="splitter", default="0", + help="Double page parsing mode. 0: Split 1: Rotate 2: Both [Default=0]") + processing_options.add_argument("-g", "--gamma", type=float, dest="gamma", default="0.0", + help="Apply gamma correction to linearize the image [Default=Auto]") + processing_options.add_argument("-c", "--cropping", type=int, dest="cropping", default="2", + help="Set cropping mode. 0: Disabled 1: Margins 2: Margins + page numbers [Default=2]") + processing_options.add_argument("--cp", "--croppingpower", type=float, dest="croppingp", default="1.0", + help="Set cropping power [Default=1.0]") + processing_options.add_argument("--cm", "--croppingminimum", type=float, dest="croppingm", default="0.0", + help="Set cropping minimum area ratio [Default=0.0]") + processing_options.add_argument("--blackborders", action="store_true", dest="black_borders", default=False, + help="Disable autodetection and force black borders") + processing_options.add_argument("--whiteborders", action="store_true", dest="white_borders", default=False, + help="Disable autodetection and force white borders") + processing_options.add_argument("--forcecolor", action="store_true", dest="forcecolor", default=False, + help="Don't convert images to grayscale") + processing_options.add_argument("--forcepng", action="store_true", dest="forcepng", default=False, + help="Create PNG files instead JPEG") + processing_options.add_argument("--mozjpeg", action="store_true", dest="mozjpeg", default=False, + help="Create JPEG files using mozJpeg") + processing_options.add_argument("--maximizestrips", action="store_true", dest="maximizestrips", default=False, + help="Turn 1x4 strips to 2x2 strips") + processing_options.add_argument("-d", "--delete", action="store_true", dest="delete", default=False, + help="Delete source file(s) or a directory. It's not recoverable.") + + custom_profile_options.add_argument("--customwidth", type=int, dest="customwidth", default=0, + help="Replace screen width provided by device profile") + custom_profile_options.add_argument("--customheight", type=int, dest="customheight", default=0, + help="Replace screen height provided by device profile") + + other_options.add_argument("-h", "--help", action="help", + help="Show this help message and exit") + return psr diff --git a/kindlecomicconverter/comic2panel.py b/kindlecomicconverter/comic2panel.py index b13cb59d..48244ad3 100644 --- a/kindlecomicconverter/comic2panel.py +++ b/kindlecomicconverter/comic2panel.py @@ -20,8 +20,8 @@ import os import sys +from argparse import ArgumentParser from shutil import rmtree, copytree, move -from optparse import OptionParser, OptionGroup from multiprocessing import Pool from PIL import Image, ImageChops, ImageOps, ImageDraw from .shared import getImageFileName, walkLevel, walkSort, sanitizeTrace @@ -102,7 +102,7 @@ def splitImage(work): opt = work[2] filePath = os.path.join(path, name) Image.warnings.simplefilter('error', Image.DecompressionBombWarning) - Image.MAX_IMAGE_PIXELS = 1000000000 + Image.MAX_IMAGE_PIXELS = 1000000000 imgOrg = Image.open(filePath).convert('RGB') imgProcess = Image.open(filePath).convert('1') widthImg, heightImg = imgOrg.size @@ -116,7 +116,7 @@ def splitImage(work): panelDetected = False panels = [] while yWork < heightImg: - tmpImg = imgProcess.crop([4, yWork, widthImg-4, yWork + 4]) + tmpImg = imgProcess.crop((4, yWork, widthImg-4, yWork + 4)) solid = detectSolid(tmpImg) if not solid and not panelDetected: panelDetected = True @@ -149,7 +149,7 @@ def splitImage(work): if opt.debug: for panel in panelsProcessed: - draw.rectangle([(0, panel[0]), (widthImg, panel[1])], (0, 255, 0, 128), (0, 0, 255, 255)) + draw.rectangle(((0, panel[0]), (widthImg, panel[1])), (0, 255, 0, 128), (0, 0, 255, 255)) debugImage = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg) debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG') @@ -182,7 +182,7 @@ def splitImage(work): if pageHeight > 15: newPage = Image.new('RGB', (widthImg, pageHeight)) for panel in page: - panelImg = imgOrg.crop([0, panelsProcessed[panel][0], widthImg, panelsProcessed[panel][1]]) + panelImg = imgOrg.crop((0, panelsProcessed[panel][0], widthImg, panelsProcessed[panel][1])) newPage.paste(panelImg, (0, targetHeight)) targetHeight += panelsProcessed[panel][2] newPage.save(os.path.join(path, os.path.splitext(name)[0] + '-' + str(pageNumber) + '.png'), 'PNG') @@ -193,97 +193,100 @@ def splitImage(work): def main(argv=None, qtgui=None): - global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput - parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False) - mainOptions = OptionGroup(parser, "MANDATORY") - otherOptions = OptionGroup(parser, "OTHER") - mainOptions.add_option("-y", "--height", type="int", dest="height", default=0, - help="Height of the target device screen") - mainOptions.add_option("-i", "--in-place", action="store_true", dest="inPlace", default=False, - help="Overwrite source directory") - mainOptions.add_option("-m", "--merge", action="store_true", dest="merge", default=False, - help="Combine every directory into a single image before splitting") - otherOptions.add_option("-d", "--debug", action="store_true", dest="debug", default=False, - help="Create debug file for every split image") - otherOptions.add_option("-h", "--help", action="help", - help="Show this help message and exit") - parser.add_option_group(mainOptions) - parser.add_option_group(otherOptions) - options, args = parser.parse_args(argv) + global args, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput + parser = ArgumentParser(prog="kcc-c2p", usage="kcc-c2p [options] [input]", add_help=False) + + mandatory_options = parser.add_argument_group("MANDATORY") + main_options = parser.add_argument_group("MAIN") + other_options = parser.add_argument_group("OTHER") + mandatory_options.add_argument("input", action="extend", nargs="*", default=None, + help="Full path to comic folder(s) to be processed. Separate multiple inputs" + " with spaces.") + main_options.add_argument("-y", "--height", type=int, dest="height", default=0, + help="Height of the target device screen") + main_options.add_argument("-i", "--in-place", action="store_true", dest="inPlace", default=False, + help="Overwrite source directory") + main_options.add_argument("-m", "--merge", action="store_true", dest="merge", default=False, + help="Combine every directory into a single image before splitting") + other_options.add_argument("-d", "--debug", action="store_true", dest="debug", default=False, + help="Create debug file for every split image") + other_options.add_argument("-h", "--help", action="help", + help="Show this help message and exit") + args = parser.parse_args(argv) if qtgui: GUI = qtgui else: GUI = None - if len(args) != 1: + if not argv or args.input == []: parser.print_help() return 1 - if options.height > 0: - options.sourceDir = args[0] - options.targetDir = args[0] + "-Splitted" - if os.path.isdir(options.sourceDir): - rmtree(options.targetDir, True) - copytree(options.sourceDir, options.targetDir) - work = [] - pagenumber = 1 - splitWorkerOutput = [] - splitWorkerPool = Pool(maxtasksperchild=10) - if options.merge: - print("Merging images...") - directoryNumer = 1 - mergeWork = [] - mergeWorkerOutput = [] - mergeWorkerPool = Pool(maxtasksperchild=10) - mergeWork.append([options.targetDir]) - for root, dirs, files in os.walk(options.targetDir, False): - dirs, files = walkSort(dirs, files) - for directory in dirs: - directoryNumer += 1 - mergeWork.append([os.path.join(root, directory)]) + if args.height > 0: + for sourceDir in args.input: + targetDir = sourceDir + "-Splitted" + if os.path.isdir(sourceDir): + rmtree(targetDir, True) + copytree(sourceDir, targetDir) + work = [] + pagenumber = 1 + splitWorkerOutput = [] + splitWorkerPool = Pool(maxtasksperchild=10) + if args.merge: + print("Merging images...") + directoryNumer = 1 + mergeWork = [] + mergeWorkerOutput = [] + mergeWorkerPool = Pool(maxtasksperchild=10) + mergeWork.append([targetDir]) + for root, dirs, files in os.walk(targetDir, False): + dirs, files = walkSort(dirs, files) + for directory in dirs: + directoryNumer += 1 + mergeWork.append([os.path.join(root, directory)]) + if GUI: + GUI.progressBarTick.emit('Combining images') + GUI.progressBarTick.emit(str(directoryNumer)) + for i in mergeWork: + mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectoryTick) + mergeWorkerPool.close() + mergeWorkerPool.join() + if GUI and not GUI.conversionAlive: + rmtree(targetDir, True) + raise UserWarning("Conversion interrupted.") + if len(mergeWorkerOutput) > 0: + rmtree(targetDir, True) + raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0], + mergeWorkerOutput[0][1]) + print("Splitting images...") + for root, _, files in os.walk(targetDir, False): + for name in files: + if getImageFileName(name) is not None: + pagenumber += 1 + work.append([root, name, args]) + else: + os.remove(os.path.join(root, name)) if GUI: - GUI.progressBarTick.emit('Combining images') - GUI.progressBarTick.emit(str(directoryNumer)) - for i in mergeWork: - mergeWorkerPool.apply_async(func=mergeDirectory, args=(i, ), callback=mergeDirectoryTick) - mergeWorkerPool.close() - mergeWorkerPool.join() - if GUI and not GUI.conversionAlive: - rmtree(options.targetDir, True) - raise UserWarning("Conversion interrupted.") - if len(mergeWorkerOutput) > 0: - rmtree(options.targetDir, True) - raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0], - mergeWorkerOutput[0][1]) - print("Splitting images...") - for root, _, files in os.walk(options.targetDir, False): - for name in files: - if getImageFileName(name) is not None: - pagenumber += 1 - work.append([root, name, options]) - else: - os.remove(os.path.join(root, name)) - if GUI: - GUI.progressBarTick.emit('Splitting images') - GUI.progressBarTick.emit(str(pagenumber)) - GUI.progressBarTick.emit('tick') - if len(work) > 0: - for i in work: - splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImageTick) - splitWorkerPool.close() - splitWorkerPool.join() - if GUI and not GUI.conversionAlive: - rmtree(options.targetDir, True) - raise UserWarning("Conversion interrupted.") - if len(splitWorkerOutput) > 0: - rmtree(options.targetDir, True) - raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0], - splitWorkerOutput[0][1]) - if options.inPlace: - rmtree(options.sourceDir) - move(options.targetDir, options.sourceDir) + GUI.progressBarTick.emit('Splitting images') + GUI.progressBarTick.emit(str(pagenumber)) + GUI.progressBarTick.emit('tick') + if len(work) > 0: + for i in work: + splitWorkerPool.apply_async(func=splitImage, args=(i, ), callback=splitImageTick) + splitWorkerPool.close() + splitWorkerPool.join() + if GUI and not GUI.conversionAlive: + rmtree(targetDir, True) + raise UserWarning("Conversion interrupted.") + if len(splitWorkerOutput) > 0: + rmtree(targetDir, True) + raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0], + splitWorkerOutput[0][1]) + if args.inPlace: + rmtree(sourceDir) + move(targetDir, sourceDir) + else: + rmtree(targetDir, True) + raise UserWarning("Source directory is empty.") else: - rmtree(options.targetDir, True) - raise UserWarning("Source directory is empty.") - else: - raise UserWarning("Provided path is not a directory.") + raise UserWarning("Provided input is not a directory.") else: raise UserWarning("Target height is not set.") diff --git a/kindlecomicconverter/comicarchive.py b/kindlecomicconverter/comicarchive.py index f0d968e9..690b418b 100644 --- a/kindlecomicconverter/comicarchive.py +++ b/kindlecomicconverter/comicarchive.py @@ -55,7 +55,7 @@ def __init__(self, filepath): def extract(self, targetdir): if not os.path.isdir(targetdir): - raise OSError('Target directory don\'t exist.') + raise OSError('Target directory doesn\'t exist.') process = Popen('7z x -y -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' + targetdir + '" "' + self.filepath + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True) process.communicate()