mirror of
https://github.com/ciromattia/kcc
synced 2026-04-15 13:38:46 +00:00
Compare commits
149 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35bba68a72 | ||
|
|
0b056a8fa8 | ||
|
|
a6f9e84251 | ||
|
|
259800e48b | ||
|
|
28e170f1d2 | ||
|
|
7120c76025 | ||
|
|
4891913b5c | ||
|
|
cd83b2899c | ||
|
|
535c2c220b | ||
|
|
409f077c3e | ||
|
|
3ecb2ba877 | ||
|
|
c07a9657ef | ||
|
|
7f719a22ad | ||
|
|
332d3d455e | ||
|
|
2070a977ae | ||
|
|
8f8d0d68a3 | ||
|
|
5a8deb4623 | ||
|
|
a7ea795df5 | ||
|
|
a2ffd259b8 | ||
|
|
93e6b51466 | ||
|
|
7904662f25 | ||
|
|
6792c2d366 | ||
|
|
ef4a91e44d | ||
|
|
a2a405e5f5 | ||
|
|
a63a46a741 | ||
|
|
2591b53a09 | ||
|
|
1c615ffc20 | ||
|
|
6eb05b3a8f | ||
|
|
968b083fb2 | ||
|
|
205907ef1e | ||
|
|
33ef8275c3 | ||
|
|
eec2099515 | ||
|
|
9027265b7c | ||
|
|
34e2af3389 | ||
|
|
5ecddaceab | ||
|
|
fe554c20aa | ||
|
|
6acf1a1802 | ||
|
|
ac81a6be4b | ||
|
|
829a5f25e7 | ||
|
|
a695a4c151 | ||
|
|
7c0b78350d | ||
|
|
aa978ab246 | ||
|
|
7524c50657 | ||
|
|
9d8663a925 | ||
|
|
08ed304f8e | ||
|
|
658d2f3281 | ||
|
|
f44bf5993e | ||
|
|
458c28281f | ||
|
|
968a1afa1d | ||
|
|
2c875673bd | ||
|
|
1a0be83d63 | ||
|
|
36a7dc49ec | ||
|
|
40d1ae63da | ||
|
|
3d3621c6ec | ||
|
|
d77f04a84e | ||
|
|
ec51d6fc51 | ||
|
|
b7861d9d9e | ||
|
|
0b4503af21 | ||
|
|
437ffb9b10 | ||
|
|
066d1401bd | ||
|
|
9babe68d2a | ||
|
|
67de77538c | ||
|
|
c3e950f2ec | ||
|
|
ac2934aba2 | ||
|
|
a5064a0c0a | ||
|
|
2d712e796d | ||
|
|
cc3da40fd7 | ||
|
|
a53c272bd0 | ||
|
|
6526b139fd | ||
|
|
283d6101cd | ||
|
|
02dab3c6ee | ||
|
|
1895aa127d | ||
|
|
c01ff83fce | ||
|
|
4b670f3754 | ||
|
|
23b1560fa2 | ||
|
|
62350608dc | ||
|
|
8048b91fa8 | ||
|
|
2e9b3389e4 | ||
|
|
40e1ab4cf3 | ||
|
|
d2c12c89e6 | ||
|
|
4647fd1f1d | ||
|
|
010ad3c88c | ||
|
|
4b0a94a8a0 | ||
|
|
807a2d1dff | ||
|
|
e1470cca15 | ||
|
|
02b9081e37 | ||
|
|
495db88a9e | ||
|
|
2bea546a9d | ||
|
|
ee042ef98d | ||
|
|
aea7c0fafb | ||
|
|
45c1afcad4 | ||
|
|
b8e314f6ca | ||
|
|
d76eea9f43 | ||
|
|
2e55f22355 | ||
|
|
30b8770e34 | ||
|
|
9ad161489f | ||
|
|
bdb459cfab | ||
|
|
2e85556543 | ||
|
|
93ebbbd0af | ||
|
|
dd5c907bad | ||
|
|
64fb4a9eca | ||
|
|
284c577894 | ||
|
|
c68c9892e4 | ||
|
|
aa00ea3aa2 | ||
|
|
88f005824c | ||
|
|
2a2bfae112 | ||
|
|
583eec787f | ||
|
|
9ce691aecb | ||
|
|
d1a07d7ffa | ||
|
|
b545f7ad48 | ||
|
|
9e01797d28 | ||
|
|
c68c5f25bf | ||
|
|
a04bf5262f | ||
|
|
b09b2527d9 | ||
|
|
94b372f47d | ||
|
|
b978adcc7c | ||
|
|
9dee4432ad | ||
|
|
15055c6c0c | ||
|
|
3f948a10b0 | ||
|
|
1c942d81db | ||
|
|
b36a5a0a93 | ||
|
|
2ca07430a0 | ||
|
|
3132aa8a21 | ||
|
|
e4dccfe603 | ||
|
|
4c56141b80 | ||
|
|
73c2e4b136 | ||
|
|
c28e9a6ef0 | ||
|
|
558bf07f7f | ||
|
|
eaa458a9c7 | ||
|
|
91b6869638 | ||
|
|
25331f5d81 | ||
|
|
9b25182393 | ||
|
|
189c03529a | ||
|
|
c9cf635229 | ||
|
|
f78dc3cd8f | ||
|
|
4079314b61 | ||
|
|
04cf732d50 | ||
|
|
9015614b1a | ||
|
|
e817c8b258 | ||
|
|
cb9059c231 | ||
|
|
75d8be0951 | ||
|
|
161abdab18 | ||
|
|
4b1c7b3124 | ||
|
|
5481c0cfe5 | ||
|
|
9543b573e3 | ||
|
|
df0bafe4b6 | ||
|
|
b2e58127cb | ||
|
|
21174338ff | ||
|
|
241801f9cb |
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,15 +1,15 @@
|
||||
*.pyc
|
||||
*.cbz
|
||||
*.cbr
|
||||
*.spec
|
||||
.idea
|
||||
.DS_Store
|
||||
.python-version
|
||||
Thumbs.db
|
||||
build
|
||||
dist
|
||||
Output
|
||||
test
|
||||
solaio
|
||||
kindlegen*
|
||||
*.spec
|
||||
setup.bat
|
||||
setup.sh
|
||||
kindlecomicconverter/sentry.py
|
||||
build/
|
||||
KindleComicConverter.egg-info/
|
||||
|
||||
37
.travis.yml
Normal file
37
.travis.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
matrix:
|
||||
include:
|
||||
- os: osx
|
||||
language: generic
|
||||
osx_image: xcode9.2
|
||||
|
||||
before_install:
|
||||
- brew update
|
||||
- brew upgrade python3
|
||||
- brew uninstall node
|
||||
- travis_wait 30 brew install node@6
|
||||
- brew link node@6 --force --overwrite
|
||||
- pip3 install --upgrade pip setuptools wheel
|
||||
- openssl aes-256-cbc -K $encrypted_a95564d8ff0d_key -iv $encrypted_a95564d8ff0d_iv -in other/osx/sentry.py.enc -out kindlecomicconverter/sentry.py -d
|
||||
|
||||
install:
|
||||
- pip3 install -r requirements.txt
|
||||
- pip3 install certifi https://github.com/pyinstaller/pyinstaller/archive/develop.zip
|
||||
- npm install -g appdmg
|
||||
|
||||
script: python3 setup.py build_binary
|
||||
|
||||
before_deploy:
|
||||
- shopt -s extglob
|
||||
- rm -r dist/!(*.deb|*.dmg)
|
||||
|
||||
deploy:
|
||||
provider: s3
|
||||
skip_cleanup: true
|
||||
access_key_id: AKIAIQNL5R4FI4C4NJYQ
|
||||
secret_access_key:
|
||||
secure: X66hYplxB4QSueljwvDfamNH/MQmHjo3mCofBcaTHAr7n2fp+yd2NzD2yy9h8NbsL0LWwx9wtJa/jpkIE02ZDfi9NrMLvKKFazzdpiyTMN5Yh85lHHyD1XIOCZRd4igaZ+O8975tJAEaEOPS+PE9XGZcRBh+y/eSJ+fMEgohaJ1MtDFbQR7X1cEw3iqbjrV2rlghZNCk/9mZEfObzAEjQiSDpv5G0IuIPRvYg/BgZt8chHVAe03B6oqcBa7uCBCTlfHIiNh1MWtP0B3NNBq3dcu9QHOFri1YqoZKuaPVCf6TFQL/NW5dFihegev2t9IwFyaBxytiT8fBkgQhP0VX8cuCwBAfnQGIogAu0eLSPp+E6dB/7Cpt2GDCk39+As8WKqt9hCRHmrvYhPA1Mq9QyEgKy/TKKKfDby3qVTIqYOQYpuQ1B7sIU651L5A+hBvZ1dqWIUz25h0zqjjeSFrcfNnf1e4tkk0QJvvnKqz0xsVaJxA2p07VJMRn8SlZQIJ2GEbMDeB5jxYtf5JzXywChP9adlPNjLna9G8ScnGSU1f7ZhsBQUEgY5jBlnX1lveyl3DUe6NP+qOTyljLWYwjx3AF4Zg10LYSecRS6hnqAUrGRmibDCIYclUzlJkVyjKGJ9uEyrUiCp0P0IsAzE1XhPVAWEyGUcWWGJG+jgmohSk=
|
||||
bucket: kcc-deploy
|
||||
region: eu-central-1
|
||||
local_dir: dist
|
||||
on:
|
||||
repo: AcidWeb/kcc
|
||||
368
CHANGELOG.md
Normal file
368
CHANGELOG.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# CHANGELOG
|
||||
#### 5.5.1:
|
||||
* Fixes some stability issues
|
||||
|
||||
#### 5.5.0:
|
||||
* Added support for WebP format
|
||||
* Added profiles for Kindle Paperwhite 4 and Kobo Forma
|
||||
* All archives are now handled by 7z
|
||||
* Removed MCD support
|
||||
* Fixed multiple smaller issues
|
||||
|
||||
#### 5.4.5:
|
||||
* Fixed EPUB output for non-Kindle devices
|
||||
|
||||
#### 5.4.4:
|
||||
* Minor bug fixes
|
||||
|
||||
#### 5.4.3:
|
||||
* Fixed conversion crash on Windows
|
||||
|
||||
#### 5.4.2:
|
||||
* Added Kindle Oasis 2 profile
|
||||
* Allowed metadata editor to edit directories
|
||||
* Fixed image stretching when HQ Panel View option was enabled
|
||||
* Fixed possible problem with directory sort order
|
||||
|
||||
#### 5.4.1:
|
||||
* Minor bug fixes and tweaks
|
||||
* Implemented new binary build pipeline
|
||||
|
||||
#### 5.4:
|
||||
* Reimplemented high quality Panel View option
|
||||
* Improved webtoon splitter
|
||||
* Fixed page splitter
|
||||
|
||||
#### 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:
|
||||
* Improved directory parsing
|
||||
* Tweaked margin detection algorithm
|
||||
* Improved error reporting
|
||||
|
||||
#### 5.2:
|
||||
* Added new Panel View options
|
||||
* Implemented new margin detection algorithm
|
||||
* Removed HQ Panel View mode
|
||||
* Fixed multiple smaller issues
|
||||
|
||||
#### 5.1.3:
|
||||
* Added Kobo Aura ONE profile
|
||||
* Fixed few small bugs
|
||||
|
||||
#### 5.1.2:
|
||||
* Fixed error reporting
|
||||
|
||||
#### 5.1.1:
|
||||
* Fixed multiple GUI bugs
|
||||
|
||||
#### 5.1:
|
||||
* GUI now can be resized and high DPI support was somewhat improved
|
||||
* Added profile for Kindle Oasis
|
||||
* Implemented new error reporting mechanism
|
||||
* CLI version now support additional cropping options
|
||||
* Fixed permission issues on Windows
|
||||
* Fixed multiple smaller issues
|
||||
|
||||
#### 5.0.1:
|
||||
* Fixed Panel View placement issues
|
||||
* Decreased application startup time
|
||||
* Fixed multiple smaller issues
|
||||
|
||||
#### 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:
|
||||
* Fixed multiple Windows and OS X issues
|
||||
* Allowed Linux release to use older PyQT5 version
|
||||
|
||||
#### 4.6.4:
|
||||
* Fixed multiple Windows specific problems
|
||||
* Improved error handling
|
||||
* Improved color detection algorithm
|
||||
* New, slimmer OS X release
|
||||
|
||||
#### 4.6.3:
|
||||
* Implemented remote bug reporting
|
||||
* Minor bug fixes and GUI tweaks
|
||||
|
||||
#### 4.6.2:
|
||||
* Fixed critical MOBI header bug
|
||||
* Fixed metadata encoding error
|
||||
|
||||
#### 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:
|
||||
* 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:
|
||||
* Added Kobo Glo HD profile
|
||||
* Fixed RAR/CBR parsing anomalies
|
||||
* Minor bug fixes and tweaks
|
||||
|
||||
#### 4.5:
|
||||
* Added simple ComicRack metadata editor
|
||||
* Re-enabled Manga Cover Database support
|
||||
* ComicRack bookmarks are now parsed
|
||||
* Fixed glitches in Kindle Voyage profile
|
||||
* Fixed problems with directory locks on Windows
|
||||
* Fixed sorting anomalies
|
||||
* Improved conversion speed
|
||||
|
||||
#### 4.4.1:
|
||||
* Fixed problems with OSX GUI
|
||||
* Added one missing DLL to Windows installer
|
||||
|
||||
#### 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:
|
||||
* 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:
|
||||
* Added profiles for Kindle Voyage and Kobo Aura H2O
|
||||
* Added missing features to CLI version
|
||||
* Other minor bug fixes
|
||||
|
||||
#### 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:
|
||||
* 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:
|
||||
* 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:
|
||||
* Fixed some Windows and OSX specific bugs
|
||||
* Fixed problem with marigns when using HQ mode
|
||||
|
||||
#### 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:
|
||||
* KCC now use Python 3.3 and Qt 5.2
|
||||
* Full UTF-8 awareness
|
||||
* CBZ output now support Manga mode
|
||||
* Improved Panel View support and margin color detection
|
||||
* Added drag&drop support
|
||||
* Output directory can be now selected
|
||||
* Windows release now have auto-updater
|
||||
* Names of chapters on Kindle should be now more user friendly
|
||||
* Fixed OSX file association support
|
||||
* Many extensive internal changes and tweaks
|
||||
|
||||
#### 3.7.2:
|
||||
* Fixed problems with HQ mode
|
||||
|
||||
#### 3.7.1:
|
||||
* Hotfixed Kobo profiles
|
||||
|
||||
#### 3.7:
|
||||
* Added profiles for KOBO devices
|
||||
* Improved Panel View support
|
||||
* Improved WebToon splitter
|
||||
* Improved margin color autodetection
|
||||
* Tweaked EPUB output
|
||||
* Fixed stretching option
|
||||
* GUI tweaks and minor bugfixes
|
||||
|
||||
#### 3.6.2:
|
||||
* Fixed previous PNG output fix
|
||||
* Fixed Panel View anomalies
|
||||
|
||||
#### 3.6.1:
|
||||
* Fixed PNG output
|
||||
|
||||
#### 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
|
||||
* Added ComicRack metadata parser
|
||||
* Implemented new method to detect border color in non-webtoon comics
|
||||
* Upscaling is now enabled by default for Kindle Fire HD/HDX
|
||||
* Windows nad Linux releases now have tray icon
|
||||
* Fixed Kindle Fire HDX 7" output
|
||||
* Increased target resolution for Kindle DX/DXG CBZ output
|
||||
|
||||
#### 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:
|
||||
* 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
|
||||
* Paths that contain UTF-8 characters are now supported
|
||||
* Migrated to new version of Pillow library
|
||||
* Merged DX and DXG profiles
|
||||
* Many other minor bug fixes and GUI tweaks
|
||||
|
||||
#### 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
|
||||
* Layout of panels in Panel View mode is now automatically adjusted to content
|
||||
* Fixed Kindle 2/DX/DXG profiles - no more blank pages
|
||||
* All Kindle Fire profiles now support hiqh quality Panel View
|
||||
* Added support of 7z/CB7 files
|
||||
* Added Kindle Fire HDX profile
|
||||
* Support for Virtual Panel View was removed
|
||||
* Profiles for Kindle Keyboard, Touch and Non-Touch are now merged
|
||||
* Windows release is now bundled with UnRAR and 7za
|
||||
* Small GUI tweaks
|
||||
|
||||
#### 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:
|
||||
* Hotfixed crash occurring on OS with Russian locale
|
||||
|
||||
#### 3.1:
|
||||
* Added profile: Kindle for Android
|
||||
* Add file/directory dialogs now support multiselect
|
||||
* Many small fixes and tweaks
|
||||
|
||||
#### 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:
|
||||
* Multiprocessing support
|
||||
* Kindle Fire support (color EPUB/MOBI)
|
||||
* Panel View support for horizontal content
|
||||
* Fixed panel order for horizontal pages when --rotate is enabled
|
||||
* Disabled cropping and page number cutting for blank pages
|
||||
* Fixed some slugify issues with specific file naming conventions (#50, #51)
|
||||
|
||||
#### 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
|
||||
* Updated rarfile library
|
||||
* Panel View support + HQ support (#36) - new option: --nopanelviewhq
|
||||
* Split profiles for K4NT and K4T
|
||||
* Rewrite of Landscape Mode support (huge readability improvement for KPW)
|
||||
* Upscale use now BILINEAR method
|
||||
* Added generic CSS file
|
||||
* Optimized archive extraction for zip/rar files (#40)
|
||||
|
||||
#### 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)
|
||||
* EPUB margins support (#30)
|
||||
* Fixed no file added if file has no spaces on Windows (#25)
|
||||
* Gracefully exit if unrar missing (#15)
|
||||
* Do not call kindlegen if source EPUB is bigger than 320MB (#17)
|
||||
* Get filetype from magic number (#14)
|
||||
* PDF conversion works again
|
||||
|
||||
#### 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
|
||||
* 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
|
||||
* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
|
||||
* Fixed "add folders" from GUI.
|
||||
|
||||
#### 2.3
|
||||
* Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders
|
||||
|
||||
#### 2.2:
|
||||
* Added (valid!) EPUB 2.0 output
|
||||
* Rename .zip files to .cbz to avoid overwriting
|
||||
|
||||
#### 2.1
|
||||
* Added basic error reporting
|
||||
|
||||
#### 2.0
|
||||
* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
|
||||
|
||||
#### 1.5
|
||||
* Added subfolder support for multiple chapters.
|
||||
|
||||
#### 1.4.1
|
||||
* Fixed a serious bug on resizing when img ratio was bigger than device one
|
||||
|
||||
#### 1.4
|
||||
* Added some options for controlling image optimization
|
||||
* Further optimization (ImageOps, page numbering cut, autocontrast)
|
||||
|
||||
#### 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
|
||||
* 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
|
||||
* Added support for CBZ/CBR files in Kindle Comic Converter
|
||||
|
||||
#### 1.1
|
||||
* Added support for CBZ/CBR files in comic2ebook.py
|
||||
|
||||
#### 1.0
|
||||
* Initial version
|
||||
26
Dockerfile
26
Dockerfile
@@ -1,26 +0,0 @@
|
||||
# Recipe used to build DEB package
|
||||
|
||||
FROM acidweb/kcc-base
|
||||
MAINTAINER Paweł Jastrzębski <pawelj@iosphe.re>
|
||||
|
||||
ENV KCCVER 5.0
|
||||
ADD . /app
|
||||
|
||||
RUN pip3 install pillow python-slugify psutil scandir pyinstaller
|
||||
RUN gem install fpm
|
||||
RUN useradd -ms /bin/bash kcc && chown -R kcc:kcc /app
|
||||
|
||||
USER kcc
|
||||
WORKDIR /app
|
||||
RUN pyinstaller -F -s kcc.py
|
||||
RUN mkdir -p dist/usr/bin dist/usr/share/applications dist/usr/share/doc/kindlecomicconverter dist/usr/share/kindlecomicconverter dist/usr/share/lintian/overrides
|
||||
RUN mv dist/kcc dist/usr/bin
|
||||
RUN cp icons/comic2ebook.png dist/usr/share/kindlecomicconverter
|
||||
RUN cp LICENSE.txt dist/usr/share/doc/kindlecomicconverter/copyright
|
||||
RUN cp other/linux/kindlecomicconverter.desktop dist/usr/share/applications
|
||||
RUN cp other/linux/kindlecomicconverter dist/usr/share/lintian/overrides
|
||||
|
||||
WORKDIR /app/dist
|
||||
RUN fpm -f -s dir -t deb -n kindlecomicconverter -v $KCCVER -m "Paweł Jastrzębski <pawelj@iosphe.re>" --license "ISC" --description "Comic and Manga converter for e-book readers.\nThis app allows you to transform your PNG, JPG, GIF, CBZ, CBR and CB7 files\ninto EPUB or MOBI format e-books." --url "https://kcc.iosphe.re/" --deb-priority "optional" --vendor "" --category "graphics" -d "unrar | unrar-free" -d "p7zip-full" usr
|
||||
|
||||
CMD mkdir -p /out/dist && cp kindlecomicconverter_${KCCVER}_amd64.deb /out/dist
|
||||
@@ -1,7 +1,7 @@
|
||||
ISC LICENSE
|
||||
|
||||
Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
Copyright (c) 2013-2015 Paweł Jastrzębski <pawelj@iosphe.re>
|
||||
Copyright (c) 2013-2019 Paweł Jastrzębski <pawelj@iosphe.re>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for
|
||||
any purpose with or without fee is hereby granted, provided that the
|
||||
|
||||
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
exclude kindlecomicconverter/sentry.py
|
||||
400
README.md
400
README.md
@@ -1,4 +1,6 @@
|
||||
# KCC
|
||||
# KCC
|
||||
|
||||
[](https://github.com/ciromattia/kcc/releases) [](https://pypi.python.org/pypi/KindleComicConverter) [](https://aur.archlinux.org/packages/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
|
||||
@@ -6,7 +8,7 @@ actually a comic/manga to EPUB converter that every e-reader owner can happily u
|
||||
It can also optionally optimize images by applying a number of transformations.
|
||||
|
||||
### A word of warning
|
||||
**KCC** _is not_ [Amazon's Kindle Comic Creator](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1001103761) nor is in any way endorsed by Amazon.
|
||||
**KCC** _is not_ [Amazon's Kindle Comic Creator](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1001103761) nor is in any way endorsed by Amazon.
|
||||
Amazon's tool is for comic publishers and involves a lot of manual effort, while **KCC** is for comic/manga readers.
|
||||
_KC2_ in no way is a replacement for **KCC** so you can be quite confident we'll going to carry on developing our little monster ;-)
|
||||
|
||||
@@ -17,54 +19,59 @@ 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:
|
||||
- **Windows (64-bit only):** [http://kcc.iosphe.re/Windows/](http://kcc.iosphe.re/Windows/)
|
||||
- **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/)
|
||||
- **[Windows](http://kcc.iosphe.re/Windows/) (64-bit only)**
|
||||
- **[macOS](http://kcc.iosphe.re/OSX/) (10.12+)**
|
||||
- **Linux:** Currently unavailable.
|
||||
|
||||
## 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](http://www.riverbankcomputing.co.uk/software/pyqt/download5) 5.2.1+ _(5.5+ is recommended)_
|
||||
- [Pillow](http://pypi.python.org/pypi/Pillow/) 3.0.0+
|
||||
- [psutil](https://pypi.python.org/pypi/psutil) 3.2.1+
|
||||
- [python-slugify](http://pypi.python.org/pypi/python-slugify) 1.1.4+
|
||||
- [scandir](https://pypi.python.org/pypi/scandir) 1.1.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 python3-pyqt5 libpng-dev libjpeg-dev p7zip-full unrar
|
||||
sudo pip3 install --upgrade pillow python-slugify psutil scandir
|
||||
sudo apt-get install python3 python3-dev python3-pip libpng-dev libjpeg-dev p7zip-full
|
||||
sudo pip3 install --upgrade pillow python-slugify psutil pyqt5 raven
|
||||
```
|
||||
|
||||
### Optional dependencies
|
||||
- [KindleGen](http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211) v2.9+ in a directory reachable by your _PATH_ or in _KCC_ directory *(For MOBI generation)*
|
||||
- [UnRAR](http://www.rarlab.com/download.htm) *(For CBR/RAR support)*
|
||||
- [7za](http://www.7-zip.org/download.html) *(For 7z/CB7 support)*
|
||||
- [7z](http://www.7-zip.org/download.html) *(For CBZ/ZIP, CBR/RAR, 7z/CB7 support)*
|
||||
|
||||
## INPUT FORMATS
|
||||
**KCC** can understand and convert, at the moment, the following input types:
|
||||
- Folders containing: PNG, JPG or GIF files
|
||||
- CBZ, ZIP
|
||||
- CBR, RAR *(With `unrar` executable)*
|
||||
- CB7, 7Z *(With `7za` executable)*
|
||||
- Folders containing: PNG, JPG, GIF or WebP files
|
||||
- CBZ, ZIP *(With `7z` executable)*
|
||||
- CBR, RAR *(With `7z` executable)*
|
||||
- CB7, 7Z *(With `7z` executable)*
|
||||
- PDF *(Only extracting JPG images)*
|
||||
|
||||
## USAGE
|
||||
|
||||
Should be pretty self-explanatory. All options have detailed informations in tooltips.
|
||||
After completed conversion you should find ready file alongside the original input file (same directory).
|
||||
Should be pretty self-explanatory. All options have detailed information in tooltips.
|
||||
After completed conversion, you should find ready file alongside the original input file (same directory).
|
||||
|
||||
Please check [our wiki](https://github.com/ciromattia/kcc/wiki/) for more details.
|
||||
|
||||
CLI version of **KCC** is intended for power users. It is not idiot-proof like GUI :-)
|
||||
CLI version of **KCC** is intended for power users. It allows using options that might not be compatible and decrease the quality of output.
|
||||
|
||||
### Standalone `kcc-c2e.py` usage:
|
||||
|
||||
@@ -74,9 +81,12 @@ Usage: kcc-c2e [options] comic_file|comic_folder
|
||||
Options:
|
||||
MAIN:
|
||||
-p PROFILE, --profile=PROFILE
|
||||
Device profile (Available options: K1, K2, K345, KDX,
|
||||
KPW, KV, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O) [Default=KV]
|
||||
Device profile (Available options: K1, K2, K34, K578,
|
||||
KDX, KPW, KV, KO, KoMT, KoG, KoGHD, KoA, KoAHD, KoAH2O,
|
||||
KoAO, KoF) [Default=KV]
|
||||
-m, --manga-style Manga style (right-to-left reading and splitting)
|
||||
-q, --hq Try to increase the quality of magnification
|
||||
-2, --two-panel Display two not four panels in Panel View mode
|
||||
-w, --webtoon Webtoon processing mode
|
||||
|
||||
OUTPUT SETTINGS:
|
||||
@@ -85,23 +95,31 @@ Options:
|
||||
-t TITLE, --title=TITLE
|
||||
Comic title [Default=filename or directory name]
|
||||
-f FORMAT, --format=FORMAT
|
||||
Output format (Available options: Auto, MOBI, EPUB, CBZ)
|
||||
[Default=Auto]
|
||||
-b, --batchsplit Split output into multiple files
|
||||
Output format (Available options: Auto, MOBI, EPUB,
|
||||
CBZ, KFX) [Default=Auto]
|
||||
-b BATCHSPLIT, --batchsplit=BATCHSPLIT
|
||||
Split output into multiple files. 0: Don't split 1:
|
||||
Automatic mode 2: Consider every subdirectory as
|
||||
separate volume [Default=0]
|
||||
|
||||
PROCESSING:
|
||||
-u, --upscale Resize images smaller than device's resolution
|
||||
-s, --stretch Stretch images to device's resolution
|
||||
-r SPLITTER, --splitter=SPLITTER
|
||||
Double page parsing mode. 0: Split 1: Rotate 2: Both [Default=0]
|
||||
Double page parsing mode. 0: Split 1: Rotate 2: Both
|
||||
[Default=0]
|
||||
-g GAMMA, --gamma=GAMMA
|
||||
Apply gamma correction to linearize the image [Default=Auto]
|
||||
--hq Enable high quality Panel View
|
||||
Apply gamma correction to linearize the image
|
||||
[Default=Auto]
|
||||
-c CROPPING, --cropping=CROPPING
|
||||
Set cropping mode. 0: Disabled 1: Margins 2: Margins +
|
||||
page numbers [Default=2]
|
||||
--cp=CROPPINGP, --croppingpower=CROPPINGP
|
||||
Set cropping power [Default=1.0]
|
||||
--blackborders Disable autodetection and force black borders
|
||||
--whiteborders Disable autodetection and force white borders
|
||||
--forcecolor Don't convert images to grayscale
|
||||
--forcepng Create PNG files instead JPEG
|
||||
--nocutpagenumbers Don't try to cut page numbers from images
|
||||
|
||||
CUSTOM PROFILE:
|
||||
--customwidth=CUSTOMWIDTH
|
||||
@@ -126,7 +144,7 @@ Options:
|
||||
-m, --merge Combine every directory into a single image before splitting
|
||||
|
||||
OTHER:
|
||||
-d, --debug Create debug file for every splitted image
|
||||
-d, --debug Create debug file for every split image
|
||||
-h, --help Show this help message and exit
|
||||
```
|
||||
|
||||
@@ -138,322 +156,28 @@ This script born as a cross-platform alternative to `KindleComicParser` by **Dc5
|
||||
The app relies and includes the following scripts:
|
||||
|
||||
- `DualMetaFix` script by **K. Hendricks**. Released with GPL-3 License.
|
||||
- `rarfile.py` script © 2005-2014 **Marko Kreen** <markokr@gmail.com>. Released with ISC License.
|
||||
- `image.py` class from **Alex Yatskov**'s [Mangle](https://github.com/FooSoft/mangle/) with subsequent [proDOOMman](https://github.com/proDOOMman/Mangle)'s and [Birua](https://github.com/Birua/Mangle)'s patches.
|
||||
- Icon is by **Nikolay Verin** ([http://ncrow.deviantart.com/](http://ncrow.deviantart.com/)) and released under [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/) License.
|
||||
|
||||
## SAMPLE FILES CREATED BY KCC
|
||||
* [Kindle Paperwhite 3 / Voyage](http://kcc.iosphe.re/Samples/Ubunchu!-KV.mobi)
|
||||
* [Kindle Oasis 2](http://kcc.iosphe.re/Samples/Ubunchu!-KO.mobi)
|
||||
* [Kindle Paperwhite 3 / 4 / Voyage / Oasis](http://kcc.iosphe.re/Samples/Ubunchu!-KV.mobi)
|
||||
* [Kindle Paperwhite 1 / 2](http://kcc.iosphe.re/Samples/Ubunchu!-KPW.mobi)
|
||||
* [Kindle](http://kcc.iosphe.re/Samples/Ubunchu!-K345.mobi)
|
||||
* [Kindle DX/DXG](http://kcc.iosphe.re/Samples/Ubunchu!-KDX.cbz)
|
||||
* [Kobo Mini/Touch](http://kcc.iosphe.re/Samples/Ubunchu-KoMT.kepub.epub)
|
||||
* [Kobo Glo](http://kcc.iosphe.re/Samples/Ubunchu-KoG.kepub.epub)
|
||||
* [Kobo Glo HD](http://kcc.iosphe.re/Samples/Ubunchu-KoGHD.kepub.epub)
|
||||
* [Kindle](http://kcc.iosphe.re/Samples/Ubunchu!-K578.mobi)
|
||||
* [Kobo Aura](http://kcc.iosphe.re/Samples/Ubunchu-KoA.kepub.epub)
|
||||
* [Kobo Aura HD](http://kcc.iosphe.re/Samples/Ubunchu-KoAHD.kepub.epub)
|
||||
* [Kobo Aura H2O](http://kcc.iosphe.re/Samples/Ubunchu-KoAH2O.kepub.epub)
|
||||
|
||||
## CHANGELOG
|
||||
####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:
|
||||
* Fixed multiple Windows and OS X issues
|
||||
* Allowed Linux release to use older PyQT5 version
|
||||
|
||||
####4.6.4:
|
||||
* Fixed multiple Windows specific problems
|
||||
* Improved error handling
|
||||
* Improved color detection algorithm
|
||||
* New, slimmer OS X release
|
||||
|
||||
####4.6.3:
|
||||
* Implemented remote bug reporting
|
||||
* Minor bug fixes and GUI tweaks
|
||||
|
||||
####4.6.2:
|
||||
* Fixed critical MOBI header bug
|
||||
* Fixed metadata encoding error
|
||||
|
||||
####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:
|
||||
* 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:
|
||||
* Added Kobo Glo HD profile
|
||||
* Fixed RAR/CBR parsing anomalies
|
||||
* Minor bug fixes and tweaks
|
||||
|
||||
####4.5:
|
||||
* Added simple ComicRack metadata editor
|
||||
* Re-enabled Manga Cover Database support
|
||||
* ComicRack bookmarks are now parsed
|
||||
* Fixed glitches in Kindle Voyage profile
|
||||
* Fixed problems with directory locks on Windows
|
||||
* Fixed sorting anomalies
|
||||
* Improved conversion speed
|
||||
|
||||
####4.4.1:
|
||||
* Fixed problems with OSX GUI
|
||||
* Added one missing DLL to Windows installer
|
||||
|
||||
####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:
|
||||
* 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:
|
||||
* Added profiles for Kindle Voyage and Kobo Aura H2O
|
||||
* Added missing features to CLI version
|
||||
* Other minor bug fixes
|
||||
|
||||
####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:
|
||||
* 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:
|
||||
* 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:
|
||||
* Fixed some Windows and OSX specific bugs
|
||||
* Fixed problem with marigns when using HQ mode
|
||||
|
||||
####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:
|
||||
* KCC now use Python 3.3 and Qt 5.2
|
||||
* Full UTF-8 awareness
|
||||
* CBZ output now support Manga mode
|
||||
* Improved Panel View support and margin color detection
|
||||
* Added drag&drop support
|
||||
* Output directory can be now selected
|
||||
* Windows release now have auto-updater
|
||||
* Names of chapters on Kindle should be now more user friendly
|
||||
* Fixed OSX file association support
|
||||
* Many extensive internal changes and tweaks
|
||||
|
||||
####3.7.2:
|
||||
* Fixed problems with HQ mode
|
||||
|
||||
####3.7.1:
|
||||
* Hotfixed Kobo profiles
|
||||
|
||||
####3.7:
|
||||
* Added profiles for KOBO devices
|
||||
* Improved Panel View support
|
||||
* Improved WebToon splitter
|
||||
* Improved margin color autodetection
|
||||
* Tweaked EPUB output
|
||||
* Fixed stretching option
|
||||
* GUI tweaks and minor bugfixes
|
||||
|
||||
####3.6.2:
|
||||
* Fixed previous PNG output fix
|
||||
* Fixed Panel View anomalies
|
||||
|
||||
####3.6.1:
|
||||
* Fixed PNG output
|
||||
|
||||
####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
|
||||
* Added ComicRack metadata parser
|
||||
* Implemented new method to detect border color in non-webtoon comics
|
||||
* Upscaling is now enabled by default for Kindle Fire HD/HDX
|
||||
* Windows nad Linux releases now have tray icon
|
||||
* Fixed Kindle Fire HDX 7" output
|
||||
* Increased target resolution for Kindle DX/DXG CBZ output
|
||||
|
||||
####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:
|
||||
* 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
|
||||
* Paths that contain UTF-8 characters are now supported
|
||||
* Migrated to new version of Pillow library
|
||||
* Merged DX and DXG profiles
|
||||
* Many other minor bug fixes and GUI tweaks
|
||||
|
||||
####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
|
||||
* Layout of panels in Panel View mode is now automatically adjusted to content
|
||||
* Fixed Kindle 2/DX/DXG profiles - no more blank pages
|
||||
* All Kindle Fire profiles now support hiqh quality Panel View
|
||||
* Added support of 7z/CB7 files
|
||||
* Added Kindle Fire HDX profile
|
||||
* Support for Virtual Panel View was removed
|
||||
* Profiles for Kindle Keyboard, Touch and Non-Touch are now merged
|
||||
* Windows release is now bundled with UnRAR and 7za
|
||||
* Small GUI tweaks
|
||||
|
||||
####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:
|
||||
* Hotfixed crash occurring on OS with Russian locale
|
||||
|
||||
####3.1:
|
||||
* Added profile: Kindle for Android
|
||||
* Add file/directory dialogs now support multiselect
|
||||
* Many small fixes and tweaks
|
||||
|
||||
####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:
|
||||
* Multiprocessing support
|
||||
* Kindle Fire support (color EPUB/MOBI)
|
||||
* Panel View support for horizontal content
|
||||
* Fixed panel order for horizontal pages when --rotate is enabled
|
||||
* Disabled cropping and page number cutting for blank pages
|
||||
* Fixed some slugify issues with specific file naming conventions (#50, #51)
|
||||
|
||||
####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
|
||||
* Updated rarfile library
|
||||
* Panel View support + HQ support (#36) - new option: --nopanelviewhq
|
||||
* Split profiles for K4NT and K4T
|
||||
* Rewrite of Landscape Mode support (huge readability improvement for KPW)
|
||||
* Upscale use now BILINEAR method
|
||||
* Added generic CSS file
|
||||
* Optimized archive extraction for zip/rar files (#40)
|
||||
|
||||
####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)
|
||||
* EPUB margins support (#30)
|
||||
* Fixed no file added if file has no spaces on Windows (#25)
|
||||
* Gracefully exit if unrar missing (#15)
|
||||
* Do not call kindlegen if source EPUB is bigger than 320MB (#17)
|
||||
* Get filetype from magic number (#14)
|
||||
* PDF conversion works again
|
||||
|
||||
####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
|
||||
* 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
|
||||
* Use temporary directory as workdir (fixes converting from external volumes and zipfiles renaming)
|
||||
* Fixed "add folders" from GUI.
|
||||
|
||||
####2.3
|
||||
* Fixed win32 EPUB generation, folder handling, filenames with spaces and subfolders
|
||||
|
||||
####2.2:
|
||||
* Added (valid!) EPUB 2.0 output
|
||||
* Rename .zip files to .cbz to avoid overwriting
|
||||
|
||||
####2.1
|
||||
* Added basic error reporting
|
||||
|
||||
####2.0
|
||||
* GUI! AppleScript is gone and Tk is used to provide cross-platform GUI support.
|
||||
|
||||
####1.5
|
||||
* Added subfolder support for multiple chapters.
|
||||
|
||||
####1.4.1
|
||||
* Fixed a serious bug on resizing when img ratio was bigger than device one
|
||||
|
||||
####1.4
|
||||
* Added some options for controlling image optimization
|
||||
* Further optimization (ImageOps, page numbering cut, autocontrast)
|
||||
|
||||
####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
|
||||
* 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
|
||||
* Added support for CBZ/CBR files in Kindle Comic Converter
|
||||
|
||||
####1.1
|
||||
* Added support for CBZ/CBR files in comic2ebook.py
|
||||
|
||||
####1.0
|
||||
* Initial version
|
||||
* [Kobo Aura ONE](http://kcc.iosphe.re/Samples/Ubunchu-KoAO.kepub.epub)
|
||||
* [Kobo Forma](http://kcc.iosphe.re/Samples/Ubunchu-KoF.kepub.epub)
|
||||
|
||||
## PRIVACY
|
||||
**KCC** is initiating internet connections in three cases:
|
||||
* During startup - Version check
|
||||
* When MCD metadata are used - Cover download
|
||||
* When error occurs - Automatic reporting
|
||||
|
||||
Error report include **KCC** version, OS version and content of error message.
|
||||
**KCC** is initiating internet connections in two cases:
|
||||
* During startup - Version check.
|
||||
* When error occurs - Automatic reporting on Windows and MacOS.
|
||||
|
||||
## KNOWN ISSUES
|
||||
Please check [wiki page](https://github.com/ciromattia/kcc/wiki/Known-issues).
|
||||
|
||||
## COPYRIGHT
|
||||
Copyright (c) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski.
|
||||
Copyright (c) 2012-2019 Ciro Mattia Gonano and Paweł Jastrzębski.
|
||||
**KCC** is released under ISC LICENSE; see LICENSE.txt for further details.
|
||||
|
||||
25
appveyor.yml
Normal file
25
appveyor.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
environment:
|
||||
PYTHON: "C:\\Python37-x64"
|
||||
|
||||
install:
|
||||
- set PATH="%PYTHON%\\Scripts";"C:\\Program Files (x86)\\Inno Setup 5";%PATH%
|
||||
- "%PYTHON%\\python.exe -m pip install --upgrade pip setuptools wheel"
|
||||
- "%PYTHON%\\python.exe -m pip install -r requirements.txt"
|
||||
- "%PYTHON%\\python.exe -m pip install certifi https://github.com/pyinstaller/pyinstaller/archive/develop.zip"
|
||||
- nuget install secure-file -ExcludeVersion
|
||||
- secure-file\tools\secure-file -decrypt other\windows\sentry.py.enc -out kindlecomicconverter\sentry.py -secret %ENCRYPTION%
|
||||
|
||||
build_script:
|
||||
- "%PYTHON%\\python.exe setup.py build_binary"
|
||||
|
||||
after_build:
|
||||
- ps: Get-ChildItem .\dist\KCC* | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name }
|
||||
|
||||
deploy:
|
||||
provider: S3
|
||||
access_key_id:
|
||||
secure: pWfyU8wtAHt354mBILwM41TemOjb+My9n3CRMnrpLzI=
|
||||
secret_access_key:
|
||||
secure: G0Xpxe355LMqV3s8v+TsdJYdmhFoKKA+mxK37Tlu8yNwKXKJgcnY7pcFKSdX5xS5
|
||||
bucket: kcc-deploy
|
||||
region: eu-central-1
|
||||
676
gui/KCC-Linux.ui
676
gui/KCC-Linux.ui
@@ -1,676 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KCC</class>
|
||||
<widget class="QMainWindow" name="KCC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Kindle Comic Converter</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<property name="locale">
|
||||
<locale language="C" country="AnyCountry"/>
|
||||
</property>
|
||||
<widget class="QWidget" name="Form">
|
||||
<widget class="QComboBox" name="DeviceBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>200</y>
|
||||
<width>141</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Target device.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="FormatBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>260</x>
|
||||
<y>200</y>
|
||||
<width>151</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Output format.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ConvertButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>200</y>
|
||||
<width>91</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DirectoryButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<width>141</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add directory</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/folder_new.png</normaloff>:/Other/icons/folder_new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="FileButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>260</x>
|
||||
<y>160</y>
|
||||
<width>151</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add file</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/document_new.png</normaloff>:/Other/icons/document_new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ClearButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>160</y>
|
||||
<width>91</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear list</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="Options">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>237</y>
|
||||
<width>401</width>
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>25</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="MangaBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable right-to-left reading.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manga mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="RotateBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Spread splitter</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QCheckBox" name="QualityBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>High quality Panel View.<br/>Require source files with bigger resolution than target device.<br/><span style=" font-weight:600;">Highly impact size of output file!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HQ zoom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QCheckBox" name="GammaBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable automatic gamma correction.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom gamma</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="NoDitheringBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=" font-weight:600;">might</span> be smaller.<br/><span style=" font-weight:600;">MOBI conversion will be much slower.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PNG output</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QCheckBox" name="ColorBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable conversion to grayscale.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="UpscaleBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stretch/Upscale</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="WebtoonBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable special parsing mode for Korean Webtoons.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Webtoon mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="BorderBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>W/B margins</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QListWidget" name="JobList">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>401</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}</string>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="OptionsGamma">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>305</y>
|
||||
<width>401</width>
|
||||
<height>35</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="GammaLabel">
|
||||
<property name="text">
|
||||
<string>Gamma: Auto</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="GammaSlider">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="ProgressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>401</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="OptionsCustom">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>336</y>
|
||||
<width>401</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="wLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom width: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="customWidth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="hLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom height: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="customHeight">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>200</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/editor.png</normaloff>:/Other/icons/editor.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="WikiButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>211</x>
|
||||
<y>10</y>
|
||||
<width>200</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Wiki</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/wiki.png</normaloff>:/Other/icons/wiki.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
<zorder>ConvertButton</zorder>
|
||||
<zorder>DirectoryButton</zorder>
|
||||
<zorder>FileButton</zorder>
|
||||
<zorder>ClearButton</zorder>
|
||||
<zorder>Options</zorder>
|
||||
<zorder>JobList</zorder>
|
||||
<zorder>OptionsGamma</zorder>
|
||||
<zorder>OptionsCustom</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>WikiButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="ActionBasic">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Basic</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionAdvanced">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>DirectoryButton</tabstop>
|
||||
<tabstop>FileButton</tabstop>
|
||||
<tabstop>ConvertButton</tabstop>
|
||||
<tabstop>ClearButton</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
689
gui/KCC-OSX.ui
689
gui/KCC-OSX.ui
@@ -1,689 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>KCC</class>
|
||||
<widget class="QMainWindow" name="KCC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>390</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Kindle Comic Converter</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<property name="locale">
|
||||
<locale language="C" country="AnyCountry"/>
|
||||
</property>
|
||||
<widget class="QWidget" name="Form">
|
||||
<widget class="QComboBox" name="DeviceBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>8</x>
|
||||
<y>204</y>
|
||||
<width>151</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Target device.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="FormatBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>264</x>
|
||||
<y>204</y>
|
||||
<width>150</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Output format.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ConvertButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>159</x>
|
||||
<y>200</y>
|
||||
<width>104</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Shift+Click to select the output directory.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Convert</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="DirectoryButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>4</x>
|
||||
<y>160</y>
|
||||
<width>158</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add directory</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/folder_new.png</normaloff>:/Other/icons/folder_new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="FileButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>260</x>
|
||||
<y>160</y>
|
||||
<width>157</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add file</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/document_new.png</normaloff>:/Other/icons/document_new.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="ClearButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>159</x>
|
||||
<y>160</y>
|
||||
<width>104</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear list</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="Options">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>237</y>
|
||||
<width>401</width>
|
||||
<height>70</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>31</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="MangaBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable right-to-left reading.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Manga mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="RotateBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Spread splitter</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QCheckBox" name="QualityBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>High quality Panel View.<br/>Require source files with bigger resolution than target device.<br/><span style=" font-weight:600;">Highly impact size of output file!</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>HQ zoom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QCheckBox" name="GammaBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable automatic gamma correction.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom gamma</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="NoDitheringBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=" font-weight:600;">might</span> be smaller.<br/><span style=" font-weight:600;">MOBI conversion will be much slower.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>PNG output</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QCheckBox" name="ColorBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Disable conversion to grayscale.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Color mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="UpscaleBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stretch/Upscale</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="WebtoonBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Enable special parsing mode for Korean Webtoons.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Webtoon mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="BorderBox">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=" font-weight:600; text-decoration: underline;">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=" font-weight:600; text-decoration: underline;">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>W/B margins</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QListWidget" name="JobList">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>401</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}</string>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>15</width>
|
||||
<height>15</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="OptionsGamma">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>305</y>
|
||||
<width>401</width>
|
||||
<height>35</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>15</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="GammaLabel">
|
||||
<property name="text">
|
||||
<string>Gamma: Auto</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="GammaSlider">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>500</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="ProgressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>401</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignJustify|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QFrame" name="OptionsCustom">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>337</y>
|
||||
<width>401</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="wLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom width: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="customWidth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="hLabel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Custom height: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="customHeight">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::ClickFocus</enum>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p style='white-space:pre'>Resolution of target device.</p></body></html></string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>0000</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>4</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/editor.png</normaloff>:/Other/icons/editor.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="WikiButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>207</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Wiki</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/wiki.png</normaloff>:/Other/icons/wiki.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
<zorder>ConvertButton</zorder>
|
||||
<zorder>DirectoryButton</zorder>
|
||||
<zorder>FileButton</zorder>
|
||||
<zorder>ClearButton</zorder>
|
||||
<zorder>Options</zorder>
|
||||
<zorder>JobList</zorder>
|
||||
<zorder>OptionsGamma</zorder>
|
||||
<zorder>OptionsCustom</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>WikiButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="ActionBasic">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Basic</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>11</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="ActionAdvanced">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Advanced</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>DirectoryButton</tabstop>
|
||||
<tabstop>FileButton</tabstop>
|
||||
<tabstop>ConvertButton</tabstop>
|
||||
<tabstop>ClearButton</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
1111
gui/KCC.ui
1111
gui/KCC.ui
File diff suppressed because it is too large
Load Diff
@@ -1,225 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>290</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>290</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>290</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>250</y>
|
||||
<width>381</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>241</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>266</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<zorder>formLayoutWidget</zorder>
|
||||
<zorder>horizontalLayoutWidget</zorder>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,226 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>295</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>260</y>
|
||||
<width>381</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>251</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>250</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MetaEditorDialog</class>
|
||||
<widget class="QDialog" name="MetaEditorDialog">
|
||||
<class>editorDialog</class>
|
||||
<widget class="QDialog" name="editorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@@ -16,12 +16,6 @@
|
||||
<height>260</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>260</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Metadata editor</string>
|
||||
</property>
|
||||
@@ -29,191 +23,164 @@
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Icon/icons/comic2ebook.png</normaloff>:/Icon/icons/comic2ebook.png</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>220</y>
|
||||
<width>381</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="StatusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<item>
|
||||
<widget class="QWidget" name="editorWidget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0);</string>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="seriesLine"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="volumeLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="numberLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="writerLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="pencillerLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="inkerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="coloristLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="optionWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="CancelButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QFrame" name="EditorFrame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>381</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Series:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="SeriesLine"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Volume:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="VolumeLine"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Number:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="NumberLine"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Writer:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="WriterLine"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Penciller:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="PencillerLine"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Inker:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="InkerLine"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Colorist:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="ColoristLine"/>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support"><span style=" text-decoration: underline; color:#0000ff;">MUid:</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="MUidLine"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="okButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/convert.png</normaloff>:/Other/icons/convert.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="KCC.qrc">
|
||||
<normaloff>:/Other/icons/clear.png</normaloff>:/Other/icons/clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 23 KiB |
Binary file not shown.
14
kcc-c2e.py
14
kcc-c2e.py
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -23,14 +23,10 @@ if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(2)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2ebook import main
|
||||
from multiprocessing import freeze_support, set_start_method
|
||||
from kindlecomicconverter.startup import startC2E
|
||||
|
||||
if __name__ == "__main__":
|
||||
set_start_method('spawn')
|
||||
freeze_support()
|
||||
print('comic2ebook v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
startC2E()
|
||||
|
||||
14
kcc-c2p.py
14
kcc-c2p.py
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -23,14 +23,10 @@ if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(1)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2panel import main
|
||||
from multiprocessing import freeze_support, set_start_method
|
||||
from kindlecomicconverter.startup import startC2P
|
||||
|
||||
if __name__ == "__main__":
|
||||
set_start_method('spawn')
|
||||
freeze_support()
|
||||
print('comic2panel v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
startC2P()
|
||||
|
||||
9
kcc.iss
9
kcc.iss
@@ -1,5 +1,5 @@
|
||||
#define MyAppName "Kindle Comic Converter"
|
||||
#define MyAppVersion "5.0"
|
||||
#define MyAppVersion "5.5.1"
|
||||
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
|
||||
#define MyAppURL "http://kcc.iosphe.re/"
|
||||
#define MyAppExeName "KCC.exe"
|
||||
@@ -12,7 +12,7 @@ AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
AppCopyright=Copyright (C) 2012-2015 Ciro Mattia Gonano and Paweł Jastrzębski
|
||||
AppCopyright=Copyright (C) 2012-2019 Ciro Mattia Gonano and Paweł Jastrzębski
|
||||
ArchitecturesAllowed=x64
|
||||
DefaultDirName={pf}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
@@ -32,6 +32,7 @@ InfoAfterFile=other\windows\InstallWarning.rtf
|
||||
SignTool=SignTool /d $q{#MyAppName}$q /du $q{#MyAppURL}$q $f
|
||||
MinVersion=0,6.0
|
||||
OutputDir=dist
|
||||
ArchitecturesInstallIn64BitMode=x64
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
@@ -46,8 +47,8 @@ Name: "CB7association"; Description: "CB7"; GroupDescription: "File associations
|
||||
Source: "dist\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion solidbreak
|
||||
Source: "other\windows\Additional-LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\windows\UnRAR.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\windows\7za.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\windows\7z.exe"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "other\windows\7z.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
|
||||
52
kcc.py
52
kcc.py
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -28,52 +28,30 @@ import os
|
||||
if sys.platform.startswith('darwin'):
|
||||
if getattr(sys, 'frozen', False):
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(sys.executable)) + \
|
||||
'/../Resources:/usr/local/bin:/usr/bin:/bin'
|
||||
'/../Resources:/usr/local/bin:/usr/bin:/bin'
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.executable)) + '/../Resources')
|
||||
os.system('defaults write com.kindlecomicconverter.KindleComicConverter ApplePersistenceIgnoreState YES')
|
||||
os.system('defaults write com.kindlecomicconverter.KindleComicConverter NSInitialToolTipDelay -int 1000')
|
||||
else:
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/osx/:' + os.environ['PATH']
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
elif sys.platform.startswith('win'):
|
||||
import multiprocessing.popen_spawn_win32 as forking
|
||||
|
||||
class _Popen(forking.Popen):
|
||||
def __init__(self, *args, **kw):
|
||||
if hasattr(sys, 'frozen'):
|
||||
# noinspection PyProtectedMember
|
||||
os.putenv('_MEIPASS2', sys._MEIPASS)
|
||||
try:
|
||||
super(_Popen, self).__init__(*args, **kw)
|
||||
finally:
|
||||
if hasattr(sys, 'frozen'):
|
||||
if hasattr(os, 'unsetenv'):
|
||||
os.unsetenv('_MEIPASS2')
|
||||
else:
|
||||
os.putenv('_MEIPASS2', '')
|
||||
forking.Popen = _Popen
|
||||
|
||||
if getattr(sys, 'frozen', False):
|
||||
os.chdir(os.path.dirname(os.path.abspath(sys.executable)))
|
||||
else:
|
||||
os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + '/other/windows/;' + os.environ['PATH']
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
# Load additional Sentry configuration
|
||||
if getattr(sys, 'frozen', False):
|
||||
try:
|
||||
import kindlecomicconverter.sentry
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from kcc.shared import dependencyCheck
|
||||
dependencyCheck(3)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import KCC_gui
|
||||
from multiprocessing import freeze_support, set_start_method
|
||||
from kindlecomicconverter.startup import start
|
||||
|
||||
if __name__ == "__main__":
|
||||
set_start_method('spawn')
|
||||
freeze_support()
|
||||
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()
|
||||
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 11:52:00 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 260)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 260))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 260))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 220, 381, 31))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 211))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 211))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,148 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui/MetaEditor-Linux.ui'
|
||||
#
|
||||
# Created: Wed Oct 28 08:59:02 2015
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 290)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 290))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 290))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 250, 381, 31))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 241))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 266))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,149 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file '/Users/pawelj/Documents/KCC/gui/MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 12:47:09 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_MetaEditorDialog(object):
|
||||
def setupUi(self, MetaEditorDialog):
|
||||
MetaEditorDialog.setObjectName("MetaEditorDialog")
|
||||
MetaEditorDialog.resize(400, 295)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 295))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 295))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
MetaEditorDialog.setWindowIcon(icon)
|
||||
self.horizontalLayoutWidget = QtWidgets.QWidget(MetaEditorDialog)
|
||||
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 260, 381, 32))
|
||||
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.StatusLabel = QtWidgets.QLabel(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.StatusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.StatusLabel.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.StatusLabel.setFont(font)
|
||||
self.StatusLabel.setStyleSheet("color: rgb(255, 0, 0);")
|
||||
self.StatusLabel.setObjectName("StatusLabel")
|
||||
self.horizontalLayout.addWidget(self.StatusLabel)
|
||||
self.OKButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.OKButton.sizePolicy().hasHeightForWidth())
|
||||
self.OKButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.OKButton.setFont(font)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.OKButton.setIcon(icon1)
|
||||
self.OKButton.setObjectName("OKButton")
|
||||
self.horizontalLayout.addWidget(self.OKButton)
|
||||
self.CancelButton = QtWidgets.QPushButton(self.horizontalLayoutWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.CancelButton.sizePolicy().hasHeightForWidth())
|
||||
self.CancelButton.setSizePolicy(sizePolicy)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.CancelButton.setFont(font)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.CancelButton.setIcon(icon2)
|
||||
self.CancelButton.setObjectName("CancelButton")
|
||||
self.horizontalLayout.addWidget(self.CancelButton)
|
||||
self.EditorFrame = QtWidgets.QFrame(MetaEditorDialog)
|
||||
self.EditorFrame.setGeometry(QtCore.QRect(10, 10, 381, 251))
|
||||
self.EditorFrame.setObjectName("EditorFrame")
|
||||
self.formLayoutWidget = QtWidgets.QWidget(self.EditorFrame)
|
||||
self.formLayoutWidget.setGeometry(QtCore.QRect(0, 0, 381, 250))
|
||||
self.formLayoutWidget.setObjectName("formLayoutWidget")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.formLayoutWidget)
|
||||
self.formLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.formLayout.setFieldGrowthPolicy(QtWidgets.QFormLayout.ExpandingFieldsGrow)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.label = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label.setObjectName("label")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
|
||||
self.SeriesLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.SeriesLine.setObjectName("SeriesLine")
|
||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.SeriesLine)
|
||||
self.label_2 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_2)
|
||||
self.VolumeLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.VolumeLine.setObjectName("VolumeLine")
|
||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.VolumeLine)
|
||||
self.label_3 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_3)
|
||||
self.NumberLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.NumberLine.setObjectName("NumberLine")
|
||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.NumberLine)
|
||||
self.label_4 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_4)
|
||||
self.WriterLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.WriterLine.setObjectName("WriterLine")
|
||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.WriterLine)
|
||||
self.label_5 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_5)
|
||||
self.PencillerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.PencillerLine.setObjectName("PencillerLine")
|
||||
self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.PencillerLine)
|
||||
self.label_6 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_6)
|
||||
self.InkerLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.InkerLine.setObjectName("InkerLine")
|
||||
self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.InkerLine)
|
||||
self.label_7 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_7)
|
||||
self.ColoristLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.ColoristLine.setObjectName("ColoristLine")
|
||||
self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.ColoristLine)
|
||||
self.label_8 = QtWidgets.QLabel(self.formLayoutWidget)
|
||||
self.label_8.setTextFormat(QtCore.Qt.RichText)
|
||||
self.label_8.setOpenExternalLinks(True)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_8)
|
||||
self.MUidLine = QtWidgets.QLineEdit(self.formLayoutWidget)
|
||||
self.MUidLine.setObjectName("MUidLine")
|
||||
self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.MUidLine)
|
||||
|
||||
self.retranslateUi(MetaEditorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(MetaEditorDialog)
|
||||
|
||||
def retranslateUi(self, MetaEditorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
MetaEditorDialog.setWindowTitle(_translate("MetaEditorDialog", "Metadata editor"))
|
||||
self.OKButton.setText(_translate("MetaEditorDialog", "Save"))
|
||||
self.CancelButton.setText(_translate("MetaEditorDialog", "Cancel"))
|
||||
self.label.setText(_translate("MetaEditorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("MetaEditorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("MetaEditorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("MetaEditorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("MetaEditorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("MetaEditorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("MetaEditorDialog", "Colorist:"))
|
||||
self.label_8.setText(_translate("MetaEditorDialog", "<html><head/><body><p><a href=\"https://github.com/ciromattia/kcc/wiki/Manga-Cover-Database-support\"><span style=\" text-decoration: underline; color:#0000ff;\">MUid:</span></a></p></body></html>"))
|
||||
|
||||
from . import KCC_rc
|
||||
314
kcc/KCC_ui.py
314
kcc/KCC_ui.py
@@ -1,314 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui\KCC.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 390)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 390))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 390))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
KCC.setFont(font)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.Options = QtWidgets.QFrame(self.Form)
|
||||
self.Options.setGeometry(QtCore.QRect(10, 237, 401, 70))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.Options.setFont(font)
|
||||
self.Options.setObjectName("Options")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.Options)
|
||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout.setHorizontalSpacing(40)
|
||||
self.gridLayout.setVerticalSpacing(5)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.gridLayout.addWidget(self.MangaBox, 2, 0, 1, 1)
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setTristate(True)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.gridLayout.addWidget(self.RotateBox, 2, 1, 1, 1)
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.gridLayout.addWidget(self.QualityBox, 2, 2, 1, 1)
|
||||
self.GammaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.GammaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.GammaBox.setObjectName("GammaBox")
|
||||
self.gridLayout.addWidget(self.GammaBox, 4, 2, 1, 1)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 5, 1, 1, 1)
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.gridLayout.addWidget(self.ColorBox, 5, 2, 1, 1)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 4, 1, 1, 1)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 4, 0, 1, 1)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 5, 0, 1, 1)
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.OptionsGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsGamma.setEnabled(True)
|
||||
self.OptionsGamma.setGeometry(QtCore.QRect(10, 305, 401, 35))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsGamma.setFont(font)
|
||||
self.OptionsGamma.setObjectName("OptionsGamma")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.OptionsGamma)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setSpacing(15)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.horizontalLayout.addWidget(self.GammaLabel)
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsGamma)
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.horizontalLayout.addWidget(self.GammaSlider)
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsCustom = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsCustom.setGeometry(QtCore.QRect(10, 340, 401, 25))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsCustom.setFont(font)
|
||||
self.OptionsCustom.setObjectName("OptionsCustom")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.OptionsCustom)
|
||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_2.setSpacing(15)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.horizontalLayout_2.addWidget(self.wLabel)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
self.customWidth.setSizePolicy(sizePolicy)
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.horizontalLayout_2.addWidget(self.customWidth)
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.horizontalLayout_2.addWidget(self.hLabel)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
self.customHeight.setSizePolicy(sizePolicy)
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.horizontalLayout_2.addWidget(self.customHeight)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(10, 10, 200, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
self.WikiButton = QtWidgets.QPushButton(self.Form)
|
||||
self.WikiButton.setGeometry(QtCore.QRect(211, 10, 200, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.WikiButton.setFont(font)
|
||||
self.WikiButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/Other/icons/wiki.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.WikiButton.setIcon(icon6)
|
||||
self.WikiButton.setObjectName("WikiButton")
|
||||
self.DeviceBox.raise_()
|
||||
self.FormatBox.raise_()
|
||||
self.ConvertButton.raise_()
|
||||
self.DirectoryButton.raise_()
|
||||
self.FileButton.raise_()
|
||||
self.ClearButton.raise_()
|
||||
self.Options.raise_()
|
||||
self.JobList.raise_()
|
||||
self.OptionsGamma.raise_()
|
||||
self.OptionsCustom.raise_()
|
||||
self.EditorButton.raise_()
|
||||
self.WikiButton.raise_()
|
||||
self.ProgressBar.raise_()
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("MS Shell Dlg 2")
|
||||
font.setPointSize(8)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
KCC.setTabOrder(self.DirectoryButton, self.FileButton)
|
||||
KCC.setTabOrder(self.FileButton, self.ConvertButton)
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<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>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Spread splitter"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>High quality Panel View.<br/>Require source files with bigger resolution than target device.<br/><span style=\" font-weight:600;\">Highly impact size of output file!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "HQ zoom"))
|
||||
self.GammaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable automatic gamma correction.</p></body></html>"))
|
||||
self.GammaBox.setText(_translate("KCC", "Custom gamma"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable conversion to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for Korean Webtoons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.WikiButton.setText(_translate("KCC", "Wiki"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,299 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui/KCC-Linux.ui'
|
||||
#
|
||||
# Created: Wed Oct 28 08:34:21 2015
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 390)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 390))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 390))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
KCC.setFont(font)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(10, 200, 141, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(260, 200, 151, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(160, 200, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(10, 160, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(160, 160, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.Options = QtWidgets.QFrame(self.Form)
|
||||
self.Options.setGeometry(QtCore.QRect(10, 237, 401, 70))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.Options.setFont(font)
|
||||
self.Options.setObjectName("Options")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.Options)
|
||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout.setHorizontalSpacing(25)
|
||||
self.gridLayout.setVerticalSpacing(4)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.gridLayout.addWidget(self.MangaBox, 2, 0, 1, 1)
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setTristate(True)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.gridLayout.addWidget(self.RotateBox, 2, 1, 1, 1)
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.gridLayout.addWidget(self.QualityBox, 2, 2, 1, 1)
|
||||
self.GammaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.GammaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.GammaBox.setObjectName("GammaBox")
|
||||
self.gridLayout.addWidget(self.GammaBox, 4, 2, 1, 1)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 5, 1, 1, 1)
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.gridLayout.addWidget(self.ColorBox, 5, 2, 1, 1)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 4, 1, 1, 1)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 4, 0, 1, 1)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 5, 0, 1, 1)
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setIconSize(QtCore.QSize(18, 18))
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.OptionsGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsGamma.setEnabled(True)
|
||||
self.OptionsGamma.setGeometry(QtCore.QRect(10, 305, 401, 35))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsGamma.setFont(font)
|
||||
self.OptionsGamma.setObjectName("OptionsGamma")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.OptionsGamma)
|
||||
self.horizontalLayout.setSpacing(15)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.horizontalLayout.addWidget(self.GammaLabel)
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsGamma)
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.horizontalLayout.addWidget(self.GammaSlider)
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(10)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsCustom = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsCustom.setGeometry(QtCore.QRect(10, 336, 401, 25))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.OptionsCustom.setFont(font)
|
||||
self.OptionsCustom.setObjectName("OptionsCustom")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.OptionsCustom)
|
||||
self.horizontalLayout_2.setSpacing(10)
|
||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.horizontalLayout_2.addWidget(self.wLabel)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
self.customWidth.setSizePolicy(sizePolicy)
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.horizontalLayout_2.addWidget(self.customWidth)
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.horizontalLayout_2.addWidget(self.hLabel)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
self.customHeight.setSizePolicy(sizePolicy)
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.horizontalLayout_2.addWidget(self.customHeight)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(10, 10, 200, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
self.WikiButton = QtWidgets.QPushButton(self.Form)
|
||||
self.WikiButton.setGeometry(QtCore.QRect(211, 10, 200, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.WikiButton.setFont(font)
|
||||
self.WikiButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/Other/icons/wiki.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.WikiButton.setIcon(icon6)
|
||||
self.WikiButton.setObjectName("WikiButton")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(8)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
KCC.setTabOrder(self.DirectoryButton, self.FileButton)
|
||||
KCC.setTabOrder(self.FileButton, self.ConvertButton)
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<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>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Spread splitter"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>High quality Panel View.<br/>Require source files with bigger resolution than target device.<br/><span style=\" font-weight:600;\">Highly impact size of output file!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "HQ zoom"))
|
||||
self.GammaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable automatic gamma correction.</p></body></html>"))
|
||||
self.GammaBox.setText(_translate("KCC", "Custom gamma"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable conversion to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for Korean Webtoons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.WikiButton.setText(_translate("KCC", "Wiki"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,317 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC-OSX.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.5.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_KCC(object):
|
||||
def setupUi(self, KCC):
|
||||
KCC.setObjectName("KCC")
|
||||
KCC.resize(420, 390)
|
||||
KCC.setMinimumSize(QtCore.QSize(420, 390))
|
||||
KCC.setMaximumSize(QtCore.QSize(420, 390))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
KCC.setFont(font)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
KCC.setWindowIcon(icon)
|
||||
KCC.setLocale(QtCore.QLocale(QtCore.QLocale.C, QtCore.QLocale.AnyCountry))
|
||||
self.Form = QtWidgets.QWidget(KCC)
|
||||
self.Form.setObjectName("Form")
|
||||
self.DeviceBox = QtWidgets.QComboBox(self.Form)
|
||||
self.DeviceBox.setGeometry(QtCore.QRect(8, 204, 151, 26))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.DeviceBox.setFont(font)
|
||||
self.DeviceBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.DeviceBox.setObjectName("DeviceBox")
|
||||
self.FormatBox = QtWidgets.QComboBox(self.Form)
|
||||
self.FormatBox.setGeometry(QtCore.QRect(264, 204, 150, 26))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.FormatBox.setFont(font)
|
||||
self.FormatBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.FormatBox.setObjectName("FormatBox")
|
||||
self.ConvertButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ConvertButton.setGeometry(QtCore.QRect(159, 200, 104, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ConvertButton.setFont(font)
|
||||
self.ConvertButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ConvertButton.setIcon(icon1)
|
||||
self.ConvertButton.setObjectName("ConvertButton")
|
||||
self.DirectoryButton = QtWidgets.QPushButton(self.Form)
|
||||
self.DirectoryButton.setGeometry(QtCore.QRect(4, 160, 158, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.DirectoryButton.setFont(font)
|
||||
self.DirectoryButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.DirectoryButton.setIcon(icon2)
|
||||
self.DirectoryButton.setObjectName("DirectoryButton")
|
||||
self.FileButton = QtWidgets.QPushButton(self.Form)
|
||||
self.FileButton.setGeometry(QtCore.QRect(260, 160, 157, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.FileButton.setFont(font)
|
||||
self.FileButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.FileButton.setIcon(icon3)
|
||||
self.FileButton.setObjectName("FileButton")
|
||||
self.ClearButton = QtWidgets.QPushButton(self.Form)
|
||||
self.ClearButton.setGeometry(QtCore.QRect(159, 160, 104, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.ClearButton.setFont(font)
|
||||
self.ClearButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.ClearButton.setIcon(icon4)
|
||||
self.ClearButton.setObjectName("ClearButton")
|
||||
self.Options = QtWidgets.QFrame(self.Form)
|
||||
self.Options.setGeometry(QtCore.QRect(10, 237, 401, 70))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.Options.setFont(font)
|
||||
self.Options.setObjectName("Options")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.Options)
|
||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout.setHorizontalSpacing(31)
|
||||
self.gridLayout.setVerticalSpacing(5)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.MangaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.MangaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.MangaBox.setObjectName("MangaBox")
|
||||
self.gridLayout.addWidget(self.MangaBox, 2, 0, 1, 1)
|
||||
self.RotateBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.RotateBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.RotateBox.setTristate(True)
|
||||
self.RotateBox.setObjectName("RotateBox")
|
||||
self.gridLayout.addWidget(self.RotateBox, 2, 1, 1, 1)
|
||||
self.QualityBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.QualityBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.QualityBox.setObjectName("QualityBox")
|
||||
self.gridLayout.addWidget(self.QualityBox, 2, 2, 1, 1)
|
||||
self.GammaBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.GammaBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.GammaBox.setObjectName("GammaBox")
|
||||
self.gridLayout.addWidget(self.GammaBox, 4, 2, 1, 1)
|
||||
self.NoDitheringBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.NoDitheringBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.NoDitheringBox.setObjectName("NoDitheringBox")
|
||||
self.gridLayout.addWidget(self.NoDitheringBox, 5, 1, 1, 1)
|
||||
self.ColorBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.ColorBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.ColorBox.setObjectName("ColorBox")
|
||||
self.gridLayout.addWidget(self.ColorBox, 5, 2, 1, 1)
|
||||
self.UpscaleBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.UpscaleBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.UpscaleBox.setTristate(True)
|
||||
self.UpscaleBox.setObjectName("UpscaleBox")
|
||||
self.gridLayout.addWidget(self.UpscaleBox, 4, 1, 1, 1)
|
||||
self.WebtoonBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.WebtoonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.WebtoonBox.setObjectName("WebtoonBox")
|
||||
self.gridLayout.addWidget(self.WebtoonBox, 4, 0, 1, 1)
|
||||
self.BorderBox = QtWidgets.QCheckBox(self.Options)
|
||||
self.BorderBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BorderBox.setTristate(True)
|
||||
self.BorderBox.setObjectName("BorderBox")
|
||||
self.gridLayout.addWidget(self.BorderBox, 5, 0, 1, 1)
|
||||
self.JobList = QtWidgets.QListWidget(self.Form)
|
||||
self.JobList.setGeometry(QtCore.QRect(10, 50, 401, 101))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.JobList.setFont(font)
|
||||
self.JobList.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.JobList.setStyleSheet("QListWidget#JobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;}QScrollBar:vertical{border:1px solid #999;background:#FFF;width:5px;margin:0}QScrollBar::handle:vertical{background:DarkGray;min-height:0}QScrollBar::add-line:vertical{height:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:vertical{height:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}QScrollBar:horizontal{border:1px solid #999;background:#FFF;height:5px;margin:0}QScrollBar::handle:horizontal{background:DarkGray;min-width:0}QScrollBar::add-line:horizontal{width:0;background:DarkGray;subcontrol-position:bottom;subcontrol-origin:margin}QScrollBar::sub-line:horizontal{width:0;background:DarkGray;subcontrol-position:top;subcontrol-origin:margin}")
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setIconSize(QtCore.QSize(15, 15))
|
||||
self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.OptionsGamma = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsGamma.setEnabled(True)
|
||||
self.OptionsGamma.setGeometry(QtCore.QRect(10, 305, 401, 35))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.OptionsGamma.setFont(font)
|
||||
self.OptionsGamma.setObjectName("OptionsGamma")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.OptionsGamma)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setSpacing(15)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.GammaLabel = QtWidgets.QLabel(self.OptionsGamma)
|
||||
self.GammaLabel.setObjectName("GammaLabel")
|
||||
self.horizontalLayout.addWidget(self.GammaLabel)
|
||||
self.GammaSlider = QtWidgets.QSlider(self.OptionsGamma)
|
||||
self.GammaSlider.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.GammaSlider.setMaximum(500)
|
||||
self.GammaSlider.setSingleStep(5)
|
||||
self.GammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.GammaSlider.setObjectName("GammaSlider")
|
||||
self.horizontalLayout.addWidget(self.GammaSlider)
|
||||
self.ProgressBar = QtWidgets.QProgressBar(self.Form)
|
||||
self.ProgressBar.setGeometry(QtCore.QRect(10, 10, 401, 31))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.ProgressBar.setFont(font)
|
||||
self.ProgressBar.setProperty("value", 0)
|
||||
self.ProgressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.ProgressBar.setFormat("")
|
||||
self.ProgressBar.setObjectName("ProgressBar")
|
||||
self.OptionsCustom = QtWidgets.QFrame(self.Form)
|
||||
self.OptionsCustom.setGeometry(QtCore.QRect(10, 337, 401, 25))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.OptionsCustom.setFont(font)
|
||||
self.OptionsCustom.setObjectName("OptionsCustom")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.OptionsCustom)
|
||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_2.setSpacing(5)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.wLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.horizontalLayout_2.addWidget(self.wLabel)
|
||||
self.customWidth = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customWidth.sizePolicy().hasHeightForWidth())
|
||||
self.customWidth.setSizePolicy(sizePolicy)
|
||||
self.customWidth.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customWidth.setAcceptDrops(False)
|
||||
self.customWidth.setMaxLength(4)
|
||||
self.customWidth.setObjectName("customWidth")
|
||||
self.horizontalLayout_2.addWidget(self.customWidth)
|
||||
self.hLabel = QtWidgets.QLabel(self.OptionsCustom)
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.horizontalLayout_2.addWidget(self.hLabel)
|
||||
self.customHeight = QtWidgets.QLineEdit(self.OptionsCustom)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.customHeight.sizePolicy().hasHeightForWidth())
|
||||
self.customHeight.setSizePolicy(sizePolicy)
|
||||
self.customHeight.setFocusPolicy(QtCore.Qt.ClickFocus)
|
||||
self.customHeight.setAcceptDrops(False)
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.horizontalLayout_2.addWidget(self.customHeight)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(4, 10, 210, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.EditorButton.setFont(font)
|
||||
self.EditorButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.EditorButton.setIcon(icon5)
|
||||
self.EditorButton.setObjectName("EditorButton")
|
||||
self.WikiButton = QtWidgets.QPushButton(self.Form)
|
||||
self.WikiButton.setGeometry(QtCore.QRect(207, 10, 210, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.WikiButton.setFont(font)
|
||||
self.WikiButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/Other/icons/wiki.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.WikiButton.setIcon(icon6)
|
||||
self.WikiButton.setObjectName("WikiButton")
|
||||
self.DeviceBox.raise_()
|
||||
self.FormatBox.raise_()
|
||||
self.ConvertButton.raise_()
|
||||
self.DirectoryButton.raise_()
|
||||
self.FileButton.raise_()
|
||||
self.ClearButton.raise_()
|
||||
self.Options.raise_()
|
||||
self.JobList.raise_()
|
||||
self.OptionsGamma.raise_()
|
||||
self.OptionsCustom.raise_()
|
||||
self.EditorButton.raise_()
|
||||
self.WikiButton.raise_()
|
||||
self.ProgressBar.raise_()
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.statusBar.setFont(font)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
KCC.setStatusBar(self.statusBar)
|
||||
self.ActionBasic = QtWidgets.QAction(KCC)
|
||||
self.ActionBasic.setCheckable(True)
|
||||
self.ActionBasic.setChecked(False)
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(11)
|
||||
self.ActionBasic.setFont(font)
|
||||
self.ActionBasic.setObjectName("ActionBasic")
|
||||
self.ActionAdvanced = QtWidgets.QAction(KCC)
|
||||
self.ActionAdvanced.setCheckable(True)
|
||||
self.ActionAdvanced.setObjectName("ActionAdvanced")
|
||||
|
||||
self.retranslateUi(KCC)
|
||||
QtCore.QMetaObject.connectSlotsByName(KCC)
|
||||
KCC.setTabOrder(self.DirectoryButton, self.FileButton)
|
||||
KCC.setTabOrder(self.FileButton, self.ConvertButton)
|
||||
KCC.setTabOrder(self.ConvertButton, self.ClearButton)
|
||||
|
||||
def retranslateUi(self, KCC):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
KCC.setWindowTitle(_translate("KCC", "Kindle Comic Converter"))
|
||||
self.DeviceBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.FormatBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.ConvertButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.ConvertButton.setText(_translate("KCC", "Convert"))
|
||||
self.DirectoryButton.setToolTip(_translate("KCC", "<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>"))
|
||||
self.DirectoryButton.setText(_translate("KCC", "Add directory"))
|
||||
self.FileButton.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.FileButton.setText(_translate("KCC", "Add file"))
|
||||
self.ClearButton.setText(_translate("KCC", "Clear list"))
|
||||
self.MangaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.MangaBox.setText(_translate("KCC", "Manga mode"))
|
||||
self.RotateBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html>"))
|
||||
self.RotateBox.setText(_translate("KCC", "Spread splitter"))
|
||||
self.QualityBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>High quality Panel View.<br/>Require source files with bigger resolution than target device.<br/><span style=\" font-weight:600;\">Highly impact size of output file!</span></p></body></html>"))
|
||||
self.QualityBox.setText(_translate("KCC", "HQ zoom"))
|
||||
self.GammaBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable automatic gamma correction.</p></body></html>"))
|
||||
self.GammaBox.setText(_translate("KCC", "Custom gamma"))
|
||||
self.NoDitheringBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Create PNG files instead JPEG.<br/>Quality increase is not noticeable on most of devices.<br/>Output files <span style=\" font-weight:600;\">might</span> be smaller.<br/><span style=\" font-weight:600;\">MOBI conversion will be much slower.</span></p></body></html>"))
|
||||
self.NoDitheringBox.setText(_translate("KCC", "PNG output"))
|
||||
self.ColorBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Disable conversion to grayscale.</p></body></html>"))
|
||||
self.ColorBox.setText(_translate("KCC", "Color mode"))
|
||||
self.UpscaleBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.UpscaleBox.setText(_translate("KCC", "Stretch/Upscale"))
|
||||
self.WebtoonBox.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for Korean Webtoons.</p></body></html>"))
|
||||
self.WebtoonBox.setText(_translate("KCC", "Webtoon mode"))
|
||||
self.BorderBox.setToolTip(_translate("KCC", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>Color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.BorderBox.setText(_translate("KCC", "W/B margins"))
|
||||
self.GammaLabel.setText(_translate("KCC", "Gamma: Auto"))
|
||||
self.wLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("KCC", "Custom width: "))
|
||||
self.customWidth.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customWidth.setInputMask(_translate("KCC", "0000"))
|
||||
self.hLabel.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("KCC", "Custom height: "))
|
||||
self.customHeight.setToolTip(_translate("KCC", "<html><head/><body><p style=\'white-space:pre\'>Resolution of target device.</p></body></html>"))
|
||||
self.customHeight.setInputMask(_translate("KCC", "0000"))
|
||||
self.EditorButton.setText(_translate("KCC", "Editor"))
|
||||
self.WikiButton.setText(_translate("KCC", "Wiki"))
|
||||
self.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,105 +0,0 @@
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# 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 sys
|
||||
import os
|
||||
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
|
||||
|
||||
|
||||
class CBxArchive:
|
||||
def __init__(self, origFileName):
|
||||
self.origFileName = origFileName
|
||||
if is_zipfile(origFileName):
|
||||
self.compressor = 'zip'
|
||||
elif rarfile.is_rarfile(origFileName):
|
||||
self.compressor = 'rar'
|
||||
elif is_7zfile(origFileName):
|
||||
self.compressor = '7z'
|
||||
else:
|
||||
self.compressor = None
|
||||
|
||||
def isCbxFile(self):
|
||||
return self.compressor is not None
|
||||
|
||||
def extractCBZ(self, targetdir):
|
||||
cbzFile = ZipFile(self.origFileName)
|
||||
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
|
||||
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.
|
||||
else:
|
||||
filelist.append(f)
|
||||
cbzFile.extractall(targetdir, filelist)
|
||||
|
||||
def extractCBR(self, targetdir):
|
||||
cbrFile = rarfile.RarFile(self.origFileName)
|
||||
cbrFile.extractall(targetdir)
|
||||
for root, dirnames, filenames in walk(targetdir):
|
||||
for filename in filenames:
|
||||
if filename.startswith('__MACOSX') or filename.endswith('.DS_Store') or filename.endswith('humbs.db'):
|
||||
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'):
|
||||
os.remove(self.origFileName)
|
||||
if not extracted:
|
||||
raise OSError
|
||||
|
||||
def extract(self, targetdir):
|
||||
if self.compressor == 'rar':
|
||||
self.extractCBR(targetdir)
|
||||
elif self.compressor == 'zip':
|
||||
self.extractCBZ(targetdir)
|
||||
elif self.compressor == '7z':
|
||||
self.extractCB7(targetdir)
|
||||
adir = os.listdir(targetdir)
|
||||
if 'ComicInfo.xml' in adir:
|
||||
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
|
||||
463
kcc/image.py
463
kcc/image.py
@@ -1,463 +0,0 @@
|
||||
# Copyright (C) 2010 Alex Yatskov
|
||||
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
from io import BytesIO
|
||||
from urllib.request import Request, urlopen
|
||||
from urllib.parse import quote
|
||||
from PIL import Image, ImageOps, ImageStat, ImageChops
|
||||
from .shared import md5Checksum
|
||||
from . import __version__
|
||||
|
||||
|
||||
class ProfileData:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
Palette4 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x55, 0x55, 0x55,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xff, 0xff, 0xff
|
||||
]
|
||||
|
||||
Palette15 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11,
|
||||
0x22, 0x22, 0x22,
|
||||
0x33, 0x33, 0x33,
|
||||
0x44, 0x44, 0x44,
|
||||
0x55, 0x55, 0x55,
|
||||
0x66, 0x66, 0x66,
|
||||
0x77, 0x77, 0x77,
|
||||
0x88, 0x88, 0x88,
|
||||
0x99, 0x99, 0x99,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xbb, 0xbb, 0xbb,
|
||||
0xcc, 0xcc, 0xcc,
|
||||
0xdd, 0xdd, 0xdd,
|
||||
0xff, 0xff, 0xff,
|
||||
]
|
||||
|
||||
Palette16 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11,
|
||||
0x22, 0x22, 0x22,
|
||||
0x33, 0x33, 0x33,
|
||||
0x44, 0x44, 0x44,
|
||||
0x55, 0x55, 0x55,
|
||||
0x66, 0x66, 0x66,
|
||||
0x77, 0x77, 0x77,
|
||||
0x88, 0x88, 0x88,
|
||||
0x99, 0x99, 0x99,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xbb, 0xbb, 0xbb,
|
||||
0xcc, 0xcc, 0xcc,
|
||||
0xdd, 0xdd, 0xdd,
|
||||
0xee, 0xee, 0xee,
|
||||
0xff, 0xff, 0xff,
|
||||
]
|
||||
|
||||
PalleteNull = [
|
||||
]
|
||||
|
||||
Profiles = {
|
||||
'K1': ("Kindle 1", (600, 670), Palette4, 1.8, (900, 1005)),
|
||||
'K2': ("Kindle 2", (600, 670), Palette15, 1.8, (900, 1005)),
|
||||
'K345': ("Kindle", (600, 800), Palette16, 1.8, (900, 1200)),
|
||||
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8, (1236, 1500)),
|
||||
'KPW': ("Kindle Paperwhite 1/2", (758, 1024), Palette16, 1.8, (1137, 1536)),
|
||||
'KV': ("Kindle Paperwhite 3/Voyage", (1072, 1448), Palette16, 1.8, (1608, 2172)),
|
||||
'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8, (900, 1200)),
|
||||
'KoG': ("Kobo Glo", (768, 1024), Palette16, 1.8, (1152, 1536)),
|
||||
'KoGHD': ("Kobo Glo HD", (1072, 1448), Palette16, 1.8, (1608, 2172)),
|
||||
'KoA': ("Kobo Aura", (758, 1024), Palette16, 1.8, (1137, 1536)),
|
||||
'KoAHD': ("Kobo Aura HD", (1080, 1440), Palette16, 1.8, (1620, 2160)),
|
||||
'KoAH2O': ("Kobo Aura H2O", (1080, 1430), Palette16, 1.8, (1620, 2145)),
|
||||
'OTHER': ("Other", (0, 0), Palette16, 1.8, (0, 0)),
|
||||
}
|
||||
|
||||
|
||||
class ComicPageParser:
|
||||
def __init__(self, source, options):
|
||||
self.opt = options
|
||||
self.source = source
|
||||
self.size = self.opt.profileData[1]
|
||||
self.payload = []
|
||||
self.image = Image.open(os.path.join(source[0], source[1])).convert('RGB')
|
||||
self.color = self.colorCheck()
|
||||
self.fill = self.fillCheck()
|
||||
self.splitCheck()
|
||||
if self.opt.hqmode:
|
||||
self.sizeCheck()
|
||||
|
||||
def getImageHistogram(self, image):
|
||||
histogram = image.histogram()
|
||||
if histogram[0] == 0:
|
||||
return -1
|
||||
elif histogram[255] == 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def splitCheck(self):
|
||||
width, height = self.image.size
|
||||
dstwidth, dstheight = self.size
|
||||
# Only split if origin is not oriented the same as target
|
||||
if (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
|
||||
if self.opt.splitter != 1:
|
||||
if width > height:
|
||||
# Source is landscape, so split by the width
|
||||
leftbox = (0, 0, int(width / 2), height)
|
||||
rightbox = (int(width / 2), 0, width, height)
|
||||
else:
|
||||
# Source is portrait and target is landscape, so split by the height
|
||||
leftbox = (0, 0, width, int(height / 2))
|
||||
rightbox = (0, int(height / 2), width, height)
|
||||
if self.opt.righttoleft:
|
||||
pageone = self.image.crop(rightbox)
|
||||
pagetwo = self.image.crop(leftbox)
|
||||
else:
|
||||
pageone = self.image.crop(leftbox)
|
||||
pagetwo = self.image.crop(rightbox)
|
||||
self.payload.append(['S1', self.source, pageone, self.color, self.fill])
|
||||
self.payload.append(['S2', self.source, pagetwo, self.color, self.fill])
|
||||
if self.opt.splitter > 0:
|
||||
self.payload.append(['R', self.source, self.image.rotate(90, Image.BICUBIC, True),
|
||||
self.color, self.fill])
|
||||
else:
|
||||
self.payload.append(['N', self.source, self.image, self.color, self.fill])
|
||||
|
||||
def colorCheck(self):
|
||||
if self.opt.webtoon:
|
||||
return True
|
||||
else:
|
||||
img = self.image.copy()
|
||||
bands = img.getbands()
|
||||
if bands == ('R', 'G', 'B') or bands == ('R', 'G', 'B', 'A'):
|
||||
thumb = img.resize((40, 40))
|
||||
SSE, bias = 0, [0, 0, 0]
|
||||
bias = ImageStat.Stat(thumb).mean[:3]
|
||||
bias = [b - sum(bias) / 3 for b in bias]
|
||||
for pixel in thumb.getdata():
|
||||
mu = sum(pixel) / 3
|
||||
SSE += sum((pixel[i] - mu - bias[i]) * (pixel[i] - mu - bias[i]) for i in [0, 1, 2])
|
||||
MSE = float(SSE) / (40 * 40)
|
||||
if MSE > 22:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def fillCheck(self):
|
||||
if self.opt.bordersColor:
|
||||
return self.opt.bordersColor
|
||||
else:
|
||||
bw = self.image.convert('L').point(lambda x: 0 if x < 128 else 255, '1')
|
||||
imageBoxA = bw.getbbox()
|
||||
imageBoxB = ImageChops.invert(bw).getbbox()
|
||||
if imageBoxA is None or imageBoxB is None:
|
||||
surfaceB, surfaceW = 0, 0
|
||||
diff = 0
|
||||
else:
|
||||
surfaceB = (imageBoxA[2] - imageBoxA[0]) * (imageBoxA[3] - imageBoxA[1])
|
||||
surfaceW = (imageBoxB[2] - imageBoxB[0]) * (imageBoxB[3] - imageBoxB[1])
|
||||
diff = ((max(surfaceB, surfaceW) - min(surfaceB, surfaceW)) / min(surfaceB, surfaceW)) * 100
|
||||
if diff > 0.5:
|
||||
if surfaceW < surfaceB:
|
||||
return 'white'
|
||||
elif surfaceW > surfaceB:
|
||||
return 'black'
|
||||
else:
|
||||
fill = 0
|
||||
startY = 0
|
||||
while startY < bw.size[1]:
|
||||
if startY + 5 > bw.size[1]:
|
||||
startY = bw.size[1] - 5
|
||||
fill += self.getImageHistogram(bw.crop((0, startY, bw.size[0], startY + 5)))
|
||||
startY += 5
|
||||
startX = 0
|
||||
while startX < bw.size[0]:
|
||||
if startX + 5 > bw.size[0]:
|
||||
startX = bw.size[0] - 5
|
||||
fill += self.getImageHistogram(bw.crop((startX, 0, startX + 5, bw.size[1])))
|
||||
startX += 5
|
||||
if fill > 0:
|
||||
return 'black'
|
||||
else:
|
||||
return 'white'
|
||||
|
||||
def sizeCheck(self):
|
||||
additionalPayload = []
|
||||
width, height = self.image.size
|
||||
dstwidth, dstheight = self.size
|
||||
for work in self.payload:
|
||||
if width > dstwidth and height > dstheight:
|
||||
additionalPayload.append([work[0] + '+', work[1], work[2].copy(), work[3], work[4]])
|
||||
self.payload = self.payload + additionalPayload
|
||||
|
||||
|
||||
class ComicPage:
|
||||
def __init__(self, mode, path, image, color, fill, options):
|
||||
self.opt = options
|
||||
_, self.size, self.palette, self.gamma, self.panelviewsize = self.opt.profileData
|
||||
self.image = image
|
||||
self.color = color
|
||||
self.fill = fill
|
||||
self.rotated = False
|
||||
self.orgPath = os.path.join(path[0], path[1])
|
||||
if '+' in mode:
|
||||
self.hqMode = True
|
||||
else:
|
||||
self.hqMode = False
|
||||
if 'N' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC'
|
||||
elif 'R' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-A'
|
||||
self.rotated = True
|
||||
elif 'S1' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-B'
|
||||
elif 'S2' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-C'
|
||||
|
||||
def saveToDir(self):
|
||||
try:
|
||||
flags = []
|
||||
if not self.opt.forcecolor and not self.opt.forcepng:
|
||||
self.image = self.image.convert('L')
|
||||
if self.rotated:
|
||||
flags.append('Rotated')
|
||||
if self.fill != 'white':
|
||||
flags.append('BlackFill')
|
||||
if self.hqMode:
|
||||
self.targetPath += '-HQ'
|
||||
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)
|
||||
return [md5Checksum(self.targetPath), flags, self.orgPath]
|
||||
except IOError:
|
||||
raise RuntimeError('Cannot save image.')
|
||||
|
||||
def autocontrastImage(self):
|
||||
gamma = self.opt.gamma
|
||||
if gamma < 0.1:
|
||||
gamma = self.gamma
|
||||
if self.gamma != 1.0 and self.color:
|
||||
gamma = 1.0
|
||||
if gamma == 1.0:
|
||||
self.image = ImageOps.autocontrast(self.image)
|
||||
else:
|
||||
self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma))
|
||||
|
||||
def quantizeImage(self):
|
||||
colors = len(self.palette) // 3
|
||||
if colors < 256:
|
||||
self.palette += self.palette[:3] * (256 - colors)
|
||||
palImg = Image.new('P', (1, 1))
|
||||
palImg.putpalette(self.palette)
|
||||
self.image = self.image.convert('L')
|
||||
self.image = self.image.convert('RGB')
|
||||
# Quantize is deprecated but new function call it internally anyway...
|
||||
self.image = self.image.quantize(palette=palImg)
|
||||
|
||||
def resizeImage(self):
|
||||
if self.hqMode:
|
||||
size = (self.panelviewsize[0], self.panelviewsize[1])
|
||||
if self.image.size[0] > size[0] or self.image.size[1] > size[1]:
|
||||
self.image.thumbnail(size, Image.LANCZOS)
|
||||
else:
|
||||
size = (self.size[0], self.size[1])
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
|
||||
method = Image.BICUBIC
|
||||
else:
|
||||
method = Image.LANCZOS
|
||||
if self.opt.stretch:
|
||||
self.image = self.image.resize(size, method)
|
||||
elif self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not self.opt.upscale:
|
||||
if self.opt.format == 'CBZ':
|
||||
borderw = int((size[0] - self.image.size[0]) / 2)
|
||||
borderh = int((size[1] - self.image.size[1]) / 2)
|
||||
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=self.fill)
|
||||
if self.image.size[0] != size[0] or self.image.size[1] != size[1]:
|
||||
self.image = ImageOps.fit(self.image, size, method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
else:
|
||||
if self.opt.format == 'CBZ':
|
||||
ratioDev = float(size[0]) / float(size[1])
|
||||
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
|
||||
diff = int(self.image.size[1] * ratioDev) - self.image.size[0]
|
||||
self.image = ImageOps.expand(self.image, border=(int(diff / 2), 0), fill=self.fill)
|
||||
elif (float(self.image.size[0]) / float(self.image.size[1])) > ratioDev:
|
||||
diff = int(self.image.size[0] / ratioDev) - self.image.size[1]
|
||||
self.image = ImageOps.expand(self.image, border=(0, int(diff / 2)), fill=self.fill)
|
||||
self.image = ImageOps.fit(self.image, size, method=method, centering=(0.5, 0.5))
|
||||
else:
|
||||
hpercent = size[1] / float(self.image.size[1])
|
||||
wsize = int((float(self.image.size[0]) * float(hpercent)))
|
||||
self.image = self.image.resize((wsize, size[1]), method)
|
||||
if self.image.size[0] > size[0] or self.image.size[1] > size[1]:
|
||||
self.image.thumbnail(size, Image.LANCZOS)
|
||||
|
||||
def cutPageNumber(self):
|
||||
if ImageChops.invert(self.image).getbbox() is not None:
|
||||
widthImg, heightImg = self.image.size
|
||||
delta = 2
|
||||
diff = delta
|
||||
fixedThreshold = 5
|
||||
if ImageStat.Stat(self.image).var[0] < 2 * fixedThreshold:
|
||||
return self.image
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
|
||||
and diff < heightImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberCut1 = diff
|
||||
if diff < delta:
|
||||
diff = delta
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
|
||||
diff += delta
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] - oldStat > 0\
|
||||
and diff < heightImg // 4:
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0]
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberCut2 = diff
|
||||
diff += delta
|
||||
oldStat = ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg,
|
||||
heightImg - pageNumberCut2))).var[0]
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg - pageNumberCut2))).var[0]\
|
||||
< fixedThreshold + oldStat and diff < heightImg // 4:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberCut3 = diff
|
||||
delta = 5
|
||||
diff = delta
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut2, diff, heightImg))).var[0]\
|
||||
< fixedThreshold and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberX1 = diff
|
||||
diff = delta
|
||||
while ImageStat.Stat(self.image.crop((widthImg - diff, heightImg - pageNumberCut2,
|
||||
widthImg, heightImg))).var[0] < fixedThreshold and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
pageNumberX2 = widthImg - diff
|
||||
if pageNumberCut3 - pageNumberCut1 > 2 * delta\
|
||||
and float(pageNumberX2 - pageNumberX1) / float(pageNumberCut2 - pageNumberCut1) <= 9.0\
|
||||
and ImageStat.Stat(self.image.crop((0, heightImg - pageNumberCut3, widthImg, heightImg))).var[0]\
|
||||
/ ImageStat.Stat(self.image).var[0] < 0.1\
|
||||
and pageNumberCut3 < heightImg / 4 - delta:
|
||||
diff = pageNumberCut3
|
||||
else:
|
||||
diff = pageNumberCut1
|
||||
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
|
||||
|
||||
def cropWhiteSpace(self):
|
||||
if ImageChops.invert(self.image).getbbox() is not None:
|
||||
widthImg, heightImg = self.image.size
|
||||
delta = 10
|
||||
diff = delta
|
||||
fixedThreshold = 0.1
|
||||
# top
|
||||
while ImageStat.Stat(self.image.crop((0, 0, widthImg, diff))).var[0] < fixedThreshold and diff < heightImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
self.image = self.image.crop((0, diff, widthImg, heightImg))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# left
|
||||
while ImageStat.Stat(self.image.crop((0, 0, diff, heightImg))).var[0] < fixedThreshold and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
self.image = self.image.crop((diff, 0, widthImg, heightImg))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# down
|
||||
while ImageStat.Stat(self.image.crop((0, heightImg - diff, widthImg, heightImg))).var[0] < fixedThreshold\
|
||||
and diff < heightImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
|
||||
widthImg, heightImg = self.image.size
|
||||
diff = delta
|
||||
# right
|
||||
while ImageStat.Stat(self.image.crop((widthImg - diff, 0, widthImg, heightImg))).var[0] < fixedThreshold\
|
||||
and diff < widthImg:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
|
||||
|
||||
|
||||
class Cover:
|
||||
def __init__(self, source, target, opt, tomeNumber):
|
||||
self.options = opt
|
||||
self.source = source
|
||||
self.target = target
|
||||
if tomeNumber == 0:
|
||||
self.tomeNumber = 1
|
||||
else:
|
||||
self.tomeNumber = tomeNumber
|
||||
if self.tomeNumber in self.options.remoteCovers:
|
||||
try:
|
||||
source = urlopen(Request(quote(self.options.remoteCovers[self.tomeNumber]).replace('%3A', ':', 1),
|
||||
headers={'User-Agent': 'KindleComicConverter/' + __version__})).read()
|
||||
self.image = Image.open(BytesIO(source))
|
||||
self.processExternal()
|
||||
except Exception:
|
||||
self.image = Image.open(source)
|
||||
self.processInternal()
|
||||
else:
|
||||
self.image = Image.open(source)
|
||||
self.processInternal()
|
||||
|
||||
def processInternal(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image = self.trim()
|
||||
self.save()
|
||||
|
||||
def processExternal(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
|
||||
self.save()
|
||||
|
||||
def trim(self):
|
||||
bg = Image.new(self.image.mode, self.image.size, self.image.getpixel((0, 0)))
|
||||
diff = ImageChops.difference(self.image, bg)
|
||||
diff = ImageChops.add(diff, diff, 2.0, -100)
|
||||
bbox = diff.getbbox()
|
||||
if bbox:
|
||||
return self.image.crop(bbox)
|
||||
else:
|
||||
return self.image
|
||||
|
||||
def save(self):
|
||||
try:
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=80)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to process downloaded cover.')
|
||||
|
||||
def saveToKindle(self, kindle, asin):
|
||||
self.image = self.image.resize((300, 470), Image.ANTIALIAS).convert('L')
|
||||
try:
|
||||
self.image.save(os.path.join(kindle.path.split('documents')[0], 'system', 'thumbnails',
|
||||
'thumbnail_' + asin + '_EBOK_portrait.jpg'), 'JPEG')
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to upload cover.')
|
||||
1990
kcc/rarfile.py
1990
kcc/rarfile.py
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
273
kindlecomicconverter/KCC_ui.py
Normal file
273
kindlecomicconverter/KCC_ui.py
Normal file
@@ -0,0 +1,273 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui\KCC.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.8.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_mainWindow(object):
|
||||
def setupUi(self, mainWindow):
|
||||
mainWindow.setObjectName("mainWindow")
|
||||
mainWindow.resize(450, 400)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
mainWindow.setWindowIcon(icon)
|
||||
self.centralWidget = QtWidgets.QWidget(mainWindow)
|
||||
self.centralWidget.setObjectName("centralWidget")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
|
||||
self.gridLayout.setContentsMargins(-1, -1, -1, 5)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.progressBar = QtWidgets.QProgressBar(self.centralWidget)
|
||||
self.progressBar.setMinimumSize(QtCore.QSize(0, 30))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.progressBar.setFont(font)
|
||||
self.progressBar.setVisible(False)
|
||||
self.progressBar.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter)
|
||||
self.progressBar.setObjectName("progressBar")
|
||||
self.gridLayout.addWidget(self.progressBar, 1, 0, 1, 2)
|
||||
self.jobList = QtWidgets.QListWidget(self.centralWidget)
|
||||
self.jobList.setStyleSheet("QListWidget#jobList {background:#ffffff;background-image:url(:/Other/icons/list_background.png);background-position:center center;background-repeat:no-repeat;color:rgb(0,0,0);}")
|
||||
self.jobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.jobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.jobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.jobList.setObjectName("jobList")
|
||||
self.gridLayout.addWidget(self.jobList, 2, 0, 1, 2)
|
||||
self.customWidget = QtWidgets.QWidget(self.centralWidget)
|
||||
self.customWidget.setVisible(False)
|
||||
self.customWidget.setObjectName("customWidget")
|
||||
self.gridLayout_3 = QtWidgets.QGridLayout(self.customWidget)
|
||||
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout_3.setObjectName("gridLayout_3")
|
||||
self.hLabel = QtWidgets.QLabel(self.customWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.hLabel.sizePolicy().hasHeightForWidth())
|
||||
self.hLabel.setSizePolicy(sizePolicy)
|
||||
self.hLabel.setObjectName("hLabel")
|
||||
self.gridLayout_3.addWidget(self.hLabel, 0, 2, 1, 1)
|
||||
self.widthBox = QtWidgets.QSpinBox(self.customWidget)
|
||||
self.widthBox.setMaximum(2160)
|
||||
self.widthBox.setObjectName("widthBox")
|
||||
self.gridLayout_3.addWidget(self.widthBox, 0, 1, 1, 1)
|
||||
self.wLabel = QtWidgets.QLabel(self.customWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.wLabel.sizePolicy().hasHeightForWidth())
|
||||
self.wLabel.setSizePolicy(sizePolicy)
|
||||
self.wLabel.setObjectName("wLabel")
|
||||
self.gridLayout_3.addWidget(self.wLabel, 0, 0, 1, 1)
|
||||
self.heightBox = QtWidgets.QSpinBox(self.customWidget)
|
||||
self.heightBox.setMaximum(3840)
|
||||
self.heightBox.setObjectName("heightBox")
|
||||
self.gridLayout_3.addWidget(self.heightBox, 0, 3, 1, 1)
|
||||
self.gridLayout.addWidget(self.customWidget, 6, 0, 1, 2)
|
||||
self.optionWidget = QtWidgets.QWidget(self.centralWidget)
|
||||
self.optionWidget.setObjectName("optionWidget")
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout(self.optionWidget)
|
||||
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.mangaBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.mangaBox.setObjectName("mangaBox")
|
||||
self.gridLayout_2.addWidget(self.mangaBox, 0, 0, 1, 1)
|
||||
self.rotateBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.rotateBox.setTristate(True)
|
||||
self.rotateBox.setObjectName("rotateBox")
|
||||
self.gridLayout_2.addWidget(self.rotateBox, 0, 1, 1, 1)
|
||||
self.qualityBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.qualityBox.setTristate(True)
|
||||
self.qualityBox.setObjectName("qualityBox")
|
||||
self.gridLayout_2.addWidget(self.qualityBox, 0, 2, 1, 1)
|
||||
self.webtoonBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.webtoonBox.setObjectName("webtoonBox")
|
||||
self.gridLayout_2.addWidget(self.webtoonBox, 1, 0, 1, 1)
|
||||
self.upscaleBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.upscaleBox.setTristate(True)
|
||||
self.upscaleBox.setObjectName("upscaleBox")
|
||||
self.gridLayout_2.addWidget(self.upscaleBox, 1, 1, 1, 1)
|
||||
self.gammaBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.gammaBox.setObjectName("gammaBox")
|
||||
self.gridLayout_2.addWidget(self.gammaBox, 1, 2, 1, 1)
|
||||
self.borderBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.borderBox.setTristate(True)
|
||||
self.borderBox.setObjectName("borderBox")
|
||||
self.gridLayout_2.addWidget(self.borderBox, 2, 0, 1, 1)
|
||||
self.outputSplit = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.outputSplit.setObjectName("outputSplit")
|
||||
self.gridLayout_2.addWidget(self.outputSplit, 2, 1, 1, 1)
|
||||
self.colorBox = QtWidgets.QCheckBox(self.optionWidget)
|
||||
self.colorBox.setObjectName("colorBox")
|
||||
self.gridLayout_2.addWidget(self.colorBox, 2, 2, 1, 1)
|
||||
self.gridLayout.addWidget(self.optionWidget, 4, 0, 1, 2)
|
||||
self.gammaWidget = QtWidgets.QWidget(self.centralWidget)
|
||||
self.gammaWidget.setVisible(False)
|
||||
self.gammaWidget.setObjectName("gammaWidget")
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.gammaWidget)
|
||||
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
self.gammaLabel = QtWidgets.QLabel(self.gammaWidget)
|
||||
self.gammaLabel.setObjectName("gammaLabel")
|
||||
self.horizontalLayout_2.addWidget(self.gammaLabel)
|
||||
self.gammaSlider = QtWidgets.QSlider(self.gammaWidget)
|
||||
self.gammaSlider.setMaximum(250)
|
||||
self.gammaSlider.setSingleStep(5)
|
||||
self.gammaSlider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.gammaSlider.setObjectName("gammaSlider")
|
||||
self.horizontalLayout_2.addWidget(self.gammaSlider)
|
||||
self.gridLayout.addWidget(self.gammaWidget, 5, 0, 1, 2)
|
||||
self.toolWidget = QtWidgets.QWidget(self.centralWidget)
|
||||
self.toolWidget.setObjectName("toolWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.toolWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.editorButton = QtWidgets.QPushButton(self.toolWidget)
|
||||
self.editorButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/editor.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.editorButton.setIcon(icon1)
|
||||
self.editorButton.setObjectName("editorButton")
|
||||
self.horizontalLayout.addWidget(self.editorButton)
|
||||
self.wikiButton = QtWidgets.QPushButton(self.toolWidget)
|
||||
self.wikiButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/wiki.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.wikiButton.setIcon(icon2)
|
||||
self.wikiButton.setObjectName("wikiButton")
|
||||
self.horizontalLayout.addWidget(self.wikiButton)
|
||||
self.gridLayout.addWidget(self.toolWidget, 0, 0, 1, 2)
|
||||
self.buttonWidget = QtWidgets.QWidget(self.centralWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.buttonWidget.sizePolicy().hasHeightForWidth())
|
||||
self.buttonWidget.setSizePolicy(sizePolicy)
|
||||
self.buttonWidget.setObjectName("buttonWidget")
|
||||
self.gridLayout_4 = QtWidgets.QGridLayout(self.buttonWidget)
|
||||
self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout_4.setObjectName("gridLayout_4")
|
||||
self.directoryButton = QtWidgets.QPushButton(self.buttonWidget)
|
||||
self.directoryButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon3 = QtGui.QIcon()
|
||||
icon3.addPixmap(QtGui.QPixmap(":/Other/icons/folder_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.directoryButton.setIcon(icon3)
|
||||
self.directoryButton.setObjectName("directoryButton")
|
||||
self.gridLayout_4.addWidget(self.directoryButton, 0, 0, 1, 1)
|
||||
self.fileButton = QtWidgets.QPushButton(self.buttonWidget)
|
||||
self.fileButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon4 = QtGui.QIcon()
|
||||
icon4.addPixmap(QtGui.QPixmap(":/Other/icons/document_new.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.fileButton.setIcon(icon4)
|
||||
self.fileButton.setObjectName("fileButton")
|
||||
self.gridLayout_4.addWidget(self.fileButton, 0, 3, 1, 1)
|
||||
self.deviceBox = QtWidgets.QComboBox(self.buttonWidget)
|
||||
self.deviceBox.setMinimumSize(QtCore.QSize(0, 28))
|
||||
self.deviceBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.deviceBox.setObjectName("deviceBox")
|
||||
self.gridLayout_4.addWidget(self.deviceBox, 1, 0, 1, 1)
|
||||
self.formatBox = QtWidgets.QComboBox(self.buttonWidget)
|
||||
self.formatBox.setMinimumSize(QtCore.QSize(0, 28))
|
||||
self.formatBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)
|
||||
self.formatBox.setObjectName("formatBox")
|
||||
self.gridLayout_4.addWidget(self.formatBox, 1, 3, 1, 1)
|
||||
self.convertButton = QtWidgets.QPushButton(self.buttonWidget)
|
||||
self.convertButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.convertButton.setFont(font)
|
||||
icon5 = QtGui.QIcon()
|
||||
icon5.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.convertButton.setIcon(icon5)
|
||||
self.convertButton.setObjectName("convertButton")
|
||||
self.gridLayout_4.addWidget(self.convertButton, 1, 2, 1, 1)
|
||||
self.clearButton = QtWidgets.QPushButton(self.buttonWidget)
|
||||
self.clearButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon6 = QtGui.QIcon()
|
||||
icon6.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.clearButton.setIcon(icon6)
|
||||
self.clearButton.setObjectName("clearButton")
|
||||
self.gridLayout_4.addWidget(self.clearButton, 0, 2, 1, 1)
|
||||
self.directoryButton.raise_()
|
||||
self.clearButton.raise_()
|
||||
self.fileButton.raise_()
|
||||
self.deviceBox.raise_()
|
||||
self.convertButton.raise_()
|
||||
self.formatBox.raise_()
|
||||
self.gridLayout.addWidget(self.buttonWidget, 3, 0, 1, 2)
|
||||
mainWindow.setCentralWidget(self.centralWidget)
|
||||
self.statusBar = QtWidgets.QStatusBar(mainWindow)
|
||||
self.statusBar.setSizeGripEnabled(False)
|
||||
self.statusBar.setObjectName("statusBar")
|
||||
mainWindow.setStatusBar(self.statusBar)
|
||||
|
||||
self.retranslateUi(mainWindow)
|
||||
QtCore.QMetaObject.connectSlotsByName(mainWindow)
|
||||
mainWindow.setTabOrder(self.convertButton, self.clearButton)
|
||||
mainWindow.setTabOrder(self.clearButton, self.directoryButton)
|
||||
mainWindow.setTabOrder(self.directoryButton, self.fileButton)
|
||||
mainWindow.setTabOrder(self.fileButton, self.deviceBox)
|
||||
mainWindow.setTabOrder(self.deviceBox, self.formatBox)
|
||||
mainWindow.setTabOrder(self.formatBox, self.mangaBox)
|
||||
mainWindow.setTabOrder(self.mangaBox, self.rotateBox)
|
||||
mainWindow.setTabOrder(self.rotateBox, self.qualityBox)
|
||||
mainWindow.setTabOrder(self.qualityBox, self.webtoonBox)
|
||||
mainWindow.setTabOrder(self.webtoonBox, self.upscaleBox)
|
||||
mainWindow.setTabOrder(self.upscaleBox, self.gammaBox)
|
||||
mainWindow.setTabOrder(self.gammaBox, self.borderBox)
|
||||
mainWindow.setTabOrder(self.borderBox, self.outputSplit)
|
||||
mainWindow.setTabOrder(self.outputSplit, self.colorBox)
|
||||
mainWindow.setTabOrder(self.colorBox, self.editorButton)
|
||||
mainWindow.setTabOrder(self.editorButton, self.wikiButton)
|
||||
mainWindow.setTabOrder(self.wikiButton, self.jobList)
|
||||
mainWindow.setTabOrder(self.jobList, self.gammaSlider)
|
||||
mainWindow.setTabOrder(self.gammaSlider, self.widthBox)
|
||||
mainWindow.setTabOrder(self.widthBox, self.heightBox)
|
||||
|
||||
def retranslateUi(self, mainWindow):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
mainWindow.setWindowTitle(_translate("mainWindow", "Kindle Comic Converter"))
|
||||
self.hLabel.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Resolution of the target device.</p></body></html>"))
|
||||
self.hLabel.setText(_translate("mainWindow", "Custom height:"))
|
||||
self.widthBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Resolution of the target device.</p></body></html>"))
|
||||
self.wLabel.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Resolution of the target device.</p></body></html>"))
|
||||
self.wLabel.setText(_translate("mainWindow", "Custom width:"))
|
||||
self.heightBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Resolution of the target device.</p></body></html>"))
|
||||
self.mangaBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Enable right-to-left reading.</p></body></html>"))
|
||||
self.mangaBox.setText(_translate("mainWindow", "Manga mode"))
|
||||
self.rotateBox.setToolTip(_translate("mainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Split<br/></span>Double page spreads will be cut into two separate pages.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Rotate and split<br/></span>Double page spreads will be displayed twice. First rotated and then split. </p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Rotate<br/></span>Double page spreads will be rotated.</p></body></html>"))
|
||||
self.rotateBox.setText(_translate("mainWindow", "Spread splitter"))
|
||||
self.qualityBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - 4 panels<br/></span>Zoom each corner separately.</p><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - 2 panels<br/></span>Zoom only the top and bottom of the page.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - 4 high-quality panels<br/></span>Zoom each corner separately. Try to increase the quality of magnification. Check wiki for more details.</p></body></html>"))
|
||||
self.qualityBox.setText(_translate("mainWindow", "Panel View 4/2/HQ"))
|
||||
self.webtoonBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Enable special parsing mode for Korean Webtoons.</p></body></html>"))
|
||||
self.webtoonBox.setText(_translate("mainWindow", "Webtoon mode"))
|
||||
self.upscaleBox.setToolTip(_translate("mainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Nothing<br/></span>Images smaller than device resolution will not be resized.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - Stretching<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be not preserved.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Upscaling<br/></span>Images smaller than device resolution will be resized. Aspect ratio will be preserved.</p></body></html>"))
|
||||
self.upscaleBox.setText(_translate("mainWindow", "Stretch/Upscale"))
|
||||
self.gammaBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Disable automatic gamma correction.</p></body></html>"))
|
||||
self.gammaBox.setText(_translate("mainWindow", "Custom gamma"))
|
||||
self.borderBox.setToolTip(_translate("mainWindow", "<html><head/><body><p><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Autodetection<br/></span>The color of margins fill will be detected automatically.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Indeterminate - White<br/></span>Margins will be filled with white color.</p><p><span style=\" font-weight:600; text-decoration: underline;\">Checked - Black<br/></span>Margins will be filled with black color.</p></body></html>"))
|
||||
self.borderBox.setText(_translate("mainWindow", "W/B margins"))
|
||||
self.outputSplit.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Unchecked - Automatic mode<br/></span>The output will be split automatically.</p><p style=\'white-space:pre\'><span style=\" font-weight:600; text-decoration: underline;\">Checked - Volume mode<br/></span>Every subdirectory will be considered as a separate volume.</p></body></html>"))
|
||||
self.outputSplit.setText(_translate("mainWindow", "Output split"))
|
||||
self.colorBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Disable conversion to grayscale.</p></body></html>"))
|
||||
self.colorBox.setText(_translate("mainWindow", "Color mode"))
|
||||
self.gammaLabel.setText(_translate("mainWindow", "Gamma: Auto"))
|
||||
self.editorButton.setText(_translate("mainWindow", "Editor"))
|
||||
self.editorButton.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to edit directory.</p></body></html>"))
|
||||
self.wikiButton.setText(_translate("mainWindow", "Wiki"))
|
||||
self.directoryButton.setToolTip(_translate("mainWindow", "<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>"))
|
||||
self.directoryButton.setText(_translate("mainWindow", "Add directory"))
|
||||
self.fileButton.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Add CBR, CBZ, CB7 or PDF file to queue.</p></body></html>"))
|
||||
self.fileButton.setText(_translate("mainWindow", "Add file"))
|
||||
self.deviceBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Target device.</p></body></html>"))
|
||||
self.formatBox.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Output format.</p></body></html>"))
|
||||
self.convertButton.setToolTip(_translate("mainWindow", "<html><head/><body><p style=\'white-space:pre\'>Shift+Click to select the output directory.</p></body></html>"))
|
||||
self.convertButton.setText(_translate("mainWindow", "Convert"))
|
||||
self.clearButton.setText(_translate("mainWindow", "Clear list"))
|
||||
|
||||
from . import KCC_rc
|
||||
116
kindlecomicconverter/KCC_ui_editor.py
Normal file
116
kindlecomicconverter/KCC_ui_editor.py
Normal file
@@ -0,0 +1,116 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui\MetaEditor.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.6
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
class Ui_editorDialog(object):
|
||||
def setupUi(self, editorDialog):
|
||||
editorDialog.setObjectName("editorDialog")
|
||||
editorDialog.resize(400, 260)
|
||||
editorDialog.setMinimumSize(QtCore.QSize(400, 260))
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(":/Icon/icons/comic2ebook.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
editorDialog.setWindowIcon(icon)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(editorDialog)
|
||||
self.verticalLayout.setContentsMargins(-1, -1, -1, 5)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.editorWidget = QtWidgets.QWidget(editorDialog)
|
||||
self.editorWidget.setObjectName("editorWidget")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.editorWidget)
|
||||
self.gridLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label_1 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_1.setObjectName("label_1")
|
||||
self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
|
||||
self.seriesLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.seriesLine.setObjectName("seriesLine")
|
||||
self.gridLayout.addWidget(self.seriesLine, 0, 1, 1, 1)
|
||||
self.label_2 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
|
||||
self.volumeLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.volumeLine.setObjectName("volumeLine")
|
||||
self.gridLayout.addWidget(self.volumeLine, 1, 1, 1, 1)
|
||||
self.label_3 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1)
|
||||
self.numberLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.numberLine.setObjectName("numberLine")
|
||||
self.gridLayout.addWidget(self.numberLine, 2, 1, 1, 1)
|
||||
self.label_4 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.gridLayout.addWidget(self.label_4, 3, 0, 1, 1)
|
||||
self.writerLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.writerLine.setObjectName("writerLine")
|
||||
self.gridLayout.addWidget(self.writerLine, 3, 1, 1, 1)
|
||||
self.label_5 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.gridLayout.addWidget(self.label_5, 4, 0, 1, 1)
|
||||
self.pencillerLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.pencillerLine.setObjectName("pencillerLine")
|
||||
self.gridLayout.addWidget(self.pencillerLine, 4, 1, 1, 1)
|
||||
self.label_6 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1)
|
||||
self.inkerLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.inkerLine.setObjectName("inkerLine")
|
||||
self.gridLayout.addWidget(self.inkerLine, 5, 1, 1, 1)
|
||||
self.label_7 = QtWidgets.QLabel(self.editorWidget)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.gridLayout.addWidget(self.label_7, 6, 0, 1, 1)
|
||||
self.coloristLine = QtWidgets.QLineEdit(self.editorWidget)
|
||||
self.coloristLine.setObjectName("coloristLine")
|
||||
self.gridLayout.addWidget(self.coloristLine, 6, 1, 1, 1)
|
||||
self.verticalLayout.addWidget(self.editorWidget)
|
||||
self.optionWidget = QtWidgets.QWidget(editorDialog)
|
||||
self.optionWidget.setObjectName("optionWidget")
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.optionWidget)
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.statusLabel = QtWidgets.QLabel(self.optionWidget)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.statusLabel.sizePolicy().hasHeightForWidth())
|
||||
self.statusLabel.setSizePolicy(sizePolicy)
|
||||
self.statusLabel.setText("")
|
||||
self.statusLabel.setObjectName("statusLabel")
|
||||
self.horizontalLayout.addWidget(self.statusLabel)
|
||||
self.okButton = QtWidgets.QPushButton(self.optionWidget)
|
||||
self.okButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap(":/Other/icons/convert.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.okButton.setIcon(icon1)
|
||||
self.okButton.setObjectName("okButton")
|
||||
self.horizontalLayout.addWidget(self.okButton)
|
||||
self.cancelButton = QtWidgets.QPushButton(self.optionWidget)
|
||||
self.cancelButton.setMinimumSize(QtCore.QSize(0, 30))
|
||||
icon2 = QtGui.QIcon()
|
||||
icon2.addPixmap(QtGui.QPixmap(":/Other/icons/clear.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.cancelButton.setIcon(icon2)
|
||||
self.cancelButton.setObjectName("cancelButton")
|
||||
self.horizontalLayout.addWidget(self.cancelButton)
|
||||
self.verticalLayout.addWidget(self.optionWidget)
|
||||
|
||||
self.retranslateUi(editorDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(editorDialog)
|
||||
|
||||
def retranslateUi(self, editorDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
editorDialog.setWindowTitle(_translate("editorDialog", "Metadata editor"))
|
||||
self.label_1.setText(_translate("editorDialog", "Series:"))
|
||||
self.label_2.setText(_translate("editorDialog", "Volume:"))
|
||||
self.label_3.setText(_translate("editorDialog", "Number:"))
|
||||
self.label_4.setText(_translate("editorDialog", "Writer:"))
|
||||
self.label_5.setText(_translate("editorDialog", "Penciller:"))
|
||||
self.label_6.setText(_translate("editorDialog", "Inker:"))
|
||||
self.label_7.setText(_translate("editorDialog", "Colorist:"))
|
||||
self.okButton.setText(_translate("editorDialog", "Save"))
|
||||
self.cancelButton.setText(_translate("editorDialog", "Cancel"))
|
||||
|
||||
from . import KCC_rc
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '5.0'
|
||||
__version__ = '5.5.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__copyright__ = '2012-2019, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -23,16 +23,12 @@ import sys
|
||||
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
|
||||
from PIL import Image, ImageChops, ImageOps, ImageDraw
|
||||
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))
|
||||
@@ -71,8 +67,7 @@ def mergeDirectory(work):
|
||||
result = Image.new('RGB', (targetWidth, targetHeight))
|
||||
y = 0
|
||||
for i in imagesValid:
|
||||
img = Image.open(i)
|
||||
img = img.convert('RGB')
|
||||
img = Image.open(i).convert('RGB')
|
||||
if img.size[0] < targetWidth:
|
||||
img = ImageOps.fit(img, (targetWidth, img.size[1]), method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
result.paste(img, (0, y))
|
||||
@@ -81,33 +76,11 @@ def mergeDirectory(work):
|
||||
savePath = os.path.split(imagesValid[0])
|
||||
result.save(os.path.join(savePath[0], os.path.splitext(savePath[1])[0] + '.png'), 'PNG')
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1])
|
||||
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
|
||||
|
||||
|
||||
def sanitizePanelSize(panel, opt):
|
||||
newPanels = []
|
||||
if panel[2] > 6 * opt.height:
|
||||
diff = int(panel[2] / 8)
|
||||
newPanels.append([panel[0], panel[1] - diff * 7, diff])
|
||||
newPanels.append([panel[1] - diff * 7, panel[1] - diff * 6, diff])
|
||||
newPanels.append([panel[1] - diff * 6, panel[1] - diff * 5, diff])
|
||||
newPanels.append([panel[1] - diff * 5, panel[1] - diff * 4, diff])
|
||||
newPanels.append([panel[1] - diff * 4, panel[1] - diff * 3, diff])
|
||||
newPanels.append([panel[1] - diff * 3, panel[1] - diff * 2, diff])
|
||||
newPanels.append([panel[1] - diff * 2, panel[1] - diff, diff])
|
||||
newPanels.append([panel[1] - diff, panel[1], diff])
|
||||
elif panel[2] > 3 * opt.height:
|
||||
diff = int(panel[2] / 4)
|
||||
newPanels.append([panel[0], panel[1] - diff * 3, diff])
|
||||
newPanels.append([panel[1] - diff * 3, panel[1] - diff * 2, diff])
|
||||
newPanels.append([panel[1] - diff * 2, panel[1] - diff, diff])
|
||||
newPanels.append([panel[1] - diff, panel[1], diff])
|
||||
elif panel[2] > 1.5 * opt.height:
|
||||
newPanels.append([panel[0], panel[1] - int(panel[2] / 2), int(panel[2] / 2)])
|
||||
newPanels.append([panel[1] - int(panel[2] / 2), panel[1], int(panel[2] / 2)])
|
||||
else:
|
||||
newPanels = [panel]
|
||||
return newPanels
|
||||
def detectSolid(img):
|
||||
return not ImageChops.invert(img).getbbox() or not img.getbbox()
|
||||
|
||||
|
||||
def splitImageTick(output):
|
||||
@@ -120,61 +93,64 @@ def splitImageTick(output):
|
||||
splitWorkerPool.terminate()
|
||||
|
||||
|
||||
# noinspection PyUnboundLocalVariable
|
||||
def splitImage(work):
|
||||
try:
|
||||
path = work[0]
|
||||
name = work[1]
|
||||
opt = work[2]
|
||||
# Hardcoded options
|
||||
threshold = 1.0
|
||||
delta = 15
|
||||
fileExpanded = os.path.splitext(name)
|
||||
filePath = os.path.join(path, name)
|
||||
image = Image.open(filePath)
|
||||
image = image.convert('RGB')
|
||||
widthImg, heightImg = image.size
|
||||
imgOrg = Image.open(filePath).convert('RGB')
|
||||
imgProcess = Image.open(filePath).convert('1')
|
||||
widthImg, heightImg = imgOrg.size
|
||||
if heightImg > opt.height:
|
||||
if opt.debug:
|
||||
from PIL import ImageDraw
|
||||
debugImage = Image.open(filePath)
|
||||
draw = ImageDraw.Draw(debugImage)
|
||||
drawImg = Image.open(filePath).convert(mode='RGBA')
|
||||
draw = ImageDraw.Draw(drawImg)
|
||||
|
||||
# Find panels
|
||||
y1 = 0
|
||||
y2 = 15
|
||||
yWork = 0
|
||||
panelDetected = False
|
||||
panels = []
|
||||
while y2 < heightImg:
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] < threshold and y2 < heightImg:
|
||||
y2 += delta
|
||||
y2 -= delta
|
||||
y1Temp = y2
|
||||
y1 = y2 + delta
|
||||
y2 = y1 + delta
|
||||
while ImageStat.Stat(image.crop([0, y1, widthImg, y2])).var[0] >= threshold and y2 < heightImg:
|
||||
y1 += delta
|
||||
y2 += delta
|
||||
if y1 + delta >= heightImg:
|
||||
y1 = heightImg - 1
|
||||
y2Temp = y1
|
||||
if opt.debug:
|
||||
draw.line([(0, y1Temp), (widthImg, y1Temp)], fill=(0, 255, 0))
|
||||
draw.line([(0, y2Temp), (widthImg, y2Temp)], fill=(255, 0, 0))
|
||||
panelHeight = y2Temp - y1Temp
|
||||
if panelHeight > delta:
|
||||
# Panels that can't be cut nicely will be forcefully splitted
|
||||
panelsCleaned = sanitizePanelSize([y1Temp, y2Temp, panelHeight], opt)
|
||||
for panel in panelsCleaned:
|
||||
panels.append(panel)
|
||||
while yWork < heightImg:
|
||||
tmpImg = imgProcess.crop([0, yWork, widthImg, yWork + 4])
|
||||
solid = detectSolid(tmpImg)
|
||||
if not solid and not panelDetected:
|
||||
panelDetected = True
|
||||
panelY1 = yWork - 2
|
||||
if solid and panelDetected:
|
||||
panelDetected = False
|
||||
panelY2 = yWork + 6
|
||||
panels.append((panelY1, panelY2, panelY2 - panelY1))
|
||||
yWork += 5
|
||||
|
||||
# Split too big panels
|
||||
panelsProcessed = []
|
||||
for panel in panels:
|
||||
if panel[2] <= opt.height * 1.5:
|
||||
panelsProcessed.append(panel)
|
||||
elif panel[2] < opt.height * 2:
|
||||
diff = panel[2] - opt.height
|
||||
panelsProcessed.append((panel[0], panel[1] - diff, opt.height))
|
||||
panelsProcessed.append((panel[1] - opt.height, panel[1], opt.height))
|
||||
else:
|
||||
parts = round(panel[2] / opt.height)
|
||||
diff = panel[2] // parts
|
||||
for x in range(0, parts):
|
||||
panelsProcessed.append((panel[0] + (x * diff), panel[1] - ((parts - x - 1) * diff), diff))
|
||||
|
||||
if opt.debug:
|
||||
# noinspection PyUnboundLocalVariable
|
||||
debugImage.save(os.path.join(path, fileExpanded[0] + '-debug.png'), 'PNG')
|
||||
for panel in panelsProcessed:
|
||||
draw.rectangle([(0, panel[0]), (widthImg, panel[1])], (0, 255, 0, 128), (0, 0, 255, 255))
|
||||
debugImage = Image.alpha_composite(imgOrg.convert(mode='RGBA'), drawImg)
|
||||
debugImage.save(os.path.join(path, os.path.splitext(name)[0] + '-debug.png'), 'PNG')
|
||||
|
||||
# Create virtual pages
|
||||
pages = []
|
||||
currentPage = []
|
||||
pageLeft = opt.height
|
||||
panelNumber = 0
|
||||
for panel in panels:
|
||||
for panel in panelsProcessed:
|
||||
if pageLeft - panel[2] > 0:
|
||||
pageLeft -= panel[2]
|
||||
currentPage.append(panelNumber)
|
||||
@@ -194,21 +170,21 @@ def splitImage(work):
|
||||
pageHeight = 0
|
||||
targetHeight = 0
|
||||
for panel in page:
|
||||
pageHeight += panels[panel][2]
|
||||
if pageHeight > delta:
|
||||
pageHeight += panelsProcessed[panel][2]
|
||||
if pageHeight > 15:
|
||||
newPage = Image.new('RGB', (widthImg, pageHeight))
|
||||
for panel in page:
|
||||
panelImg = image.crop([0, panels[panel][0], widthImg, panels[panel][1]])
|
||||
panelImg = imgOrg.crop([0, panelsProcessed[panel][0], widthImg, panelsProcessed[panel][1]])
|
||||
newPage.paste(panelImg, (0, targetHeight))
|
||||
targetHeight += panels[panel][2]
|
||||
newPage.save(os.path.join(path, fileExpanded[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
||||
targetHeight += panelsProcessed[panel][2]
|
||||
newPage.save(os.path.join(path, os.path.splitext(name)[0] + '-' + str(pageNumber) + '.png'), 'PNG')
|
||||
pageNumber += 1
|
||||
os.remove(filePath)
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1])
|
||||
return str(sys.exc_info()[1]), sanitizeTrace(sys.exc_info()[2])
|
||||
|
||||
|
||||
def main(argv=None, qtGUI=None):
|
||||
def main(argv=None, qtgui=None):
|
||||
global options, GUI, splitWorkerPool, splitWorkerOutput, mergeWorkerPool, mergeWorkerOutput
|
||||
parser = OptionParser(usage="Usage: kcc-c2p [options] comic_folder", add_help_option=False)
|
||||
mainOptions = OptionGroup(parser, "MANDATORY")
|
||||
@@ -220,14 +196,14 @@ def main(argv=None, qtGUI=None):
|
||||
mainOptions.add_option("-m", "--merge", action="store_true", dest="merge", default=False,
|
||||
help="Combine every directory into a single image before splitting")
|
||||
otherOptions.add_option("-d", "--debug", action="store_true", dest="debug", default=False,
|
||||
help="Create debug file for every splitted image")
|
||||
help="Create debug file for every split image")
|
||||
otherOptions.add_option("-h", "--help", action="help",
|
||||
help="Show this help message and exit")
|
||||
parser.add_option_group(mainOptions)
|
||||
parser.add_option_group(otherOptions)
|
||||
options, args = parser.parse_args(argv)
|
||||
if qtGUI:
|
||||
GUI = qtGUI
|
||||
if qtgui:
|
||||
GUI = qtgui
|
||||
else:
|
||||
GUI = None
|
||||
if len(args) != 1:
|
||||
@@ -242,15 +218,15 @@ def main(argv=None, qtGUI=None):
|
||||
work = []
|
||||
pagenumber = 1
|
||||
splitWorkerOutput = []
|
||||
splitWorkerPool = Pool()
|
||||
splitWorkerPool = Pool(maxtasksperchild=10)
|
||||
if options.merge:
|
||||
print("Merging images...")
|
||||
directoryNumer = 1
|
||||
mergeWork = []
|
||||
mergeWorkerOutput = []
|
||||
mergeWorkerPool = Pool()
|
||||
mergeWorkerPool = Pool(maxtasksperchild=10)
|
||||
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
|
||||
@@ -267,9 +243,10 @@ def main(argv=None, qtGUI=None):
|
||||
raise UserWarning("Conversion interrupted.")
|
||||
if len(mergeWorkerOutput) > 0:
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0])
|
||||
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
|
||||
@@ -290,7 +267,8 @@ def main(argv=None, qtGUI=None):
|
||||
raise UserWarning("Conversion interrupted.")
|
||||
if len(splitWorkerOutput) > 0:
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0])
|
||||
raise RuntimeError("One of workers crashed. Cause: " + splitWorkerOutput[0][0],
|
||||
splitWorkerOutput[0][1])
|
||||
if options.inPlace:
|
||||
rmtree(options.sourceDir)
|
||||
move(options.targetDir, options.sourceDir)
|
||||
81
kindlecomicconverter/comicarchive.py
Normal file
81
kindlecomicconverter/comicarchive.py
Normal file
@@ -0,0 +1,81 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# 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
|
||||
from psutil import Popen
|
||||
from shutil import move
|
||||
from subprocess import STDOUT, PIPE
|
||||
from xml.dom.minidom import parseString
|
||||
from xml.parsers.expat import ExpatError
|
||||
|
||||
|
||||
class ComicArchive:
|
||||
def __init__(self, filepath):
|
||||
self.filepath = filepath
|
||||
self.type = None
|
||||
if not os.path.isfile(self.filepath):
|
||||
raise OSError('File not found.')
|
||||
process = Popen('7z l -y -p1 "' + self.filepath + '"', stderr=STDOUT, stdout=PIPE, stdin=PIPE, shell=True)
|
||||
for line in process.stdout:
|
||||
if b'Type =' in line:
|
||||
self.type = line.rstrip().decode().split(' = ')[1].upper()
|
||||
break
|
||||
process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise OSError('Archive is corrupted or encrypted.')
|
||||
elif self.type not in ['7Z', 'RAR', 'RAR5', 'ZIP']:
|
||||
raise OSError('Unsupported archive format.')
|
||||
|
||||
def extract(self, targetdir):
|
||||
if not os.path.isdir(targetdir):
|
||||
raise OSError('Target directory don\'t exist.')
|
||||
process = Popen('7z x -y -xr!__MACOSX -xr!.DS_Store -xr!thumbs.db -xr!Thumbs.db -o"' + targetdir + '" "' +
|
||||
self.filepath + '"', stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||
process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise OSError('Failed to extract archive.')
|
||||
tdir = os.listdir(targetdir)
|
||||
if 'ComicInfo.xml' in tdir:
|
||||
tdir.remove('ComicInfo.xml')
|
||||
if len(tdir) == 1 and os.path.isdir(os.path.join(targetdir, tdir[0])):
|
||||
for f in os.listdir(os.path.join(targetdir, tdir[0])):
|
||||
move(os.path.join(targetdir, tdir[0], f), targetdir)
|
||||
os.rmdir(os.path.join(targetdir, tdir[0]))
|
||||
return targetdir
|
||||
|
||||
def addFile(self, sourcefile):
|
||||
if self.type in ['RAR', 'RAR5']:
|
||||
raise NotImplementedError
|
||||
process = Popen('7z a -y "' + self.filepath + '" "' + sourcefile + '"',
|
||||
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||
process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise OSError('Failed to add the file.')
|
||||
|
||||
def extractMetadata(self):
|
||||
process = Popen('7z x -y -so "' + self.filepath + '" ComicInfo.xml',
|
||||
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||
xml = process.communicate()
|
||||
if process.returncode != 0:
|
||||
raise OSError('Failed to extract archive.')
|
||||
try:
|
||||
return parseString(xml[0])
|
||||
except ExpatError:
|
||||
return None
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Based on initial version of DualMetaFix. Copyright (C) 2013 Kevin Hendricks
|
||||
# Changes for KCC Copyright (C) 2014-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Changes for KCC Copyright (C) 2014-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -24,6 +24,7 @@ import shutil
|
||||
class DualMetaFixException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# palm database offset constants
|
||||
number_of_pdb_records = 76
|
||||
first_pdb_record = 78
|
||||
369
kindlecomicconverter/image.py
Executable file
369
kindlecomicconverter/image.py
Executable file
@@ -0,0 +1,369 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2010 Alex Yatskov
|
||||
# Copyright (C) 2011 Stanislav (proDOOMman) Kosolapov <prodoomman@gmail.com>
|
||||
# Copyright (c) 2016 Alberto Planas <aplanas@gmail.com>
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
from PIL import Image, ImageOps, ImageStat, ImageChops, ImageFilter
|
||||
from .shared import md5Checksum
|
||||
|
||||
|
||||
class ProfileData:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
Palette4 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x55, 0x55, 0x55,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xff, 0xff, 0xff
|
||||
]
|
||||
|
||||
Palette15 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11,
|
||||
0x22, 0x22, 0x22,
|
||||
0x33, 0x33, 0x33,
|
||||
0x44, 0x44, 0x44,
|
||||
0x55, 0x55, 0x55,
|
||||
0x66, 0x66, 0x66,
|
||||
0x77, 0x77, 0x77,
|
||||
0x88, 0x88, 0x88,
|
||||
0x99, 0x99, 0x99,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xbb, 0xbb, 0xbb,
|
||||
0xcc, 0xcc, 0xcc,
|
||||
0xdd, 0xdd, 0xdd,
|
||||
0xff, 0xff, 0xff,
|
||||
]
|
||||
|
||||
Palette16 = [
|
||||
0x00, 0x00, 0x00,
|
||||
0x11, 0x11, 0x11,
|
||||
0x22, 0x22, 0x22,
|
||||
0x33, 0x33, 0x33,
|
||||
0x44, 0x44, 0x44,
|
||||
0x55, 0x55, 0x55,
|
||||
0x66, 0x66, 0x66,
|
||||
0x77, 0x77, 0x77,
|
||||
0x88, 0x88, 0x88,
|
||||
0x99, 0x99, 0x99,
|
||||
0xaa, 0xaa, 0xaa,
|
||||
0xbb, 0xbb, 0xbb,
|
||||
0xcc, 0xcc, 0xcc,
|
||||
0xdd, 0xdd, 0xdd,
|
||||
0xee, 0xee, 0xee,
|
||||
0xff, 0xff, 0xff,
|
||||
]
|
||||
|
||||
PalleteNull = [
|
||||
]
|
||||
|
||||
Profiles = {
|
||||
'K1': ("Kindle 1", (600, 670), Palette4, 1.8),
|
||||
'K2': ("Kindle 2", (600, 670), Palette15, 1.8),
|
||||
'K34': ("Kindle Keyboard/Touch", (600, 800), Palette16, 1.8),
|
||||
'K578': ("Kindle", (600, 800), Palette16, 1.8),
|
||||
'KDX': ("Kindle DX/DXG", (824, 1000), Palette16, 1.8),
|
||||
'KPW': ("Kindle Paperwhite 1/2", (758, 1024), Palette16, 1.8),
|
||||
'KV': ("Kindle Paperwhite 3/4/Voyage/Oasis", (1072, 1448), Palette16, 1.8),
|
||||
'KO': ("Kindle Oasis 2", (1264, 1680), Palette16, 1.8),
|
||||
'KoMT': ("Kobo Mini/Touch", (600, 800), Palette16, 1.8),
|
||||
'KoG': ("Kobo Glo", (768, 1024), Palette16, 1.8),
|
||||
'KoGHD': ("Kobo Glo HD", (1072, 1448), Palette16, 1.8),
|
||||
'KoA': ("Kobo Aura", (758, 1024), Palette16, 1.8),
|
||||
'KoAHD': ("Kobo Aura HD", (1080, 1440), Palette16, 1.8),
|
||||
'KoAH2O': ("Kobo Aura H2O", (1080, 1430), Palette16, 1.8),
|
||||
'KoAO': ("Kobo Aura ONE", (1404, 1872), Palette16, 1.8),
|
||||
'KoF': ("Kobo Forma", (1440, 1920), Palette16, 1.8),
|
||||
'OTHER': ("Other", (0, 0), Palette16, 1.8),
|
||||
}
|
||||
|
||||
|
||||
class ComicPageParser:
|
||||
def __init__(self, source, options):
|
||||
Image.MAX_IMAGE_PIXELS = int(2048 * 2048 * 2048 // 4 // 3)
|
||||
self.opt = options
|
||||
self.source = source
|
||||
self.size = self.opt.profileData[1]
|
||||
self.payload = []
|
||||
self.image = Image.open(os.path.join(source[0], source[1])).convert('RGB')
|
||||
self.color = self.colorCheck()
|
||||
self.fill = self.fillCheck()
|
||||
self.splitCheck()
|
||||
|
||||
def getImageHistogram(self, image):
|
||||
histogram = image.histogram()
|
||||
if histogram[0] == 0:
|
||||
return -1
|
||||
elif histogram[255] == 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def splitCheck(self):
|
||||
width, height = self.image.size
|
||||
dstwidth, dstheight = self.size
|
||||
if (width > height) != (dstwidth > dstheight) and width <= dstheight and height <= dstwidth \
|
||||
and not self.opt.webtoon and self.opt.splitter == 1:
|
||||
self.payload.append(['R', self.source, self.image.rotate(90, Image.BICUBIC, True), self.color, self.fill])
|
||||
elif (width > height) != (dstwidth > dstheight) and not self.opt.webtoon:
|
||||
if self.opt.splitter != 1:
|
||||
if width > height:
|
||||
leftbox = (0, 0, int(width / 2), height)
|
||||
rightbox = (int(width / 2), 0, width, height)
|
||||
else:
|
||||
leftbox = (0, 0, width, int(height / 2))
|
||||
rightbox = (0, int(height / 2), width, height)
|
||||
if self.opt.righttoleft:
|
||||
pageone = self.image.crop(rightbox)
|
||||
pagetwo = self.image.crop(leftbox)
|
||||
else:
|
||||
pageone = self.image.crop(leftbox)
|
||||
pagetwo = self.image.crop(rightbox)
|
||||
self.payload.append(['S1', self.source, pageone, self.color, self.fill])
|
||||
self.payload.append(['S2', self.source, pagetwo, self.color, self.fill])
|
||||
if self.opt.splitter > 0:
|
||||
self.payload.append(['R', self.source, self.image.rotate(90, Image.BICUBIC, True),
|
||||
self.color, self.fill])
|
||||
else:
|
||||
self.payload.append(['N', self.source, self.image, self.color, self.fill])
|
||||
|
||||
def colorCheck(self):
|
||||
if self.opt.webtoon:
|
||||
return True
|
||||
else:
|
||||
img = self.image.copy()
|
||||
bands = img.getbands()
|
||||
if bands == ('R', 'G', 'B') or bands == ('R', 'G', 'B', 'A'):
|
||||
thumb = img.resize((40, 40))
|
||||
SSE, bias = 0, [0, 0, 0]
|
||||
bias = ImageStat.Stat(thumb).mean[:3]
|
||||
bias = [b - sum(bias) / 3 for b in bias]
|
||||
for pixel in thumb.getdata():
|
||||
mu = sum(pixel) / 3
|
||||
SSE += sum((pixel[i] - mu - bias[i]) * (pixel[i] - mu - bias[i]) for i in [0, 1, 2])
|
||||
MSE = float(SSE) / (40 * 40)
|
||||
if MSE > 22:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def fillCheck(self):
|
||||
if self.opt.bordersColor:
|
||||
return self.opt.bordersColor
|
||||
else:
|
||||
bw = self.image.convert('L').point(lambda x: 0 if x < 128 else 255, '1')
|
||||
imageBoxA = bw.getbbox()
|
||||
imageBoxB = ImageChops.invert(bw).getbbox()
|
||||
if imageBoxA is None or imageBoxB is None:
|
||||
surfaceB, surfaceW = 0, 0
|
||||
diff = 0
|
||||
else:
|
||||
surfaceB = (imageBoxA[2] - imageBoxA[0]) * (imageBoxA[3] - imageBoxA[1])
|
||||
surfaceW = (imageBoxB[2] - imageBoxB[0]) * (imageBoxB[3] - imageBoxB[1])
|
||||
diff = ((max(surfaceB, surfaceW) - min(surfaceB, surfaceW)) / min(surfaceB, surfaceW)) * 100
|
||||
if diff > 0.5:
|
||||
if surfaceW < surfaceB:
|
||||
return 'white'
|
||||
elif surfaceW > surfaceB:
|
||||
return 'black'
|
||||
else:
|
||||
fill = 0
|
||||
startY = 0
|
||||
while startY < bw.size[1]:
|
||||
if startY + 5 > bw.size[1]:
|
||||
startY = bw.size[1] - 5
|
||||
fill += self.getImageHistogram(bw.crop((0, startY, bw.size[0], startY + 5)))
|
||||
startY += 5
|
||||
startX = 0
|
||||
while startX < bw.size[0]:
|
||||
if startX + 5 > bw.size[0]:
|
||||
startX = bw.size[0] - 5
|
||||
fill += self.getImageHistogram(bw.crop((startX, 0, startX + 5, bw.size[1])))
|
||||
startX += 5
|
||||
if fill > 0:
|
||||
return 'black'
|
||||
else:
|
||||
return 'white'
|
||||
|
||||
|
||||
class ComicPage:
|
||||
def __init__(self, options, mode, path, image, color, fill):
|
||||
self.opt = options
|
||||
_, self.size, self.palette, self.gamma = self.opt.profileData
|
||||
if self.opt.hq:
|
||||
self.size = (int(self.size[0] * 1.5), int(self.size[1] * 1.5))
|
||||
self.image = image
|
||||
self.color = color
|
||||
self.fill = fill
|
||||
self.rotated = False
|
||||
self.orgPath = os.path.join(path[0], path[1])
|
||||
if 'N' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC'
|
||||
elif 'R' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-A'
|
||||
self.rotated = True
|
||||
elif 'S1' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-B'
|
||||
elif 'S2' in mode:
|
||||
self.targetPath = os.path.join(path[0], os.path.splitext(path[1])[0]) + '-KCC-C'
|
||||
|
||||
def saveToDir(self):
|
||||
try:
|
||||
flags = []
|
||||
if not self.opt.forcecolor and not self.opt.forcepng:
|
||||
self.image = self.image.convert('L')
|
||||
if self.rotated:
|
||||
flags.append('Rotated')
|
||||
if self.fill != 'white':
|
||||
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=85)
|
||||
return [md5Checksum(self.targetPath), flags, self.orgPath]
|
||||
except IOError as err:
|
||||
raise RuntimeError('Cannot save image. ' + str(err))
|
||||
|
||||
def autocontrastImage(self):
|
||||
gamma = self.opt.gamma
|
||||
if gamma < 0.1:
|
||||
gamma = self.gamma
|
||||
if self.gamma != 1.0 and self.color:
|
||||
gamma = 1.0
|
||||
if gamma == 1.0:
|
||||
self.image = ImageOps.autocontrast(self.image)
|
||||
else:
|
||||
self.image = ImageOps.autocontrast(Image.eval(self.image, lambda a: 255 * (a / 255.) ** gamma))
|
||||
|
||||
def quantizeImage(self):
|
||||
colors = len(self.palette) // 3
|
||||
if colors < 256:
|
||||
self.palette += self.palette[:3] * (256 - colors)
|
||||
palImg = Image.new('P', (1, 1))
|
||||
palImg.putpalette(self.palette)
|
||||
self.image = self.image.convert('L')
|
||||
self.image = self.image.convert('RGB')
|
||||
# Quantize is deprecated but new function call it internally anyway...
|
||||
self.image = self.image.quantize(palette=palImg)
|
||||
|
||||
def resizeImage(self):
|
||||
if self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
method = Image.BICUBIC
|
||||
else:
|
||||
method = Image.LANCZOS
|
||||
if self.opt.stretch or (self.opt.kfx and ('-KCC-B' in self.targetPath or '-KCC-C' in self.targetPath)):
|
||||
self.image = self.image.resize(self.size, method)
|
||||
elif self.image.size[0] <= self.size[0] and self.image.size[1] <= self.size[1] and not self.opt.upscale:
|
||||
if self.opt.format == 'CBZ' or self.opt.kfx:
|
||||
borderw = int((self.size[0] - self.image.size[0]) / 2)
|
||||
borderh = int((self.size[1] - self.image.size[1]) / 2)
|
||||
self.image = ImageOps.expand(self.image, border=(borderw, borderh), fill=self.fill)
|
||||
if self.image.size[0] != self.size[0] or self.image.size[1] != self.size[1]:
|
||||
self.image = ImageOps.fit(self.image, self.size, method=Image.BICUBIC, centering=(0.5, 0.5))
|
||||
else:
|
||||
if self.opt.format == 'CBZ' or self.opt.kfx:
|
||||
ratioDev = float(self.size[0]) / float(self.size[1])
|
||||
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
|
||||
diff = int(self.image.size[1] * ratioDev) - self.image.size[0]
|
||||
self.image = ImageOps.expand(self.image, border=(int(diff / 2), 0), fill=self.fill)
|
||||
elif (float(self.image.size[0]) / float(self.image.size[1])) > ratioDev:
|
||||
diff = int(self.image.size[0] / ratioDev) - self.image.size[1]
|
||||
self.image = ImageOps.expand(self.image, border=(0, int(diff / 2)), fill=self.fill)
|
||||
self.image = ImageOps.fit(self.image, self.size, method=method, centering=(0.5, 0.5))
|
||||
else:
|
||||
hpercent = self.size[1] / float(self.image.size[1])
|
||||
wsize = int((float(self.image.size[0]) * float(hpercent)))
|
||||
self.image = self.image.resize((wsize, self.size[1]), method)
|
||||
if self.image.size[0] > self.size[0] or self.image.size[1] > self.size[1]:
|
||||
self.image.thumbnail(self.size, Image.LANCZOS)
|
||||
|
||||
def getBoundingBox(self, tmptmg):
|
||||
min_margin = [int(0.005 * i + 0.5) for i in tmptmg.size]
|
||||
max_margin = [int(0.1 * i + 0.5) for i in tmptmg.size]
|
||||
bbox = tmptmg.getbbox()
|
||||
bbox = (
|
||||
max(0, min(max_margin[0], bbox[0] - min_margin[0])),
|
||||
max(0, min(max_margin[1], bbox[1] - min_margin[1])),
|
||||
min(tmptmg.size[0],
|
||||
max(tmptmg.size[0] - max_margin[0], bbox[2] + min_margin[0])),
|
||||
min(tmptmg.size[1],
|
||||
max(tmptmg.size[1] - max_margin[1], bbox[3] + min_margin[1])),
|
||||
)
|
||||
return bbox
|
||||
|
||||
def cropPageNumber(self, power):
|
||||
if self.fill != 'white':
|
||||
tmptmg = self.image.convert(mode='L')
|
||||
else:
|
||||
tmptmg = ImageOps.invert(self.image.convert(mode='L'))
|
||||
tmptmg = tmptmg.point(lambda x: x and 255)
|
||||
tmptmg = tmptmg.filter(ImageFilter.MinFilter(size=3))
|
||||
tmptmg = tmptmg.filter(ImageFilter.GaussianBlur(radius=5))
|
||||
tmptmg = tmptmg.point(lambda x: (x >= 16 * power) and x)
|
||||
self.image = self.image.crop(tmptmg.getbbox()) if tmptmg.getbbox() else self.image
|
||||
|
||||
def cropMargin(self, power):
|
||||
if self.fill != 'white':
|
||||
tmptmg = self.image.convert(mode='L')
|
||||
else:
|
||||
tmptmg = ImageOps.invert(self.image.convert(mode='L'))
|
||||
tmptmg = tmptmg.filter(ImageFilter.GaussianBlur(radius=3))
|
||||
tmptmg = tmptmg.point(lambda x: (x >= 16 * power) and x)
|
||||
self.image = self.image.crop(self.getBoundingBox(tmptmg)) if tmptmg.getbbox() else self.image
|
||||
|
||||
|
||||
class Cover:
|
||||
def __init__(self, source, target, opt, tomeid):
|
||||
self.options = opt
|
||||
self.source = source
|
||||
self.target = target
|
||||
if tomeid == 0:
|
||||
self.tomeid = 1
|
||||
else:
|
||||
self.tomeid = tomeid
|
||||
self.image = Image.open(source)
|
||||
self.process()
|
||||
|
||||
def process(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image = ImageOps.autocontrast(self.image)
|
||||
if not self.options.forcecolor:
|
||||
self.image = self.image.convert('L')
|
||||
self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
|
||||
self.save()
|
||||
|
||||
def save(self):
|
||||
try:
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=85)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to process downloaded cover.')
|
||||
|
||||
def saveToKindle(self, kindle, asin):
|
||||
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', optimize=1, quality=85)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to upload cover.')
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -29,8 +29,10 @@ class Kindle:
|
||||
self.coverSupport = False
|
||||
|
||||
def findDevice(self):
|
||||
for drive in psutil.disk_partitions(False):
|
||||
if 'removable' in drive[3] or 'vfat' in drive[2] or 'msdos' in drive[2]:
|
||||
for drive in reversed(psutil.disk_partitions(False)):
|
||||
if (drive[2] == 'FAT32' and drive[3] == 'rw,removable') or \
|
||||
(drive[2] == 'vfat' and 'rw' in drive[3]) or \
|
||||
(drive[2] == 'msdos' and 'rw' in drive[3]):
|
||||
if os.path.isdir(os.path.join(drive[1], 'system')) and \
|
||||
os.path.isdir(os.path.join(drive[1], 'documents')):
|
||||
return drive[1]
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -18,14 +18,9 @@
|
||||
|
||||
import os
|
||||
from xml.dom.minidom import parse, Document
|
||||
from re import compile
|
||||
from zipfile import is_zipfile, ZipFile, ZIP_DEFLATED
|
||||
from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
from .shared import removeFromZIP, check7ZFile as is_7zfile
|
||||
from . import rarfile
|
||||
from . import comicarchive
|
||||
|
||||
|
||||
class MetadataParser:
|
||||
@@ -39,50 +34,20 @@ class MetadataParser:
|
||||
'Inkers': [],
|
||||
'Colorists': [],
|
||||
'Summary': '',
|
||||
'MUid': '',
|
||||
'Bookmarks': []}
|
||||
self.rawdata = None
|
||||
self.compressor = None
|
||||
if self.source.endswith('.xml'):
|
||||
self.format = None
|
||||
if self.source.endswith('.xml') and os.path.exists(self.source):
|
||||
self.rawdata = parse(self.source)
|
||||
elif not self.source.endswith('.xml'):
|
||||
try:
|
||||
cbx = comicarchive.ComicArchive(self.source)
|
||||
self.rawdata = cbx.extractMetadata()
|
||||
self.format = cbx.type
|
||||
except OSError as e:
|
||||
raise UserWarning(e.strerror)
|
||||
if self.rawdata:
|
||||
self.parseXML()
|
||||
else:
|
||||
if is_zipfile(self.source):
|
||||
self.compressor = 'zip'
|
||||
with ZipFile(self.source) as zip_file:
|
||||
for member in zip_file.namelist():
|
||||
if member != 'ComicInfo.xml':
|
||||
continue
|
||||
with zip_file.open(member) as xml_file:
|
||||
self.rawdata = parse(xml_file)
|
||||
elif rarfile.is_rarfile(self.source):
|
||||
self.compressor = 'rar'
|
||||
with rarfile.RarFile(self.source) as rar_file:
|
||||
for member in rar_file.namelist():
|
||||
if member != 'ComicInfo.xml':
|
||||
continue
|
||||
with rar_file.open(member) as xml_file:
|
||||
self.rawdata = parse(xml_file)
|
||||
elif is_7zfile(self.source):
|
||||
self.compressor = '7z'
|
||||
workdir = mkdtemp('', 'KCC-')
|
||||
tmpXML = os.path.join(workdir, 'ComicInfo.xml')
|
||||
output = Popen('7za e "' + self.source + '" ComicInfo.xml -o"' + workdir + '"',
|
||||
stdout=PIPE, stderr=STDOUT, stdin=PIPE, shell=True)
|
||||
extracted = False
|
||||
for line in output.stdout:
|
||||
if b"Everything is Ok" in line or b"No files to process" in line:
|
||||
extracted = True
|
||||
if not extracted:
|
||||
rmtree(workdir)
|
||||
raise OSError('Failed to extract 7ZIP file.')
|
||||
if os.path.isfile(tmpXML):
|
||||
self.rawdata = parse(tmpXML)
|
||||
rmtree(workdir)
|
||||
else:
|
||||
raise OSError('Failed to detect archive format.')
|
||||
if self.rawdata:
|
||||
self.parseXML()
|
||||
|
||||
def parseXML(self):
|
||||
if len(self.rawdata.getElementsByTagName('Series')) != 0:
|
||||
@@ -99,11 +64,6 @@ class MetadataParser:
|
||||
self.data[field + 's'].append(person)
|
||||
self.data[field + 's'] = list(set(self.data[field + 's']))
|
||||
self.data[field + 's'].sort()
|
||||
if len(self.rawdata.getElementsByTagName('ScanInformation')) != 0:
|
||||
coverId = compile('(MCD\\()(\\d+)(\\))')\
|
||||
.search(self.rawdata.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue)
|
||||
if coverId:
|
||||
self.data['MUid'] = coverId.group(2)
|
||||
if len(self.rawdata.getElementsByTagName('Page')) != 0:
|
||||
for page in self.rawdata.getElementsByTagName('Page'):
|
||||
if 'Bookmark' in page.attributes and 'Image' in page.attributes:
|
||||
@@ -116,8 +76,7 @@ class MetadataParser:
|
||||
for row in (['Series', self.data['Series']], ['Volume', self.data['Volume']],
|
||||
['Number', self.data['Number']], ['Writer', ', '.join(self.data['Writers'])],
|
||||
['Penciller', ', '.join(self.data['Pencillers'])], ['Inker', ', '.join(self.data['Inkers'])],
|
||||
['Colorist', ', '.join(self.data['Colorists'])], ['Summary', self.data['Summary']],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
['Colorist', ', '.join(self.data['Colorists'])], ['Summary', self.data['Summary']]):
|
||||
if self.rawdata.getElementsByTagName(row[0]):
|
||||
node = self.rawdata.getElementsByTagName(row[0])[0]
|
||||
if row[1]:
|
||||
@@ -138,8 +97,7 @@ class MetadataParser:
|
||||
for row in (['Series', self.data['Series']], ['Volume', self.data['Volume']],
|
||||
['Number', self.data['Number']], ['Writer', ', '.join(self.data['Writers'])],
|
||||
['Penciller', ', '.join(self.data['Pencillers'])], ['Inker', ', '.join(self.data['Inkers'])],
|
||||
['Colorist', ', '.join(self.data['Colorists'])], ['Summary', self.data['Summary']],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
['Colorist', ', '.join(self.data['Colorists'])], ['Summary', self.data['Summary']]):
|
||||
if row[1]:
|
||||
main = doc.createElement(row[0])
|
||||
root.appendChild(main)
|
||||
@@ -154,20 +112,9 @@ class MetadataParser:
|
||||
tmpXML = os.path.join(workdir, 'ComicInfo.xml')
|
||||
with open(tmpXML, 'w', encoding='utf-8') as f:
|
||||
self.rawdata.writexml(f, encoding='utf-8')
|
||||
if is_zipfile(self.source):
|
||||
removeFromZIP(self.source, 'ComicInfo.xml')
|
||||
with ZipFile(self.source, mode='a', compression=ZIP_DEFLATED) as zip_file:
|
||||
zip_file.write(tmpXML, arcname=tmpXML.split(os.sep)[-1])
|
||||
elif rarfile.is_rarfile(self.source):
|
||||
raise NotImplementedError
|
||||
elif is_7zfile(self.source):
|
||||
output = Popen('7za a "' + self.source + '" "' + tmpXML + '"',
|
||||
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 not extracted:
|
||||
rmtree(workdir)
|
||||
raise OSError('Failed to modify 7ZIP file.')
|
||||
try:
|
||||
cbx = comicarchive.ComicArchive(self.source)
|
||||
cbx.addFile(tmpXML)
|
||||
except OSError as e:
|
||||
raise UserWarning(e.strerror)
|
||||
rmtree(workdir)
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Based upon the code snippet by Ned Batchelder
|
||||
# (http://nedbatchelder.com/blog/200712/extracting_jpgs_from_pdfs.html)
|
||||
@@ -25,17 +27,16 @@ from string import ascii_uppercase, digits
|
||||
|
||||
|
||||
class PdfJpgExtract:
|
||||
def __init__(self, origFileName):
|
||||
self.origFileName = origFileName
|
||||
self.filename = os.path.splitext(origFileName)
|
||||
# noinspection PyUnusedLocal
|
||||
self.path = self.filename[0] + "-KCC-" + ''.join(choice(ascii_uppercase + digits) for x in range(3))
|
||||
def __init__(self, fname):
|
||||
self.fname = fname
|
||||
self.filename = os.path.splitext(fname)
|
||||
self.path = self.filename[0] + "-KCC-" + ''.join(choice(ascii_uppercase + digits) for _ in range(3))
|
||||
|
||||
def getPath(self):
|
||||
return self.path
|
||||
|
||||
def extract(self):
|
||||
pdf = open(self.origFileName, "rb").read()
|
||||
pdf = open(self.fname, "rb").read()
|
||||
startmark = b"\xff\xd8"
|
||||
startfix = 0
|
||||
endmark = b"\xff\xd9"
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2015 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for
|
||||
# any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -17,20 +19,11 @@
|
||||
#
|
||||
|
||||
import os
|
||||
from sys import version_info
|
||||
from hashlib import md5
|
||||
from html.parser import HTMLParser
|
||||
from distutils.version import StrictVersion
|
||||
from time import sleep
|
||||
from shutil import rmtree, copy
|
||||
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):
|
||||
@@ -54,7 +47,7 @@ class HTMLStripper(HTMLParser):
|
||||
def getImageFileName(imgfile):
|
||||
name, ext = os.path.splitext(imgfile)
|
||||
ext = ext.lower()
|
||||
if name.startswith('.') or (ext != '.png' and ext != '.jpg' and ext != '.jpeg' and ext != '.gif'):
|
||||
if name.startswith('.') or ext not in ['.png', '.jpg', '.jpeg', '.gif', '.webp']:
|
||||
return None
|
||||
return [name, ext]
|
||||
|
||||
@@ -71,7 +64,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)
|
||||
@@ -79,8 +72,8 @@ def walkLevel(some_dir, level=1):
|
||||
del dirs[:]
|
||||
|
||||
|
||||
def md5Checksum(filePath):
|
||||
with open(filePath, 'rb') as fh:
|
||||
def md5Checksum(fpath):
|
||||
with open(fpath, 'rb') as fh:
|
||||
m = md5()
|
||||
while True:
|
||||
data = fh.read(8192)
|
||||
@@ -90,100 +83,51 @@ def md5Checksum(filePath):
|
||||
return m.hexdigest()
|
||||
|
||||
|
||||
def check7ZFile(filePath):
|
||||
with open(filePath, 'rb') as fh:
|
||||
header = fh.read(6)
|
||||
return header == b"7z\xbc\xaf'\x1c"
|
||||
|
||||
|
||||
def saferReplace(old, new):
|
||||
for x in range(50):
|
||||
try:
|
||||
os.replace(old, new)
|
||||
except PermissionError:
|
||||
sleep(0.1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
|
||||
|
||||
def saferRemove(target):
|
||||
for x in range(50):
|
||||
try:
|
||||
os.remove(target)
|
||||
except PermissionError:
|
||||
sleep(0.1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
|
||||
|
||||
def removeFromZIP(zipfname, *filenames):
|
||||
tempdir = mkdtemp('', 'KCC-')
|
||||
try:
|
||||
tempname = os.path.join(tempdir, 'KCC.zip')
|
||||
with ZipFile(zipfname, 'r') as zipread:
|
||||
with ZipFile(tempname, 'w', compression=ZIP_DEFLATED) as zipwrite:
|
||||
for item in zipread.infolist():
|
||||
if item.filename not in filenames:
|
||||
zipwrite.writestr(item, zipread.read(item.filename))
|
||||
for x in range(50):
|
||||
try:
|
||||
copy(tempname, zipfname)
|
||||
except PermissionError:
|
||||
sleep(0.1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
finally:
|
||||
rmtree(tempdir, True)
|
||||
|
||||
|
||||
def sanitizeTrace(traceback):
|
||||
return ''.join(format_tb(traceback))\
|
||||
.replace('C:\\Users\\pawel\\Documents\\Projekty\\KCC\\', '')\
|
||||
.replace('C:\\Python34\\', '')\
|
||||
.replace('C:\\Python34_64\\', '')
|
||||
.replace('C:/projects/kcc/', '')\
|
||||
.replace('c:/projects/kcc/', '')\
|
||||
.replace('C:/python37-x64/', '')\
|
||||
.replace('c:/python37-x64/', '')\
|
||||
.replace('C:\\projects\\kcc\\', '')\
|
||||
.replace('c:\\projects\\kcc\\', '')\
|
||||
.replace('C:\\python37-x64\\', '')\
|
||||
.replace('c:\\python37-x64\\', '')
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
def dependencyCheck(level):
|
||||
missing = []
|
||||
if level > 2:
|
||||
try:
|
||||
from PyQt5.QtCore import qVersion as qtVersion
|
||||
if StrictVersion('5.2.1') > StrictVersion(qtVersion()):
|
||||
missing.append('PyQt 5.2.1+')
|
||||
if StrictVersion('5.6.0') > StrictVersion(qtVersion()):
|
||||
missing.append('PyQt 5.6.0+')
|
||||
except ImportError:
|
||||
missing.append('PyQt 5.2.1+')
|
||||
missing.append('PyQt 5.6.0+')
|
||||
try:
|
||||
import raven
|
||||
except ImportError:
|
||||
missing.append('raven 6.0.0+')
|
||||
if level > 1:
|
||||
try:
|
||||
from psutil import __version__ as psutilVersion
|
||||
if StrictVersion('3.2.2') > StrictVersion(psutilVersion):
|
||||
missing.append('psutil 3.2.2+')
|
||||
if StrictVersion('5.0.0') > StrictVersion(psutilVersion):
|
||||
missing.append('psutil 5.0.0+')
|
||||
except ImportError:
|
||||
missing.append('psutil 3.2.2+')
|
||||
missing.append('psutil 5.0.0+')
|
||||
try:
|
||||
from slugify import __version__ as slugifyVersion
|
||||
if StrictVersion('1.1.4') > StrictVersion(slugifyVersion):
|
||||
missing.append('python-slugify 1.1.4+')
|
||||
if StrictVersion('1.2.1') > StrictVersion(slugifyVersion):
|
||||
missing.append('python-slugify 1.2.1+')
|
||||
except ImportError:
|
||||
missing.append('python-slugify 1.1.4+')
|
||||
missing.append('python-slugify 1.2.1+')
|
||||
try:
|
||||
from PIL import PILLOW_VERSION as pillowVersion
|
||||
if StrictVersion('3.0.0') > StrictVersion(pillowVersion):
|
||||
missing.append('Pillow 3.0.0+')
|
||||
from PIL import __version__ as pillowVersion
|
||||
if StrictVersion('5.2.0') > StrictVersion(pillowVersion):
|
||||
missing.append('Pillow 5.2.0+')
|
||||
except ImportError:
|
||||
missing.append('Pillow 3.0.0+')
|
||||
if version_info[1] < 5:
|
||||
try:
|
||||
from scandir import __version__ as scandirVersion
|
||||
if StrictVersion('1.1') > StrictVersion(scandirVersion):
|
||||
missing.append('scandir 1.1+')
|
||||
except ImportError:
|
||||
missing.append('scandir 1.1+')
|
||||
missing.append('Pillow 5.2.0+')
|
||||
if len(missing) > 0:
|
||||
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
|
||||
exit(1)
|
||||
56
kindlecomicconverter/startup.py
Normal file
56
kindlecomicconverter/startup.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2012-2014 Ciro Mattia Gonano <ciromattia@gmail.com>
|
||||
# Copyright (c) 2013-2019 Pawel Jastrzebski <pawelj@iosphe.re>
|
||||
#
|
||||
# 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():
|
||||
for i in range(1, len(sys.argv)):
|
||||
KCCAplication.sendMessage(sys.argv[i])
|
||||
else:
|
||||
KCCAplication.sendMessage('ARISE')
|
||||
else:
|
||||
KCCWindow = KCC_gui.QMainWindowKCC()
|
||||
KCCUI = KCC_gui.KCCGUI(KCCAplication, KCCWindow)
|
||||
for i in range(1, len(sys.argv)):
|
||||
KCCUI.handleMessage(sys.argv[i])
|
||||
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:]))
|
||||
@@ -1,4 +0,0 @@
|
||||
kindlecomicconverter: statically-linked-binary usr/bin/kcc
|
||||
kindlecomicconverter: binary-without-manpage usr/bin/kcc
|
||||
kindlecomicconverter: wrong-name-for-changelog-of-native-package usr/share/doc/kindlecomicconverter/changelog.Debian.gz
|
||||
kindlecomicconverter: file-missing-in-md5sums usr/share/doc/kindlecomicconverter/changelog.Debian.gz
|
||||
@@ -1,11 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Kindle Comic Converter
|
||||
GenericName=Kindle Comic Converter
|
||||
Comment=Comic and Manga converter for e-book readers
|
||||
Icon=/usr/share/kindlecomicconverter/comic2ebook.png
|
||||
Exec=/usr/bin/kcc
|
||||
Terminal=false
|
||||
Categories=Graphics;
|
||||
MimeType=application/zip;application/x-rar;application/x-7z-compressed;
|
||||
BIN
other/osx/7z
Executable file
BIN
other/osx/7z
Executable file
Binary file not shown.
BIN
other/osx/7z.so
Normal file
BIN
other/osx/7z.so
Normal file
Binary file not shown.
BIN
other/osx/7za
BIN
other/osx/7za
Binary file not shown.
@@ -6,10 +6,31 @@
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Kindle Comic Converter</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>cbz</string>
|
||||
<string>cbr</string>
|
||||
<string>cb7</string>
|
||||
<string>zip</string>
|
||||
<string>rar</string>
|
||||
<string>7z</string>
|
||||
<string>pdf</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>comic2ebook.icns</string>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>Comics</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Editor</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>MacOS/Kindle Comic Converter</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>KindleComicConverter 5.0, written 2012-2015 by Ciro Mattia Gonano and Pawel Jastrzebski</string>
|
||||
<string>KindleComicConverter 5.5.1, written 2012-2019 by Ciro Mattia Gonano and Pawel Jastrzebski</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>comic2ebook.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -21,11 +42,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.0.0</string>
|
||||
<string>5.5.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>5.0.0</string>
|
||||
<string>5.5.1</string>
|
||||
<key>LSEnvironment</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
@@ -34,7 +55,7 @@
|
||||
<key>LSHasLocalizedDisplayName</key>
|
||||
<false/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.9.0</string>
|
||||
<string>10.12.0</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<false/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
|
||||
BIN
other/osx/Rar.so
Normal file
BIN
other/osx/Rar.so
Normal file
Binary file not shown.
BIN
other/osx/sentry.py.enc
Normal file
BIN
other/osx/sentry.py.enc
Normal file
Binary file not shown.
BIN
other/osx/unrar
BIN
other/osx/unrar
Binary file not shown.
BIN
other/windows/7z.dll
Normal file
BIN
other/windows/7z.dll
Normal file
Binary file not shown.
BIN
other/windows/7z.exe
Normal file
BIN
other/windows/7z.exe
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,56 +1,22 @@
|
||||
****** ***** ****** UnRAR - free utility for RAR archives
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
****** ******* ****** License for use and distribution of
|
||||
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
** ** ** ** ** ** FREEWARE version
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The UnRAR utility is freeware. This means:
|
||||
|
||||
1. All copyrights to RAR and the utility UnRAR are exclusively
|
||||
owned by the author - Alexander Roshal.
|
||||
|
||||
2. The UnRAR utility may be freely distributed. It is allowed
|
||||
to distribute UnRAR inside of other software packages.
|
||||
|
||||
3. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS".
|
||||
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
|
||||
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
|
||||
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
|
||||
OR MISUSING THIS SOFTWARE.
|
||||
|
||||
4. Neither RAR binary code, WinRAR binary code, UnRAR source or UnRAR
|
||||
binary code may be used or reverse engineered to re-create the RAR
|
||||
compression algorithm, which is proprietary, without written
|
||||
permission of the author.
|
||||
|
||||
5. If you don't agree with terms of the license you must remove
|
||||
UnRAR files from your storage devices and cease to use the
|
||||
utility.
|
||||
|
||||
Thank you for your interest in RAR and UnRAR.
|
||||
|
||||
|
||||
Alexander L. Roshal
|
||||
|
||||
7-Zip
|
||||
~~~~~
|
||||
License for use and distribution
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
7-Zip Copyright (C) 1999-2012 Igor Pavlov.
|
||||
7-Zip Copyright (C) 1999-2018 Igor Pavlov.
|
||||
|
||||
Licenses for files are:
|
||||
The licenses for files are:
|
||||
|
||||
1) 7z.dll: GNU LGPL + unRAR restriction
|
||||
2) All other files: GNU LGPL
|
||||
1) 7z.dll:
|
||||
- The "GNU LGPL" as main license for most of the code
|
||||
- The "GNU LGPL" with "unRAR license restriction" for some code
|
||||
- The "BSD 3-clause License" for some code
|
||||
2) All other files: the "GNU LGPL".
|
||||
|
||||
The GNU LGPL + unRAR restriction means that you must follow both
|
||||
GNU LGPL rules and unRAR restriction rules.
|
||||
Redistributions in binary form must reproduce related license information from this file.
|
||||
|
||||
|
||||
Note:
|
||||
You can use 7-Zip on any computer, including a computer in a commercial
|
||||
Note:
|
||||
You can use 7-Zip on any computer, including a computer in a commercial
|
||||
organization. You don't need to register or pay for 7-Zip.
|
||||
|
||||
|
||||
@@ -67,21 +33,54 @@
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You can receive a copy of the GNU Lesser General Public License from
|
||||
You can receive a copy of the GNU Lesser General Public License from
|
||||
http://www.gnu.org/
|
||||
|
||||
|
||||
unRAR restriction
|
||||
-----------------
|
||||
|
||||
The decompression engine for RAR archives was developed using source
|
||||
|
||||
BSD 3-clause License
|
||||
--------------------
|
||||
|
||||
The "BSD 3-clause License" is used for the code in 7z.dll that implements LZFSE data decompression.
|
||||
That code was derived from the code in the "LZFSE compression library" developed by Apple Inc,
|
||||
that also uses the "BSD 3-clause License":
|
||||
|
||||
----
|
||||
Copyright (c) 2015-2016, Apple Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder(s) nor the names of any contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----
|
||||
|
||||
|
||||
|
||||
|
||||
unRAR license restriction
|
||||
-------------------------
|
||||
|
||||
The decompression engine for RAR archives was developed using source
|
||||
code of unRAR program.
|
||||
All copyrights to original unRAR code are owned by Alexander Roshal.
|
||||
|
||||
The license for original unRAR code has the following restriction:
|
||||
|
||||
The unRAR sources cannot be used to re-create the RAR compression algorithm,
|
||||
which is proprietary. Distribution of modified unRAR sources in separate form
|
||||
The unRAR sources cannot be used to re-create the RAR compression algorithm,
|
||||
which is proprietary. Distribution of modified unRAR sources in separate form
|
||||
or as a part of other software is permitted, provided that it is clearly
|
||||
stated in the documentation and source comments that the code may
|
||||
not be used to develop a RAR (WinRAR) compatible archiver.
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
{\flomajor\f31500\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fhimajor\f31502\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0302020204030204}Calibri Light;}{\fbimajor\f31503\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\flominor\f31504\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}
|
||||
{\fhiminor\f31506\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f41\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f411\fbidi \fswiss\fcharset0\fprq2 Calibri;}
|
||||
{\f410\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f412\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f413\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f416\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
|
||||
{\f417\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}
|
||||
{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}
|
||||
{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}
|
||||
{\fhiminor\f31506\fbidi \fswiss\fcharset238\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f44\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f43\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f45\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f46\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f47\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f48\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f49\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f50\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f44\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\f43\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f45\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f46\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f47\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\f48\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f49\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f50\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f414\fbidi \fswiss\fcharset0\fprq2 Calibri;}
|
||||
{\f413\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\f415\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f416\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f417\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}
|
||||
{\f418\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\f419\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f420\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\flomajor\f31510\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31520\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\fhimajor\f31530\fbidi \fswiss\fcharset0\fprq2 Calibri Light;}{\fhimajor\f31529\fbidi \fswiss\fcharset204\fprq2 Calibri Light Cyr;}{\fhimajor\f31531\fbidi \fswiss\fcharset161\fprq2 Calibri Light Greek;}
|
||||
{\fhimajor\f31532\fbidi \fswiss\fcharset162\fprq2 Calibri Light Tur;}{\fhimajor\f31533\fbidi \fswiss\fcharset177\fprq2 Calibri Light (Hebrew);}{\fhimajor\f31534\fbidi \fswiss\fcharset178\fprq2 Calibri Light (Arabic);}
|
||||
{\fhimajor\f31535\fbidi \fswiss\fcharset186\fprq2 Calibri Light Baltic;}{\fhimajor\f31536\fbidi \fswiss\fcharset163\fprq2 Calibri Light (Vietnamese);}{\fbimajor\f31540\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
@@ -26,20 +27,21 @@
|
||||
{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}
|
||||
{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31570\fbidi \fswiss\fcharset0\fprq2 Calibri;}
|
||||
{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}
|
||||
{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}
|
||||
{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}
|
||||
{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
|
||||
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;
|
||||
\chyperlink\ctint255\cshade255\red5\green99\blue193;\cfollowedhyperlink\ctint255\cshade255\red149\green79\blue114;}{\*\defchp \f31506\fs22\lang1045\langfe1033\langfenp1033 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0
|
||||
\f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
|
||||
{\fhiminor\f31573\fbidi \fswiss\fcharset177\fprq2 Calibri (Hebrew);}{\fhiminor\f31574\fbidi \fswiss\fcharset178\fprq2 Calibri (Arabic);}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}
|
||||
{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31580\fbidi \froman\fcharset0\fprq2 Times New Roman;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}
|
||||
{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}
|
||||
{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}
|
||||
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;
|
||||
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\chyperlink\ctint255\cshade255\red5\green99\blue193;\cfollowedhyperlink\ctint255\cshade255\red149\green79\blue114;}{\*\defchp
|
||||
\f31506\fs22\lang1045\langfe1033\langfenp1033 }{\*\defpap \ql \li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa160\sl259\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive
|
||||
\ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\*
|
||||
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa160\sl259\slmult1
|
||||
\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31506\afs22\alang1025 \ltrch\fcs0 \f31506\fs22\lang1045\langfe1033\cgrid\langnp1045\langfenp1033 \snext11 \ssemihidden \sunhideused Normal Table;}{\*\cs15 \additive
|
||||
\rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf17 \sbasedon10 \sunhideused \styrsid3562894 Hyperlink;}{\*\cs16 \additive \rtlch\fcs1 \af0 \ltrch\fcs0 \ul\cf18 \sbasedon10 \ssemihidden \sunhideused \styrsid7678248 FollowedHyperlink;}}{\*\rsidtbl \rsid1081196
|
||||
\rsid3146412\rsid3562894\rsid5731975\rsid7678248\rsid9265883\rsid11107340\rsid12600926\rsid13187577}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info
|
||||
{\author Pawe\'b3 Jastrz\'eabski}{\operator Pawe\'b3 Jastrz\'eabski}{\creatim\yr2013\mo10\dy29\hr15\min17}{\revtim\yr2013\mo10\dy29\hr15\min28}{\version8}{\edmins8}{\nofpages1}{\nofwords33}{\nofchars200}{\nofcharsws232}{\vern57435}}{\*\xmlnstbl {\xmlns1 h
|
||||
ttp://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
|
||||
\rsid3146412\rsid3562894\rsid5731975\rsid7678248\rsid9265883\rsid11107340\rsid11629590\rsid12600926\rsid13187577}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info
|
||||
{\author Pawe\'b3 Jastrz\'eabski}{\operator Pawe\'b3 Jastrz\'eabski}{\creatim\yr2013\mo10\dy29\hr15\min17}{\revtim\yr2017\mo8\dy20\hr17\min40}{\version9}{\edmins8}{\nofpages1}{\nofwords33}{\nofchars201}{\nofcharsws233}{\vern39}}{\*\xmlnstbl {\xmlns1 http:
|
||||
//schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\margl1417\margr1417\margt1417\margb1417\gutter0\ltrsect
|
||||
\deftab708\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
|
||||
\showxmlerrors1\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1417\dgvorigin1417\dghshow1\dgvshow1
|
||||
\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
|
||||
@@ -52,12 +54,13 @@ ttp://schemas.microsoft.com/office/word/2003/wordml}}\paperw11906\paperh16838\ma
|
||||
\b\fs52\cf6\lang2057\langfe1033\langnp2057\insrsid13187577\charrsid3562894
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid1081196 Creation of}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 MOBI}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 files }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 require additional software.}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 require}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid11629590 s}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 additional software.}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 Please download: }{\field\flddirty{\*\fldinst {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 HYPERLINK "http://www.amazon.com/gp/feature.html?ie=UTF8&docId=1000765211" }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
{\*\datafield
|
||||
00d0c9ea79f9bace118c8200aa004ba90b0200000003000000e0c9ea79f9bace118c8200aa004ba90b9600000068007400740070003a002f002f007700770077002e0061006d0061007a006f006e002e0063006f006d002f00670070002f0066006500610074007500720065002e00680074006d006c003f00690065003d00
|
||||
5500540046003800260064006f006300490064003d0031003000300030003700360035003200310031000000795881f43b1d7f48af2c825dc485276300000000a5ab000000}}}{\fldrslt {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
5500540046003800260064006f006300490064003d0031003000300030003700360035003200310031000000795881f43b1d7f48af2c825dc485276300000000a5ab00000000}}}{\fldrslt {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\cs15\b\fs28\ul\cf17\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 KindleGen}}}\sectd \ltrsect\linex0\headery708\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0
|
||||
\b\fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926
|
||||
\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \fs28\lang2057\langfe1033\langnp2057\insrsid3562894\charrsid12600926 And place }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \i\fs28\lang2057\langfe1033\langnp2057\insrsid5731975\charrsid12600926 kindlegen.exe}{\rtlch\fcs1
|
||||
@@ -119,7 +122,7 @@ d40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719a
|
||||
617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169
|
||||
6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363
|
||||
656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e}
|
||||
{\*\latentstyles\lsdstimax371\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||
{\*\latentstyles\lsdstimax375\lsdlockeddef0\lsdsemihiddendef0\lsdunhideuseddef0\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdsemihidden1 \lsdunhideused1 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 index 1;
|
||||
@@ -196,7 +199,8 @@ d40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719a
|
||||
\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 4;\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 5;\lsdpriority47 \lsdlocked0 List Table 2 Accent 5;\lsdpriority48 \lsdlocked0 List Table 3 Accent 5;
|
||||
\lsdpriority49 \lsdlocked0 List Table 4 Accent 5;\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 5;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 5;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 5;
|
||||
\lsdpriority46 \lsdlocked0 List Table 1 Light Accent 6;\lsdpriority47 \lsdlocked0 List Table 2 Accent 6;\lsdpriority48 \lsdlocked0 List Table 3 Accent 6;\lsdpriority49 \lsdlocked0 List Table 4 Accent 6;
|
||||
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;}}{\*\datastore 010500000200000018000000
|
||||
\lsdpriority50 \lsdlocked0 List Table 5 Dark Accent 6;\lsdpriority51 \lsdlocked0 List Table 6 Colorful Accent 6;\lsdpriority52 \lsdlocked0 List Table 7 Colorful Accent 6;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Mention;
|
||||
\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Smart Hyperlink;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Hashtag;\lsdsemihidden1 \lsdunhideused1 \lsdlocked0 Unresolved Mention;}}{\*\datastore 010500000200000018000000
|
||||
4d73786d6c322e534158584d4c5265616465722e362e30000000000000000000000e0000
|
||||
d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
@@ -206,24 +210,24 @@ fffffffffffffffffdffffff04000000feffffff05000000fefffffffeffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e50000000000000000000000006069
|
||||
e214b3d4ce010300000080020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff0200000000000000000000000000000000000000000000006069e214b3d4ce01
|
||||
6069e214b3d4ce010000000000000000000000003500d900ca00dd00ce004400cc00c8005a0045004700c400cd0057004900c500d400c900cb00ce00570051003d003d000000000000000000000000000000000032000101ffffffffffffffff0300000000000000000000000000000000000000000000006069e214b3d4
|
||||
ce016069e214b3d4ce010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000fc00000000000000010000000200000003000000feffffff0500000006000000070000000800000009000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e5000000000000000000000000b00f
|
||||
9da8ca19d30103000000c0020000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff020000000000000000000000000000000000000000000000b00f9da8ca19d301
|
||||
b00f9da8ca19d301000000000000000000000000ca0041004300c300d300d300c70058004d00d4003000c9004d00c200590043003100320055004a00300051003d003d000000000000000000000000000000000032000101ffffffffffffffff030000000000000000000000000000000000000000000000b00f9da8ca19
|
||||
d301b00f9da8ca19d3010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000320100000000000001000000020000000300000004000000feffffff060000000700000008000000090000000a000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c623a536f75726365732053656c65637465645374796c653d225c415041536978746845646974696f6e4f66666963654f6e6c696e652e78736c22205374796c654e616d653d22415041222056657273696f6e3d22362220786d6c6e733a
|
||||
623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f6772617068792220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e74
|
||||
2f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b42384244
|
||||
394137462d323833422d343136342d413442352d3632323544323941454535397d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c
|
||||
64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000400000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000
|
||||
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e3c623a536f75726365732053656c65637465645374796c653d225c41504153697874684564697469
|
||||
6f6e4f66666963654f6e6c696e652e78736c22205374796c654e616d653d22415041222056657273696f6e3d22362220786d6c6e733a623d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222078
|
||||
6d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879223e3c2f623a536f75726365733e00000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f6469
|
||||
6e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b43464133303041382d443733392d343633332d413933322d3236303236444335303936397d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70
|
||||
656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000500000055010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f
|
||||
72654974656d3e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f7267
|
||||
2f6f6666696365446f63756d656e742f323030362f6269626c696f677261706879222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000105000000000000}}
|
||||
Binary file not shown.
3
other/windows/sentry.py.enc
Normal file
3
other/windows/sentry.py.enc
Normal file
@@ -0,0 +1,3 @@
|
||||
éd¼7¶ÍÑ<>ßñ|l“z6¯n¸I_œ—Åž:£ê-ˆ!ën‚BCDÇ}fðzIe|¦ÜÖà\9KW°f½H[íY¶LYô7^Ï@mª*<2A>YmÎ_z`3©WSD{Ö"áˆa@>®;}\¥—,D›š˜Ý·Ý!yX<79>±è–<C3A8>¯~ÿ~Y_æxdÕï BøŠT
|
||||
B”𢯣
|
||||
uô|91u~¿Pa¸¸LDÜjh
|
||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
PyQt5>=5.6.0
|
||||
Pillow>=5.2.0
|
||||
psutil>=5.0.0
|
||||
python-slugify>=1.2.1,<3.0.0
|
||||
raven>=6.0.0
|
||||
122
setup.py
122
setup.py
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
pip/pyinstaller build script for KCC.
|
||||
|
||||
Usage (Windows):
|
||||
py -3 setup.py build_binary
|
||||
Install as Python package:
|
||||
python3 setup.py install
|
||||
|
||||
Usage (Linux/OS X):
|
||||
python3 setup.py build_binary or python3 setup.py build_binary --pyz
|
||||
Create EXE/APP:
|
||||
python3 setup.py build_binary
|
||||
"""
|
||||
|
||||
import os
|
||||
@@ -14,115 +15,48 @@ import sys
|
||||
import shutil
|
||||
import setuptools
|
||||
import distutils.cmd
|
||||
from distutils.command.build import build
|
||||
from kcc import __version__
|
||||
from kindlecomicconverter import __version__
|
||||
|
||||
NAME = 'KindleComicConverter'
|
||||
MAIN = 'kcc.py'
|
||||
VERSION = __version__
|
||||
OPTIONS = {}
|
||||
|
||||
|
||||
class BuildBinaryCommand(distutils.cmd.Command):
|
||||
description = 'build binary release'
|
||||
user_options = [
|
||||
('pyz', None, 'build PYZ package'),
|
||||
]
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
# noinspection PyAttributeOutsideInit
|
||||
self.pyz = False
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
def run(self):
|
||||
VERSION = __version__
|
||||
if sys.platform == 'darwin':
|
||||
os.system('pyinstaller -y -F -i icons/comic2ebook.icns -n "Kindle Comic Converter" -w -s kcc.py')
|
||||
shutil.copy('other/osx/7za', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
shutil.copy('other/osx/unrar', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
os.makedirs('dist/Kindle Comic Converter.app/Contents/Resources/Codecs')
|
||||
shutil.copy('other/osx/7z', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
shutil.copy('other/osx/7z.so', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
shutil.copy('other/osx/Rar.so', 'dist/Kindle Comic Converter.app/Contents/Resources/Codecs')
|
||||
shutil.copy('other/osx/Info.plist', 'dist/Kindle Comic Converter.app/Contents')
|
||||
shutil.copy('LICENSE.txt', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
shutil.copy('other/windows/Additional-LICENSE.txt', 'dist/Kindle Comic Converter.app/Contents/Resources')
|
||||
os.chmod('dist/Kindle Comic Converter.app/Contents/Resources/unrar', 0o777)
|
||||
os.chmod('dist/Kindle Comic Converter.app/Contents/Resources/7za', 0o777)
|
||||
if os.path.isfile('setup.sh'):
|
||||
os.system('./setup.sh')
|
||||
os.chmod('dist/Kindle Comic Converter.app/Contents/Resources/7z', 0o777)
|
||||
os.system('appdmg kcc.json dist/KindleComicConverter_osx_' + VERSION + '.dmg')
|
||||
exit(0)
|
||||
elif sys.platform == 'win32':
|
||||
os.system('pyinstaller -y -F -i icons\comic2ebook.ico -n KCC -w kcc.py')
|
||||
if os.path.isfile('setup.bat'):
|
||||
os.system('setup.bat ' + VERSION)
|
||||
os.system('pyinstaller -y -F -i icons\\comic2ebook.ico -n KCC -w --noupx kcc.py')
|
||||
exit(0)
|
||||
else:
|
||||
if self.pyz:
|
||||
script = '''
|
||||
cp kcc.py __main__.py
|
||||
zip kcc.zip __main__.py kcc/*.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 kcc/*.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 kcc/*.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 build --no-cache -t kcc . && docker run --rm -v ' + os.getcwd() +
|
||||
':/out kcc && docker rmi 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=[
|
||||
'Pillow>=3.0.0',
|
||||
'psutil>=3.2.2',
|
||||
'python-slugify>=1.1.4',
|
||||
],
|
||||
zip_safe=False,
|
||||
)
|
||||
if sys.version_info[1] < 5:
|
||||
OPTIONS['install_requires'].append('scandir>=1.1.0')
|
||||
build.run(self)
|
||||
exit(0)
|
||||
|
||||
|
||||
setuptools.setup(
|
||||
cmdclass={
|
||||
'build_binary': BuildBinaryCommand,
|
||||
'build': BuildCommand,
|
||||
},
|
||||
name=NAME,
|
||||
version=VERSION,
|
||||
@@ -130,7 +64,25 @@ setuptools.setup(
|
||||
author_email='ciromattia@gmail.com, pawelj@iosphe.re',
|
||||
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>=5.2.0',
|
||||
'psutil>=5.0.0',
|
||||
'python-slugify>=1.2.1',
|
||||
'raven>=6.0.0',
|
||||
],
|
||||
classifiers=[],
|
||||
zip_safe=False,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user