mirror of
https://github.com/ciromattia/kcc
synced 2025-12-13 01:36:27 +00:00
Code cleanup
This commit is contained in:
@@ -26,12 +26,12 @@ from shutil import move
|
||||
from subprocess import STDOUT, PIPE
|
||||
from PyQt5 import QtGui, QtCore, QtWidgets, QtNetwork
|
||||
from xml.dom.minidom import parse
|
||||
from xml.sax.saxutils import escape
|
||||
from psutil import Popen, Process
|
||||
from copy import copy
|
||||
from distutils.version import StrictVersion
|
||||
from xml.sax.saxutils import escape
|
||||
from raven import Client
|
||||
from .shared import md5Checksum, HTMLStripper, sanitizeTrace, saferRemove
|
||||
from .shared import md5Checksum, HTMLStripper, sanitizeTrace
|
||||
from . import __version__
|
||||
from . import comic2ebook
|
||||
from . import metadata
|
||||
@@ -334,7 +334,7 @@ class WorkerThread(QtCore.QThread):
|
||||
if 'outputPath' in locals():
|
||||
for item in outputPath:
|
||||
if os.path.exists(item):
|
||||
saferRemove(item)
|
||||
os.remove(item)
|
||||
self.clean()
|
||||
return
|
||||
if not self.errors:
|
||||
@@ -361,9 +361,9 @@ class WorkerThread(QtCore.QThread):
|
||||
if not self.conversionAlive:
|
||||
for item in outputPath:
|
||||
if os.path.exists(item):
|
||||
saferRemove(item)
|
||||
os.remove(item)
|
||||
if os.path.exists(item.replace('.epub', '.mobi')):
|
||||
saferRemove(item.replace('.epub', '.mobi'))
|
||||
os.remove(item.replace('.epub', '.mobi'))
|
||||
self.clean()
|
||||
return
|
||||
if self.kindlegenErrorCode[0] == 0:
|
||||
@@ -384,7 +384,7 @@ class WorkerThread(QtCore.QThread):
|
||||
for item in outputPath:
|
||||
GUI.progress.content = ''
|
||||
mobiPath = item.replace('.epub', '.mobi')
|
||||
saferRemove(mobiPath + '_toclean')
|
||||
os.remove(mobiPath + '_toclean')
|
||||
if GUI.targetDirectory and GUI.targetDirectory != os.path.dirname(mobiPath):
|
||||
try:
|
||||
move(mobiPath, GUI.targetDirectory)
|
||||
@@ -402,9 +402,9 @@ class WorkerThread(QtCore.QThread):
|
||||
for item in outputPath:
|
||||
mobiPath = item.replace('.epub', '.mobi')
|
||||
if os.path.exists(mobiPath):
|
||||
saferRemove(mobiPath)
|
||||
os.remove(mobiPath)
|
||||
if os.path.exists(mobiPath + '_toclean'):
|
||||
saferRemove(mobiPath + '_toclean')
|
||||
os.remove(mobiPath + '_toclean')
|
||||
MW.addMessage.emit('Failed to process MOBI file!', 'error', False)
|
||||
MW.addTrayMessage.emit('Failed to process MOBI file!', 'Critical')
|
||||
else:
|
||||
@@ -412,9 +412,9 @@ class WorkerThread(QtCore.QThread):
|
||||
epubSize = (os.path.getsize(self.kindlegenErrorCode[2])) // 1024 // 1024
|
||||
for item in outputPath:
|
||||
if os.path.exists(item):
|
||||
saferRemove(item)
|
||||
os.remove(item)
|
||||
if os.path.exists(item.replace('.epub', '.mobi')):
|
||||
saferRemove(item.replace('.epub', '.mobi'))
|
||||
os.remove(item.replace('.epub', '.mobi'))
|
||||
MW.addMessage.emit('KindleGen failed to create MOBI!', 'error', False)
|
||||
MW.addTrayMessage.emit('KindleGen failed to create MOBI!', 'Critical')
|
||||
if self.kindlegenErrorCode[0] == 1 and self.kindlegenErrorCode[1] != '':
|
||||
|
||||
@@ -23,7 +23,7 @@ from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen
|
||||
from shutil import move, copy
|
||||
from . import rarfile
|
||||
from .shared import check7ZFile as is_7zfile, saferReplace, saferRemove
|
||||
from .shared import check7ZFile as is_7zfile
|
||||
|
||||
|
||||
class CBxArchive:
|
||||
@@ -46,12 +46,12 @@ class CBxArchive:
|
||||
filelist = []
|
||||
for f in cbzFile.namelist():
|
||||
if f.startswith('__MACOSX') or f.endswith('.DS_Store') or f.endswith('humbs.db'):
|
||||
pass # skip MacOS special files
|
||||
pass
|
||||
elif f.endswith('/'):
|
||||
try:
|
||||
os.makedirs(os.path.join(targetdir, f))
|
||||
except Exception:
|
||||
pass # the dir exists so we are going to extract the images only.
|
||||
pass
|
||||
else:
|
||||
filelist.append(f)
|
||||
cbzFile.extractall(targetdir, filelist)
|
||||
@@ -59,24 +59,18 @@ class CBxArchive:
|
||||
def extractCBR(self, targetdir):
|
||||
cbrFile = rarfile.RarFile(self.origFileName)
|
||||
cbrFile.extractall(targetdir)
|
||||
for root, dirnames, filenames in os.walk(targetdir):
|
||||
for root, _, filenames in os.walk(targetdir):
|
||||
for filename in filenames:
|
||||
if filename.startswith('__MACOSX') or filename.endswith('.DS_Store') or filename.endswith('humbs.db'):
|
||||
saferRemove(os.path.join(root, filename))
|
||||
os.remove(os.path.join(root, filename))
|
||||
|
||||
def extractCB7(self, targetdir):
|
||||
# Workaround for some wide UTF-8 + Popen abnormalities
|
||||
if sys.platform.startswith('darwin'):
|
||||
copy(self.origFileName, os.path.join(os.path.dirname(self.origFileName), 'TMP_KCC_TMP'))
|
||||
self.origFileName = os.path.join(os.path.dirname(self.origFileName), 'TMP_KCC_TMP')
|
||||
output = Popen('7za x "' + self.origFileName + '" -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' +
|
||||
targetdir + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||
extracted = False
|
||||
for line in output.stdout:
|
||||
if b"Everything is Ok" in line:
|
||||
extracted = True
|
||||
if sys.platform.startswith('darwin'):
|
||||
saferRemove(self.origFileName)
|
||||
if not extracted:
|
||||
raise OSError
|
||||
|
||||
@@ -92,10 +86,6 @@ class CBxArchive:
|
||||
adir.remove('ComicInfo.xml')
|
||||
if len(adir) == 1 and os.path.isdir(os.path.join(targetdir, adir[0])):
|
||||
for f in os.listdir(os.path.join(targetdir, adir[0])):
|
||||
# If directory names contain UTF-8 chars shutil.move can't clean up the mess alone
|
||||
if os.path.isdir(os.path.join(targetdir, f)):
|
||||
saferReplace(os.path.join(targetdir, adir[0], f), os.path.join(targetdir, adir[0], f + '-A'))
|
||||
f += '-A'
|
||||
move(os.path.join(targetdir, adir[0], f), targetdir)
|
||||
os.rmdir(os.path.join(targetdir, adir[0]))
|
||||
return targetdir
|
||||
|
||||
@@ -42,7 +42,7 @@ try:
|
||||
from PyQt5 import QtCore
|
||||
except ImportError:
|
||||
QtCore = None
|
||||
from .shared import md5Checksum, getImageFileName, walkSort, walkLevel, saferReplace, saferRemove, sanitizeTrace
|
||||
from .shared import md5Checksum, getImageFileName, walkSort, walkLevel, sanitizeTrace
|
||||
from . import comic2panel
|
||||
from . import image
|
||||
from . import cbxarchive
|
||||
@@ -81,11 +81,11 @@ def buildHTML(path, imgfile, imgfilepath):
|
||||
imgfilepath = md5Checksum(imgfilepath)
|
||||
filename = getImageFileName(imgfile)
|
||||
deviceres = options.profileData[1]
|
||||
if "Rotated" in options.imgIndex[imgfilepath]:
|
||||
if "Rotated" in options.imgMetadata[imgfilepath]:
|
||||
rotatedPage = True
|
||||
else:
|
||||
rotatedPage = False
|
||||
if "BlackFill" in options.imgIndex[imgfilepath]:
|
||||
if "BlackBackground" in options.imgMetadata[imgfilepath]:
|
||||
additionalStyle = 'background-color:#000000;'
|
||||
else:
|
||||
additionalStyle = 'background-color:#FFFFFF;'
|
||||
@@ -420,7 +420,7 @@ def buildEPUB(path, chapterNames, tomeNumber):
|
||||
"display: none;\n",
|
||||
"}\n"])
|
||||
f.close()
|
||||
for (dirpath, dirnames, filenames) in os.walk(os.path.join(path, 'OEBPS', 'Images')):
|
||||
for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
|
||||
chapter = False
|
||||
dirnames, filenames = walkSort(dirnames, filenames)
|
||||
for afile in filenames:
|
||||
@@ -457,11 +457,11 @@ def imgDirectoryProcessing(path):
|
||||
global workerPool, workerOutput
|
||||
workerPool = Pool()
|
||||
workerOutput = []
|
||||
options.imgIndex = {}
|
||||
options.imgPurgeIndex = []
|
||||
options.imgMetadata = {}
|
||||
options.imgOld = []
|
||||
work = []
|
||||
pagenumber = 0
|
||||
for (dirpath, dirnames, filenames) in os.walk(path):
|
||||
for dirpath, _, filenames in os.walk(path):
|
||||
for afile in filenames:
|
||||
pagenumber += 1
|
||||
work.append([afile, dirpath, options])
|
||||
@@ -478,9 +478,9 @@ def imgDirectoryProcessing(path):
|
||||
if len(workerOutput) > 0:
|
||||
rmtree(os.path.join(path, '..', '..'), True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + workerOutput[0][0], workerOutput[0][1])
|
||||
for file in options.imgPurgeIndex:
|
||||
for file in options.imgOld:
|
||||
if os.path.isfile(file):
|
||||
saferRemove(file)
|
||||
os.remove(file)
|
||||
else:
|
||||
rmtree(os.path.join(path, '..', '..'), True)
|
||||
raise UserWarning("Source directory is empty.")
|
||||
@@ -493,8 +493,8 @@ def imgFileProcessingTick(output):
|
||||
else:
|
||||
for page in output:
|
||||
if page is not None:
|
||||
options.imgIndex[page[0]] = page[1]
|
||||
options.imgPurgeIndex.append(page[2])
|
||||
options.imgMetadata[page[0]] = page[1]
|
||||
options.imgOld.append(page[2])
|
||||
if GUI:
|
||||
GUI.progressBarTick.emit('tick')
|
||||
if not GUI.conversionAlive:
|
||||
@@ -509,7 +509,7 @@ def imgFileProcessing(work):
|
||||
output = []
|
||||
workImg = image.ComicPageParser((dirpath, afile), opt)
|
||||
for i in workImg.payload:
|
||||
img = image.ComicPage(i[0], i[1], i[2], i[3], i[4], opt)
|
||||
img = image.ComicPage(opt, *i)
|
||||
if opt.cropping == 2 and not opt.webtoon:
|
||||
img.cropPageNumber(opt.croppingp)
|
||||
if opt.cropping > 0 and not opt.webtoon:
|
||||
@@ -615,7 +615,7 @@ def getComicInfo(path, originalPath):
|
||||
try:
|
||||
xml = metadata.MetadataParser(xmlPath)
|
||||
except Exception:
|
||||
saferRemove(xmlPath)
|
||||
os.remove(xmlPath)
|
||||
return
|
||||
options.authors = []
|
||||
if defaultTitle:
|
||||
@@ -640,7 +640,7 @@ def getComicInfo(path, originalPath):
|
||||
options.chapters = xml.data['Bookmarks']
|
||||
if xml.data['Summary']:
|
||||
options.summary = escape(xml.data['Summary'])
|
||||
saferRemove(xmlPath)
|
||||
os.remove(xmlPath)
|
||||
|
||||
|
||||
def getCoversFromMCB(mangaID):
|
||||
@@ -659,7 +659,7 @@ def getCoversFromMCB(mangaID):
|
||||
|
||||
def getDirectorySize(start_path='.'):
|
||||
total_size = 0
|
||||
for dirpath, dirnames, filenames in os.walk(start_path):
|
||||
for dirpath, _, filenames in os.walk(start_path):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
total_size += os.path.getsize(fp)
|
||||
@@ -694,7 +694,7 @@ def sanitizeTree(filetree):
|
||||
newKey = os.path.join(root, slugified + splitname[1])
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
saferReplace(key, newKey)
|
||||
os.replace(key, newKey)
|
||||
for name in dirs:
|
||||
tmpName = name
|
||||
slugified = slugify(name)
|
||||
@@ -704,7 +704,7 @@ def sanitizeTree(filetree):
|
||||
newKey = os.path.join(root, slugified)
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
saferReplace(key, newKey)
|
||||
os.replace(key, newKey)
|
||||
return chapterNames
|
||||
|
||||
|
||||
@@ -722,7 +722,7 @@ def sanitizeTreeKobo(filetree):
|
||||
newKey = os.path.join(root, slugified + splitname[1])
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
saferReplace(key, newKey)
|
||||
os.replace(key, newKey)
|
||||
|
||||
|
||||
def sanitizePermissions(filetree):
|
||||
@@ -781,7 +781,7 @@ def splitProcess(path, mode):
|
||||
move(os.path.join(root, name), os.path.join(currentTarget, name))
|
||||
else:
|
||||
firstTome = True
|
||||
for root, dirs, files in walkLevel(path, 0):
|
||||
for root, dirs, _ in walkLevel(path, 0):
|
||||
for name in dirs:
|
||||
if not firstTome:
|
||||
currentTarget, pathRoot = createNewTome()
|
||||
@@ -795,7 +795,7 @@ def splitProcess(path, mode):
|
||||
def detectCorruption(tmpPath, orgPath):
|
||||
imageNumber = 0
|
||||
imageSmaller = 0
|
||||
for root, dirs, files in os.walk(tmpPath, False):
|
||||
for root, _, files in os.walk(tmpPath, False):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
path = os.path.join(root, name)
|
||||
@@ -818,7 +818,7 @@ def detectCorruption(tmpPath, orgPath):
|
||||
else:
|
||||
raise RuntimeError('Image file %s is corrupted.' % pathOrg)
|
||||
else:
|
||||
saferRemove(os.path.join(root, name))
|
||||
os.remove(os.path.join(root, name))
|
||||
if imageSmaller > imageNumber * 0.25 and not options.upscale and not options.stretch:
|
||||
print("WARNING: More than 25% of images are smaller than target device resolution. "
|
||||
"Consider enabling stretching or upscaling to improve readability.")
|
||||
@@ -846,7 +846,7 @@ def makeZIP(zipFilename, baseDir, isEPUB=False):
|
||||
zipOutput = ZipFile(zipFilename, 'w', ZIP_DEFLATED)
|
||||
if isEPUB:
|
||||
zipOutput.writestr('mimetype', 'application/epub+zip', ZIP_STORED)
|
||||
for dirpath, dirnames, filenames in os.walk(baseDir):
|
||||
for dirpath, _, filenames in os.walk(baseDir):
|
||||
for name in filenames:
|
||||
path = os.path.normpath(os.path.join(dirpath, name))
|
||||
aPath = os.path.normpath(os.path.join(dirpath.replace(baseDir, ''), name))
|
||||
@@ -1103,14 +1103,14 @@ def makeBook(source, qtGUI=None):
|
||||
print('Error: Failed to tweak KindleGen output!')
|
||||
return filepath
|
||||
else:
|
||||
saferRemove(i.replace('.epub', '.mobi') + '_toclean')
|
||||
os.remove(i.replace('.epub', '.mobi') + '_toclean')
|
||||
if k.path and k.coverSupport:
|
||||
options.covers[filepath.index(i)][0].saveToKindle(k, options.covers[filepath.index(i)][1])
|
||||
return filepath
|
||||
|
||||
|
||||
def makeMOBIFix(item, uuid):
|
||||
saferRemove(item)
|
||||
os.remove(item)
|
||||
mobiPath = item.replace('.epub', '.mobi')
|
||||
move(mobiPath, mobiPath + '_toclean')
|
||||
try:
|
||||
|
||||
@@ -24,7 +24,7 @@ from shutil import rmtree, copytree, move
|
||||
from optparse import OptionParser, OptionGroup
|
||||
from multiprocessing import Pool
|
||||
from PIL import Image, ImageStat, ImageOps
|
||||
from .shared import getImageFileName, walkLevel, walkSort, saferRemove, sanitizeTrace
|
||||
from .shared import getImageFileName, walkLevel, walkSort, sanitizeTrace
|
||||
try:
|
||||
from PyQt5 import QtCore
|
||||
except ImportError:
|
||||
@@ -48,7 +48,7 @@ def mergeDirectory(work):
|
||||
imagesValid = []
|
||||
sizes = []
|
||||
targetHeight = 0
|
||||
for root, dirs, files in walkLevel(directory, 0):
|
||||
for root, _, files in walkLevel(directory, 0):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
i = Image.open(os.path.join(root, name))
|
||||
@@ -73,7 +73,7 @@ def mergeDirectory(work):
|
||||
img = ImageOps.fit(img, (targetWidth, img.size[1]), method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
result.paste(img, (0, y))
|
||||
y += img.size[1]
|
||||
saferRemove(i)
|
||||
os.remove(i)
|
||||
savePath = os.path.split(imagesValid[0])
|
||||
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
|
||||
except Exception:
|
||||
@@ -199,7 +199,7 @@ def splitImage(work):
|
||||
targetHeight += panels[panel][2]
|
||||
newPage.save(os.path.join(path, fileExpanded[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
||||
pageNumber += 1
|
||||
saferRemove(filePath)
|
||||
os.remove(filePath)
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
|
||||
|
||||
@@ -265,13 +265,13 @@ def main(argv=None, qtGUI=None):
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0][0], mergeWorkerOutput[0][1])
|
||||
print("Splitting images...")
|
||||
for root, dirs, files in os.walk(options.targetDir, False):
|
||||
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:
|
||||
saferRemove(os.path.join(root, name))
|
||||
os.remove(os.path.join(root, name))
|
||||
if GUI:
|
||||
GUI.progressBarTick.emit('Splitting images')
|
||||
GUI.progressBarTick.emit(str(pagenumber))
|
||||
|
||||
@@ -206,7 +206,7 @@ class ComicPageParser:
|
||||
|
||||
|
||||
class ComicPage:
|
||||
def __init__(self, mode, path, image, color, fill, options):
|
||||
def __init__(self, options, mode, path, image, color, fill):
|
||||
self.opt = options
|
||||
_, self.size, self.palette, self.gamma = self.opt.profileData
|
||||
self.image = image
|
||||
@@ -232,16 +232,16 @@ class ComicPage:
|
||||
if self.rotated:
|
||||
flags.append('Rotated')
|
||||
if self.fill != 'white':
|
||||
flags.append('BlackFill')
|
||||
flags.append('BlackBackground')
|
||||
if self.opt.forcepng:
|
||||
self.targetPath += '.png'
|
||||
self.image.save(self.targetPath, 'PNG', optimize=1)
|
||||
else:
|
||||
self.targetPath += '.jpg'
|
||||
self.image.save(self.targetPath, 'JPEG', optimize=1, quality=80)
|
||||
self.image.save(self.targetPath, 'JPEG', optimize=1, quality=85)
|
||||
return [md5Checksum(self.targetPath), flags, self.orgPath]
|
||||
except IOError:
|
||||
raise RuntimeError('Cannot save image.')
|
||||
except IOError as err:
|
||||
raise RuntimeError('Cannot save image. ' + str(err))
|
||||
|
||||
def autocontrastImage(self):
|
||||
gamma = self.opt.gamma
|
||||
@@ -361,7 +361,7 @@ class Cover:
|
||||
|
||||
def save(self):
|
||||
try:
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=80)
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=85)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to process downloaded cover.')
|
||||
|
||||
@@ -369,6 +369,6 @@ class Cover:
|
||||
self.image = self.image.resize((300, 470), Image.ANTIALIAS)
|
||||
try:
|
||||
self.image.save(os.path.join(kindle.path.split('documents')[0], 'system', 'thumbnails',
|
||||
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG')
|
||||
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG', optimize=1, quality=85)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to upload cover.')
|
||||
|
||||
@@ -92,30 +92,6 @@ def check7ZFile(filePath):
|
||||
return header == b"7z\xbc\xaf'\x1c"
|
||||
|
||||
|
||||
def saferReplace(old, new):
|
||||
for x in range(30):
|
||||
try:
|
||||
os.replace(old, new)
|
||||
except PermissionError:
|
||||
sleep(1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError("Failed to move the file.")
|
||||
|
||||
|
||||
def saferRemove(target):
|
||||
for x in range(30):
|
||||
try:
|
||||
os.remove(target)
|
||||
except PermissionError:
|
||||
sleep(1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError("Failed to remove the file.")
|
||||
|
||||
|
||||
def removeFromZIP(zipfname, *filenames):
|
||||
tempdir = mkdtemp('', 'KCC-')
|
||||
try:
|
||||
@@ -125,15 +101,7 @@ def removeFromZIP(zipfname, *filenames):
|
||||
for item in zipread.infolist():
|
||||
if item.filename not in filenames:
|
||||
zipwrite.writestr(item, zipread.read(item.filename))
|
||||
for x in range(30):
|
||||
try:
|
||||
copy(tempname, zipfname)
|
||||
except PermissionError:
|
||||
sleep(1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
finally:
|
||||
rmtree(tempdir, True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user