1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-21 16:38:50 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Xu
46a6103e19 Revert "huge speed optimization on HDD by removing md5 (#845)"
This reverts commit 01625904d1.
2025-03-06 13:54:11 -08:00
6 changed files with 46 additions and 43 deletions

View File

@@ -46,25 +46,11 @@ jobs:
mv dist/windows/kcc.exe dist/windows/KCC_${version_built}.exe
mv dist/windows/kcc-c2e.exe dist/windows/KCC_c2e_${version_built}.exe
mv dist/windows/kcc-c2p.exe dist/windows/KCC_c2p_${version_built}.exe
- name: upload-unsigned-artifact
id: upload-unsigned-artifact
- name: upload build
uses: actions/upload-artifact@v4
with:
name: windows-build
path: dist/windows/*.exe
- id: optional_step_id
uses: signpath/github-action-submit-signing-request@v1.1
with:
api-token: '${{ secrets.SIGNPATH_API_TOKEN }}'
organization-id: '1dc1bad6-4a8c-4f85-af30-5c5d3d392ea6'
project-slug: 'kcc'
signing-policy-slug: 'release-signing'
github-artifact-id: '${{ steps.upload-unsigned-artifact.outputs.artifact-id }}'
wait-for-completion: true
output-artifact-directory: 'dist/windows/signed/'
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
@@ -74,4 +60,4 @@ jobs:
files: |
CHANGELOG.md
LICENSE.txt
dist/windows/signed/*.exe
dist/windows/*.exe

View File

@@ -33,9 +33,6 @@ If you find **KCC** valuable you can consider donating to the authors:
- Alex Xu (active 2023-Present)
- [![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate/?business=QFJVE7A6LCP6U&no_recurring=0&item_name=Kindle+Comic+Converter&currency_code=USD)
## Sponsors
- Free code signing on Windows provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/)
## DOWNLOADS

View File

@@ -1,4 +1,4 @@
__version__ = '7.3.1'
__version__ = '7.3.0'
__license__ = 'ISC'
__copyright__ = '2012-2022, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>, darodi'
__docformat__ = 'restructuredtext en'

View File

@@ -40,7 +40,7 @@ from subprocess import STDOUT, PIPE
from psutil import virtual_memory, disk_usage
from html import escape as hescape
from .shared import available_archive_tools, getImageFileName, walkSort, walkLevel, sanitizeTrace, subprocess_run
from .shared import available_archive_tools, md5Checksum, getImageFileName, walkSort, walkLevel, sanitizeTrace, subprocess_run
from . import comic2panel
from . import image
from . import comicarchive
@@ -77,14 +77,15 @@ def main(argv=None):
return 0
def buildHTML(path, imgfile):
def buildHTML(path, imgfile, imgfilepath):
imgfilepath = md5Checksum(imgfilepath)
filename = getImageFileName(imgfile)
deviceres = options.profileData[1]
if not options.noprocessing and "Rotated" in imgfile:
if not options.noprocessing and "Rotated" in options.imgMetadata[imgfilepath]:
rotatedPage = True
else:
rotatedPage = False
if not options.noprocessing and "BlackBackground" in imgfile:
if not options.noprocessing and "BlackBackground" in options.imgMetadata[imgfilepath]:
additionalStyle = 'background-color:#000000;'
else:
additionalStyle = ''
@@ -424,6 +425,7 @@ def buildOPF(dstdir, title, filelist, cover=None):
"</container>"])
f.close()
def buildEPUB(path, chapternames, tomenumber, ischunked):
filelist = []
chapterlist = []
@@ -504,7 +506,6 @@ def buildEPUB(path, chapternames, tomenumber, ischunked):
"display: none;\n",
"}\n"])
f.close()
build_html_start = perf_counter()
for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'OEBPS', 'Images')):
chapter = False
dirnames, filenames = walkSort(dirnames, filenames)
@@ -514,12 +515,10 @@ def buildEPUB(path, chapternames, tomenumber, ischunked):
'cover' + getImageFileName(afile)[1])
options.covers.append((image.Cover(os.path.join(dirpath, afile), cover, options,
tomenumber), options.uuid))
filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile)))
if not chapter:
chapterlist.append((dirpath.replace('Images', 'Text'), afile))
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
chapter = True
filelist.append(buildHTML(dirpath, afile))
build_html_end = perf_counter()
print(f"buildHTML: {build_html_end - build_html_start} seconds")
# Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks
if not chapternames and options.chapters and not ischunked:
chapterlist = []
@@ -540,7 +539,7 @@ def buildEPUB(path, chapternames, tomenumber, ischunked):
global_diff = 0
for x in range(0, pageid + cur_diff + 1):
if '-KCC-B' in filelist[x][1]:
if '-kcc-b' in filelist[x][1]:
pageid += diff_delta
global_diff += diff_delta
@@ -556,6 +555,8 @@ def imgDirectoryProcessing(path):
global workerPool, workerOutput
workerPool = Pool(maxtasksperchild=100)
workerOutput = []
options.imgMetadata = {}
options.imgOld = []
work = []
pagenumber = 0
for dirpath, _, filenames in os.walk(path):
@@ -565,19 +566,19 @@ def imgDirectoryProcessing(path):
if GUI:
GUI.progressBarTick.emit(str(pagenumber))
if len(work) > 0:
img_processing_start = perf_counter()
for i in work:
workerPool.apply_async(func=imgFileProcessing, args=(i,), callback=imgFileProcessingTick)
workerPool.close()
workerPool.join()
img_processing_end = perf_counter()
print(f"imgFileProcessing: {img_processing_end - img_processing_start} seconds")
if GUI and not GUI.conversionAlive:
rmtree(os.path.join(path, '..', '..'), True)
raise UserWarning("Conversion interrupted.")
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.imgOld:
if os.path.isfile(file):
os.remove(file)
else:
rmtree(os.path.join(path, '..', '..'), True)
raise UserWarning("Source directory is empty.")
@@ -587,7 +588,11 @@ def imgFileProcessingTick(output):
if isinstance(output, tuple):
workerOutput.append(output)
workerPool.terminate()
else:
for page in output:
if page is not None:
options.imgMetadata[page[0]] = page[1]
options.imgOld.append(page[2])
if GUI:
GUI.progressBarTick.emit('tick')
if not GUI.conversionAlive:
@@ -731,7 +736,9 @@ def getComicInfo(path, originalpath):
except Exception:
os.remove(xmlPath)
return
if defaultTitle:
if xml.data['Title']:
options.title = hescape(xml.data['Title'])
elif defaultTitle:
if xml.data['Series']:
options.title = hescape(xml.data['Series'])
if xml.data['Volume']:
@@ -790,9 +797,13 @@ def sanitizeTree(filetree):
for name in files:
splitname = os.path.splitext(name)
# 9999 page limit
# file needs kcc at front AND back to avoid renaming issues
slugified = f'kcc-{page:04}'
page += 1
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)
@@ -1178,7 +1189,6 @@ def makeBook(source, qtgui=None):
print("Checking images...")
getComicInfo(os.path.join(path, "OEBPS", "Images"), source)
detectSuboptimalProcessing(os.path.join(path, "OEBPS", "Images"), source)
chapterNames = sanitizeTree(os.path.join(path, 'OEBPS', 'Images'))
if options.webtoon:
y = image.ProfileData.Profiles[options.profile][1][1]
comic2panel.main(['-y ' + str(y), '-i', '-m', path], qtgui)
@@ -1191,6 +1201,7 @@ def makeBook(source, qtgui=None):
imgDirectoryProcessing(os.path.join(path, "OEBPS", "Images"))
if GUI:
GUI.progressBarTick.emit('1')
chapterNames = sanitizeTree(os.path.join(path, 'OEBPS', 'Images'))
if options.batchsplit > 0:
tomes = chunk_directory(path)
else:

View File

@@ -20,9 +20,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import io
import os
from pathlib import Path
import mozjpeg_lossless_optimization
from PIL import Image, ImageOps, ImageStat, ImageChops, ImageFilter
from .shared import md5Checksum
from .page_number_crop_alg import get_bbox_crop_margin_page_number, get_bbox_crop_margin
from .inter_panel_crop_alg import crop_empty_inter_panel
@@ -299,12 +299,13 @@ class ComicPage:
def saveToDir(self):
try:
flags = []
if not self.opt.forcecolor and not self.opt.forcepng:
self.image = self.image.convert('L')
if self.rotated:
self.targetPath += '-Rotated'
flags.append('Rotated')
if self.fill != 'white':
self.targetPath += '-BlackBackground'
flags.append('BlackBackground')
if self.opt.forcepng:
self.image.info["transparency"] = None
self.targetPath += '.png'
@@ -320,9 +321,7 @@ class ComicPage:
output_jpeg_file.write(output_jpeg_bytes)
else:
self.image.save(self.targetPath, 'JPEG', optimize=1, quality=85)
if os.path.isfile(self.orgPath):
os.remove(self.orgPath)
return Path(self.targetPath).name
return [md5Checksum(self.targetPath), flags, self.orgPath]
except IOError as err:
raise RuntimeError('Cannot save image. ' + str(err))

View File

@@ -75,6 +75,16 @@ def walkLevel(some_dir, level=1):
del dirs[:]
def md5Checksum(fpath):
with open(fpath, 'rb') as fh:
m = md5()
while True:
data = fh.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
def sanitizeTrace(traceback):
return ''.join(format_tb(traceback))\