diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | MANIFEST.in | 1 | ||||
| -rw-r--r-- | README.md | 154 | ||||
| -rw-r--r-- | docker/Dockerfile | 7 | ||||
| -rwxr-xr-x | kcc-c2e.py | 9 | ||||
| -rwxr-xr-x | kcc-c2p.py | 9 | ||||
| -rw-r--r-- | kcc.iss | 2 | ||||
| -rwxr-xr-x | kcc.py | 20 | ||||
| -rw-r--r-- | kindlecomicconverter/KCC_gui.py | 20 | ||||
| -rw-r--r-- | kindlecomicconverter/__init__.py | 2 | ||||
| -rw-r--r-- | kindlecomicconverter/cbxarchive.py | 24 | ||||
| -rwxr-xr-x | kindlecomicconverter/comic2ebook.py | 106 | ||||
| -rw-r--r-- | kindlecomicconverter/comic2panel.py | 18 | ||||
| -rwxr-xr-x | kindlecomicconverter/image.py | 14 | ||||
| -rw-r--r-- | kindlecomicconverter/shared.py | 67 | ||||
| -rw-r--r-- | kindlecomicconverter/startup.py | 53 | ||||
| -rw-r--r-- | other/osx/Info.plist | 6 | ||||
| -rw-r--r-- | requirements.txt | 5 | ||||
| -rwxr-xr-x | setup.py | 92 |
19 files changed, 279 insertions, 331 deletions
diff --git a/.gitignore b/.gitignore index 9e0e197..d4fbd53 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ setup.sh kindlecomicconverter/sentry.py build/ .python-version +KindleComicConverter.egg-info/ diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..e938f6e --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +exclude kindlecomicconverter/sentry.py \ No newline at end of file diff --git a/README.md b/README.md index d1c8ea8..a06ad77 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# KCC +# KCC + +[]() []() []() **Kindle Comic Converter** is a Python app to convert comic/manga files or folders to EPUB, Panel View MOBI or E-Ink optimized CBZ. It was initially developed for Kindle but since version 4.6 it outputs valid EPUB 3.0 so _**despite its name, KCC is @@ -17,11 +19,11 @@ If you can fix an open issue, fork & make a pull request. If you find **KCC** valuable you can consider donating to the authors: - Ciro Mattia Gonano: - - [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D8WNYNPBGDAS2) - - [](http://flattr.com/thing/2260449/ciromattiakcc-on-GitHub) + - [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=D8WNYNPBGDAS2) + - [](http://flattr.com/thing/2260449/ciromattiakcc-on-GitHub) - Paweł Jastrzębski: - - [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YTTJ4LK2JDHPS) - - Bitcoin: 1W15wwqsfd7wbaZ6wvSJf1LW1bz6q5L8b + - [](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YTTJ4LK2JDHPS) + - [](https://jastrzeb.ski/donate/) ## BINARY RELEASES You can find the latest released binary at the following links: @@ -29,20 +31,25 @@ You can find the latest released binary at the following links: - **Linux (Glibc 2.19+):** [http://kcc.iosphe.re/Linux/](http://kcc.iosphe.re/Linux/) - **OS X (10.9+):** [http://kcc.iosphe.re/OSX/](http://kcc.iosphe.re/OSX/) +## PYPI +**KCC** is also available on PyPI. +``` +pip install KindleComicConverter +``` + ## DEPENDENCIES Following software is required to run Linux version of **KCC** and/or bare sources: - Python 3.3+ -- [PyQt](https://pypi.python.org/pypi/PyQt5) 5.6.0+ -- [Pillow](https://pypi.python.org/pypi/Pillow/) 3.2.0+ -- [psutil](https://pypi.python.org/pypi/psutil) 4.1.0+ -- [python-slugify](https://pypi.python.org/pypi/python-slugify) 1.2.0+ -- [raven](https://pypi.python.org/pypi/raven) 5.13.0+ -- [scandir](https://pypi.python.org/pypi/scandir) 1.2.0+ _(needed only when using Python 3.3 or 3.4)_ +- [PyQt5](https://pypi.python.org/pypi/PyQt5) 5.6.0+ +- [Pillow](https://pypi.python.org/pypi/Pillow/) 4.0.0+ +- [psutil](https://pypi.python.org/pypi/psutil) 5.0.0+ +- [python-slugify](https://pypi.python.org/pypi/python-slugify) 1.2.1+ +- [raven](https://pypi.python.org/pypi/raven) 6.0.0+ On Debian based distributions these two commands should install all needed dependencies: ``` sudo apt-get install python3 python3-dev python3-pip libpng-dev libjpeg-dev p7zip-full unrar -sudo pip3 install --upgrade pillow python-slugify psutil scandir raven pyqt5 +sudo pip3 install --upgrade pillow python-slugify psutil pyqt5 raven ``` ### Optional dependencies @@ -163,35 +170,40 @@ The app relies and includes the following scripts: * [Kobo Aura ONE](http://kcc.iosphe.re/Samples/Ubunchu-KoAO.kepub.epub) ## CHANGELOG -####5.3: +#### 5.3.1: +* Small increase of output quality +* Improved error reporting +* Internal changes and tweaks + +#### 5.3: * Vastly improved output compatibility for non-Kindle devices * Enabled old pinch zoom for Kindle devices * Re-enabled Panel View support for Kindle Keyboard * Partially re-enabled OS X file association mechanism * Fixed multiple smaller issues -####5.2.1: +#### 5.2.1: * Improved directory parsing * Tweaked margin detection algorithm * Improved error reporting -####5.2: +#### 5.2: * Added new Panel View options * Implemented new margin detection algorithm * Removed HQ Panel View mode * Fixed multiple smaller issues -####5.1.3: +#### 5.1.3: * Added Kobo Aura ONE profile * Fixed few small bugs -####5.1.2: +#### 5.1.2: * Fixed error reporting -####5.1.1: +#### 5.1.1: * Fixed multiple GUI bugs -####5.1: +#### 5.1: * GUI now can be resized and high DPI support was somewhat improved * Added profile for Kindle Oasis * Implemented new error reporting mechanism @@ -199,55 +211,55 @@ The app relies and includes the following scripts: * Fixed permission issues on Windows * Fixed multiple smaller issues -####5.0.1: +#### 5.0.1: * Fixed Panel View placement issues * Decreased application startup time * Fixed multiple smaller issues -####5.0: +#### 5.0: * Major overhaul of internal mechanisms and GUI * Added cover upload feature * Tweaked Webtoon parsing mode * Fixed multiple smaller issues * Migrated build enviroment to PyInstaller -####4.6.5: +#### 4.6.5: * Fixed multiple Windows and OS X issues * Allowed Linux release to use older PyQT5 version -####4.6.4: +#### 4.6.4: * Fixed multiple Windows specific problems * Improved error handling * Improved color detection algorithm * New, slimmer OS X release -####4.6.3: +#### 4.6.3: * Implemented remote bug reporting * Minor bug fixes and GUI tweaks -####4.6.2: +#### 4.6.2: * Fixed critical MOBI header bug * Fixed metadata encoding error -####4.6.1: +#### 4.6.1: * Fixed KEPUB TOC generator * Added warning about too small input files * ComicRack Summary metadata field is now parsed * Small tweaks of KEPUB output -####4.6: +#### 4.6: * KEPUB is now default output for all Kobo profiles * EPUB output now produce fully valid EPUB 3.0.1 * Added profile for Kindle Paperwhite 3 * Dropped official support of all Kindle Fire models and Kindle for Android * Other minor tweaks -####4.5.1: +#### 4.5.1: * Added Kobo Glo HD profile * Fixed RAR/CBR parsing anomalies * Minor bug fixes and tweaks -####4.5: +#### 4.5: * Added simple ComicRack metadata editor * Re-enabled Manga Cover Database support * ComicRack bookmarks are now parsed @@ -256,61 +268,61 @@ The app relies and includes the following scripts: * Fixed sorting anomalies * Improved conversion speed -####4.4.1: +#### 4.4.1: * Fixed problems with OSX GUI * Added one missing DLL to Windows installer -####4.4: +#### 4.4: * Improved speed and quality of conversion * Added RAR5 support * Dropped BMP and TIFF support * Fixed some WebToon mode bugs * Fixed CBR parsing on OSX -####4.3.1: +#### 4.3.1: * Fixed Kindle Voyage profile * Fixed some bugs in OS X release * CLI version now support multiple input files at once * Disabled MCB support * Other minor tweaks -####4.3: +#### 4.3: * Added profiles for Kindle Voyage and Kobo Aura H2O * Added missing features to CLI version * Other minor bug fixes -####4.2.1: +#### 4.2.1: * Improved margin color detection * Fixed random crashes of MOBI processing step * Fixed resizing problems in high quality mode * Fixed some MCD support bugs * Default output format for Kindle DX is now CBZ -####4.2: +#### 4.2: * Added [Manga Cover Database](http://manga.joentjuh.nl/) support * Officially dropped Windows XP support * Fixed _Other_ profile * Fixed problems with page order on stock KOBO CBZ reader * Many other small bug fixes and tweaks -####4.1: +#### 4.1: * Thanks to code contributed by Kevin Hendricks speed of MOBI creation was greatly increased * Improved performance on Windows * Improved MOBI splitting and changed maximal size of output file * Fixed _No optimization_ mode * Multiple small tweaks nad minor bug fixes -####4.0.2: +#### 4.0.2: * Fixed some Windows and OSX specific bugs * Fixed problem with marigns when using HQ mode -####4.0.1: +#### 4.0.1: * Fixed file lock problems that plagued some Windows users * Fixed content server failing to start on Windows * Improved performance of WebToon splitter * Tweaked margin color detection -####4.0: +#### 4.0: * KCC now use Python 3.3 and Qt 5.2 * Full UTF-8 awareness * CBZ output now support Manga mode @@ -322,13 +334,13 @@ The app relies and includes the following scripts: * Fixed OSX file association support * Many extensive internal changes and tweaks -####3.7.2: +#### 3.7.2: * Fixed problems with HQ mode -####3.7.1: +#### 3.7.1: * Hotfixed Kobo profiles -####3.7: +#### 3.7: * Added profiles for KOBO devices * Improved Panel View support * Improved WebToon splitter @@ -337,14 +349,14 @@ The app relies and includes the following scripts: * Fixed stretching option * GUI tweaks and minor bugfixes -####3.6.2: +#### 3.6.2: * Fixed previous PNG output fix * Fixed Panel View anomalies -####3.6.1: +#### 3.6.1: * Fixed PNG output -####3.6: +#### 3.6: * Increased quality of Panel View zoom * Creation of multipart MOBI output is now faster on machines with 4GB+ RAM * Automatic gamma correction now distinguishes color and grayscale images @@ -355,13 +367,13 @@ The app relies and includes the following scripts: * Fixed Kindle Fire HDX 7" output * Increased target resolution for Kindle DX/DXG CBZ output -####3.5: +#### 3.5: * Added simple content server - Converted files can be now delivered wireless * Added proper Windows installer * Improved multiprocessing speed * GUI tweaks and minor bug fixes -####3.4: +#### 3.4: * Improved PNG output * Increased quality of upscaling * Added support of file association - KCC can now open CBZ, CBR, CB7, ZIP, RAR, 7Z and PDF files directly @@ -370,7 +382,7 @@ The app relies and includes the following scripts: * Merged DX and DXG profiles * Many other minor bug fixes and GUI tweaks -####3.3: +#### 3.3: * Margins are now automatically omitted in Panel View mode * Margin color fill is now autodetected * Created MOBI files are not longer marked as _Personal_ on newer Kindle models @@ -384,27 +396,27 @@ The app relies and includes the following scripts: * Windows release is now bundled with UnRAR and 7za * Small GUI tweaks -####3.2: +#### 3.2: * Too big EPUB files are now splitted before conversion to MOBI * Added experimental parser of manga webtoons * Improved error handling -####3.2.1: +#### 3.2.1: * Hotfixed crash occurring on OS with Russian locale -####3.1: +#### 3.1: * Added profile: Kindle for Android * Add file/directory dialogs now support multiselect * Many small fixes and tweaks -####3.0: +#### 3.0: * New QT GUI * Merge with AWKCC * Added ultra quality mode * Added support for custom width/height * Added option to disable color conversion -####2.10: +#### 2.10: * Multiprocessing support * Kindle Fire support (color EPUB/MOBI) * Panel View support for horizontal content @@ -412,14 +424,14 @@ The app relies and includes the following scripts: * Disabled cropping and page number cutting for blank pages * Fixed some slugify issues with specific file naming conventions (#50, #51) -####2.9 +#### 2.9 * Added support for generating a plain CBZ (skipping all the EPUB/MOBI generation) (#45) * Prevent output file overwriting the source one: if a duplicate name is detected, append _kcc to the name * Rarfile library updated to 2.6 * Added GIF, TIFF and BMP to supported formats (#42) * Filenames slugifications (#28, #31, #9, #8) -####2.8 +#### 2.8 * Updated rarfile library * Panel View support + HQ support (#36) - new option: --nopanelviewhq * Split profiles for K4NT and K4T @@ -428,7 +440,7 @@ The app relies and includes the following scripts: * Added generic CSS file * Optimized archive extraction for zip/rar files (#40) -####2.7 +#### 2.7 * Lots of GUI improvements (#27, #13) * Added gamma support within --gamma option (defaults to profile-specified gamma) (#26, #27) * Added --nodithering option to prevent dithering optimizations (#27) @@ -439,57 +451,57 @@ The app relies and includes the following scripts: * Get filetype from magic number (#14) * PDF conversion works again -####2.6 +#### 2.6 * Added --rotate option to rotate landscape images instead of splitting them (#16, #24) * Added --output option to customize EPUB output dir/file (#22) * Add rendition:layout and rendition:orientation EPUB meta tags (supported by new kindlegen 2.8) * Fixed natural sorting for files (#18) -####2.5 +#### 2.5 * Added --black-borders option to set added borders black when page's ratio is not the device's one (#11). * Fixes EPUB containing zipped itself (#10) -####2.4 +#### 2.4 * Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming) * Fixed "add folders" from GUI. -####2.3 +#### 2.3 * Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders -####2.2: +#### 2.2: * Added (valid!) EPUB 2.0 output * Rename .zip files to .cbz to avoid overwriting -####2.1 +#### 2.1 * Added basic error reporting -####2.0 +#### 2.0 * GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support. -####1.5 +#### 1.5 * Added subfolder support for multiple chapters. -####1.4.1 +#### 1.4.1 * Fixed a serious bug on resizing when img ratio was bigger than device one -####1.4 +#### 1.4 * Added some options for controlling image optimization * Further optimization (ImageOps, page numbering cut, autocontrast) -####1.3 +#### 1.3 * Fixed an issue in OPF generation for device resolution * Reworked options system (call with -h option to get the inline help) -####1.2 +#### 1.2 * Comic optimizations! Split pages not target-oriented (landscape with portrait target or portrait with landscape target), add palette and other image optimizations from Mangle. WARNING: PIL is required for all image mangling! -####1.1.1 +#### 1.1.1 * Added support for CBZ/CBR files in Kindle Comic Converter -####1.1 +#### 1.1 * Added support for CBZ/CBR files in comic2ebook.py -####1.0 +#### 1.0 * Initial version ## PRIVACY diff --git a/docker/Dockerfile b/docker/Dockerfile index 784bfac..89dd7e3 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,14 +1,11 @@ # acidweb/kcc -FROM debian:jessie +FROM debian:stretch MAINTAINER Paweł Jastrzębski <[email protected]> ADD ./Build /Build -RUN printf "deb http://httpredir.debian.org/debian stretch main" > /etc/apt/sources.list.d/stretch.list -RUN printf "Package: *\nPin: release a=testing\nPin-Priority: 400\n" > /etc/apt/preferences.d/stretch.pref RUN apt-get update && apt-get -y dist-upgrade -RUN apt-get -y install build-essential curl ruby ruby-dev libpng-dev libjpeg-dev -RUN apt-get -y -t testing install python3 python3-dev python3-pyqt5 +RUN apt-get -y install build-essential curl ruby ruby-dev libpng-dev libjpeg-dev python3 python3-dev python3-pyqt5 RUN curl https://bootstrap.pypa.io/get-pip.py | python3 RUN apt-get clean -y && apt-get autoclean -y && apt-get autoremove -y && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/kcc-c2e.py b/kcc-c2e.py index cb83188..c17deec 100755 --- a/kcc-c2e.py +++ b/kcc-c2e.py @@ -23,14 +23,9 @@ if sys.version_info[0] != 3: print('ERROR: This is Python 3 script!') exit(1) -from kindlecomicconverter.shared import dependencyCheck -dependencyCheck(2) - from multiprocessing import freeze_support -from kindlecomicconverter import __version__ -from kindlecomicconverter.comic2ebook import main +from kindlecomicconverter.startup import startC2E if __name__ == "__main__": freeze_support() - print('comic2ebook v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.') - sys.exit(main(sys.argv[1:])) + startC2E() diff --git a/kcc-c2p.py b/kcc-c2p.py index bc6aa6b..f1fb915 100755 --- a/kcc-c2p.py +++ b/kcc-c2p.py @@ -23,14 +23,9 @@ if sys.version_info[0] != 3: print('ERROR: This is Python 3 script!') exit(1) -from kindlecomicconverter.shared import dependencyCheck -dependencyCheck(1) - from multiprocessing import freeze_support -from kindlecomicconverter import __version__ -from kindlecomicconverter.comic2panel import main +from kindlecomicconverter.startup import startC2P if __name__ == "__main__": freeze_support() - print('comic2panel v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.') - sys.exit(main(sys.argv[1:])) + startC2P() \ No newline at end of file diff --git a/kcc.iss b/kcc.iss index 7cd7685..7dea76f 100644 --- a/kcc.iss +++ b/kcc.iss @@ -1,5 +1,5 @@ #define MyAppName "Kindle Comic Converter" -#define MyAppVersion "5.3.0" +#define MyAppVersion "5.3.1" #define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski" #define MyAppURL "http://kcc.iosphe.re/" #define MyAppExeName "KCC.exe" diff --git a/kcc.py b/kcc.py index a93e48f..445b0a3 100755 --- a/kcc.py +++ b/kcc.py @@ -63,24 +63,10 @@ if getattr(sys, 'frozen', False): except: pass -from kindlecomicconverter.shared import dependencyCheck -dependencyCheck(3) - from multiprocessing import freeze_support -from kindlecomicconverter import KCC_gui +from kindlecomicconverter.startup import start if __name__ == "__main__": freeze_support() - os.environ['QT_AUTO_SCREEN_SCALE_FACTOR'] = "1" - KCCAplication = KCC_gui.QApplicationMessaging(sys.argv) - if KCCAplication.isRunning(): - if len(sys.argv) > 1: - KCCAplication.sendMessage(sys.argv[1]) - else: - KCCAplication.sendMessage('ARISE') - else: - KCCWindow = KCC_gui.QMainWindowKCC() - KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow) - if len(sys.argv) > 1: - KCCUI.handleMessage(sys.argv[1]) - sys.exit(KCCAplication.exec_()) + start() + diff --git a/kindlecomicconverter/KCC_gui.py b/kindlecomicconverter/KCC_gui.py index 63f004c..5cf29d7 100644 --- a/kindlecomicconverter/KCC_gui.py +++ b/kindlecomicconverter/KCC_gui.py @@ -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] != '': diff --git a/kindlecomicconverter/__init__.py b/kindlecomicconverter/__init__.py index c966b7c..3622f15 100644 --- a/kindlecomicconverter/__init__.py +++ b/kindlecomicconverter/__init__.py @@ -1,4 +1,4 @@ -__version__ = '5.3.0' +__version__ = '5.3.1' __license__ = 'ISC' __copyright__ = '2012-2017, Ciro Mattia Gonano <[email protected]>, Pawel Jastrzebski <[email protected]>' __docformat__ = 'restructuredtext en' diff --git a/kindlecomicconverter/cbxarchive.py b/kindlecomicconverter/cbxarchive.py index 726432b..7bd833f 100644 --- a/kindlecomicconverter/cbxarchive.py +++ b/kindlecomicconverter/cbxarchive.py @@ -22,12 +22,8 @@ from zipfile import is_zipfile, ZipFile from subprocess import STDOUT, PIPE from psutil import Popen from shutil import move, copy -try: - from scandir import walk -except ImportError: - walk = os.walk from . import rarfile -from .shared import check7ZFile as is_7zfile, saferReplace, saferRemove +from .shared import check7ZFile as is_7zfile class CBxArchive: @@ -50,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) @@ -63,24 +59,18 @@ class CBxArchive: def extractCBR(self, targetdir): cbrFile = rarfile.RarFile(self.origFileName) cbrFile.extractall(targetdir) - for root, dirnames, filenames in 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 @@ -96,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 diff --git a/kindlecomicconverter/comic2ebook.py b/kindlecomicconverter/comic2ebook.py index 404ca11..f5c6320 100755 --- a/kindlecomicconverter/comic2ebook.py +++ b/kindlecomicconverter/comic2ebook.py @@ -36,17 +36,13 @@ from uuid import uuid4 from slugify import slugify as slugifyExt from PIL import Image from subprocess import STDOUT, PIPE -from psutil import Popen, virtual_memory +from psutil import Popen, virtual_memory, disk_usage from html import escape try: from PyQt5 import QtCore except ImportError: QtCore = None -try: - from scandir import walk -except ImportError: - walk = os.walk -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 @@ -85,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;' @@ -424,7 +420,7 @@ def buildEPUB(path, chapterNames, tomeNumber): "display: none;\n", "}\n"]) f.close() - for (dirpath, dirnames, filenames) in 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: @@ -461,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 walk(path): + for dirpath, _, filenames in os.walk(path): for afile in filenames: pagenumber += 1 work.append([afile, dirpath, options]) @@ -482,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.") @@ -497,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: @@ -513,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: @@ -530,6 +526,8 @@ def imgFileProcessing(work): def getWorkFolder(afile): 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-') try: os.rmdir(workdir) @@ -540,24 +538,27 @@ def getWorkFolder(afile): except: rmtree(workdir, True) raise UserWarning("Failed to prepare a workspace.") - elif os.path.isfile(afile) and afile.lower().endswith('.pdf'): - pdf = pdfjpgextract.PdfJpgExtract(afile) - path, njpg = pdf.extract() - if njpg == 0: - rmtree(path, True) - raise UserWarning("Failed to extract images from PDF file.") elif os.path.isfile(afile): - workdir = mkdtemp('', 'KCC-') - cbx = cbxarchive.CBxArchive(afile) - if cbx.isCbxFile(): - try: - path = cbx.extract(workdir) - except: - rmtree(workdir, True) - raise UserWarning("Failed to extract archive.") + 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'): + pdf = pdfjpgextract.PdfJpgExtract(afile) + path, njpg = pdf.extract() + if njpg == 0: + rmtree(path, True) + raise UserWarning("Failed to extract images from PDF file.") else: - rmtree(workdir, True) - raise UserWarning("Failed to detect archive format.") + workdir = mkdtemp('', 'KCC-') + cbx = cbxarchive.CBxArchive(afile) + if cbx.isCbxFile(): + try: + path = cbx.extract(workdir) + except: + rmtree(workdir, True) + raise UserWarning("Failed to extract archive.") + else: + rmtree(workdir, True) + raise UserWarning("Failed to detect archive format.") else: raise UserWarning("Failed to open source file/directory.") sanitizePermissions(path) @@ -619,7 +620,7 @@ def getComicInfo(path, originalPath): try: xml = metadata.MetadataParser(xmlPath) except Exception: - saferRemove(xmlPath) + os.remove(xmlPath) return options.authors = [] if defaultTitle: @@ -644,7 +645,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): @@ -663,7 +664,7 @@ def getCoversFromMCB(mangaID): def getDirectorySize(start_path='.'): total_size = 0 - for dirpath, dirnames, filenames in 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) @@ -688,7 +689,7 @@ def getPanelViewSize(deviceres, size): def sanitizeTree(filetree): chapterNames = {} - for root, dirs, files in walk(filetree, False): + for root, dirs, files in os.walk(filetree, False): for name in files: splitname = os.path.splitext(name) slugified = slugify(splitname[0]) @@ -698,7 +699,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) @@ -708,13 +709,13 @@ 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 def sanitizeTreeKobo(filetree): pageNumber = 0 - for root, dirs, files in walk(filetree): + for root, dirs, files in os.walk(filetree): dirs, files = walkSort(dirs, files) for name in files: splitname = os.path.splitext(name) @@ -726,11 +727,11 @@ 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): - for root, dirs, files in walk(filetree, False): + for root, dirs, files in os.walk(filetree, False): for name in files: os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD) for name in dirs: @@ -785,7 +786,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() @@ -799,9 +800,12 @@ def splitProcess(path, mode): def detectCorruption(tmpPath, orgPath): imageNumber = 0 imageSmaller = 0 - for root, dirs, files in walk(tmpPath, False): + alreadyProcessed = False + for root, _, files in os.walk(tmpPath, False): for name in files: if getImageFileName(name) is not None: + if not alreadyProcessed and getImageFileName(name)[0].endswith('-kcc'): + alreadyProcessed = True path = os.path.join(root, name) pathOrg = orgPath + path.split('OEBPS' + os.path.sep + 'Images')[1] if os.path.getsize(path) == 0: @@ -822,7 +826,13 @@ 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 alreadyProcessed: + print("WARNING: Source files are probably created by KCC. Second conversion will decrease quality.") + if GUI: + GUI.addMessage.emit('Source files are probably created by KCC. Second conversion will decrease quality.', + 'warning', False) + GUI.addMessage.emit('', '', False) 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.") @@ -850,7 +860,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 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)) @@ -1107,14 +1117,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: diff --git a/kindlecomicconverter/comic2panel.py b/kindlecomicconverter/comic2panel.py index 522587c..e173575 100644 --- a/kindlecomicconverter/comic2panel.py +++ b/kindlecomicconverter/comic2panel.py @@ -24,15 +24,11 @@ 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: QtCore = None -try: - from scandir import walk -except ImportError: - walk = os.walk def mergeDirectoryTick(output): @@ -52,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)) @@ -77,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: @@ -203,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]) @@ -250,7 +246,7 @@ def main(argv=None, qtGUI=None): mergeWorkerOutput = [] mergeWorkerPool = Pool() mergeWork.append([options.targetDir]) - for root, dirs, files in walk(options.targetDir, False): + for root, dirs, files in os.walk(options.targetDir, False): dirs, files = walkSort(dirs, files) for directory in dirs: directoryNumer += 1 @@ -269,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 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)) diff --git a/kindlecomicconverter/image.py b/kindlecomicconverter/image.py index ecc08b9..5035a9e 100755 --- a/kindlecomicconverter/image.py +++ b/kindlecomicconverter/image.py @@ -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.') diff --git a/kindlecomicconverter/shared.py b/kindlecomicconverter/shared.py index 3843f39..00ae3b9 100644 --- a/kindlecomicconverter/shared.py +++ b/kindlecomicconverter/shared.py @@ -27,10 +27,6 @@ from tempfile import mkdtemp from zipfile import ZipFile, ZIP_DEFLATED from re import split from traceback import format_tb -try: - from scandir import walk -except ImportError: - walk = os.walk class HTMLStripper(HTMLParser): @@ -71,7 +67,7 @@ def walkLevel(some_dir, level=1): some_dir = some_dir.rstrip(os.path.sep) assert os.path.isdir(some_dir) num_sep = some_dir.count(os.path.sep) - for root, dirs, files in walk(some_dir): + for root, dirs, files in os.walk(some_dir): dirs, files = walkSort(dirs, files) yield root, dirs, files num_sep_this = root.count(os.path.sep) @@ -96,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: @@ -129,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 + copy(tempname, zipfname) finally: rmtree(tempdir, True) @@ -164,33 +128,26 @@ def dependencyCheck(level): try: import raven except ImportError: - missing.append('raven 5.13.0+') + missing.append('raven 6.0.0+') if level > 1: try: from psutil import __version__ as psutilVersion - if StrictVersion('4.1.0') > StrictVersion(psutilVersion): - missing.append('psutil 4.1.0+') + if StrictVersion('5.0.0') > StrictVersion(psutilVersion): + missing.append('psutil 5.0.0+') except ImportError: - missing.append('psutil 4.1.0+') + missing.append('psutil 5.0.0+') try: from slugify import __version__ as slugifyVersion - if StrictVersion('1.2.0') > StrictVersion(slugifyVersion): - missing.append('python-slugify 1.2.0+') + if StrictVersion('1.2.1') > StrictVersion(slugifyVersion): + missing.append('python-slugify 1.2.1+') except ImportError: - missing.append('python-slugify 1.2.0+') + missing.append('python-slugify 1.2.1+') try: from PIL import PILLOW_VERSION as pillowVersion - if StrictVersion('3.2.0') > StrictVersion(pillowVersion): - missing.append('Pillow 3.2.0+') + if StrictVersion('4.0.0') > StrictVersion(pillowVersion): + missing.append('Pillow 4.0.0+') except ImportError: - missing.append('Pillow 3.2.0+') - if version_info[1] < 5: - try: - from scandir import __version__ as scandirVersion - if StrictVersion('1.2') > StrictVersion(scandirVersion): - missing.append('scandir 1.2+') - except ImportError: - missing.append('scandir 1.2+') + missing.append('Pillow 4.0.0+') if len(missing) > 0: print('ERROR: ' + ', '.join(missing) + ' is not installed!') exit(1) diff --git a/kindlecomicconverter/startup.py b/kindlecomicconverter/startup.py new file mode 100644 index 0000000..4c47a17 --- /dev/null +++ b/kindlecomicconverter/startup.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# +# Copyright (c) 2012-2014 Ciro Mattia Gonano <[email protected]> +# Copyright (c) 2013-2017 Pawel Jastrzebski <[email protected]> +# +# Permission to use, copy, modify, and/or distribute this software for +# any purpose with or without fee is hereby granted, provided that the +# above copyright notice and this permission notice appear in all +# copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA +# OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# + +import os +import sys +from . import __version__ +from .shared import dependencyCheck + +def start(): + dependencyCheck(3) + from . import KCC_gui + os.environ['QT_AUTO_SCREEN_SCALE_FACTOR'] = "1" + KCCAplication = KCC_gui.QApplicationMessaging(sys.argv) + if KCCAplication.isRunning(): + if len(sys.argv) > 1: + KCCAplication.sendMessage(sys.argv[1]) + else: + KCCAplication.sendMessage('ARISE') + else: + KCCWindow = KCC_gui.QMainWindowKCC() + KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow) + if len(sys.argv) > 1: + KCCUI.handleMessage(sys.argv[1]) + sys.exit(KCCAplication.exec_()) + +def startC2E(): + dependencyCheck(2) + from .comic2ebook import main + print('comic2ebook v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.') + sys.exit(main(sys.argv[1:])) + +def startC2P(): + dependencyCheck(1) + from .comic2panel import main + print('comic2panel v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.') + sys.exit(main(sys.argv[1:])) \ No newline at end of file diff --git a/other/osx/Info.plist b/other/osx/Info.plist index 7600993..dce11bb 100644 --- a/other/osx/Info.plist +++ b/other/osx/Info.plist @@ -30,7 +30,7 @@ <key>CFBundleExecutable</key> <string>MacOS/Kindle Comic Converter</string> <key>CFBundleGetInfoString</key> - <string>KindleComicConverter 5.3.0, written 2012-2017 by Ciro Mattia Gonano and Pawel Jastrzebski</string> + <string>KindleComicConverter 5.3.1, written 2012-2017 by Ciro Mattia Gonano and Pawel Jastrzebski</string> <key>CFBundleIconFile</key> <string>comic2ebook.icns</string> <key>CFBundleIdentifier</key> @@ -42,11 +42,11 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>5.3.0</string> + <string>5.3.1</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> - <string>5.3.0</string> + <string>5.3.1</string> <key>LSEnvironment</key> <dict> <key>PATH</key> diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0478a95 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +PyQt5>=5.6.0 +Pillow>=4.0.0 +psutil>=5.0.0 +python-slugify>=1.2.1 +raven>=6.0.0 \ No newline at end of file diff --git a/setup.py b/setup.py index d355265..7e330fe 100755 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ Usage (Windows): py -3 setup.py build_binary Usage (Linux/OS X): - python3 setup.py build_binary or python3 setup.py build_binary --pyz + python3 setup.py build_binary """ import os @@ -20,8 +20,6 @@ from kindlecomicconverter import __version__ NAME = 'KindleComicConverter' MAIN = 'kcc.py' VERSION = __version__ -OPTIONS = {} - class BuildBinaryCommand(distutils.cmd.Command): description = 'build binary release' @@ -62,74 +60,12 @@ class BuildBinaryCommand(distutils.cmd.Command): os.system('setup.bat') exit(0) else: - if self.pyz: - script = ''' - cp kcc.py __main__.py - zip kcc.zip __main__.py kindlecomicconverter/*.py - echo "#!/usr/bin/env python3" > kcc-bin - cat kcc.zip >> kcc-bin - chmod +x kcc-bin - - cp kcc-c2e.py __main__.py - zip kcc-c2e.zip __main__.py kindlecomicconverter/*.py - echo "#!/usr/bin/env python3" > kcc-c2e-bin - cat kcc-c2e.zip >> kcc-c2e-bin - chmod +x kcc-c2e-bin - - cp kcc-c2p.py __main__.py - zip kcc-c2p.zip __main__.py kindlecomicconverter/*.py - echo "#!/usr/bin/env python3" > kcc-c2p-bin - cat kcc-c2p.zip >> kcc-c2p-bin - chmod +x kcc-c2p-bin - - mkdir dist - tar --xform s:^.*/:: \ - --xform s/LICENSE.txt/LICENSE/ \ - --xform s/kcc-bin/kcc/ \ - --xform s/kcc-c2p-bin/kcc-c2p/ \ - --xform s/kcc-c2e-bin/kcc-c2e/ \ - --xform s/comic2ebook/kcc/ \ - -czf dist/KindleComicConverter_linux_''' + VERSION + '''.tar.gz \ - kcc-bin kcc-c2e-bin kcc-c2p-bin LICENSE.txt README.md icons/comic2ebook.png - rm __main__.py kcc.zip kcc-c2e.zip kcc-c2p.zip kcc-bin kcc-c2e-bin kcc-c2p-bin - ''' - os.system("bash -c '%s'" % script) - exit(0) - else: - os.system('docker run --rm -v ' + os.getcwd() + ':/app -e KCCVER=' + VERSION + ' acidweb/kcc') - exit(0) - - -class BuildCommand(build): - def run(self): - os.makedirs('build/_scripts/', exist_ok=True) - shutil.copyfile('kcc.py', 'build/_scripts/kcc') - shutil.copyfile('kcc-c2e.py', 'build/_scripts/kcc-c2e') - shutil.copyfile('kcc-c2p.py', 'build/_scripts/kcc-c2p') - # noinspection PyShadowingNames - OPTIONS = dict( - scripts=['build/_scripts/kcc', - 'build/_scripts/kcc-c2e', - 'build/_scripts/kcc-c2p'], - packages=['kcc'], - install_requires=[ - 'PyQt5>=5.6.0' - 'Pillow>=3.2.0', - 'psutil>=4.1.0', - 'python-slugify>=1.2.0', - 'raven>=5.13.0', - ], - zip_safe=False, - ) - if sys.version_info[1] < 5: - OPTIONS['install_requires'].append('scandir>=1.2.0') - build.run(self) - + os.system('docker run --rm -v ' + os.getcwd() + ':/app -e KCCVER=' + VERSION + ' acidweb/kcc') + exit(0) setuptools.setup( cmdclass={ 'build_binary': BuildBinaryCommand, - 'build': BuildCommand, }, name=NAME, version=VERSION, @@ -137,7 +73,25 @@ setuptools.setup( author_email='[email protected], [email protected]', description='Comic and Manga converter for e-book readers.', license='ISC License (ISCL)', - keywords='kindle comic mobipocket mobi cbz cbr manga', + keywords=['kindle', 'kobo', 'comic', 'manga', 'mobi', 'epub', 'cbz'], url='http://github.com/ciromattia/kcc', - **OPTIONS + entry_points={ + 'console_scripts': [ + 'kcc-c2e = kindlecomicconverter.startup:startC2E', + 'kcc-c2p = kindlecomicconverter.startup:startC2P', + ], + 'gui_scripts': [ + 'kcc = kindlecomicconverter.startup:start', + ], + }, + packages=['kindlecomicconverter'], + install_requires=[ + 'PyQt5>=5.6.0', + 'Pillow>=4.0.0', + 'psutil>=5.0.0', + 'python-slugify>=1.2.1', + 'raven>=6.0.0', + ], + classifiers = [], + zip_safe=False, ) |