mirror of
https://github.com/ciromattia/kcc
synced 2026-04-15 21:48:44 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c26383c4b5 | ||
|
|
4e6ee8b59b | ||
|
|
6c6f591e45 | ||
|
|
78c014bf22 | ||
|
|
421e6bcb64 | ||
|
|
5168cd73c4 | ||
|
|
f7f19b99da | ||
|
|
1131bab41f | ||
|
|
8d204668a7 | ||
|
|
99d94ceaa7 |
@@ -107,7 +107,7 @@ sudo apt-get install python3 p7zip-full python3-pil python3-psutil python3-slugi
|
||||
'KPW': ("Kindle Paperwhite 1/2", (758, 1024), Palette16, 1.8),
|
||||
'KV': ("Kindle Paperwhite 3/4/Voyage/Oasis", (1072, 1448), Palette16, 1.8),
|
||||
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.8),
|
||||
'KO': ("Kindle Oasis 2/3", (1264, 1680), Palette16, 1.8),
|
||||
'KO': ("Kindle Oasis 2/3/Paperwhite 12/Colorsoft 12", (1264, 1680), Palette16, 1.8),
|
||||
'KS': ("Kindle Scribe", (1860, 2480), Palette16, 1.8),
|
||||
'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8),
|
||||
'KoG': ("Kobo Glo", (768, 1024), Palette16, 1.8),
|
||||
|
||||
@@ -8,7 +8,7 @@ a = Analysis(['kcc-c2e.py'],
|
||||
pathex=['.'],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hiddenimports=['_cffi_backend'],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
|
||||
@@ -8,7 +8,7 @@ a = Analysis(['kcc-c2p.py'],
|
||||
pathex=['.'],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hiddenimports=['_cffi_backend'],
|
||||
hookspath=[],
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
|
||||
@@ -380,7 +380,7 @@ class WorkerThread(QtCore.QThread):
|
||||
except Exception:
|
||||
pass
|
||||
MW.addMessage.emit('Processing MOBI files... <b>Done!</b>', 'info', True)
|
||||
k = kindle.Kindle()
|
||||
k = kindle.Kindle(options.profile)
|
||||
if k.path and k.coverSupport:
|
||||
for item in outputPath:
|
||||
comic2ebook.options.covers[outputPath.index(item)][0].saveToKindle(
|
||||
@@ -934,6 +934,12 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
"Kindle PW 11": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KPW5',
|
||||
},
|
||||
"Kindle PW 12": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KO',
|
||||
},
|
||||
"Kindle CS 12": {
|
||||
'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0, 'DefaultUpscale': True, 'ForceColor': True, 'Label': 'KO',
|
||||
},
|
||||
"Kindle PW 7/10": {'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0,
|
||||
'DefaultUpscale': True, 'ForceColor': False, 'Label': 'KV'},
|
||||
"Kindle PW 5/6": {'PVOptions': True, 'ForceExpert': False, 'DefaultFormat': 0,
|
||||
@@ -988,9 +994,11 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
|
||||
'Label': 'OTHER'},
|
||||
}
|
||||
profilesGUI = [
|
||||
"Kindle CS 12",
|
||||
"Kindle PW 12",
|
||||
"Kindle Scribe",
|
||||
"Kindle 11",
|
||||
"Kindle PW 11",
|
||||
"Kindle 11",
|
||||
"Kindle Oasis 9/10",
|
||||
"Separator",
|
||||
"Kobo Clara 2E",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '6.2.0'
|
||||
__version__ = '6.3.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
@@ -420,7 +420,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
|
||||
f.close()
|
||||
|
||||
|
||||
def buildEPUB(path, chapternames, tomenumber):
|
||||
def buildEPUB(path, chapternames, tomenumber, ischunked):
|
||||
filelist = []
|
||||
chapterlist = []
|
||||
cover = None
|
||||
@@ -517,7 +517,7 @@ def buildEPUB(path, chapternames, tomenumber):
|
||||
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
|
||||
chapter = True
|
||||
# Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks
|
||||
if not chapternames and options.chapters:
|
||||
if not chapternames and options.chapters and not ischunked:
|
||||
chapterlist = []
|
||||
|
||||
global_diff = 0
|
||||
@@ -532,6 +532,13 @@ def buildEPUB(path, chapternames, tomenumber):
|
||||
|
||||
for aChapter in options.chapters:
|
||||
pageid = aChapter[0]
|
||||
|
||||
if options.dedupecover:
|
||||
if pageid == 0:
|
||||
continue
|
||||
else:
|
||||
pageid -= 1
|
||||
|
||||
cur_diff = global_diff
|
||||
global_diff = 0
|
||||
|
||||
@@ -738,7 +745,7 @@ def getComicInfo(path, originalpath):
|
||||
options.authors.sort()
|
||||
else:
|
||||
options.authors = ['KCC']
|
||||
if xml.data['Bookmarks'] and options.batchsplit == 0:
|
||||
if xml.data['Bookmarks']:
|
||||
options.chapters = xml.data['Bookmarks']
|
||||
if xml.data['Summary']:
|
||||
options.summary = hescape(xml.data['Summary'])
|
||||
@@ -957,8 +964,7 @@ def makeParser():
|
||||
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, KoCC, KoL, KoLC, KoF, KoS, KoE)"
|
||||
help=f"Device profile (Available options: {', '.join(image.ProfileData.Profiles.keys())})"
|
||||
" [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)")
|
||||
@@ -1046,16 +1052,15 @@ def checkOptions(options):
|
||||
options.kfx = False
|
||||
options.supportSyntheticSpread = False
|
||||
if options.format == 'Auto':
|
||||
if options.profile in ['K1', 'K2', 'K34', 'K578', 'KPW', 'KPW5', 'KV', 'KO', 'K11', 'KS']:
|
||||
options.format = 'MOBI'
|
||||
elif options.profile in ['OTHER', 'KoMT', 'KoG', 'KoGHD', 'KoA', 'KoAHD', 'KoAH2O', 'KoAO',
|
||||
'KoN', 'KoC', 'KoCC', 'KoL', 'KoLC', 'KoF', 'KoS', 'KoE']:
|
||||
options.format = 'EPUB'
|
||||
elif options.profile in ['KDX']:
|
||||
if options.profile in ['KDX']:
|
||||
options.format = 'CBZ'
|
||||
if options.profile in ['K1', 'K2', 'K34', 'K578', 'KPW', 'KPW5', 'KV', 'KO', 'K11', 'KS']:
|
||||
elif options.profile in image.ProfileData.ProfilesKindle.keys():
|
||||
options.format = 'MOBI'
|
||||
else:
|
||||
options.format = 'EPUB'
|
||||
if options.profile in image.ProfileData.ProfilesKindle.keys():
|
||||
options.iskindle = True
|
||||
elif options.profile in ['OTHER', 'KoMT', 'KoG', 'KoGHD', 'KoA', 'KoAHD', 'KoAH2O', 'KoAO', 'KoN', 'KoC', 'KoCC', 'KoL', 'KoLC', 'KoF', 'KoS', 'KoE']:
|
||||
else:
|
||||
options.isKobo = True
|
||||
# Other Kobo devices probably support synthetic spreads as well, but
|
||||
# they haven't been tested.
|
||||
@@ -1202,10 +1207,11 @@ def makeBook(source, qtgui=None):
|
||||
makeZIP(tome + '_comic', os.path.join(tome, "OEBPS", "Images"))
|
||||
else:
|
||||
print("Creating EPUB file...")
|
||||
buildEPUB(tome, chapterNames, tomeNumber)
|
||||
if len(tomes) > 1:
|
||||
buildEPUB(tome, chapterNames, tomeNumber, True)
|
||||
filepath.append(getOutputFilename(source, options.output, '.epub', ' ' + str(tomeNumber)))
|
||||
else:
|
||||
buildEPUB(tome, chapterNames, tomeNumber, False)
|
||||
filepath.append(getOutputFilename(source, options.output, '.epub', ''))
|
||||
makeZIP(tome + '_comic', tome, True)
|
||||
copyfile(tome + '_comic.zip', filepath[-1])
|
||||
@@ -1228,7 +1234,7 @@ def makeBook(source, qtgui=None):
|
||||
print('Error: KindleGen failed to create MOBI!')
|
||||
print(errors)
|
||||
return filepath
|
||||
k = kindle.Kindle()
|
||||
k = kindle.Kindle(options.profile)
|
||||
if k.path and k.coverSupport:
|
||||
print("Kindle detected. Uploading covers...")
|
||||
for i in filepath:
|
||||
@@ -1250,12 +1256,13 @@ def makeBook(source, qtgui=None):
|
||||
|
||||
|
||||
def makeMOBIFix(item, uuid):
|
||||
is_pdoc = options.profile in image.ProfileData.ProfilesKindlePDOC.keys()
|
||||
if not options.keep_epub:
|
||||
os.remove(item)
|
||||
mobiPath = item.replace('.epub', '.mobi')
|
||||
move(mobiPath, mobiPath + '_toclean')
|
||||
try:
|
||||
dualmetafix.DualMobiMetaFix(mobiPath + '_toclean', mobiPath, bytes(uuid, 'UTF-8'))
|
||||
dualmetafix.DualMobiMetaFix(mobiPath + '_toclean', mobiPath, bytes(uuid, 'UTF-8'), is_pdoc)
|
||||
return [True]
|
||||
except Exception as err:
|
||||
return [False, format(err)]
|
||||
|
||||
@@ -136,7 +136,11 @@ def del_exth(rec0, exth_num):
|
||||
|
||||
|
||||
class DualMobiMetaFix:
|
||||
def __init__(self, infile, outfile, asin):
|
||||
def __init__(self, infile, outfile, asin, is_pdoc):
|
||||
cdetype = b'EBOK'
|
||||
if is_pdoc:
|
||||
cdetype = b'PDOC'
|
||||
|
||||
shutil.copyfile(infile, outfile)
|
||||
f = open(outfile, "r+b")
|
||||
self.datain = mmap.mmap(f.fileno(), 0)
|
||||
@@ -147,7 +151,7 @@ class DualMobiMetaFix:
|
||||
rec0 = self.datain_rec0
|
||||
rec0 = del_exth(rec0, 501)
|
||||
rec0 = del_exth(rec0, 113)
|
||||
rec0 = add_exth(rec0, 501, b'EBOK')
|
||||
rec0 = add_exth(rec0, 501, cdetype)
|
||||
rec0 = add_exth(rec0, 113, asin)
|
||||
replacesection(self.datain, 0, rec0)
|
||||
|
||||
@@ -174,7 +178,7 @@ class DualMobiMetaFix:
|
||||
rec0 = self.datain_kfrec0
|
||||
rec0 = del_exth(rec0, 501)
|
||||
rec0 = del_exth(rec0, 113)
|
||||
rec0 = add_exth(rec0, 501, b'EBOK')
|
||||
rec0 = add_exth(rec0, 501, cdetype)
|
||||
rec0 = add_exth(rec0, 113, asin)
|
||||
replacesection(self.datain, datain_kf8, rec0)
|
||||
|
||||
|
||||
@@ -78,18 +78,29 @@ class ProfileData:
|
||||
PalleteNull = [
|
||||
]
|
||||
|
||||
Profiles = {
|
||||
ProfilesKindleEBOK = {
|
||||
'K1': ("Kindle 1", (600, 670), Palette4, 1.8),
|
||||
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.8),
|
||||
'K2': ("Kindle 2", (600, 670), Palette15, 1.8),
|
||||
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8),
|
||||
'K34': ("Kindle Keyboard/Touch", (600, 800), Palette16, 1.8),
|
||||
'K578': ("Kindle", (600, 800), Palette16, 1.8),
|
||||
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8),
|
||||
'KPW': ("Kindle Paperwhite 1/2", (758, 1024), Palette16, 1.8),
|
||||
'KV': ("Kindle Paperwhite 3/4/Voyage/Oasis", (1072, 1448), Palette16, 1.8),
|
||||
}
|
||||
|
||||
ProfilesKindlePDOC = {
|
||||
'KO': ("Kindle Oasis 2/3/Paperwhite 12/Colorsoft 12", (1264, 1680), Palette16, 1.8),
|
||||
'K11': ("Kindle 11", (1072, 1448), Palette16, 1.8),
|
||||
'KPW5': ("Kindle Paperwhite 5/Signature Edition", (1236, 1648), Palette16, 1.8),
|
||||
'KO': ("Kindle Oasis 2/3", (1264, 1680), Palette16, 1.8),
|
||||
'KS': ("Kindle Scribe", (1860, 2480), Palette16, 1.8),
|
||||
}
|
||||
|
||||
ProfilesKindle = {
|
||||
**ProfilesKindleEBOK,
|
||||
**ProfilesKindlePDOC
|
||||
}
|
||||
|
||||
ProfilesKobo = {
|
||||
'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8),
|
||||
'KoG': ("Kobo Glo", (768, 1024), Palette16, 1.8),
|
||||
'KoGHD': ("Kobo Glo HD", (1072, 1448), Palette16, 1.8),
|
||||
@@ -105,6 +116,11 @@ class ProfileData:
|
||||
'KoF': ("Kobo Forma", (1440, 1920), Palette16, 1.8),
|
||||
'KoS': ("Kobo Sage", (1440, 1920), Palette16, 1.8),
|
||||
'KoE': ("Kobo Elipsa", (1404, 1872), Palette16, 1.8),
|
||||
}
|
||||
|
||||
Profiles = {
|
||||
**ProfilesKindle,
|
||||
**ProfilesKobo,
|
||||
'OTHER': ("Other", (0, 0), Palette16, 1.8),
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
import os.path
|
||||
import psutil
|
||||
|
||||
from . import image
|
||||
|
||||
|
||||
class Kindle:
|
||||
def __init__(self):
|
||||
def __init__(self, profile):
|
||||
self.profile = profile
|
||||
self.path = self.findDevice()
|
||||
if self.path:
|
||||
self.coverSupport = self.checkThumbnails()
|
||||
@@ -29,6 +32,8 @@ class Kindle:
|
||||
self.coverSupport = False
|
||||
|
||||
def findDevice(self):
|
||||
if self.profile in image.ProfileData.ProfilesKindlePDOC.keys():
|
||||
return False
|
||||
for drive in reversed(psutil.disk_partitions(False)):
|
||||
if (drive[2] == 'FAT32' and drive[3] == 'rw,removable') or \
|
||||
(drive[2] in ('vfat', 'msdos', 'FAT', 'apfs') and 'rw' in drive[3]):
|
||||
|
||||
6
setup.py
6
setup.py
@@ -36,16 +36,16 @@ class BuildBinaryCommand(setuptools.Command):
|
||||
def run(self):
|
||||
VERSION = __version__
|
||||
if sys.platform == 'darwin':
|
||||
os.system('pyinstaller -y -D -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s kcc.py')
|
||||
os.system('pyinstaller --hidden-import=_cffi_backend -y -D -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s kcc.py')
|
||||
# TODO /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime dist/Applications/Kindle\ Comic\ Converter.app -v
|
||||
os.system(f'appdmg kcc.json dist/kcc_macos_{platform.processor()}_{VERSION}.dmg')
|
||||
sys.exit(0)
|
||||
elif sys.platform == 'win32':
|
||||
os.system('pyinstaller -y -F -i icons\\comic2ebook.ico -n KCC_' + VERSION + ' -w --noupx kcc.py')
|
||||
os.system('pyinstaller --hidden-import=_cffi_backend -y -F -i icons\\comic2ebook.ico -n KCC_' + VERSION + ' -w --noupx kcc.py')
|
||||
sys.exit(0)
|
||||
elif sys.platform == 'linux':
|
||||
os.system(
|
||||
'pyinstaller --hidden-import=queue -y -F -i icons/comic2ebook.ico -n kcc_linux_' + VERSION + ' kcc.py')
|
||||
'pyinstaller --hidden-import=_cffi_backend --hidden-import=queue -y -F -i icons/comic2ebook.ico -n kcc_linux_' + VERSION + ' kcc.py')
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(0)
|
||||
|
||||
Reference in New Issue
Block a user