1
0
mirror of https://github.com/ciromattia/kcc synced 2026-04-17 06:28:49 +00:00

Compare commits

...

28 Commits

Author SHA1 Message Date
Alex Xu
9b63b7af2c Bump version to 9.3.8 2025-12-27 12:23:39 -08:00
tokyis
f74e108a3e Fixed resizing bug
caused by misplaced closing parenthesis.
2025-12-27 12:22:10 -08:00
Alex Xu
f088ad732e default MACOSX_DEPLOYMENT_TARGET 2025-12-23 13:19:40 -08:00
jaroslawjanas
8e5d57364d Remove environment.yml 2025-12-15 09:48:49 -08:00
dependabot[bot]
b767d5dc2c Bump actions/upload-artifact from 5 to 6 (#1196)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 09:48:49 -08:00
Alex Xu
7228055bca reduce file operations in webtoon and file fusion (#1191)
* reduce file operations in webtoon

* reduce file operations of file fusion

* fix file fusion failed to prepare

* close webtoon image before remove

* use temp directory
2025-12-14 23:44:30 -08:00
Alex Xu
8c57fbf318 fix add folder button sizePolicy 2025-12-14 18:59:28 -08:00
Alex Xu
7e94861fa1 input folder multiselect (#1195) 2025-12-14 16:13:24 -08:00
Alex Xu
9992ca4d26 fix mac legacy build naming 2025-12-10 22:00:56 -08:00
Alex Xu
f47d1427f0 Update README.md
Clarified description of Kindle Comic Converter's capabilities.
2025-12-09 23:22:31 -08:00
Alex Xu
ce8998375c macOS 14 minimum for non legacy 2025-12-08 22:27:40 -08:00
Alex Xu
8870898a87 macOS 14 minimum for non legacy builds (#1189) 2025-12-08 22:25:59 -08:00
Alex Xu
a017cfd00d specify 12.0 instead of 12 2025-12-08 21:31:38 -08:00
Alex Xu
3f4ef3e21e Bump version to 9.3.7 2025-12-08 20:59:26 -08:00
Alex Xu
4733c6348b specify macOS 12 minimum for standard builds (#1188) 2025-12-08 20:58:15 -08:00
Alex Xu
5ad23d9629 mention color 2025-12-08 19:50:34 -08:00
Alex Xu
db4eb78963 Bump version to 9.3.6 2025-12-08 19:15:47 -08:00
Alex Xu
988fc93dc5 Fix macOS 10.14+ legacy compatibility (#1187)
* Update requirements-osx-legacy.txt

* upgrade macos-13 to macos-15-intel

* upgrade macos-13 to macos-15-intel
2025-12-08 18:08:16 -08:00
Alex Xu
74fee9346c Bump version to 9.3.5 2025-12-03 19:15:45 -08:00
Alex Xu
9fcacd7ae6 fix comicinfo detection in corner case (9.3.4 regression) (#1185) 2025-12-03 19:13:19 -08:00
Alex Xu
8ac58e361f Bump version to 9.3.4 2025-12-03 10:23:00 -08:00
kiryl
61d6972e22 Sync setup install_requires with requirements.txt (#1176)
* remove duplicated PyMuPDF entry and change packages order for easier comparison with requirements.txt

* update packages versions to be synced to each other (requirements.txt vs install_requires in setuptools.setup()

* add missing pyinstaller package which is required to build exe/app

* clarify minimums

* fix typo

* remove pyinstaller

Remove pyinstaller from the requirements.

---------

Co-authored-by: Alex Xu <alexkurosakimh3@gmail.com>
2025-12-02 21:13:26 -08:00
Alex Xu
c7c1557e72 add tomenumber when output folder checked (#1183)
* add tomenumber when output checked

* fix all cases
2025-12-02 20:54:46 -08:00
kiryl
cb93704e08 Mention tabulation order in README.md (#1181) 2025-12-02 15:20:52 -08:00
kiryl
62c5183609 set tabulation order for KCC fields (#1178)
* set tabulation order for KCC fields

- loop through fields in more organized order including fields which visibility depends on some checkboxes state

* don't change rc

---------

Co-authored-by: Alex Xu <alexkurosakimh3@gmail.com>
2025-12-02 12:36:17 -08:00
kiryl
a629f267a1 set tabulation order for metadata editor fields (#1177)
* set tabulation order for metadata editor fields

- loop through fields in from top to down order

* don't change rc

---------

Co-authored-by: Alex Xu <alexkurosakimh3@gmail.com>
2025-12-02 12:33:38 -08:00
Alex Xu
aeec4dd294 fix output folder with period (#1180) 2025-12-02 12:04:15 -08:00
Alex Xu
0d3076465b use less file operations (#1174) 2025-12-01 19:27:17 -08:00
19 changed files with 298 additions and 205 deletions

View File

@@ -59,7 +59,7 @@ jobs:
env:
UPDATE_INFO: gh-releases-zsync|ciromattia|kcc|latest|*x86_64.AppImage.zsync
- name: upload artifact
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: AppImage
path: './*.AppImage*'

View File

@@ -25,8 +25,10 @@ jobs:
build:
strategy:
matrix:
os: [ macos-13, macos-14 ]
os: [ macos-15-intel, macos-14 ]
runs-on: ${{ matrix.os }}
env:
MACOSX_DEPLOYMENT_TARGET: '14.0'
steps:
- uses: actions/checkout@v6
- name: Set up Python
@@ -78,7 +80,7 @@ jobs:
run: |
python setup.py build_binary
- name: upload build
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: mac-os-build-${{ runner.arch }}
path: dist/*.dmg

View File

@@ -23,7 +23,7 @@ jobs:
build:
strategy:
matrix:
os: [ macos-13 ]
os: [ macos-15-intel ]
runs-on: ${{ matrix.os }}
env:
# We need the official Python, because the GA ones only support newer macOS versions
@@ -51,7 +51,7 @@ jobs:
run: |
python3 setup.py build_binary
- name: upload build
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: osx-build-${{ runner.arch }}
path: dist/*.dmg

View File

@@ -53,7 +53,7 @@ jobs:
python setup.py ${{ matrix.command }}
- name: upload-unsigned-artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: windows-build-${{ matrix.entry }}
path: dist/*.exe

View File

@@ -46,7 +46,7 @@ jobs:
python setup.py build_binary
- name: upload-unsigned-artifact
id: upload-unsigned-artifact
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v6
with:
name: windows7-build
path: dist/*.exe

View File

@@ -7,7 +7,7 @@
[![Github All Releases](https://img.shields.io/github/downloads/ciromattia/kcc/total.svg)](https://github.com/ciromattia/kcc/releases)
**Kindle Comic Converter** optimizes black & white comics and manga for E-ink ereaders
**Kindle Comic Converter** optimizes black & white (or color) comics and manga for E-ink ereaders
like Kindle, Kobo, ReMarkable, and more.
Pages display in fullscreen without margins,
with proper fixed layout support.
@@ -92,7 +92,7 @@ Click on **Assets** of the latest release.
You probably want either
- `KCC_*.*.*.exe` (Windows)
- `kcc_macos_arm_*.*.*.dmg` (recent Mac with Apple Silicon M1 chip or later)
- `kcc_macos_i386_*.*.*.dmg` (older Mac with Intel chip macOS 12+)
- `kcc_macos_i386_*.*.*.dmg` (older Mac with Intel chip macOS 14+)
There are also legacy macOS 10.14+ and Windows 7 experimental versions available.
@@ -318,6 +318,7 @@ Depending on your system [Python](https://www.python.org) may be called either `
If you want to edit the code, a good code editor is [VS Code](https://code.visualstudio.com).
If you want to edit the `.ui` files, use `pyside6-designer` which is included in the `pip install pyside6`.
If new objects have been added, verify that correct tab order has been applied by using [Tab Order Editing Mode](https://doc.qt.io/qt-6/designer-tab-order.html).
Then use the `gen_ui_files` scripts to autogenerate the python UI.
An example PR adding a new checkbox is here: https://github.com/ciromattia/kcc/pull/785

View File

@@ -1,16 +0,0 @@
name: kcc
channels:
- conda-forge
- defaults
dependencies:
- python=3.11
- Pillow>=11.3.0
- psutil>=5.9.5
- python-slugify>=1.2.1
- raven>=6.0.0
- distro
- natsort>=8.4.0
- pip
- pip:
- mozjpeg-lossless-optimization>=1.1.2
- pyside6>=6.5.1

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>566</width>
<height>573</height>
<height>581</height>
</rect>
</property>
<property name="windowTitle">
@@ -348,6 +348,51 @@
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QWidget" name="outputFolderWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="defaultOutputFolderBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - next to source&lt;br/&gt;&lt;/span&gt;Place output files next to source files&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - folder next to source&lt;br/&gt;&lt;/span&gt;Place output files in a folder next to source files&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Custom&lt;br/&gt;&lt;/span&gt;Place output files in custom directory specified by right button&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Output Folder</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="defaultOutputFolderButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use this to select the default output directory.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="KCC.qrc">
<normaloff>:/Other/icons/folder_new.png</normaloff>:/Other/icons/folder_new.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
@@ -747,7 +792,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Add CBR, CBZ, CB7 or PDF file to queue.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Add file(s)</string>
<string>Add input file(s)</string>
</property>
<property name="icon">
<iconset resource="KCC.qrc">
@@ -755,19 +800,19 @@
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QPushButton" name="defaultOutputFolderButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
<item row="0" column="4">
<widget class="QPushButton" name="directoryButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Use this to select the default output directory.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p style='white-space:pre'&gt;Add directory containing JPG, PNG or GIF files to queue.&lt;br/&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;CBR, CBZ and CB7 files inside will not be processed!&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
<string>Add input folder(s)</string>
</property>
<property name="icon">
<iconset resource="KCC.qrc">
@@ -775,26 +820,7 @@
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QCheckBox" name="defaultOutputFolderBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Unchecked - next to source&lt;br/&gt;&lt;/span&gt;Place output files next to source files&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Indeterminate - folder next to source&lt;br/&gt;&lt;/span&gt;Place output files in a folder next to source files&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; text-decoration: underline;&quot;&gt;Checked - Custom&lt;br/&gt;&lt;/span&gt;Place output files in custom directory specified by right button&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Output Folder</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="4" colspan="2">
<item row="1" column="4">
<widget class="QComboBox" name="formatBox">
<property name="minimumSize">
<size>
@@ -811,10 +837,9 @@
<zorder>clearButton</zorder>
<zorder>deviceBox</zorder>
<zorder>convertButton</zorder>
<zorder>formatBox</zorder>
<zorder>defaultOutputFolderButton</zorder>
<zorder>fileButton</zorder>
<zorder>defaultOutputFolderBox</zorder>
<zorder>directoryButton</zorder>
<zorder>formatBox</zorder>
</widget>
</item>
<item row="6" column="0">
@@ -898,36 +923,44 @@
</widget>
</widget>
<tabstops>
<tabstop>convertButton</tabstop>
<tabstop>jobList</tabstop>
<tabstop>fileButton</tabstop>
<tabstop>clearButton</tabstop>
<tabstop>deviceBox</tabstop>
<tabstop>formatBox</tabstop>
<tabstop>widthBox</tabstop>
<tabstop>heightBox</tabstop>
<tabstop>convertButton</tabstop>
<tabstop>mangaBox</tabstop>
<tabstop>rotateBox</tabstop>
<tabstop>qualityBox</tabstop>
<tabstop>webtoonBox</tabstop>
<tabstop>upscaleBox</tabstop>
<tabstop>gammaBox</tabstop>
<tabstop>gammaSlider</tabstop>
<tabstop>borderBox</tabstop>
<tabstop>outputSplit</tabstop>
<tabstop>colorBox</tabstop>
<tabstop>mozJpegBox</tabstop>
<tabstop>maximizeStrips</tabstop>
<tabstop>croppingBox</tabstop>
<tabstop>croppingPowerSlider</tabstop>
<tabstop>preserveMarginBox</tabstop>
<tabstop>spreadShiftBox</tabstop>
<tabstop>deleteBox</tabstop>
<tabstop>disableProcessingBox</tabstop>
<tabstop>chunkSizeBox</tabstop>
<tabstop>fileFusionBox</tabstop>
<tabstop>noRotateBox</tabstop>
<tabstop>interPanelCropBox</tabstop>
<tabstop>metadataTitleBox</tabstop>
<tabstop>chunkSizeCheckBox</tabstop>
<tabstop>chunkSizeBox</tabstop>
<tabstop>eraseRainbowBox</tabstop>
<tabstop>heightBox</tabstop>
<tabstop>croppingPowerSlider</tabstop>
<tabstop>rotateFirstBox</tabstop>
<tabstop>autoLevelBox</tabstop>
<tabstop>autocontrastBox</tabstop>
<tabstop>editorButton</tabstop>
<tabstop>kofiButton</tabstop>
<tabstop>wikiButton</tabstop>
<tabstop>jobList</tabstop>
<tabstop>gammaSlider</tabstop>
<tabstop>widthBox</tabstop>
</tabstops>
<resources>
<include location="KCC.qrc"/>

View File

@@ -192,6 +192,18 @@
</item>
</layout>
</widget>
<tabstops>
<tabstop>seriesLine</tabstop>
<tabstop>volumeLine</tabstop>
<tabstop>titleLine</tabstop>
<tabstop>numberLine</tabstop>
<tabstop>writerLine</tabstop>
<tabstop>pencillerLine</tabstop>
<tabstop>inkerLine</tabstop>
<tabstop>coloristLine</tabstop>
<tabstop>okButton</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources>
<include location="KCC.qrc"/>
</resources>

View File

@@ -22,7 +22,7 @@ import itertools
from pathlib import Path
from PySide6.QtCore import (QSize, QUrl, Qt, Signal, QIODeviceBase, QEvent, QThread, QSettings)
from PySide6.QtGui import (QColor, QIcon, QPixmap, QDesktopServices)
from PySide6.QtWidgets import (QApplication, QLabel, QListWidgetItem, QMainWindow, QSystemTrayIcon, QFileDialog, QMessageBox, QDialog)
from PySide6.QtWidgets import (QApplication, QLabel, QListWidgetItem, QMainWindow, QSystemTrayIcon, QFileDialog, QMessageBox, QDialog, QTreeView, QAbstractItemView)
from PySide6.QtNetwork import (QLocalSocket, QLocalServer)
import os
@@ -610,12 +610,30 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
'Comic (*.pdf);;All (*.*)')
for fname in fnames[0]:
if fname != '':
if sys.platform.startswith('win'):
fname = fname.replace('/', '\\')
self.lastPath = os.path.abspath(os.path.join(fname, os.pardir))
GUI.jobList.addItem(fname)
GUI.jobList.scrollToBottom()
def selectDir(self):
if self.needClean:
self.needClean = False
GUI.jobList.clear()
dialog = QFileDialog(MW, 'Select input folder(s)', self.lastPath)
dialog.setFileMode(QFileDialog.FileMode.Directory)
dialog.setOption(QFileDialog.Option.ShowDirsOnly, True)
dialog.setOption(QFileDialog.Option.DontUseNativeDialog, True)
dialog.findChild(QTreeView).setSelectionMode(QAbstractItemView.ExtendedSelection)
if dialog.exec():
dnames = dialog.selectedFiles()
for dname in dnames:
if dname != '':
self.lastPath = os.path.abspath(os.path.join(dname, os.pardir))
GUI.jobList.addItem(dname)
GUI.jobList.scrollToBottom()
def selectFileMetaEditor(self, sname):
if not sname:
if QApplication.keyboardModifiers() == Qt.ShiftModifier:
@@ -1319,6 +1337,7 @@ class KCCGUI(KCC_ui.Ui_mainWindow):
GUI.defaultOutputFolderButton.clicked.connect(self.selectDefaultOutputFolder)
GUI.clearButton.clicked.connect(self.clearJobs)
GUI.fileButton.clicked.connect(self.selectFile)
GUI.directoryButton.clicked.connect(self.selectDir)
GUI.editorButton.clicked.connect(self.selectFileMetaEditor)
GUI.wikiButton.clicked.connect(self.openWiki)
GUI.kofiButton.clicked.connect(self.openKofi)

View File

@@ -26,7 +26,7 @@ class Ui_mainWindow(object):
def setupUi(self, mainWindow):
if not mainWindow.objectName():
mainWindow.setObjectName(u"mainWindow")
mainWindow.resize(566, 573)
mainWindow.resize(566, 581)
icon = QIcon()
icon.addFile(u":/Icon/icons/comic2ebook.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
mainWindow.setWindowIcon(icon)
@@ -190,6 +190,33 @@ class Ui_mainWindow(object):
self.gridLayout_2.addWidget(self.autocontrastBox, 9, 2, 1, 1)
self.outputFolderWidget = QWidget(self.optionWidget)
self.outputFolderWidget.setObjectName(u"outputFolderWidget")
self.horizontalLayout_3 = QHBoxLayout(self.outputFolderWidget)
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.defaultOutputFolderBox = QCheckBox(self.outputFolderWidget)
self.defaultOutputFolderBox.setObjectName(u"defaultOutputFolderBox")
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.defaultOutputFolderBox.sizePolicy().hasHeightForWidth())
self.defaultOutputFolderBox.setSizePolicy(sizePolicy1)
self.defaultOutputFolderBox.setTristate(True)
self.horizontalLayout_3.addWidget(self.defaultOutputFolderBox)
self.defaultOutputFolderButton = QPushButton(self.outputFolderWidget)
self.defaultOutputFolderButton.setObjectName(u"defaultOutputFolderButton")
self.defaultOutputFolderButton.setMinimumSize(QSize(0, 30))
icon1 = QIcon()
icon1.addFile(u":/Other/icons/folder_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.defaultOutputFolderButton.setIcon(icon1)
self.horizontalLayout_3.addWidget(self.defaultOutputFolderButton)
self.gridLayout_2.addWidget(self.outputFolderWidget, 0, 2, 1, 1)
self.gridLayout.addWidget(self.optionWidget, 5, 0, 1, 2)
@@ -211,11 +238,11 @@ class Ui_mainWindow(object):
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
self.hLabel = QLabel(self.customWidget)
self.hLabel.setObjectName(u"hLabel")
sizePolicy1 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.hLabel.sizePolicy().hasHeightForWidth())
self.hLabel.setSizePolicy(sizePolicy1)
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.hLabel.sizePolicy().hasHeightForWidth())
self.hLabel.setSizePolicy(sizePolicy2)
self.gridLayout_3.addWidget(self.hLabel, 0, 2, 1, 1)
@@ -227,8 +254,8 @@ class Ui_mainWindow(object):
self.wLabel = QLabel(self.customWidget)
self.wLabel.setObjectName(u"wLabel")
sizePolicy1.setHeightForWidth(self.wLabel.sizePolicy().hasHeightForWidth())
self.wLabel.setSizePolicy(sizePolicy1)
sizePolicy2.setHeightForWidth(self.wLabel.sizePolicy().hasHeightForWidth())
self.wLabel.setSizePolicy(sizePolicy2)
self.gridLayout_3.addWidget(self.wLabel, 0, 0, 1, 1)
@@ -271,18 +298,18 @@ class Ui_mainWindow(object):
self.editorButton = QPushButton(self.toolWidget)
self.editorButton.setObjectName(u"editorButton")
self.editorButton.setMinimumSize(QSize(0, 30))
icon1 = QIcon()
icon1.addFile(u":/Other/icons/editor.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.editorButton.setIcon(icon1)
icon2 = QIcon()
icon2.addFile(u":/Other/icons/editor.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.editorButton.setIcon(icon2)
self.horizontalLayout.addWidget(self.editorButton)
self.kofiButton = QPushButton(self.toolWidget)
self.kofiButton.setObjectName(u"kofiButton")
self.kofiButton.setMinimumSize(QSize(0, 30))
icon2 = QIcon()
icon2.addFile(u":/Brand/icons/kofi_symbol.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.kofiButton.setIcon(icon2)
icon3 = QIcon()
icon3.addFile(u":/Brand/icons/kofi_symbol.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.kofiButton.setIcon(icon3)
self.kofiButton.setIconSize(QSize(19, 16))
self.horizontalLayout.addWidget(self.kofiButton)
@@ -290,9 +317,9 @@ class Ui_mainWindow(object):
self.wikiButton = QPushButton(self.toolWidget)
self.wikiButton.setObjectName(u"wikiButton")
self.wikiButton.setMinimumSize(QSize(0, 30))
icon3 = QIcon()
icon3.addFile(u":/Other/icons/wiki.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.wikiButton.setIcon(icon3)
icon4 = QIcon()
icon4.addFile(u":/Other/icons/wiki.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.wikiButton.setIcon(icon4)
self.horizontalLayout.addWidget(self.wikiButton)
@@ -336,11 +363,8 @@ class Ui_mainWindow(object):
self.preserveMarginBox = QSpinBox(self.croppingWidget)
self.preserveMarginBox.setObjectName(u"preserveMarginBox")
sizePolicy2 = QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.preserveMarginBox.sizePolicy().hasHeightForWidth())
self.preserveMarginBox.setSizePolicy(sizePolicy2)
sizePolicy1.setHeightForWidth(self.preserveMarginBox.sizePolicy().hasHeightForWidth())
self.preserveMarginBox.setSizePolicy(sizePolicy1)
self.preserveMarginBox.setMaximum(99)
self.preserveMarginBox.setSingleStep(5)
self.preserveMarginBox.setValue(0)
@@ -364,18 +388,18 @@ class Ui_mainWindow(object):
self.convertButton.setObjectName(u"convertButton")
self.convertButton.setMinimumSize(QSize(0, 30))
self.convertButton.setFont(font)
icon4 = QIcon()
icon4.addFile(u":/Other/icons/convert.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.convertButton.setIcon(icon4)
icon5 = QIcon()
icon5.addFile(u":/Other/icons/convert.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.convertButton.setIcon(icon5)
self.gridLayout_4.addWidget(self.convertButton, 1, 3, 1, 1)
self.clearButton = QPushButton(self.buttonWidget)
self.clearButton.setObjectName(u"clearButton")
self.clearButton.setMinimumSize(QSize(0, 30))
icon5 = QIcon()
icon5.addFile(u":/Other/icons/clear.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.clearButton.setIcon(icon5)
icon6 = QIcon()
icon6.addFile(u":/Other/icons/clear.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.clearButton.setIcon(icon6)
self.gridLayout_4.addWidget(self.clearButton, 0, 3, 1, 1)
@@ -388,42 +412,35 @@ class Ui_mainWindow(object):
self.fileButton = QPushButton(self.buttonWidget)
self.fileButton.setObjectName(u"fileButton")
self.fileButton.setMinimumSize(QSize(0, 30))
icon6 = QIcon()
icon6.addFile(u":/Other/icons/document_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.fileButton.setIcon(icon6)
icon7 = QIcon()
icon7.addFile(u":/Other/icons/document_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.fileButton.setIcon(icon7)
self.gridLayout_4.addWidget(self.fileButton, 0, 1, 1, 1)
self.defaultOutputFolderButton = QPushButton(self.buttonWidget)
self.defaultOutputFolderButton.setObjectName(u"defaultOutputFolderButton")
self.defaultOutputFolderButton.setMinimumSize(QSize(0, 30))
icon7 = QIcon()
icon7.addFile(u":/Other/icons/folder_new.png", QSize(), QIcon.Mode.Normal, QIcon.State.Off)
self.defaultOutputFolderButton.setIcon(icon7)
self.directoryButton = QPushButton(self.buttonWidget)
self.directoryButton.setObjectName(u"directoryButton")
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
sizePolicy4.setHorizontalStretch(0)
sizePolicy4.setVerticalStretch(0)
sizePolicy4.setHeightForWidth(self.directoryButton.sizePolicy().hasHeightForWidth())
self.directoryButton.setSizePolicy(sizePolicy4)
self.directoryButton.setIcon(icon1)
self.gridLayout_4.addWidget(self.defaultOutputFolderButton, 0, 5, 1, 1)
self.defaultOutputFolderBox = QCheckBox(self.buttonWidget)
self.defaultOutputFolderBox.setObjectName(u"defaultOutputFolderBox")
sizePolicy2.setHeightForWidth(self.defaultOutputFolderBox.sizePolicy().hasHeightForWidth())
self.defaultOutputFolderBox.setSizePolicy(sizePolicy2)
self.defaultOutputFolderBox.setTristate(True)
self.gridLayout_4.addWidget(self.defaultOutputFolderBox, 0, 4, 1, 1)
self.gridLayout_4.addWidget(self.directoryButton, 0, 4, 1, 1)
self.formatBox = QComboBox(self.buttonWidget)
self.formatBox.setObjectName(u"formatBox")
self.formatBox.setMinimumSize(QSize(0, 28))
self.gridLayout_4.addWidget(self.formatBox, 1, 4, 1, 2)
self.gridLayout_4.addWidget(self.formatBox, 1, 4, 1, 1)
self.clearButton.raise_()
self.deviceBox.raise_()
self.convertButton.raise_()
self.formatBox.raise_()
self.defaultOutputFolderButton.raise_()
self.fileButton.raise_()
self.defaultOutputFolderBox.raise_()
self.directoryButton.raise_()
self.formatBox.raise_()
self.gridLayout.addWidget(self.buttonWidget, 3, 0, 1, 2)
@@ -438,11 +455,11 @@ class Ui_mainWindow(object):
self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0)
self.chunkSizeLabel = QLabel(self.chunkSizeWidget)
self.chunkSizeLabel.setObjectName(u"chunkSizeLabel")
sizePolicy4 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
sizePolicy4.setHorizontalStretch(0)
sizePolicy4.setVerticalStretch(0)
sizePolicy4.setHeightForWidth(self.chunkSizeLabel.sizePolicy().hasHeightForWidth())
self.chunkSizeLabel.setSizePolicy(sizePolicy4)
sizePolicy5 = QSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Preferred)
sizePolicy5.setHorizontalStretch(0)
sizePolicy5.setVerticalStretch(0)
sizePolicy5.setHeightForWidth(self.chunkSizeLabel.sizePolicy().hasHeightForWidth())
self.chunkSizeLabel.setSizePolicy(sizePolicy5)
self.horizontalLayout_4.addWidget(self.chunkSizeLabel)
@@ -456,8 +473,8 @@ class Ui_mainWindow(object):
self.chunkSizeWarnLabel = QLabel(self.chunkSizeWidget)
self.chunkSizeWarnLabel.setObjectName(u"chunkSizeWarnLabel")
sizePolicy4.setHeightForWidth(self.chunkSizeWarnLabel.sizePolicy().hasHeightForWidth())
self.chunkSizeWarnLabel.setSizePolicy(sizePolicy4)
sizePolicy5.setHeightForWidth(self.chunkSizeWarnLabel.sizePolicy().hasHeightForWidth())
self.chunkSizeWarnLabel.setSizePolicy(sizePolicy5)
self.horizontalLayout_4.addWidget(self.chunkSizeWarnLabel)
@@ -469,35 +486,43 @@ class Ui_mainWindow(object):
self.statusBar.setObjectName(u"statusBar")
self.statusBar.setSizeGripEnabled(False)
mainWindow.setStatusBar(self.statusBar)
QWidget.setTabOrder(self.convertButton, self.clearButton)
QWidget.setTabOrder(self.jobList, self.fileButton)
QWidget.setTabOrder(self.fileButton, self.clearButton)
QWidget.setTabOrder(self.clearButton, self.deviceBox)
QWidget.setTabOrder(self.deviceBox, self.formatBox)
QWidget.setTabOrder(self.formatBox, self.mangaBox)
QWidget.setTabOrder(self.deviceBox, self.widthBox)
QWidget.setTabOrder(self.widthBox, self.heightBox)
QWidget.setTabOrder(self.heightBox, self.convertButton)
QWidget.setTabOrder(self.convertButton, self.mangaBox)
QWidget.setTabOrder(self.mangaBox, self.rotateBox)
QWidget.setTabOrder(self.rotateBox, self.qualityBox)
QWidget.setTabOrder(self.qualityBox, self.webtoonBox)
QWidget.setTabOrder(self.webtoonBox, self.upscaleBox)
QWidget.setTabOrder(self.upscaleBox, self.gammaBox)
QWidget.setTabOrder(self.gammaBox, self.borderBox)
QWidget.setTabOrder(self.gammaBox, self.gammaSlider)
QWidget.setTabOrder(self.gammaSlider, self.borderBox)
QWidget.setTabOrder(self.borderBox, self.outputSplit)
QWidget.setTabOrder(self.outputSplit, self.colorBox)
QWidget.setTabOrder(self.colorBox, self.mozJpegBox)
QWidget.setTabOrder(self.mozJpegBox, self.maximizeStrips)
QWidget.setTabOrder(self.maximizeStrips, self.croppingBox)
QWidget.setTabOrder(self.croppingBox, self.spreadShiftBox)
QWidget.setTabOrder(self.croppingBox, self.croppingPowerSlider)
QWidget.setTabOrder(self.croppingPowerSlider, self.preserveMarginBox)
QWidget.setTabOrder(self.preserveMarginBox, self.spreadShiftBox)
QWidget.setTabOrder(self.spreadShiftBox, self.deleteBox)
QWidget.setTabOrder(self.deleteBox, self.disableProcessingBox)
QWidget.setTabOrder(self.disableProcessingBox, self.chunkSizeBox)
QWidget.setTabOrder(self.chunkSizeBox, self.noRotateBox)
QWidget.setTabOrder(self.disableProcessingBox, self.fileFusionBox)
QWidget.setTabOrder(self.fileFusionBox, self.noRotateBox)
QWidget.setTabOrder(self.noRotateBox, self.interPanelCropBox)
QWidget.setTabOrder(self.interPanelCropBox, self.eraseRainbowBox)
QWidget.setTabOrder(self.eraseRainbowBox, self.heightBox)
QWidget.setTabOrder(self.heightBox, self.croppingPowerSlider)
QWidget.setTabOrder(self.croppingPowerSlider, self.editorButton)
QWidget.setTabOrder(self.editorButton, self.wikiButton)
QWidget.setTabOrder(self.wikiButton, self.jobList)
QWidget.setTabOrder(self.jobList, self.gammaSlider)
QWidget.setTabOrder(self.gammaSlider, self.widthBox)
QWidget.setTabOrder(self.interPanelCropBox, self.metadataTitleBox)
QWidget.setTabOrder(self.metadataTitleBox, self.chunkSizeCheckBox)
QWidget.setTabOrder(self.chunkSizeCheckBox, self.chunkSizeBox)
QWidget.setTabOrder(self.chunkSizeBox, self.eraseRainbowBox)
QWidget.setTabOrder(self.eraseRainbowBox, self.rotateFirstBox)
QWidget.setTabOrder(self.rotateFirstBox, self.autoLevelBox)
QWidget.setTabOrder(self.autoLevelBox, self.autocontrastBox)
QWidget.setTabOrder(self.autocontrastBox, self.editorButton)
QWidget.setTabOrder(self.editorButton, self.kofiButton)
QWidget.setTabOrder(self.kofiButton, self.wikiButton)
self.retranslateUi(mainWindow)
@@ -610,6 +635,14 @@ class Ui_mainWindow(object):
self.autocontrastBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - BW only<br/></span>Only autocontrast bw pages. Ignored for pages where near blacks or whites don't exist.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Disabled<br/></span>Disable autocontrast</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - BW and Color<br/></span>BW and color images will be autocontrasted. Ignored for pages where near blacks or whites don't exist.</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.autocontrastBox.setText(QCoreApplication.translate("mainWindow", u"Autocontrast", None))
#if QT_CONFIG(tooltip)
self.defaultOutputFolderBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - next to source<br/></span>Place output files next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - folder next to source<br/></span>Place output files in a folder next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Custom<br/></span>Place output files in custom directory specified by right button</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.defaultOutputFolderBox.setText(QCoreApplication.translate("mainWindow", u"Output Folder", None))
#if QT_CONFIG(tooltip)
self.defaultOutputFolderButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Use this to select the default output directory.</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.defaultOutputFolderButton.setText("")
#if QT_CONFIG(tooltip)
self.jobList.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Double click on source to open it in metadata editor.</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
@@ -650,15 +683,11 @@ class Ui_mainWindow(object):
#if QT_CONFIG(tooltip)
self.fileButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.fileButton.setText(QCoreApplication.translate("mainWindow", u"Add file(s)", None))
self.fileButton.setText(QCoreApplication.translate("mainWindow", u"Add input file(s)", None))
#if QT_CONFIG(tooltip)
self.defaultOutputFolderButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p>Use this to select the default output directory.</p></body></html>", None))
self.directoryButton.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Add directory containing JPG, PNG or GIF files to queue.<br/><span style=\" font-weight:600;\">CBR, CBZ and CB7 files inside will not be processed!</span></p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.defaultOutputFolderButton.setText("")
#if QT_CONFIG(tooltip)
self.defaultOutputFolderBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - next to source<br/></span>Place output files next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - folder next to source<br/></span>Place output files in a folder next to source files</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Custom<br/></span>Place output files in custom directory specified by right button</p></body></html>", None))
#endif // QT_CONFIG(tooltip)
self.defaultOutputFolderBox.setText(QCoreApplication.translate("mainWindow", u"Output Folder", None))
self.directoryButton.setText(QCoreApplication.translate("mainWindow", u"Add input folder(s)", None))
#if QT_CONFIG(tooltip)
self.formatBox.setToolTip(QCoreApplication.translate("mainWindow", u"<html><head/><body><p style='white-space:pre'>Output format.</p></body></html>", None))
#endif // QT_CONFIG(tooltip)

View File

@@ -156,6 +156,15 @@ class Ui_editorDialog(object):
self.verticalLayout.addWidget(self.optionWidget)
QWidget.setTabOrder(self.seriesLine, self.volumeLine)
QWidget.setTabOrder(self.volumeLine, self.titleLine)
QWidget.setTabOrder(self.titleLine, self.numberLine)
QWidget.setTabOrder(self.numberLine, self.writerLine)
QWidget.setTabOrder(self.writerLine, self.pencillerLine)
QWidget.setTabOrder(self.pencillerLine, self.inkerLine)
QWidget.setTabOrder(self.inkerLine, self.coloristLine)
QWidget.setTabOrder(self.coloristLine, self.okButton)
QWidget.setTabOrder(self.okButton, self.cancelButton)
self.retranslateUi(editorDialog)

View File

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

View File

@@ -851,14 +851,16 @@ def mupdf_pdf_process_pages_parallel(filename, output_dir, target_height):
def getWorkFolder(afile):
def getWorkFolder(afile, workdir=None):
if not workdir:
workdir = mkdtemp('', 'KCC-')
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
else:
fullPath = workdir
if os.path.isdir(afile):
if disk_usage(gettempdir())[2] < getDirectorySize(afile) * 2.5:
raise UserWarning("Not enough disk space to perform conversion.")
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
try:
os.rmdir(workdir)
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
copytree(afile, fullPath)
sanitizePermissions(fullPath)
return workdir
@@ -869,7 +871,8 @@ def getWorkFolder(afile):
if disk_usage(gettempdir())[2] < os.path.getsize(afile) * 2.5:
raise UserWarning("Not enough disk space to perform conversion.")
if afile.lower().endswith('.pdf'):
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
if not os.path.exists(fullPath):
os.makedirs(fullPath)
path = workdir
sanitizePermissions(path)
target_height = options.profileData[1][1]
@@ -878,39 +881,42 @@ def getWorkFolder(afile):
elif options.cropping == 2:
target_height = target_height + target_height*0.25 #Account for possible margin at the top and bottom with page number
try:
mupdf_pdf_process_pages_parallel(afile, workdir, target_height)
mupdf_pdf_process_pages_parallel(afile, fullPath, target_height)
except Exception as e:
rmtree(path, True)
raise UserWarning(f"Failed to extract images from PDF file. {e}")
return workdir
else:
workdir = mkdtemp('', 'KCC-', os.path.dirname(afile))
if not os.path.exists(fullPath):
os.makedirs(fullPath)
try:
cbx = comicarchive.ComicArchive(afile)
path = cbx.extract(workdir)
path = cbx.extract(fullPath)
sanitizePermissions(path)
tdir = os.listdir(workdir)
tdir = os.listdir(fullPath)
if len(tdir) == 2 and 'ComicInfo.xml' in tdir:
tdir.remove('ComicInfo.xml')
if os.path.isdir(os.path.join(workdir, tdir[0])):
if os.path.isdir(os.path.join(fullPath, tdir[0])):
os.replace(
os.path.join(workdir, 'ComicInfo.xml'),
os.path.join(workdir, tdir[0], 'ComicInfo.xml')
os.path.join(fullPath, 'ComicInfo.xml'),
os.path.join(fullPath, tdir[0], 'ComicInfo.xml')
)
if len(tdir) == 1 and os.path.isdir(os.path.join(workdir, tdir[0])):
path = os.path.join(workdir, tdir[0])
if len(tdir) == 1 and os.path.isdir(os.path.join(fullPath, tdir[0])):
for file in os.listdir(os.path.join(fullPath, tdir[0])):
move(os.path.join(fullPath, tdir[0], file), fullPath)
os.rmdir(os.path.join(fullPath, tdir[0]))
return workdir
except OSError as e:
rmtree(workdir, True)
raise UserWarning(e)
else:
raise UserWarning("Failed to open source file/directory.")
newpath = mkdtemp('', 'KCC-', os.path.dirname(afile))
os.renames(path, os.path.join(newpath, 'OEBPS', 'Images'))
return newpath
def getOutputFilename(srcpath, wantedname, ext, tomenumber):
source_path = Path(srcpath)
if srcpath[-1] == os.path.sep:
srcpath = srcpath[:-1]
if 'Ko' in options.profile and options.format == 'EPUB':
@@ -923,22 +929,26 @@ def getOutputFilename(srcpath, wantedname, ext, tomenumber):
wanted_root, wanted_ext = os.path.splitext(wantedname)
if wantedname.endswith(ext):
filename = os.path.abspath(wantedname)
elif wanted_ext == '.mobi' and ext == '.epub':
filename = os.path.abspath(wanted_root + ext)
# output directory
elif not wanted_ext:
else:
abs_path = os.path.abspath(options.output)
if not os.path.exists(abs_path):
os.mkdir(abs_path)
filename = os.path.join(os.path.abspath(options.output), Path(srcpath).stem + ext)
# output file
else:
filename = os.path.abspath(wanted_root) + ext
if source_path.is_file():
filename = os.path.join(os.path.abspath(options.output), source_path.stem + tomenumber + ext)
else:
filename = os.path.join(os.path.abspath(options.output), source_path.name + tomenumber + ext)
elif os.path.isdir(srcpath):
filename = srcpath + tomenumber + ext
else:
if 'Ko' in options.profile and options.format == 'EPUB':
src = pathlib.Path(srcpath)
name = re.sub(r'\W+', '_', src.stem) + tomenumber + ext
filename = src.with_name(name)
if source_path.is_file():
name = re.sub(r'\W+', '_', source_path.stem) + tomenumber + ext
else:
name = re.sub(r'\W+', '_', source_path.name) + tomenumber + ext
filename = source_path.with_name(name)
else:
filename = os.path.splitext(srcpath)[0] + tomenumber + ext
if os.path.isfile(filename):
@@ -1520,17 +1530,15 @@ def makeFusion(sources: List[str]):
print(f"Processing {source}...")
checkPre(source)
print("Checking images...")
path = getWorkFolder(source)
pathfinder = os.path.join(path, "OEBPS", "Images")
sanitizeTree(pathfinder)
# TODO: remove flattenTree when subchapters are supported
flattenTree(pathfinder)
source_path = Path(source)
if source_path.is_file():
os.renames(pathfinder, fusion_path.joinpath(source_path.stem))
targetpath = fusion_path.joinpath(source_path.stem)
else:
os.renames(pathfinder, fusion_path.joinpath(source_path.name))
targetpath = fusion_path.joinpath(source_path.name)
getWorkFolder(source, str(targetpath))
sanitizeTree(targetpath)
# TODO: remove flattenTree when subchapters are supported
flattenTree(targetpath)
end = perf_counter()
print(f"makefusion: {end - start} seconds")

View File

@@ -67,13 +67,14 @@ def mergeDirectory(work):
result = Image.new('RGB', (targetWidth, targetHeight))
y = 0
for i in imagesValid:
img = Image.open(i).convert('RGB')
if img.size[0] < targetWidth or img.size[0] > targetWidth:
widthPercent = (targetWidth / float(img.size[0]))
heightSize = int((float(img.size[1]) * float(widthPercent)))
img = ImageOps.fit(img, (targetWidth, heightSize), method=Image.BICUBIC, centering=(0.5, 0.5))
result.paste(img, (0, y))
y += img.size[1]
with Image.open(i) as img:
img = img.convert('RGB')
if img.size[0] < targetWidth or img.size[0] > targetWidth:
widthPercent = (targetWidth / float(img.size[0]))
heightSize = int((float(img.size[1]) * float(widthPercent)))
img = ImageOps.fit(img, (targetWidth, heightSize), method=Image.BICUBIC, centering=(0.5, 0.5))
result.paste(img, (0, y))
y += img.size[1]
os.remove(i)
savePath = os.path.split(imagesValid[0])
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
@@ -253,10 +254,8 @@ def main(argv=None, job_progress='', qtgui=None):
return 1
if args.height > 0:
for sourceDir in args.input:
targetDir = sourceDir + "-Splitted"
targetDir = sourceDir
if os.path.isdir(sourceDir):
rmtree(targetDir, True)
os.renames(sourceDir, targetDir)
work = []
pagenumber = 1
splitWorkerOutput = []
@@ -313,8 +312,6 @@ def main(argv=None, job_progress='', qtgui=None):
rmtree(targetDir, True)
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0],
splitWorkerOutput[0][1])
if args.inPlace:
os.renames(targetDir, sourceDir)
else:
rmtree(targetDir, True)
raise UserWarning("C2P: Source directory is empty.")

View File

@@ -485,7 +485,7 @@ class ComicPage:
if self.opt.kindle_azw3 and any(dim > 1920 for dim in self.image.size):
self.image = ImageOps.contain(self.image, (1920, 1920), Image.Resampling.LANCZOS)
elif self.image.size[0] > self.size[0] * 2 or self.image.size[1] > self.size[1]:
self.image = ImageOps.contain(self.image, (self.size[0] * 2, self.size[1], Image.Resampling.LANCZOS))
self.image = ImageOps.contain(self.image, (self.size[0] * 2, self.size[1]), Image.Resampling.LANCZOS)
return
ratio_device = float(self.size[1]) / float(self.size[0])

View File

@@ -1,4 +1,4 @@
PySide6==6.5.2
PySide6==6.4.3
Pillow>=11.3.0
psutil>=5.9.5
requests>=2.31.0

View File

@@ -2,7 +2,7 @@ PySide6<6.10
Pillow>=11.3.0
psutil>=5.9.5
requests>=2.31.0
python-slugify>=1.2.1
python-slugify>=1.2.1,<9.0.0
raven>=6.0.0
packaging>=23.2
mozjpeg-lossless-optimization>=1.2.0

View File

@@ -40,8 +40,8 @@ class BuildBinaryCommand(setuptools.Command):
if sys.platform == 'darwin':
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
min_os = os.getenv('MACOSX_DEPLOYMENT_TARGET')
if min_os:
min_os = os.getenv('MACOSX_DEPLOYMENT_TARGET', '')
if min_os.startswith('10.1'):
os.system(f'appdmg kcc.json dist/kcc_osx_{min_os.replace(".", "_")}_legacy_{VERSION}.dmg')
else:
os.system(f'appdmg kcc.json dist/kcc_macos_{platform.processor()}_{VERSION}.dmg')
@@ -148,16 +148,15 @@ setuptools.setup(
},
packages=['kindlecomicconverter'],
install_requires=[
'pyside6>=6.0.0',
'PySide6>=6.0.0',
'Pillow>=9.3.0',
'PyMuPDF>=1.18.0',
'psutil>=5.9.5',
'requests>=2.31.0',
'python-slugify>=1.2.1,<9.0.0',
'raven>=6.0.0',
'requests>=2.31.0',
'mozjpeg-lossless-optimization>=1.1.2',
'mozjpeg-lossless-optimization>=1.2.0',
'natsort>=8.4.0',
'distro',
'distro>=1.8.0',
'numpy>=1.22.4',
'PyMuPDF>=1.16.1',
],