diff --git a/kcc.py b/kcc.py index 3c18461..67db9d6 100755 --- a/kcc.py +++ b/kcc.py @@ -34,19 +34,20 @@ if sys.platform.startswith('darwin'): if getattr(sys, 'frozen', False): os.environ['PATH'] += os.pathsep + os.pathsep.join(mac_paths + [ - os.path.dirname(os.path.abspath(sys.executable)) + '/../Resources', + '/opt/homebrew/bin', '/usr/local/bin', '/usr/bin', '/bin', ] ) - os.chdir(os.path.dirname(os.path.abspath(sys.executable)) + '/../Resources') + os.chdir(os.path.dirname(os.path.abspath(sys.executable))) else: os.environ['PATH'] += os.pathsep + os.pathsep.join(mac_paths) os.chdir(os.path.dirname(os.path.abspath(__file__))) elif sys.platform.startswith('win'): win_paths = [ - '%LOCALAPPDATA%\\Amazon\\Kindle Previewer 3\\lib\\fc\\bin\\', + os.path.expandvars('%LOCALAPPDATA%\\Amazon\\Kindle Previewer 3\\lib\\fc\\bin\\'), + os.path.expandvars('%LOCALAPPDATA%\\Amazon\\KC2'), 'C:\\Program Files\\7-Zip', ] if getattr(sys, 'frozen', False): diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index 1eb419e..0111adb 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -19,6 +19,7 @@ import json import os import re +import subprocess import sys from urllib.parse import unquote from urllib.request import urlopen @@ -644,6 +645,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): if not GUI.webtoonBox.isChecked(): GUI.qualityBox.setEnabled(profile['PVOptions']) GUI.upscaleBox.setChecked(profile['DefaultUpscale']) + GUI.mangaBox.setChecked(True) if not profile['PVOptions']: GUI.qualityBox.setChecked(False) if str(GUI.deviceBox.currentText()) == 'Other': @@ -757,7 +759,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): if sys.platform.startswith('win'): self.addMessage('Download it and place EXE in KCC directory.', 'error') elif sys.platform.startswith('darwin'): - self.addMessage('' + self.addMessage('' 'Install the kindle-comic-creator cask using Homebrew to enable MOBI conversion', 'error') else: @@ -859,6 +861,12 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.addMessage('Your KindleGen' ' is outdated! MOBI conversion might fail.', 'warning') break + where_command = 'where kindlegen.exe' + if os.name == 'posix': + where_command = 'which kindlegen' + process = subprocess.run(where_command, stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True) + locations = process.stdout.decode('utf-8').split('\n') + self.addMessage(f"KindleGen Found: {locations[0]}", 'info') else: self.kindleGen = False if startup: @@ -932,7 +940,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): "Kindle Voyage": {'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'Label': 'KV'}, "Kindle Scribe": { - 'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'Label': 'KS', + 'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': False, 'Label': 'KS', }, "Kindle 11": { 'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'Label': 'K11', @@ -1046,7 +1054,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow): self.sevenzip = True else: self.sevenzip = False - self.addMessage('Install 7z and add to PATH!!' + self.addMessage('Cannot find 7z!' ' CBZ/CBR/ZIP/etc processing disabled.', 'warning') self.detectKindleGen(True) diff --git a/kindlecomicconverter/__init__.py b/kindlecomicconverter/__init__.py index 72dcee0..b50ed63 100644 --- a/kindlecomicconverter/__init__.py +++ b/kindlecomicconverter/__init__.py @@ -1,4 +1,4 @@ -__version__ = '5.6.2' +__version__ = '5.6.3' __license__ = 'ISC' __copyright__ = '2012-2022, Ciro Mattia Gonano , Pawel Jastrzebski , darodi' __docformat__ = 'restructuredtext en' diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index d8d6d97..ac205c5 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -291,13 +291,14 @@ def buildOPF(dstdir, title, filelist, cover=None): "\n", "\n", "\n", - "\n"]) + "\n", + "landscape\n", + "pre-paginated\n", + "\n"]) if options.kfx: - f.writelines(["\n", - "\n"]) + f.writelines(["\n"]) else: - f.writelines(["\n", - "\n"]) + f.writelines(["\n"]) elif options.supportSyntheticSpread: f.writelines([ "landscape\n", @@ -509,18 +510,30 @@ def buildEPUB(path, chapternames, tomenumber): # Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks if not chapternames and options.chapters: chapterlist = [] - globaldiff = 0 + + global_diff = 0 + diff_delta = 0 + + # if split + if options.splitter == 0: + diff_delta = 1 + # if rotate and split + elif options.splitter == 2: + diff_delta = 2 + for aChapter in options.chapters: pageid = aChapter[0] - for x in range(0, pageid + globaldiff + 1): + cur_diff = global_diff + global_diff = 0 + + for x in range(0, pageid + cur_diff + 1): if '-kcc-b' in filelist[x][1]: - pageid += 1 - if '-kcc-c' in filelist[pageid][1]: - pageid -= 1 + pageid += diff_delta + global_diff += diff_delta + filename = filelist[pageid][1] chapterlist.append((filelist[pageid][0].replace('Images', 'Text'), filename)) chapternames[filename] = aChapter[1] - globaldiff = pageid - (aChapter[0] + globaldiff) buildNCX(path, options.title, chapterlist, chapternames) buildNAV(path, options.title, chapterlist, chapternames) buildOPF(path, options.title, filelist, cover) @@ -744,19 +757,23 @@ def getPanelViewSize(deviceres, size): def sanitizeTree(filetree): chapterNames = {} for root, dirs, files in os.walk(filetree, False): - for name in files: + for i, name in enumerate(sorted(files)): splitname = os.path.splitext(name) - slugified = slugify(splitname[0], False) - while os.path.exists(os.path.join(root, slugified + splitname[1])) and splitname[0].upper()\ - != slugified.upper(): - slugified += "A" + + # file needs kcc at front AND back to avoid renaming issues + slugified = f'kcc-{i:04}' + for suffix in '-KCC', '-KCC-A', '-KCC-B', '-KCC-C': + if splitname[0].endswith(suffix): + slugified += suffix.lower() + break + newKey = os.path.join(root, slugified + splitname[1]) key = os.path.join(root, name) if key != newKey: os.replace(key, newKey) for name in dirs: tmpName = name - slugified = slugify(name, True) + slugified = slugify(name) while os.path.exists(os.path.join(root, slugified)) and name.upper() != slugified.upper(): slugified += "A" chapterNames[slugified] = tmpName @@ -767,23 +784,6 @@ def sanitizeTree(filetree): return chapterNames -def sanitizeTreeKobo(filetree): - pageNumber = 0 - for root, dirs, files in os.walk(filetree): - dirs, files = walkSort(dirs, files) - for name in files: - splitname = os.path.splitext(name) - slugified = str(pageNumber).zfill(5) - pageNumber += 1 - while os.path.exists(os.path.join(root, slugified + splitname[1])) and splitname[0].upper()\ - != slugified.upper(): - slugified += "A" - newKey = os.path.join(root, slugified + splitname[1]) - key = os.path.join(root, name) - if key != newKey: - os.replace(key, newKey) - - def sanitizePermissions(filetree): for root, dirs, files in os.walk(filetree, False): for name in files: @@ -906,11 +906,8 @@ def createNewTome(): return tomePath, tomePathRoot -def slugify(value, isdir): - if isdir: - value = slugify_ext(value, regex_pattern=r'[^-a-z0-9_\.]+').strip('.') - else: - value = slugify_ext(value).strip('.') +def slugify(value): + value = slugify_ext(value, regex_pattern=r'[^-a-z0-9_\.]+').strip('.') value = sub(r'0*([0-9]{4,})', r'\1', sub(r'([0-9]+)', r'0000\1', value, count=2)) return value @@ -1157,8 +1154,6 @@ def makeBook(source, qtgui=None): if GUI: GUI.progressBarTick.emit('1') chapterNames = sanitizeTree(os.path.join(path, 'OEBPS', 'Images')) - if 'Ko' in options.profile and options.format == 'CBZ': - sanitizeTreeKobo(os.path.join(path, 'OEBPS', 'Images')) if options.batchsplit > 0: tomes = splitDirectory(path) else: diff --git a/kindlecomicconverter/comicarchive.py b/kindlecomicconverter/comicarchive.py index 690b418..596d865 100644 --- a/kindlecomicconverter/comicarchive.py +++ b/kindlecomicconverter/comicarchive.py @@ -19,6 +19,8 @@ # import os +import platform +import subprocess import distro from psutil import Popen from shutil import move @@ -65,6 +67,11 @@ class ComicArchive: process.communicate() if process.returncode != 0: raise OSError('Failed to extract archive.') + elif process.returncode != 0 and platform.system() == 'Darwin': + process = subprocess.run(f"unar '{self.filepath}' -f -o '{targetdir}'", + stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True) + if process.returncode != 0: + raise Exception(process.stdout.decode("utf-8")) elif process.returncode != 0: raise OSError('Failed to extract archive. Check if p7zip-rar is installed.') tdir = os.listdir(targetdir) diff --git a/kindlecomicconverter/pdfjpgextract.py b/kindlecomicconverter/pdfjpgextract.py index 9a24771..c9e224e 100644 --- a/kindlecomicconverter/pdfjpgextract.py +++ b/kindlecomicconverter/pdfjpgextract.py @@ -25,6 +25,11 @@ import os from random import choice from string import ascii_uppercase, digits +# skip stray images a few pixels in size in some PDFs +# typical images are many thousands in length +# https://github.com/ciromattia/kcc/pull/546 +STRAY_IMAGE_LENGTH_THRESHOLD = 300 + class PdfJpgExtract: def __init__(self, fname): @@ -60,10 +65,15 @@ class PdfJpgExtract: raise Exception("Didn't find end of JPG!") istart += startfix iend += endfix + i = iend + + if iend - istart < STRAY_IMAGE_LENGTH_THRESHOLD: + continue + jpg = pdf[istart:iend] jpgfile = open(self.path + "/jpg%d.jpg" % njpg, "wb") jpgfile.write(jpg) jpgfile.close() njpg += 1 - i = iend + return self.path, njpg diff --git a/other/osx/7z b/other/osx/7z deleted file mode 100755 index e0d826b..0000000 Binary files a/other/osx/7z and /dev/null differ diff --git a/other/osx/7z.so b/other/osx/7z.so deleted file mode 100644 index 84d5285..0000000 Binary files a/other/osx/7z.so and /dev/null differ diff --git a/other/osx/Info.plist b/other/osx/Info.plist deleted file mode 100644 index 969c499..0000000 --- a/other/osx/Info.plist +++ /dev/null @@ -1,72 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleDisplayName - Kindle Comic Converter - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - cbz - cbr - cb7 - zip - rar - 7z - pdf - - CFBundleTypeIconFile - comic2ebook.icns - CFBundleTypeName - Comics - CFBundleTypeRole - Editor - - - CFBundleExecutable - MacOS/Kindle Comic Converter - CFBundleGetInfoString - KindleComicConverter 5.5.2, written 2012-2019 by Ciro Mattia Gonano and Pawel Jastrzebski - CFBundleIconFile - comic2ebook.icns - CFBundleIdentifier - com.kindlecomicconverter.KindleComicConverter - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Kindle Comic Converter - CFBundlePackageType - APPL - CFBundleShortVersionString - 5.5.2 - CFBundleSignature - ???? - CFBundleVersion - 5.5.2 - LSEnvironment - - PATH - ./../Resources:/Applications/Kindle Comic Creator/Kindle Comic Creator.app/Contents/MacOS:/usr/local/bin:/usr/bin:/bin - - LSHasLocalizedDisplayName - - LSMinimumSystemVersion - 10.14.0 - NSAppleScriptEnabled - - NSHumanReadableCopyright - ISC License (ISCL) - NSMainNibFile - MainMenu - NSPrincipalClass - NSApplication - NSRequiresAquaSystemAppearance - false - NSInitialToolTipDelay - 1000 - - diff --git a/other/osx/Rar.so b/other/osx/Rar.so deleted file mode 100644 index bc21ea1..0000000 Binary files a/other/osx/Rar.so and /dev/null differ diff --git a/setup.py b/setup.py index b20617c..af1b9d4 100644 --- a/setup.py +++ b/setup.py @@ -17,8 +17,6 @@ import setuptools import distutils.cmd from kindlecomicconverter import __version__ -OSX_INFO_PLIST = "other/osx/Info.plist" - NAME = 'KindleComicConverter' MAIN = 'kcc.py' VERSION = __version__ @@ -39,22 +37,7 @@ class BuildBinaryCommand(distutils.cmd.Command): def run(self): VERSION = __version__ if sys.platform == 'darwin': - - with open(OSX_INFO_PLIST, 'r') as file: - filedata = file.read() - filedata = filedata.replace('5.5.2', VERSION) - with open(OSX_INFO_PLIST, 'w') as file: - file.write(filedata) - os.system('pyinstaller -y -F -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s kcc.py') - os.makedirs('dist/Kindle Comic Converter.app/Contents/Resources/Codecs') - shutil.copy('other/osx/7z', 'dist/Kindle Comic Converter.app/Contents/Resources') - shutil.copy('other/osx/7z.so', 'dist/Kindle Comic Converter.app/Contents/Resources') - shutil.copy('other/osx/Rar.so', 'dist/Kindle Comic Converter.app/Contents/Resources/Codecs') - shutil.copy('other/osx/Info.plist', 'dist/Kindle Comic Converter.app/Contents') - shutil.copy('LICENSE.txt', 'dist/Kindle Comic Converter.app/Contents/Resources') - shutil.copy('other/windows/Additional-LICENSE.txt', 'dist/Kindle Comic Converter.app/Contents/Resources') - os.chmod('dist/Kindle Comic Converter.app/Contents/Resources/7z', 0o777) # TODO /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime dist/Applications/Kindle\ Comic\ Converter.app -v os.system('appdmg kcc.json dist/KindleComicConverter_osx_' + VERSION + '.dmg') exit(0)