mirror of
https://github.com/ciromattia/kcc
synced 2025-12-15 10:46:40 +00:00
OptionParser to ArgumentParser (#517)
This commit is contained in:
82
README.md
82
README.md
@@ -136,53 +136,34 @@ sudo apt-get install python3 p7zip-full python3-pil python3-psutil python3-slugi
|
|||||||
### Standalone `kcc-c2e.py` usage:
|
### Standalone `kcc-c2e.py` usage:
|
||||||
|
|
||||||
```
|
```
|
||||||
Usage: kcc-c2e [options] comic_file|comic_folder
|
usage: kcc-c2e [options] [input]
|
||||||
|
|
||||||
|
MANDATORY:
|
||||||
|
input Full path to comic folder or file(s) to be processed.
|
||||||
|
|
||||||
Options:
|
|
||||||
MAIN:
|
MAIN:
|
||||||
-p PROFILE, --profile=PROFILE
|
-p PROFILE, --profile PROFILE
|
||||||
Device profile (Available options: K1, K2, K34, K578,
|
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]
|
||||||
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)
|
-m, --manga-style Manga style (right-to-left reading and splitting)
|
||||||
-q, --hq Try to increase the quality of magnification
|
-q, --hq Try to increase the quality of magnification
|
||||||
-2, --two-panel Display two not four panels in Panel View mode
|
-2, --two-panel Display two not four panels in Panel View mode
|
||||||
-w, --webtoon Webtoon processing mode
|
-w, --webtoon Webtoon processing mode
|
||||||
--targetsize=TARGETSIZE
|
--ts TARGETSIZE, --targetsize TARGETSIZE
|
||||||
the maximal size of output file in MB. [Default=100MB
|
the maximal size of output file in MB. [Default=100MB for webtoon and 400MB for others]
|
||||||
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:
|
PROCESSING:
|
||||||
-n, --noprocessing Do not modify image and ignore any profil or
|
-n, --noprocessing Do not modify image and ignore any profil or processing option
|
||||||
processing option
|
|
||||||
-u, --upscale Resize images smaller than device's resolution
|
-u, --upscale Resize images smaller than device's resolution
|
||||||
-s, --stretch Stretch images to device's resolution
|
-s, --stretch Stretch images to device's resolution
|
||||||
-r SPLITTER, --splitter=SPLITTER
|
-r SPLITTER, --splitter SPLITTER
|
||||||
Double page parsing mode. 0: Split 1: Rotate 2: Both
|
Double page parsing mode. 0: Split 1: Rotate 2: Both [Default=0]
|
||||||
[Default=0]
|
-g GAMMA, --gamma GAMMA
|
||||||
-g GAMMA, --gamma=GAMMA
|
Apply gamma correction to linearize the image [Default=Auto]
|
||||||
Apply gamma correction to linearize the image
|
-c CROPPING, --cropping CROPPING
|
||||||
[Default=Auto]
|
Set cropping mode. 0: Disabled 1: Margins 2: Margins + page numbers [Default=2]
|
||||||
-c CROPPING, --cropping=CROPPING
|
--cp CROPPINGP, --croppingpower CROPPINGP
|
||||||
Set cropping mode. 0: Disabled 1: Margins 2: Margins +
|
|
||||||
page numbers [Default=2]
|
|
||||||
--cp=CROPPINGP, --croppingpower=CROPPINGP
|
|
||||||
Set cropping power [Default=1.0]
|
Set cropping power [Default=1.0]
|
||||||
--cm=CROPPINGM, --croppingminimum=CROPPINGM
|
--cm CROPPINGM, --croppingminimum CROPPINGM
|
||||||
Set cropping minimum area ratio [Default=0.0]
|
Set cropping minimum area ratio [Default=0.0]
|
||||||
--blackborders Disable autodetection and force black borders
|
--blackborders Disable autodetection and force black borders
|
||||||
--whiteborders Disable autodetection and force white borders
|
--whiteborders Disable autodetection and force white borders
|
||||||
@@ -190,31 +171,42 @@ Options:
|
|||||||
--forcepng Create PNG files instead JPEG
|
--forcepng Create PNG files instead JPEG
|
||||||
--mozjpeg Create JPEG files using mozJpeg
|
--mozjpeg Create JPEG files using mozJpeg
|
||||||
--maximizestrips Turn 1x4 strips to 2x2 strips
|
--maximizestrips Turn 1x4 strips to 2x2 strips
|
||||||
-d, --delete Delete source file(s) or a directory. It's not
|
-d, --delete Delete source file(s) or a directory. It's not recoverable.
|
||||||
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:
|
CUSTOM PROFILE:
|
||||||
--customwidth=CUSTOMWIDTH
|
--customwidth CUSTOMWIDTH
|
||||||
Replace screen width provided by device profile
|
Replace screen width provided by device profile
|
||||||
--customheight=CUSTOMHEIGHT
|
--customheight CUSTOMHEIGHT
|
||||||
Replace screen height provided by device profile
|
Replace screen height provided by device profile
|
||||||
|
|
||||||
OTHER:
|
OTHER:
|
||||||
-h, --help Show this help message and exit
|
-h, --help Show this help message and exit
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Standalone `kcc-c2p.py` usage:
|
### Standalone `kcc-c2p.py` usage:
|
||||||
|
|
||||||
```
|
```
|
||||||
Usage: kcc-c2p [options] comic_folder
|
usage: kcc-c2p [options] [input]
|
||||||
|
|
||||||
Options:
|
|
||||||
MANDATORY:
|
MANDATORY:
|
||||||
-y HEIGHT, --height=HEIGHT
|
input Full path to comic folder(s) to be processed. Separate multiple inputs with spaces.
|
||||||
|
|
||||||
|
MAIN:
|
||||||
|
-y HEIGHT, --height HEIGHT
|
||||||
Height of the target device screen
|
Height of the target device screen
|
||||||
-i, --in-place Overwrite source directory
|
-i, --in-place Overwrite source directory
|
||||||
-m, --merge Combine every directory into a single image before
|
-m, --merge Combine every directory into a single image before splitting
|
||||||
splitting
|
|
||||||
|
|
||||||
OTHER:
|
OTHER:
|
||||||
-d, --debug Create debug file for every split image
|
-d, --debug Create debug file for every split image
|
||||||
|
|||||||
@@ -19,8 +19,9 @@
|
|||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import sys
|
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)
|
exit(1)
|
||||||
|
|
||||||
from multiprocessing import freeze_support, set_start_method
|
from multiprocessing import freeze_support, set_start_method
|
||||||
|
|||||||
@@ -19,8 +19,9 @@
|
|||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import sys
|
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)
|
exit(1)
|
||||||
|
|
||||||
from multiprocessing import freeze_support, set_start_method
|
from multiprocessing import freeze_support, set_start_method
|
||||||
|
|||||||
5
kcc.py
5
kcc.py
@@ -19,8 +19,9 @@
|
|||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
import sys
|
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)
|
exit(1)
|
||||||
|
|
||||||
# OS specific workarounds
|
# OS specific workarounds
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ class WorkerThread(QtCore.QThread):
|
|||||||
MW.modeConvert.emit(0)
|
MW.modeConvert.emit(0)
|
||||||
|
|
||||||
parser = comic2ebook.makeParser()
|
parser = comic2ebook.makeParser()
|
||||||
options, _ = parser.parse_args()
|
options = parser.parse_args()
|
||||||
argv = ''
|
argv = ''
|
||||||
currentJobs = []
|
currentJobs = []
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from argparse import ArgumentParser
|
||||||
from time import strftime, gmtime
|
from time import strftime, gmtime
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from glob import glob, escape
|
from glob import glob, escape
|
||||||
@@ -28,10 +29,9 @@ from stat import S_IWRITE, S_IREAD, S_IEXEC
|
|||||||
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
|
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
|
||||||
from tempfile import mkdtemp, gettempdir, TemporaryFile
|
from tempfile import mkdtemp, gettempdir, TemporaryFile
|
||||||
from shutil import move, copytree, rmtree, copyfile
|
from shutil import move, copytree, rmtree, copyfile
|
||||||
from optparse import OptionParser, OptionGroup
|
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from slugify import slugify as slugifyExt
|
from slugify import slugify as slugify_ext
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from subprocess import STDOUT, PIPE
|
from subprocess import STDOUT, PIPE
|
||||||
from psutil import Popen, virtual_memory, disk_usage
|
from psutil import Popen, virtual_memory, disk_usage
|
||||||
@@ -54,22 +54,22 @@ from . import __version__
|
|||||||
def main(argv=None):
|
def main(argv=None):
|
||||||
global options
|
global options
|
||||||
parser = makeParser()
|
parser = makeParser()
|
||||||
optionstemplate, args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
if len(args) == 0:
|
options = copy(args)
|
||||||
|
if not argv or options.input == []:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 0
|
return 0
|
||||||
if sys.platform.startswith('win'):
|
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:
|
else:
|
||||||
sources = set(args)
|
sources = set(options.input)
|
||||||
if len(sources) == 0:
|
if len(sources) == 0:
|
||||||
print('No matching files found.')
|
print('No matching files found.')
|
||||||
return 1
|
return 1
|
||||||
for source in sources:
|
for source in sources:
|
||||||
source = source.rstrip('\\').rstrip('/')
|
source = source.rstrip('\\').rstrip('/')
|
||||||
options = copy(optionstemplate)
|
options = copy(args)
|
||||||
options = checkOptions(options)
|
options = checkOptions(options)
|
||||||
if len(sources) > 1:
|
|
||||||
print('Working on ' + source + '...')
|
print('Working on ' + source + '...')
|
||||||
makeBook(source)
|
makeBook(source)
|
||||||
return 0
|
return 0
|
||||||
@@ -910,9 +910,9 @@ def createNewTome():
|
|||||||
|
|
||||||
def slugify(value, isdir):
|
def slugify(value, isdir):
|
||||||
if 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:
|
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))
|
value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value, count=2))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@@ -933,85 +933,84 @@ def makeZIP(zipfilename, basedir, isepub=False):
|
|||||||
|
|
||||||
|
|
||||||
def makeParser():
|
def makeParser():
|
||||||
psr = OptionParser(usage="Usage: kcc-c2e [options] comic_file|comic_folder", add_help_option=False)
|
psr = ArgumentParser(prog="kcc-c2e", usage="kcc-c2e [options] [input]", add_help=False)
|
||||||
|
|
||||||
mainOptions = OptionGroup(psr, "MAIN")
|
mandatory_options = psr.add_argument_group("MANDATORY")
|
||||||
processingOptions = OptionGroup(psr, "PROCESSING")
|
main_options = psr.add_argument_group("MAIN")
|
||||||
outputOptions = OptionGroup(psr, "OUTPUT SETTINGS")
|
processing_options = psr.add_argument_group("PROCESSING")
|
||||||
customProfileOptions = OptionGroup(psr, "CUSTOM PROFILE")
|
output_options = psr.add_argument_group("OUTPUT SETTINGS")
|
||||||
otherOptions = OptionGroup(psr, "OTHER")
|
custom_profile_options = psr.add_argument_group("CUSTOM PROFILE")
|
||||||
|
other_options = psr.add_argument_group("OTHER")
|
||||||
|
|
||||||
mainOptions.add_option("-p", "--profile", action="store", dest="profile", default="KV",
|
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, "
|
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)"
|
"K11, KS, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O, KoAO, KoN, KoC, KoL, KoF, KoS, KoE)"
|
||||||
" [Default=KV]")
|
" [Default=KV]")
|
||||||
mainOptions.add_option("-m", "--manga-style", action="store_true", dest="righttoleft", default=False,
|
main_options.add_argument("-m", "--manga-style", action="store_true", dest="righttoleft", default=False,
|
||||||
help="Manga style (right-to-left reading and splitting)")
|
help="Manga style (right-to-left reading and splitting)")
|
||||||
mainOptions.add_option("-q", "--hq", action="store_true", dest="hq", default=False,
|
main_options.add_argument("-q", "--hq", action="store_true", dest="hq", default=False,
|
||||||
help="Try to increase the quality of magnification")
|
help="Try to increase the quality of magnification")
|
||||||
mainOptions.add_option("-2", "--two-panel", action="store_true", dest="autoscale", default=False,
|
main_options.add_argument("-2", "--two-panel", action="store_true", dest="autoscale", default=False,
|
||||||
help="Display two not four panels in Panel View mode")
|
help="Display two not four panels in Panel View mode")
|
||||||
mainOptions.add_option("-w", "--webtoon", action="store_true", dest="webtoon", default=False,
|
main_options.add_argument("-w", "--webtoon", action="store_true", dest="webtoon", default=False,
|
||||||
help="Webtoon processing mode"),
|
help="Webtoon processing mode"),
|
||||||
mainOptions.add_option("--targetsize", type="int", dest="targetsize", default=None,
|
main_options.add_argument("--ts", "--targetsize", type=int, dest="targetsize", default=None,
|
||||||
help="the maximal size of output file in MB."
|
help="the maximal size of output file in MB."
|
||||||
" [Default=100MB for webtoon and 400MB for others]")
|
" [Default=100MB for webtoon and 400MB for others]")
|
||||||
|
|
||||||
outputOptions.add_option("-o", "--output", action="store", dest="output", default=None,
|
output_options.add_argument("-o", "--output", action="store", dest="output", default=None,
|
||||||
help="Output generated file to specified directory or file")
|
help="Output generated file to specified directory or file")
|
||||||
outputOptions.add_option("-t", "--title", action="store", dest="title", default="defaulttitle",
|
output_options.add_argument("-t", "--title", action="store", dest="title", default="defaulttitle",
|
||||||
help="Comic title [Default=filename or directory name]")
|
help="Comic title [Default=filename or directory name]")
|
||||||
outputOptions.add_option("-f", "--format", action="store", dest="format", default="Auto",
|
output_options.add_argument("-f", "--format", action="store", dest="format", default="Auto",
|
||||||
help="Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX, MOBI+EPUB) "
|
help="Output format (Available options: Auto, MOBI, EPUB, CBZ, KFX, MOBI+EPUB) "
|
||||||
"[Default=Auto]")
|
"[Default=Auto]")
|
||||||
outputOptions.add_option("-b", "--batchsplit", type="int", dest="batchsplit", default="0",
|
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 "
|
help="Split output into multiple files. 0: Don't split 1: Automatic mode "
|
||||||
"2: Consider every subdirectory as separate volume [Default=0]")
|
"2: Consider every subdirectory as separate volume [Default=0]")
|
||||||
|
|
||||||
processingOptions.add_option("-n", "--noprocessing", action="store_true", dest="noprocessing", default=False,
|
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")
|
help="Do not modify image and ignore any profil or processing option")
|
||||||
processingOptions.add_option("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
processing_options.add_argument("-u", "--upscale", action="store_true", dest="upscale", default=False,
|
||||||
help="Resize images smaller than device's resolution")
|
help="Resize images smaller than device's resolution")
|
||||||
processingOptions.add_option("-s", "--stretch", action="store_true", dest="stretch", default=False,
|
processing_options.add_argument("-s", "--stretch", action="store_true", dest="stretch", default=False,
|
||||||
help="Stretch images to device's resolution")
|
help="Stretch images to device's resolution")
|
||||||
processingOptions.add_option("-r", "--splitter", type="int", dest="splitter", default="0",
|
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]")
|
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",
|
processing_options.add_argument("-g", "--gamma", type=float, dest="gamma", default="0.0",
|
||||||
help="Apply gamma correction to linearize the image [Default=Auto]")
|
help="Apply gamma correction to linearize the image [Default=Auto]")
|
||||||
processingOptions.add_option("-c", "--cropping", type="int", dest="cropping", default="2",
|
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]")
|
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",
|
processing_options.add_argument("--cp", "--croppingpower", type=float, dest="croppingp", default="1.0",
|
||||||
help="Set cropping power [Default=1.0]")
|
help="Set cropping power [Default=1.0]")
|
||||||
processingOptions.add_option("--cm", "--croppingminimum", type="float", dest="croppingm", default="0.0",
|
processing_options.add_argument("--cm", "--croppingminimum", type=float, dest="croppingm", default="0.0",
|
||||||
help="Set cropping minimum area ratio [Default=0.0]")
|
help="Set cropping minimum area ratio [Default=0.0]")
|
||||||
processingOptions.add_option("--blackborders", action="store_true", dest="black_borders", default=False,
|
processing_options.add_argument("--blackborders", action="store_true", dest="black_borders", default=False,
|
||||||
help="Disable autodetection and force black borders")
|
help="Disable autodetection and force black borders")
|
||||||
processingOptions.add_option("--whiteborders", action="store_true", dest="white_borders", default=False,
|
processing_options.add_argument("--whiteborders", action="store_true", dest="white_borders", default=False,
|
||||||
help="Disable autodetection and force white borders")
|
help="Disable autodetection and force white borders")
|
||||||
processingOptions.add_option("--forcecolor", action="store_true", dest="forcecolor", default=False,
|
processing_options.add_argument("--forcecolor", action="store_true", dest="forcecolor", default=False,
|
||||||
help="Don't convert images to grayscale")
|
help="Don't convert images to grayscale")
|
||||||
processingOptions.add_option("--forcepng", action="store_true", dest="forcepng", default=False,
|
processing_options.add_argument("--forcepng", action="store_true", dest="forcepng", default=False,
|
||||||
help="Create PNG files instead JPEG")
|
help="Create PNG files instead JPEG")
|
||||||
processingOptions.add_option("--mozjpeg", action="store_true", dest="mozjpeg", default=False,
|
processing_options.add_argument("--mozjpeg", action="store_true", dest="mozjpeg", default=False,
|
||||||
help="Create JPEG files using mozJpeg")
|
help="Create JPEG files using mozJpeg")
|
||||||
processingOptions.add_option("--maximizestrips", action="store_true", dest="maximizestrips", default=False,
|
processing_options.add_argument("--maximizestrips", action="store_true", dest="maximizestrips", default=False,
|
||||||
help="Turn 1x4 strips to 2x2 strips")
|
help="Turn 1x4 strips to 2x2 strips")
|
||||||
processingOptions.add_option("-d", "--delete", action="store_true", dest="delete", default=False,
|
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.")
|
help="Delete source file(s) or a directory. It's not recoverable.")
|
||||||
|
|
||||||
customProfileOptions.add_option("--customwidth", type="int", dest="customwidth", default=0,
|
custom_profile_options.add_argument("--customwidth", type=int, dest="customwidth", default=0,
|
||||||
help="Replace screen width provided by device profile")
|
help="Replace screen width provided by device profile")
|
||||||
customProfileOptions.add_option("--customheight", type="int", dest="customheight", default=0,
|
custom_profile_options.add_argument("--customheight", type=int, dest="customheight", default=0,
|
||||||
help="Replace screen height provided by device profile")
|
help="Replace screen height provided by device profile")
|
||||||
|
|
||||||
otherOptions.add_option("-h", "--help", action="help",
|
other_options.add_argument("-h", "--help", action="help",
|
||||||
help="Show this help message and exit")
|
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)
|
|
||||||
return psr
|
return psr
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from argparse import ArgumentParser
|
||||||
from shutil import rmtree, copytree, move
|
from shutil import rmtree, copytree, move
|
||||||
from optparse import OptionParser, OptionGroup
|
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from PIL import Image, ImageChops, ImageOps, ImageDraw
|
from PIL import Image, ImageChops, ImageOps, ImageDraw
|
||||||
from .shared import getImageFileName, walkLevel, walkSort, sanitizeTrace
|
from .shared import getImageFileName, walkLevel, walkSort, sanitizeTrace
|
||||||
@@ -116,7 +116,7 @@ def splitImage(work):
|
|||||||
panelDetected = False
|
panelDetected = False
|
||||||
panels = []
|
panels = []
|
||||||
while yWork < heightImg:
|
while yWork < heightImg:
|
||||||
tmpImg = imgProcess.crop([4, yWork, widthImg-4, yWork + 4])
|
tmpImg = imgProcess.crop((4, yWork, widthImg-4, yWork + 4))
|
||||||
solid = detectSolid(tmpImg)
|
solid = detectSolid(tmpImg)
|
||||||
if not solid and not panelDetected:
|
if not solid and not panelDetected:
|
||||||
panelDetected = True
|
panelDetected = True
|
||||||
@@ -149,7 +149,7 @@ def splitImage(work):
|
|||||||
|
|
||||||
if opt.debug:
|
if opt.debug:
|
||||||
for panel in panelsProcessed:
|
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 = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg)
|
||||||
debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG')
|
debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG')
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ def splitImage(work):
|
|||||||
if pageHeight > 15:
|
if pageHeight > 15:
|
||||||
newPage = Image.new('RGB', (widthImg, pageHeight))
|
newPage = Image.new('RGB', (widthImg, pageHeight))
|
||||||
for panel in page:
|
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))
|
newPage.paste(panelImg, (0, targetHeight))
|
||||||
targetHeight += panelsProcessed[panel][2]
|
targetHeight += panelsProcessed[panel][2]
|
||||||
newPage.save(os.path.join(path, os.path.splitext(name)[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
newPage.save(os.path.join(path, os.path.splitext(name)[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
||||||
@@ -193,48 +193,51 @@ def splitImage(work):
|
|||||||
|
|
||||||
|
|
||||||
def main(argv=None, qtgui=None):
|
def main(argv=None, qtgui=None):
|
||||||
global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
|
global args, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
|
||||||
parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False)
|
parser = ArgumentParser(prog="kcc-c2p", usage="kcc-c2p [options] [input]", add_help=False)
|
||||||
mainOptions = OptionGroup(parser, "MANDATORY")
|
|
||||||
otherOptions = OptionGroup(parser, "OTHER")
|
mandatory_options = parser.add_argument_group("MANDATORY")
|
||||||
mainOptions.add_option("-y", "--height", type="int", dest="height", default=0,
|
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")
|
help="Height of the target device screen")
|
||||||
mainOptions.add_option("-i", "--in-place", action="store_true", dest="inPlace", default=False,
|
main_options.add_argument("-i", "--in-place", action="store_true", dest="inPlace", default=False,
|
||||||
help="Overwrite source directory")
|
help="Overwrite source directory")
|
||||||
mainOptions.add_option("-m", "--merge", action="store_true", dest="merge", default=False,
|
main_options.add_argument("-m", "--merge", action="store_true", dest="merge", default=False,
|
||||||
help="Combine every directory into a single image before splitting")
|
help="Combine every directory into a single image before splitting")
|
||||||
otherOptions.add_option("-d", "--debug", action="store_true", dest="debug", default=False,
|
other_options.add_argument("-d", "--debug", action="store_true", dest="debug", default=False,
|
||||||
help="Create debug file for every split image")
|
help="Create debug file for every split image")
|
||||||
otherOptions.add_option("-h", "--help", action="help",
|
other_options.add_argument("-h", "--help", action="help",
|
||||||
help="Show this help message and exit")
|
help="Show this help message and exit")
|
||||||
parser.add_option_group(mainOptions)
|
args = parser.parse_args(argv)
|
||||||
parser.add_option_group(otherOptions)
|
|
||||||
options, args = parser.parse_args(argv)
|
|
||||||
if qtgui:
|
if qtgui:
|
||||||
GUI = qtgui
|
GUI = qtgui
|
||||||
else:
|
else:
|
||||||
GUI = None
|
GUI = None
|
||||||
if len(args) != 1:
|
if not argv or args.input == []:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
if options.height > 0:
|
if args.height > 0:
|
||||||
options.sourceDir = args[0]
|
for sourceDir in args.input:
|
||||||
options.targetDir = args[0] + "-Splitted"
|
targetDir = sourceDir + "-Splitted"
|
||||||
if os.path.isdir(options.sourceDir):
|
if os.path.isdir(sourceDir):
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
copytree(options.sourceDir, options.targetDir)
|
copytree(sourceDir, targetDir)
|
||||||
work = []
|
work = []
|
||||||
pagenumber = 1
|
pagenumber = 1
|
||||||
splitWorkerOutput = []
|
splitWorkerOutput = []
|
||||||
splitWorkerPool = Pool(maxtasksperchild=10)
|
splitWorkerPool = Pool(maxtasksperchild=10)
|
||||||
if options.merge:
|
if args.merge:
|
||||||
print("Merging images...")
|
print("Merging images...")
|
||||||
directoryNumer = 1
|
directoryNumer = 1
|
||||||
mergeWork = []
|
mergeWork = []
|
||||||
mergeWorkerOutput = []
|
mergeWorkerOutput = []
|
||||||
mergeWorkerPool = Pool(maxtasksperchild=10)
|
mergeWorkerPool = Pool(maxtasksperchild=10)
|
||||||
mergeWork.append([options.targetDir])
|
mergeWork.append([targetDir])
|
||||||
for root, dirs, files in os.walk(options.targetDir, False):
|
for root, dirs, files in os.walk(targetDir, False):
|
||||||
dirs, files = walkSort(dirs, files)
|
dirs, files = walkSort(dirs, files)
|
||||||
for directory in dirs:
|
for directory in dirs:
|
||||||
directoryNumer += 1
|
directoryNumer += 1
|
||||||
@@ -247,18 +250,18 @@ def main(argv=None, qtgui=None):
|
|||||||
mergeWorkerPool.close()
|
mergeWorkerPool.close()
|
||||||
mergeWorkerPool.join()
|
mergeWorkerPool.join()
|
||||||
if GUI and not GUI.conversionAlive:
|
if GUI and not GUI.conversionAlive:
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
raise UserWarning("Conversion interrupted.")
|
raise UserWarning("Conversion interrupted.")
|
||||||
if len(mergeWorkerOutput) > 0:
|
if len(mergeWorkerOutput) > 0:
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0],
|
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0],
|
||||||
mergeWorkerOutput[0][1])
|
mergeWorkerOutput[0][1])
|
||||||
print("Splitting images...")
|
print("Splitting images...")
|
||||||
for root, _, files in os.walk(options.targetDir, False):
|
for root, _, files in os.walk(targetDir, False):
|
||||||
for name in files:
|
for name in files:
|
||||||
if getImageFileName(name) is not None:
|
if getImageFileName(name) is not None:
|
||||||
pagenumber += 1
|
pagenumber += 1
|
||||||
work.append([root, name, options])
|
work.append([root, name, args])
|
||||||
else:
|
else:
|
||||||
os.remove(os.path.join(root, name))
|
os.remove(os.path.join(root, name))
|
||||||
if GUI:
|
if GUI:
|
||||||
@@ -271,19 +274,19 @@ def main(argv=None, qtgui=None):
|
|||||||
splitWorkerPool.close()
|
splitWorkerPool.close()
|
||||||
splitWorkerPool.join()
|
splitWorkerPool.join()
|
||||||
if GUI and not GUI.conversionAlive:
|
if GUI and not GUI.conversionAlive:
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
raise UserWarning("Conversion interrupted.")
|
raise UserWarning("Conversion interrupted.")
|
||||||
if len(splitWorkerOutput) > 0:
|
if len(splitWorkerOutput) > 0:
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0],
|
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0],
|
||||||
splitWorkerOutput[0][1])
|
splitWorkerOutput[0][1])
|
||||||
if options.inPlace:
|
if args.inPlace:
|
||||||
rmtree(options.sourceDir)
|
rmtree(sourceDir)
|
||||||
move(options.targetDir, options.sourceDir)
|
move(targetDir, sourceDir)
|
||||||
else:
|
else:
|
||||||
rmtree(options.targetDir, True)
|
rmtree(targetDir, True)
|
||||||
raise UserWarning("Source directory is empty.")
|
raise UserWarning("Source directory is empty.")
|
||||||
else:
|
else:
|
||||||
raise UserWarning("Provided path is not a directory.")
|
raise UserWarning("Provided input is not a directory.")
|
||||||
else:
|
else:
|
||||||
raise UserWarning("Target height is not set.")
|
raise UserWarning("Target height is not set.")
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class ComicArchive:
|
|||||||
|
|
||||||
def extract(self, targetdir):
|
def extract(self, targetdir):
|
||||||
if not os.path.isdir(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 + '" "' +
|
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)
|
self.filepath + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||||
process.communicate()
|
process.communicate()
|
||||||
|
|||||||
Reference in New Issue
Block a user