mirror of
https://github.com/ciromattia/kcc
synced 2025-12-13 17:56:30 +00:00
27
KCC.qrc
27
KCC.qrc
@@ -1,27 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="Icon">
|
||||
<file>icons/comic2ebook.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Devices">
|
||||
<file>icons/Kobo.png</file>
|
||||
<file>icons/Other.png</file>
|
||||
<file>icons/Kindle.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Formats">
|
||||
<file>icons/CBZ.png</file>
|
||||
<file>icons/EPUB.png</file>
|
||||
<file>icons/MOBI.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Status">
|
||||
<file>icons/error.png</file>
|
||||
<file>icons/info.png</file>
|
||||
<file>icons/warning.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Other">
|
||||
<file>icons/list_background.png</file>
|
||||
<file>icons/clear.png</file>
|
||||
<file>icons/convert.png</file>
|
||||
<file>icons/document_new.png</file>
|
||||
<file>icons/folder_new.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
12
README.md
12
README.md
@@ -48,11 +48,12 @@ You can find the latest released binary at the following links:
|
||||
- [Pillow](http://pypi.python.org/pypi/Pillow/) 2.7.0+
|
||||
- [psutil](https://pypi.python.org/pypi/psutil) 2.0+
|
||||
- [python-slugify](http://pypi.python.org/pypi/python-slugify) 0.1.0+
|
||||
- [scandir](https://pypi.python.org/pypi/scandir) 0.9+
|
||||
|
||||
On Debian based distributions these two commands should install all dependencies:
|
||||
```
|
||||
sudo apt-get install python3 python3-dev python3-pip python3-pyqt5 libpng-dev libjpeg-dev p7zip-full unrar
|
||||
sudo pip3 install pillow python-slugify psutil
|
||||
sudo pip3 install pillow python-slugify psutil scandir
|
||||
```
|
||||
|
||||
### For freezing code:
|
||||
@@ -158,6 +159,15 @@ The app relies and includes the following scripts:
|
||||
* [Kobo Aura H2O](http://kcc.iosphe.re/Samples/Ubunchu!-KoAH2O.cbz)
|
||||
|
||||
## CHANGELOG
|
||||
####4.5:
|
||||
* Added simple ComicRack medadata 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
|
||||
|
||||
@@ -451,9 +451,6 @@
|
||||
<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="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -466,19 +463,13 @@
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="BasicModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>141</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -498,9 +489,9 @@
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>217</x>
|
||||
<x>260</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>151</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -767,6 +758,32 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>91</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans</family>
|
||||
<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>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
@@ -780,6 +797,7 @@
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
@@ -456,28 +456,19 @@
|
||||
<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="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="BasicModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<width>156</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -499,9 +490,9 @@
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>207</x>
|
||||
<x>260</x>
|
||||
<y>10</y>
|
||||
<width>210</width>
|
||||
<width>156</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -782,9 +773,34 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>101</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Lucida Grande</family>
|
||||
<pointsize>12</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>
|
||||
<zorder>BasicModeButton</zorder>
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
<zorder>JobList</zorder>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
@@ -796,6 +812,8 @@
|
||||
<zorder>OptionsBasic</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
<property name="font">
|
||||
28
gui/KCC.qrc
Normal file
28
gui/KCC.qrc
Normal file
@@ -0,0 +1,28 @@
|
||||
<RCC>
|
||||
<qresource prefix="Icon">
|
||||
<file>../icons/comic2ebook.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Devices">
|
||||
<file>../icons/Kobo.png</file>
|
||||
<file>../icons/Other.png</file>
|
||||
<file>../icons/Kindle.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Formats">
|
||||
<file>../icons/CBZ.png</file>
|
||||
<file>../icons/EPUB.png</file>
|
||||
<file>../icons/MOBI.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Status">
|
||||
<file>../icons/error.png</file>
|
||||
<file>../icons/info.png</file>
|
||||
<file>../icons/warning.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="Other">
|
||||
<file>../icons/editor.png</file>
|
||||
<file>../icons/list_background.png</file>
|
||||
<file>../icons/clear.png</file>
|
||||
<file>../icons/convert.png</file>
|
||||
<file>../icons/document_new.png</file>
|
||||
<file>../icons/folder_new.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -391,28 +391,19 @@
|
||||
<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="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="BasicModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>141</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -431,9 +422,9 @@
|
||||
<widget class="QPushButton" name="AdvModeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>217</x>
|
||||
<x>261</x>
|
||||
<y>10</y>
|
||||
<width>195</width>
|
||||
<width>151</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -656,6 +647,31 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="EditorButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>10</y>
|
||||
<width>91</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>
|
||||
<zorder>OptionsAdvanced</zorder>
|
||||
<zorder>DeviceBox</zorder>
|
||||
<zorder>FormatBox</zorder>
|
||||
@@ -669,6 +685,7 @@
|
||||
<zorder>AdvModeButton</zorder>
|
||||
<zorder>OptionsAdvancedGamma</zorder>
|
||||
<zorder>OptionsExpert</zorder>
|
||||
<zorder>EditorButton</zorder>
|
||||
<zorder>ProgressBar</zorder>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar">
|
||||
226
gui/MetaEditor-Linux.ui
Normal file
226
gui/MetaEditor-Linux.ui
Normal file
@@ -0,0 +1,226 @@
|
||||
<?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>320</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>320</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>320</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>280</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>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>271</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>
|
||||
</widget>
|
||||
<zorder>horizontalLayoutWidget</zorder>
|
||||
<zorder>EditorFrame</zorder>
|
||||
<zorder>StatusLabel</zorder>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
223
gui/MetaEditor-OSX.ui
Normal file
223
gui/MetaEditor-OSX.ui
Normal file
@@ -0,0 +1,223 @@
|
||||
<?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">
|
||||
<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>
|
||||
222
gui/MetaEditor.ui
Normal file
222
gui/MetaEditor.ui
Normal file
@@ -0,0 +1,222 @@
|
||||
<?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>260</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<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>
|
||||
<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>220</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>
|
||||
<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>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>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="KCC.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
icons/editor.png
Normal file
BIN
icons/editor.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -18,11 +18,6 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
@@ -32,10 +27,11 @@ from kcc.shared import dependencyCheck
|
||||
dependencyCheck(2)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2ebook import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
print(('comic2ebook v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
|
||||
print('comic2ebook v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
main(sys.argv[1:])
|
||||
sys.exit(0)
|
||||
@@ -18,11 +18,6 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
@@ -32,10 +27,11 @@ from kcc.shared import dependencyCheck
|
||||
dependencyCheck(1)
|
||||
|
||||
from multiprocessing import freeze_support
|
||||
from kcc import __version__
|
||||
from kcc.comic2panel import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
freeze_support()
|
||||
print(('comic2panel v%(__version__)s. Written by Ciro Mattia Gonano and Pawel Jastrzebski.' % globals()))
|
||||
print('comic2panel v' + __version__ + ' - Written by Ciro Mattia Gonano and Pawel Jastrzebski.')
|
||||
main(sys.argv[1:])
|
||||
sys.exit(0)
|
||||
48
kcc.iss
48
kcc.iss
@@ -1,5 +1,5 @@
|
||||
#define MyAppName "Kindle Comic Converter"
|
||||
#define MyAppVersion "4.4.1"
|
||||
#define MyAppVersion "4.5"
|
||||
#define MyAppPublisher "Ciro Mattia Gonano, Paweł Jastrzębski"
|
||||
#define MyAppURL "http://kcc.iosphe.re/"
|
||||
#define MyAppExeName "KCC.exe"
|
||||
@@ -85,3 +85,49 @@ Root: HKCR; SubKey: ".cb7"; ValueType: string; ValueData: "KCCCB7"; Flags: unins
|
||||
Root: HKCR; SubKey: "KCCCB7"; ValueType: string; ValueData: "KCC 7z Archive"; Flags: uninsdeletekey; Tasks: CB7association
|
||||
Root: HKCR; SubKey: "KCCCB7\Shell\Open\Command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey; Tasks: CB7association
|
||||
Root: HKCR; Subkey: "KCCCB7\DefaultIcon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletevalue; Tasks: CB7association
|
||||
|
||||
[Code]
|
||||
function GetUninstallString(): String;
|
||||
var
|
||||
sUnInstPath: String;
|
||||
sUnInstallString: String;
|
||||
begin
|
||||
sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
|
||||
sUnInstallString := '';
|
||||
if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
|
||||
RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
|
||||
Result := sUnInstallString;
|
||||
end;
|
||||
|
||||
function IsUpgrade(): Boolean;
|
||||
begin
|
||||
Result := (GetUninstallString() <> '');
|
||||
end;
|
||||
|
||||
function UnInstallOldVersion(): Integer;
|
||||
var
|
||||
sUnInstallString: String;
|
||||
iResultCode: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
sUnInstallString := GetUninstallString();
|
||||
if sUnInstallString <> '' then begin
|
||||
sUnInstallString := RemoveQuotes(sUnInstallString);
|
||||
if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then
|
||||
Result := 3
|
||||
else
|
||||
Result := 2;
|
||||
end else
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
procedure CurStepChanged(CurStep: TSetupStep);
|
||||
begin
|
||||
if (CurStep=ssInstall) then
|
||||
begin
|
||||
if (IsUpgrade()) then
|
||||
begin
|
||||
UnInstallOldVersion();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
5
kcc.py
5
kcc.py
@@ -18,11 +18,6 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
if sys.version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
|
||||
147
kcc/KCC_MetaEditor_ui.py
Normal file
147
kcc/KCC_MetaEditor_ui.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# -*- 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
|
||||
148
kcc/KCC_MetaEditor_ui_linux.py
Normal file
148
kcc/KCC_MetaEditor_ui_linux.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'gui/MetaEditor.ui'
|
||||
#
|
||||
# Created: Sun Feb 8 03:24:23 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, 320)
|
||||
MetaEditorDialog.setMinimumSize(QtCore.QSize(400, 320))
|
||||
MetaEditorDialog.setMaximumSize(QtCore.QSize(400, 320))
|
||||
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, 280, 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(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, 271))
|
||||
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
|
||||
148
kcc/KCC_MetaEditor_ui_osx.py
Normal file
148
kcc/KCC_MetaEditor_ui_osx.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- 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.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
|
||||
100
kcc/KCC_gui.py
100
kcc/KCC_gui.py
@@ -17,11 +17,6 @@
|
||||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
import sys
|
||||
from urllib.parse import unquote
|
||||
@@ -38,15 +33,24 @@ from xml.dom.minidom import parse
|
||||
from psutil import Popen, Process
|
||||
from copy import copy
|
||||
from distutils.version import StrictVersion
|
||||
from xml.sax.saxutils import escape
|
||||
from .shared import md5Checksum, HTMLStripper
|
||||
from . import __version__
|
||||
from . import comic2ebook
|
||||
from . import KCC_rc_web
|
||||
from . import metadata
|
||||
if sys.platform.startswith('darwin'):
|
||||
from . import KCC_ui_osx as KCC_ui
|
||||
elif sys.platform.startswith('linux'):
|
||||
from . import KCC_ui_linux as KCC_ui
|
||||
else:
|
||||
from . import KCC_ui
|
||||
if sys.platform.startswith('darwin'):
|
||||
from . import KCC_MetaEditor_ui_osx as KCC_MetaEditor_ui
|
||||
elif sys.platform.startswith('linux'):
|
||||
from . import KCC_MetaEditor_ui_linux as KCC_MetaEditor_ui
|
||||
else:
|
||||
from . import KCC_MetaEditor_ui
|
||||
|
||||
|
||||
class QApplicationMessaging(QtWidgets.QApplication):
|
||||
@@ -608,6 +612,34 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
GUI.JobList.addItem(fname)
|
||||
GUI.JobList.scrollToBottom()
|
||||
|
||||
def selectFileMetaEditor(self):
|
||||
if self.UnRAR:
|
||||
if self.sevenza:
|
||||
fname = QtWidgets.QFileDialog.getOpenFileName(MW, 'Select file', self.lastPath,
|
||||
'Comic (*.cbz *.cbr *.cb7)')
|
||||
else:
|
||||
fname = QtWidgets.QFileDialog.getOpenFileName(MW, 'Select file', self.lastPath,
|
||||
'Comic (*.cbz *.cbr)')
|
||||
else:
|
||||
if self.sevenza:
|
||||
fname = QtWidgets.QFileDialog.getOpenFileName(MW, 'Select file', self.lastPath,
|
||||
'Comic (*.cbz *.cb7)')
|
||||
else:
|
||||
fname = QtWidgets.QFileDialog.getOpenFileName(MW, 'Select file', self.lastPath,
|
||||
'Comic (*.cbz)')
|
||||
if fname[0] != '':
|
||||
if sys.platform.startswith('win'):
|
||||
fname = fname[0].replace('/', '\\')
|
||||
else:
|
||||
fname = fname[0]
|
||||
self.lastPath = os.path.abspath(os.path.join(fname, os.pardir))
|
||||
try:
|
||||
self.editor.loadData(fname)
|
||||
except:
|
||||
self.showDialog('Failed to parse metadata!', 'error')
|
||||
else:
|
||||
self.editor.ui.exec_()
|
||||
|
||||
def clearJobs(self):
|
||||
GUI.JobList.clear()
|
||||
|
||||
@@ -622,6 +654,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
MW.setMinimumSize(QtCore.QSize(420, 287))
|
||||
MW.resize(420, 287)
|
||||
GUI.BasicModeButton.setEnabled(True)
|
||||
GUI.EditorButton.setEnabled(True)
|
||||
GUI.AdvModeButton.setEnabled(True)
|
||||
GUI.BasicModeButton.setStyleSheet('font-weight:Bold;')
|
||||
GUI.AdvModeButton.setStyleSheet('font-weight:Normal;')
|
||||
@@ -651,6 +684,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
MW.setMinimumSize(QtCore.QSize(420, 365))
|
||||
MW.resize(420, 365)
|
||||
GUI.BasicModeButton.setEnabled(True)
|
||||
GUI.EditorButton.setEnabled(True)
|
||||
GUI.AdvModeButton.setEnabled(True)
|
||||
GUI.BasicModeButton.setStyleSheet('font-weight:Normal;')
|
||||
GUI.AdvModeButton.setStyleSheet('font-weight:Bold;')
|
||||
@@ -680,6 +714,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
MW.setMinimumSize(QtCore.QSize(420, 397))
|
||||
MW.resize(420, 397)
|
||||
GUI.BasicModeButton.setEnabled(False)
|
||||
GUI.EditorButton.setEnabled(True)
|
||||
GUI.AdvModeButton.setEnabled(False)
|
||||
GUI.BasicModeButton.setStyleSheet('font-weight:Normal;')
|
||||
GUI.AdvModeButton.setStyleSheet('font-weight:Normal;')
|
||||
@@ -710,6 +745,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
status = True
|
||||
if self.currentMode != 3:
|
||||
GUI.BasicModeButton.setEnabled(status)
|
||||
GUI.EditorButton.setEnabled(status)
|
||||
GUI.AdvModeButton.setEnabled(status)
|
||||
if self.currentMode != 1:
|
||||
GUI.FormatBox.setEnabled(status)
|
||||
@@ -905,6 +941,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
elif command.isdigit():
|
||||
GUI.ProgressBar.setMaximum(int(command) - 1)
|
||||
GUI.BasicModeButton.hide()
|
||||
GUI.EditorButton.hide()
|
||||
GUI.AdvModeButton.hide()
|
||||
GUI.ProgressBar.reset()
|
||||
GUI.ProgressBar.show()
|
||||
@@ -960,6 +997,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
def hideProgressBar(self):
|
||||
GUI.ProgressBar.hide()
|
||||
GUI.BasicModeButton.show()
|
||||
GUI.EditorButton.show()
|
||||
GUI.AdvModeButton.show()
|
||||
|
||||
def saveSettings(self, event):
|
||||
@@ -1077,6 +1115,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
MW = KCCWindow
|
||||
GUI = self
|
||||
self.setupUi(MW)
|
||||
self.editor = KCCGUI_MetaEditor()
|
||||
self.icons = Icons()
|
||||
self.webContent = KCC_rc_web.WebContent()
|
||||
self.settings = QtCore.QSettings('KindleComicConverter', 'KindleComicConverter')
|
||||
@@ -1220,6 +1259,7 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
GUI.DirectoryButton.clicked.connect(self.selectDir)
|
||||
GUI.ClearButton.clicked.connect(self.clearJobs)
|
||||
GUI.FileButton.clicked.connect(self.selectFile)
|
||||
GUI.EditorButton.clicked.connect(self.selectFileMetaEditor)
|
||||
GUI.ConvertButton.clicked.connect(self.convertStart)
|
||||
GUI.GammaSlider.valueChanged.connect(self.changeGamma)
|
||||
GUI.NoRotateBox.stateChanged.connect(self.toggleNoSplitRotate)
|
||||
@@ -1282,3 +1322,53 @@ class KCCGUI(KCC_ui.Ui_KCC):
|
||||
MW.setWindowTitle("Kindle Comic Converter " + __version__)
|
||||
MW.show()
|
||||
MW.raise_()
|
||||
|
||||
|
||||
class KCCGUI_MetaEditor(KCC_MetaEditor_ui.Ui_MetaEditorDialog):
|
||||
def loadData(self, file):
|
||||
self.parser = metadata.MetadataParser(file)
|
||||
if self.parser.compressor == 'rar':
|
||||
self.EditorFrame.setEnabled(False)
|
||||
self.OKButton.setEnabled(False)
|
||||
self.StatusLabel.setText('CBR metadata are read-only.')
|
||||
else:
|
||||
self.EditorFrame.setEnabled(True)
|
||||
self.OKButton.setEnabled(True)
|
||||
self.StatusLabel.setText('Separate authors with a comma.')
|
||||
for field in (self.SeriesLine, self.VolumeLine, self.NumberLine, self.MUidLine):
|
||||
field.setText(self.parser.data[field.objectName()[:-4]])
|
||||
for field in (self.WriterLine, self.PencillerLine, self.InkerLine, self.ColoristLine):
|
||||
field.setText(', '.join(self.parser.data[field.objectName()[:-4] + 's']))
|
||||
|
||||
def saveData(self):
|
||||
for field in (self.VolumeLine, self.NumberLine, self.MUidLine):
|
||||
if field.text().isnumeric() or self.cleanData(field.text()) == '':
|
||||
self.parser.data[field.objectName()[:-4]] = self.cleanData(field.text())
|
||||
else:
|
||||
self.StatusLabel.setText(field.objectName()[:-4] + ' field must be a number.')
|
||||
break
|
||||
else:
|
||||
self.parser.data['Series'] = self.cleanData(self.SeriesLine.text())
|
||||
for field in (self.WriterLine, self.PencillerLine, self.InkerLine, self.ColoristLine):
|
||||
values = self.cleanData(field.text()).split(',')
|
||||
tmpData = []
|
||||
for value in values:
|
||||
if self.cleanData(value) != '':
|
||||
tmpData.append(self.cleanData(value))
|
||||
self.parser.data[field.objectName()[:-4] + 's'] = tmpData
|
||||
try:
|
||||
self.parser.saveXML()
|
||||
except:
|
||||
GUI.showDialog('Failed to save metadata!', 'error')
|
||||
self.ui.close()
|
||||
|
||||
def cleanData(self, s):
|
||||
return escape(s.strip())
|
||||
|
||||
def __init__(self):
|
||||
self.ui = QtWidgets.QDialog()
|
||||
self.parser = None
|
||||
self.setupUi(self.ui)
|
||||
self.ui.setWindowFlags(self.ui.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
|
||||
self.OKButton.clicked.connect(self.saveData)
|
||||
self.CancelButton.clicked.connect(self.ui.close)
|
||||
|
||||
7166
kcc/KCC_rc.py
7166
kcc/KCC_rc.py
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC.ui'
|
||||
#
|
||||
# Created: Sun Jan 4 09:58:25 2015
|
||||
# Created: Sun Feb 8 09:50:43 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
@@ -139,21 +139,18 @@ class Ui_KCC(object):
|
||||
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.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
|
||||
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.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.BasicModeButton.setFont(font)
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(261, 10, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setPointSize(9)
|
||||
self.AdvModeButton.setFont(font)
|
||||
@@ -232,6 +229,16 @@ class Ui_KCC(object):
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 91, 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")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
@@ -301,6 +308,7 @@ class Ui_KCC(object):
|
||||
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.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC-Linux.ui'
|
||||
# Form implementation generated from reading ui file 'gui/KCC-Linux.ui'
|
||||
#
|
||||
# Created: Sun Jan 4 10:06:14 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
# Created: Sun Feb 8 03:10:09 2015
|
||||
# by: PyQt5 UI code generator 5.2.1
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
@@ -179,15 +179,12 @@ class Ui_KCC(object):
|
||||
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.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
|
||||
self.JobList.setProperty("showDropIndicator", False)
|
||||
self.JobList.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
|
||||
self.JobList.setIconSize(QtCore.QSize(18, 18))
|
||||
self.JobList.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setHorizontalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
|
||||
self.JobList.setObjectName("JobList")
|
||||
self.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 195, 32))
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(10, 10, 141, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
@@ -195,7 +192,7 @@ class Ui_KCC(object):
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(217, 10, 195, 32))
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(260, 10, 151, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("DejaVu Sans")
|
||||
font.setPointSize(9)
|
||||
@@ -302,6 +299,17 @@ class Ui_KCC(object):
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 91, 32))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("DejaVu Sans")
|
||||
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")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
@@ -370,6 +378,7 @@ class Ui_KCC(object):
|
||||
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.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'KCC-OSX.ui'
|
||||
# Form implementation generated from reading ui file '/Users/pawelj/Documents/KCC/gui/KCC-OSX.ui'
|
||||
#
|
||||
# Created: Sun Jan 4 10:26:09 2015
|
||||
# Created: Sun Feb 8 12:37:33 2015
|
||||
# by: PyQt5 UI code generator 5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
@@ -186,14 +186,11 @@ class Ui_KCC(object):
|
||||
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.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
|
||||
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.BasicModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 210, 41))
|
||||
self.BasicModeButton.setGeometry(QtCore.QRect(5, 10, 156, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
@@ -203,7 +200,7 @@ class Ui_KCC(object):
|
||||
self.BasicModeButton.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.BasicModeButton.setObjectName("BasicModeButton")
|
||||
self.AdvModeButton = QtWidgets.QPushButton(self.Form)
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(207, 10, 210, 41))
|
||||
self.AdvModeButton.setGeometry(QtCore.QRect(260, 10, 156, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
@@ -324,6 +321,17 @@ class Ui_KCC(object):
|
||||
self.customHeight.setMaxLength(4)
|
||||
self.customHeight.setObjectName("customHeight")
|
||||
self.gridLayout_2.addWidget(self.customHeight, 0, 3, 1, 1)
|
||||
self.EditorButton = QtWidgets.QPushButton(self.Form)
|
||||
self.EditorButton.setGeometry(QtCore.QRect(160, 10, 101, 41))
|
||||
font = QtGui.QFont()
|
||||
font.setFamily("Lucida Grande")
|
||||
font.setPointSize(12)
|
||||
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")
|
||||
KCC.setCentralWidget(self.Form)
|
||||
self.statusBar = QtWidgets.QStatusBar(KCC)
|
||||
font = QtGui.QFont()
|
||||
@@ -393,6 +401,7 @@ class Ui_KCC(object):
|
||||
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.ActionBasic.setText(_translate("KCC", "Basic"))
|
||||
self.ActionAdvanced.setText(_translate("KCC", "Advanced"))
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
__version__ = '4.4.1'
|
||||
__version__ = '4.5'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
@@ -16,10 +16,6 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import sys
|
||||
import os
|
||||
from zipfile import is_zipfile, ZipFile
|
||||
@@ -27,7 +23,7 @@ from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen
|
||||
from shutil import move, copy
|
||||
from . import rarfile
|
||||
from .shared import check7ZFile as is_7zfile
|
||||
from .shared import check7ZFile as is_7zfile, saferReplace
|
||||
|
||||
|
||||
class CBxArchive:
|
||||
@@ -105,7 +101,7 @@ class CBxArchive:
|
||||
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)):
|
||||
os.replace(os.path.join(targetdir, adir[0], f), os.path.join(targetdir, adir[0], f + '-A'))
|
||||
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]))
|
||||
|
||||
@@ -18,40 +18,37 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
import sys
|
||||
from copy import copy
|
||||
from glob import glob
|
||||
from json import loads
|
||||
from urllib.request import Request, urlopen
|
||||
from re import split, sub
|
||||
from re import sub
|
||||
from stat import S_IWRITE, S_IREAD, S_IEXEC
|
||||
from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
|
||||
from tempfile import mkdtemp
|
||||
from shutil import move, copytree, rmtree
|
||||
from optparse import OptionParser, OptionGroup
|
||||
from multiprocessing import Pool
|
||||
from xml.dom.minidom import parse
|
||||
from uuid import uuid4
|
||||
from slugify import slugify as slugifyExt
|
||||
from PIL import Image
|
||||
from subprocess import STDOUT, PIPE
|
||||
from psutil import Popen, virtual_memory
|
||||
from scandir import walk
|
||||
try:
|
||||
from PyQt5 import QtCore
|
||||
except ImportError:
|
||||
QtCore = None
|
||||
from .shared import md5Checksum, getImageFileName, walkLevel
|
||||
from .shared import md5Checksum, getImageFileName, walkSort, walkLevel, saferReplace
|
||||
from . import comic2panel
|
||||
from . import image
|
||||
from . import cbxarchive
|
||||
from . import pdfjpgextract
|
||||
from . import dualmetafix
|
||||
from . import metadata
|
||||
from . import __version__
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
@@ -75,9 +72,10 @@ def main(argv=None):
|
||||
return outputPath
|
||||
|
||||
|
||||
def buildHTML(path, imgfile, imgfilepath):
|
||||
def buildHTML(path, imgfile, imgfilepath, forcePV=False):
|
||||
imgfilepath = md5Checksum(imgfilepath)
|
||||
filename = getImageFileName(imgfile)
|
||||
additionalStyle = ''
|
||||
if options.imgproc:
|
||||
if "Rotated" in options.imgIndex[imgfilepath]:
|
||||
rotatedPage = True
|
||||
@@ -95,11 +93,17 @@ def buildHTML(path, imgfile, imgfilepath):
|
||||
noVerticalPV = True
|
||||
else:
|
||||
noVerticalPV = False
|
||||
if "BlackFill" in options.imgIndex[imgfilepath]:
|
||||
additionalStyle = ' style="background-color:#000000" '
|
||||
else:
|
||||
rotatedPage = False
|
||||
noPV = False
|
||||
noHorizontalPV = False
|
||||
noVerticalPV = False
|
||||
if forcePV and noPV:
|
||||
noPV = False
|
||||
noHorizontalPV = True
|
||||
noVerticalPV = True
|
||||
htmlpath = ''
|
||||
postfix = ''
|
||||
backref = 1
|
||||
@@ -124,12 +128,13 @@ def buildHTML(path, imgfile, imgfilepath):
|
||||
"<link href=\"", "../" * (backref - 1),
|
||||
"style.css\" type=\"text/css\" rel=\"stylesheet\"/>\n",
|
||||
"</head>\n",
|
||||
"<body>\n",
|
||||
"<body" + additionalStyle + ">\n",
|
||||
"<div class=\"fs\">\n",
|
||||
"<div><img src=\"", "../" * backref, "Images/", postfix, imgfile, "\" alt=\"",
|
||||
imgfile, "\" class=\"singlePage\"/></div>\n"
|
||||
])
|
||||
if options.panelview and not noPV:
|
||||
if (options.panelview or forcePV) and not noPV:
|
||||
options.panelviewused = True
|
||||
if not noHorizontalPV and not noVerticalPV:
|
||||
if rotatedPage:
|
||||
if options.righttoleft:
|
||||
@@ -167,8 +172,8 @@ def buildHTML(path, imgfile, imgfilepath):
|
||||
f.writelines(["<div id=\"" + boxes[i] + "\"><a class=\"app-amzn-magnify\" data-app-amzn-magnify=",
|
||||
"'{\"targetId\":\"" + boxes[i] + "-Panel-Parent\", \"ordinal\":" + str(order[i]),
|
||||
"}'></a></div>\n"])
|
||||
if options.quality == 2:
|
||||
imgfilepv = str.split(imgfile, ".")
|
||||
if options.quality == 2 and not forcePV:
|
||||
imgfilepv = imgfile.split(".")
|
||||
imgfilepv[0] += "-hq"
|
||||
imgfilepv = ".".join(imgfilepv)
|
||||
else:
|
||||
@@ -215,10 +220,14 @@ def buildNCX(dstdir, title, chapters, chapterNames):
|
||||
])
|
||||
for chapter in chapters:
|
||||
folder = chapter[0].replace(os.path.join(dstdir, 'OEBPS'), '').lstrip('/').lstrip('\\\\')
|
||||
if os.path.basename(folder) != "Text":
|
||||
title = chapterNames[os.path.basename(folder)]
|
||||
filename = getImageFileName(os.path.join(folder, chapter[1]))
|
||||
f.write("<navPoint id=\"" + folder.replace('/', '_').replace('\\', '_') + "\"><navLabel><text>"
|
||||
navID = folder.replace('/', '_').replace('\\', '_')
|
||||
if options.chapters:
|
||||
title = chapterNames[chapter[1]]
|
||||
navID = filename[0].replace('/', '_').replace('\\', '_')
|
||||
elif os.path.basename(folder) != "Text":
|
||||
title = chapterNames[os.path.basename(folder)]
|
||||
f.write("<navPoint id=\"" + navID + "\"><navLabel><text>"
|
||||
+ title + "</text></navLabel><content src=\"" + filename[0].replace("\\", "/")
|
||||
+ ".html\"/></navPoint>\n")
|
||||
f.write("</navMap>\n</ncx>")
|
||||
@@ -304,6 +313,7 @@ def buildEPUB(path, chapterNames, tomeNumber):
|
||||
filelist = []
|
||||
chapterlist = []
|
||||
cover = None
|
||||
lastfile = None
|
||||
_, deviceres, _, _, panelviewsize = options.profileData
|
||||
os.mkdir(os.path.join(path, 'OEBPS', 'Text'))
|
||||
f = open(os.path.join(path, 'OEBPS', 'Text', 'style.css'), 'w', encoding='UTF-8')
|
||||
@@ -416,12 +426,14 @@ def buildEPUB(path, chapterNames, tomeNumber):
|
||||
"}",
|
||||
])
|
||||
f.close()
|
||||
for (dirpath, dirnames, filenames) in os.walk(os.path.join(path, 'OEBPS', 'Images')):
|
||||
for (dirpath, dirnames, filenames) in walk(os.path.join(path, 'OEBPS', 'Images')):
|
||||
chapter = False
|
||||
dirnames, filenames = walkSort(dirnames, filenames)
|
||||
for afile in filenames:
|
||||
filename = getImageFileName(afile)
|
||||
if '-kcc-hq' not in filename[0]:
|
||||
filelist.append(buildHTML(dirpath, afile, os.path.join(dirpath, afile)))
|
||||
lastfile = (dirpath, afile, os.path.join(dirpath, afile))
|
||||
if not chapter:
|
||||
chapterlist.append((dirpath.replace('Images', 'Text'), filelist[-1][1]))
|
||||
chapter = True
|
||||
@@ -429,32 +441,40 @@ def buildEPUB(path, chapterNames, tomeNumber):
|
||||
cover = os.path.join(os.path.join(path, 'OEBPS', 'Images'),
|
||||
'cover' + getImageFileName(filelist[-1][1])[1])
|
||||
image.Cover(os.path.join(filelist[-1][0], filelist[-1][1]), cover, options, tomeNumber)
|
||||
# Hack that force Panel View on at last one page
|
||||
if lastfile and not options.panelviewused and 'Ko' not in options.profile \
|
||||
and options.profile not in ['K1', 'K2', 'KDX', 'OTHER']:
|
||||
filelist[-1] = buildHTML(lastfile[0], lastfile[1], lastfile[2], True)
|
||||
# Overwrite chapternames if tree is flat and ComicInfo.xml has bookmarks
|
||||
if not chapterNames and options.chapters:
|
||||
chapterlist = []
|
||||
globaldiff = 0
|
||||
for aChapter in options.chapters:
|
||||
pageid = aChapter[0]
|
||||
for x in range(0, pageid + globaldiff + 1):
|
||||
if '-aaa-kcc' in filelist[x][1]:
|
||||
pageid += 1
|
||||
if '-bbb-kcc' in filelist[pageid][1]:
|
||||
pageid -= 1
|
||||
filename = filelist[pageid][1]
|
||||
chapterlist.append((filelist[pageid][0].replace('Images', 'Text'), filename))
|
||||
chapterNames[filename] = aChapter[1]
|
||||
globaldiff = pageid - (aChapter[0] + globaldiff)
|
||||
buildNCX(path, options.title, chapterlist, chapterNames)
|
||||
# Ensure we're sorting files alphabetically
|
||||
convert = lambda text: int(text) if text.isdigit() else text
|
||||
alphanum_key = lambda key: [convert(c) for c in split('([0-9]+)', key)]
|
||||
filelist.sort(key=lambda name: (alphanum_key(name[0].lower()), alphanum_key(name[1].lower())))
|
||||
buildOPF(path, options.title, filelist, cover)
|
||||
|
||||
|
||||
def imgOptimization(img, opt, hqImage=None):
|
||||
def imgOptimization(img, opt):
|
||||
if not img.fill:
|
||||
img.getImageFill()
|
||||
if not opt.webtoon:
|
||||
img.cropWhiteSpace()
|
||||
if opt.cutpagenumbers and not opt.webtoon:
|
||||
img.cutPageNumber()
|
||||
img.optimizeImage()
|
||||
if hqImage:
|
||||
img.resizeImage(0)
|
||||
img.calculateBorder(hqImage, True)
|
||||
else:
|
||||
img.autocontrastImage()
|
||||
img.resizeImage()
|
||||
if opt.panelview:
|
||||
if opt.quality == 0:
|
||||
img.calculateBorder(img)
|
||||
elif opt.quality == 1:
|
||||
img.calculateBorder(img, True)
|
||||
if not img.second and opt.panelview:
|
||||
img.calculateBorder()
|
||||
if opt.forcepng and not opt.forcecolor:
|
||||
img.quantizeImage()
|
||||
|
||||
@@ -467,7 +487,7 @@ def imgDirectoryProcessing(path):
|
||||
options.imgPurgeIndex = []
|
||||
work = []
|
||||
pagenumber = 0
|
||||
for (dirpath, dirnames, filenames) in os.walk(path):
|
||||
for (dirpath, dirnames, filenames) in walk(path):
|
||||
for afile in filenames:
|
||||
pagenumber += 1
|
||||
work.append([afile, dirpath, options])
|
||||
@@ -516,10 +536,6 @@ def imgFileProcessing(work):
|
||||
opt = work[2]
|
||||
output = []
|
||||
img = image.ComicPage(os.path.join(dirpath, afile), opt)
|
||||
if opt.quality == 2:
|
||||
wipe = False
|
||||
else:
|
||||
wipe = True
|
||||
if opt.nosplitrotate:
|
||||
splitter = None
|
||||
else:
|
||||
@@ -527,36 +543,30 @@ def imgFileProcessing(work):
|
||||
if splitter is not None:
|
||||
img0 = image.ComicPage(splitter[0], opt)
|
||||
imgOptimization(img0, opt)
|
||||
if not img0.noHQ:
|
||||
output.append(img0.saveToDir(dirpath))
|
||||
img1 = image.ComicPage(splitter[1], opt)
|
||||
imgOptimization(img1, opt)
|
||||
if not img1.noHQ:
|
||||
output.append(img1.saveToDir(dirpath))
|
||||
if wipe:
|
||||
output.append(img0.origFileName)
|
||||
output.append(img1.origFileName)
|
||||
output.extend([img.origFileName, img0.origFileName, img1.origFileName])
|
||||
if opt.quality == 2:
|
||||
img0b = image.ComicPage(splitter[0], opt, img0.fill)
|
||||
imgOptimization(img0b, opt, img0)
|
||||
output.extend([img0.origFileName, img1.origFileName])
|
||||
img0b = image.ComicPage(splitter[0], opt, img0)
|
||||
imgOptimization(img0b, opt)
|
||||
output.append(img0b.saveToDir(dirpath))
|
||||
img1b = image.ComicPage(splitter[1], opt, img1.fill)
|
||||
imgOptimization(img1b, opt, img1)
|
||||
img1b = image.ComicPage(splitter[1], opt, img1)
|
||||
imgOptimization(img1b, opt)
|
||||
output.append(img1b.saveToDir(dirpath))
|
||||
output.append(img0.origFileName)
|
||||
output.append(img1.origFileName)
|
||||
output.append(img.origFileName)
|
||||
else:
|
||||
output.append(img.origFileName)
|
||||
imgOptimization(img, opt)
|
||||
if not img.noHQ:
|
||||
output.append(img.saveToDir(dirpath))
|
||||
if wipe:
|
||||
output.append(img.origFileName)
|
||||
if opt.quality == 2:
|
||||
img2 = image.ComicPage(os.path.join(dirpath, afile), opt, img.fill)
|
||||
if img.rotated:
|
||||
img2.image = img2.image.rotate(90, Image.BICUBIC, True)
|
||||
img2.rotated = True
|
||||
imgOptimization(img2, opt, img)
|
||||
img2 = image.ComicPage(os.path.join(dirpath, afile), opt, img)
|
||||
imgOptimization(img2, opt)
|
||||
output.append(img2.saveToDir(dirpath))
|
||||
output.append(img.origFileName)
|
||||
return output
|
||||
except Exception:
|
||||
return str(sys.exc_info()[1])
|
||||
@@ -568,7 +578,7 @@ def getWorkFolder(afile):
|
||||
if os.path.isdir(afile):
|
||||
workdir = mkdtemp('', 'KCC-TMP-')
|
||||
try:
|
||||
os.rmdir(workdir) # needed for copytree() fails if dst already exists
|
||||
os.rmdir(workdir)
|
||||
fullPath = os.path.join(workdir, 'OEBPS', 'Images')
|
||||
if len(fullPath) > 240:
|
||||
raise UserWarning("Path is too long.")
|
||||
@@ -633,6 +643,7 @@ def getComicInfo(path, originalPath):
|
||||
xmlPath = os.path.join(path, 'ComicInfo.xml')
|
||||
options.authors = ['KCC']
|
||||
options.remoteCovers = {}
|
||||
options.chapters = []
|
||||
titleSuffix = ''
|
||||
if options.title == 'defaulttitle':
|
||||
defaultTitle = True
|
||||
@@ -644,57 +655,43 @@ def getComicInfo(path, originalPath):
|
||||
defaultTitle = False
|
||||
if os.path.exists(xmlPath):
|
||||
try:
|
||||
xml = parse(xmlPath)
|
||||
xml = metadata.MetadataParser(xmlPath)
|
||||
except Exception:
|
||||
os.remove(xmlPath)
|
||||
return
|
||||
options.authors = []
|
||||
if defaultTitle:
|
||||
if len(xml.getElementsByTagName('Series')) != 0:
|
||||
options.title = xml.getElementsByTagName('Series')[0].firstChild.nodeValue
|
||||
if len(xml.getElementsByTagName('Volume')) != 0:
|
||||
titleSuffix += ' V' + xml.getElementsByTagName('Volume')[0].firstChild.nodeValue
|
||||
if len(xml.getElementsByTagName('Number')) != 0:
|
||||
titleSuffix += ' #' + xml.getElementsByTagName('Number')[0].firstChild.nodeValue
|
||||
if xml.data['Series']:
|
||||
options.title = xml.data['Series']
|
||||
if xml.data['Volume']:
|
||||
titleSuffix += ' V' + xml.data['Volume']
|
||||
if xml.data['Number']:
|
||||
titleSuffix += ' #' + xml.data['Number']
|
||||
options.title += titleSuffix
|
||||
if len(xml.getElementsByTagName('Writer')) != 0:
|
||||
authorsTemp = str.split(xml.getElementsByTagName('Writer')[0].firstChild.nodeValue, ', ')
|
||||
for author in authorsTemp:
|
||||
options.authors.append(author)
|
||||
if len(xml.getElementsByTagName('Penciller')) != 0:
|
||||
authorsTemp = str.split(xml.getElementsByTagName('Penciller')[0].firstChild.nodeValue, ', ')
|
||||
for author in authorsTemp:
|
||||
options.authors.append(author)
|
||||
if len(xml.getElementsByTagName('Inker')) != 0:
|
||||
authorsTemp = str.split(xml.getElementsByTagName('Inker')[0].firstChild.nodeValue, ', ')
|
||||
for author in authorsTemp:
|
||||
options.authors.append(author)
|
||||
if len(xml.getElementsByTagName('Colorist')) != 0:
|
||||
authorsTemp = str.split(xml.getElementsByTagName('Colorist')[0].firstChild.nodeValue, ', ')
|
||||
for author in authorsTemp:
|
||||
options.authors.append(author)
|
||||
for field in ['Writers', 'Pencillers', 'Inkers', 'Colorists']:
|
||||
for person in xml.data[field]:
|
||||
options.authors.append(person)
|
||||
if len(options.authors) > 0:
|
||||
options.authors = list(set(options.authors))
|
||||
options.authors.sort()
|
||||
else:
|
||||
options.authors = ['KCC']
|
||||
# Disabled due to closure of MCD
|
||||
# if len(xml.getElementsByTagName('ScanInformation')) != 0:
|
||||
# coverId = xml.getElementsByTagName('ScanInformation')[0].firstChild.nodeValue
|
||||
# coverId = compile('(MCD\\()(\\d+)(\\))').search(coverId)
|
||||
# if coverId:
|
||||
# options.remoteCovers = getCoversFromMCB(coverId.group(2))
|
||||
if xml.data['MUid']:
|
||||
options.remoteCovers = getCoversFromMCB(xml.data['MUid'])
|
||||
if xml.data['Bookmarks']:
|
||||
options.chapters = xml.data['Bookmarks']
|
||||
os.remove(xmlPath)
|
||||
|
||||
|
||||
def getCoversFromMCB(mangaID):
|
||||
covers = {}
|
||||
try:
|
||||
jsonRaw = urlopen(Request('http://manga.joentjuh.nl/json/series/' + mangaID + '/',
|
||||
jsonRaw = urlopen(Request('http://mcd.iosphe.re/api/v1/series/' + mangaID + '/',
|
||||
headers={'User-Agent': 'KindleComicConverter/' + __version__}))
|
||||
jsonData = loads(jsonRaw.readall().decode('utf-8'))
|
||||
for volume in jsonData['volumes']:
|
||||
covers[int(volume['volume'])] = volume['releases'][0]['files']['front']['url']
|
||||
for volume in jsonData['Covers']['a']:
|
||||
if volume['Side'] == 'front':
|
||||
covers[int(volume['Volume'])] = volume['Raw']
|
||||
except Exception:
|
||||
return {}
|
||||
return covers
|
||||
@@ -702,7 +699,7 @@ def getCoversFromMCB(mangaID):
|
||||
|
||||
def getDirectorySize(start_path='.'):
|
||||
total_size = 0
|
||||
for dirpath, dirnames, filenames in os.walk(start_path):
|
||||
for dirpath, dirnames, filenames in walk(start_path):
|
||||
for f in filenames:
|
||||
fp = os.path.join(dirpath, f)
|
||||
total_size += os.path.getsize(fp)
|
||||
@@ -711,7 +708,7 @@ def getDirectorySize(start_path='.'):
|
||||
|
||||
def sanitizeTree(filetree):
|
||||
chapterNames = {}
|
||||
for root, dirs, files in os.walk(filetree, False):
|
||||
for root, dirs, files in walk(filetree, False):
|
||||
for name in files:
|
||||
splitname = os.path.splitext(name)
|
||||
slugified = slugify(splitname[0])
|
||||
@@ -721,7 +718,7 @@ def sanitizeTree(filetree):
|
||||
newKey = os.path.join(root, slugified + splitname[1])
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
os.replace(key, newKey)
|
||||
saferReplace(key, newKey)
|
||||
for name in dirs:
|
||||
tmpName = name
|
||||
slugified = slugify(name)
|
||||
@@ -731,15 +728,14 @@ def sanitizeTree(filetree):
|
||||
newKey = os.path.join(root, slugified)
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
os.replace(key, newKey)
|
||||
saferReplace(key, newKey)
|
||||
return chapterNames
|
||||
|
||||
|
||||
def sanitizeTreeKobo(filetree):
|
||||
pageNumber = 0
|
||||
for root, dirs, files in os.walk(filetree):
|
||||
files.sort()
|
||||
dirs.sort()
|
||||
for root, dirs, files in walk(filetree):
|
||||
dirs, files = walkSort(dirs, files)
|
||||
for name in files:
|
||||
splitname = os.path.splitext(name)
|
||||
slugified = str(pageNumber).zfill(5)
|
||||
@@ -750,11 +746,11 @@ def sanitizeTreeKobo(filetree):
|
||||
newKey = os.path.join(root, slugified + splitname[1])
|
||||
key = os.path.join(root, name)
|
||||
if key != newKey:
|
||||
os.replace(key, newKey)
|
||||
saferReplace(key, newKey)
|
||||
|
||||
|
||||
def sanitizePermissions(filetree):
|
||||
for root, dirs, files in os.walk(filetree, False):
|
||||
for root, dirs, files in walk(filetree, False):
|
||||
for name in files:
|
||||
os.chmod(os.path.join(root, name), S_IWRITE | S_IREAD)
|
||||
for name in dirs:
|
||||
@@ -886,7 +882,7 @@ def splitProcess(path, mode):
|
||||
|
||||
|
||||
def detectCorruption(tmpPath, orgPath):
|
||||
for root, dirs, files in os.walk(tmpPath, False):
|
||||
for root, dirs, files in walk(tmpPath, False):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
path = os.path.join(root, name)
|
||||
@@ -915,20 +911,20 @@ def detectMargins(path):
|
||||
yu = flag[2]
|
||||
xr = flag[3]
|
||||
yd = flag[4]
|
||||
if xl != "0":
|
||||
xl = "-" + str(float(xl)/100) + "%"
|
||||
if xl != "0.0":
|
||||
xl = "-" + xl + "%"
|
||||
else:
|
||||
xl = "0%"
|
||||
if xr != "0":
|
||||
xr = "-" + str(float(xr)/100) + "%"
|
||||
if xr != "0.0":
|
||||
xr = "-" + xr + "%"
|
||||
else:
|
||||
xr = "0%"
|
||||
if yu != "0":
|
||||
yu = "-" + str(float(yu)/100) + "%"
|
||||
if yu != "0.0":
|
||||
yu = "-" + yu + "%"
|
||||
else:
|
||||
yu = "0%"
|
||||
if yd != "0":
|
||||
yd = "-" + str(float(yd)/100) + "%"
|
||||
if yd != "0.0":
|
||||
yd = "-" + yd + "%"
|
||||
else:
|
||||
yd = "0%"
|
||||
return xl, yu, xr, yd
|
||||
@@ -953,7 +949,7 @@ def makeZIP(zipFilename, baseDir, isEPUB=False):
|
||||
zipOutput = ZipFile(zipFilename, 'w', ZIP_DEFLATED)
|
||||
if isEPUB:
|
||||
zipOutput.writestr('mimetype', 'application/epub+zip', ZIP_STORED)
|
||||
for dirpath, dirnames, filenames in os.walk(baseDir):
|
||||
for dirpath, dirnames, filenames in walk(baseDir):
|
||||
for name in filenames:
|
||||
path = os.path.normpath(os.path.join(dirpath, name))
|
||||
aPath = os.path.normpath(os.path.join(dirpath.replace(baseDir, ''), name))
|
||||
@@ -1034,6 +1030,7 @@ def makeParser():
|
||||
def checkOptions():
|
||||
global options
|
||||
options.panelview = True
|
||||
options.panelviewused = False
|
||||
options.bordersColor = None
|
||||
if options.format == 'Auto':
|
||||
if options.profile in ['K1', 'K2', 'K345', 'KPW', 'KV', 'KFHD', 'KFHDX', 'KFHDX8', 'KFA']:
|
||||
@@ -1131,9 +1128,6 @@ def makeBook(source, qtGUI=None):
|
||||
getComicInfo(os.path.join(path, "OEBPS", "Images"), source)
|
||||
detectCorruption(os.path.join(path, "OEBPS", "Images"), source)
|
||||
if options.webtoon:
|
||||
if options.customheight > 0:
|
||||
comic2panel.main(['-y ' + str(options.customheight), '-i', '-m', path], qtGUI)
|
||||
else:
|
||||
comic2panel.main(['-y ' + str(image.ProfileData.Profiles[options.profile][1][1]), '-i', '-m', path], qtGUI)
|
||||
if options.imgproc:
|
||||
print("\nProcessing images...")
|
||||
|
||||
@@ -18,18 +18,14 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
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
|
||||
from scandir import walk
|
||||
from .shared import getImageFileName, walkLevel, walkSort
|
||||
try:
|
||||
from PyQt5 import QtCore
|
||||
except ImportError:
|
||||
@@ -251,7 +247,8 @@ def main(argv=None, qtGUI=None):
|
||||
mergeWorkerOutput = []
|
||||
mergeWorkerPool = Pool()
|
||||
mergeWork.append([options.targetDir])
|
||||
for root, dirs, files in os.walk(options.targetDir, False):
|
||||
for root, dirs, files in walk(options.targetDir, False):
|
||||
dirs, files = walkSort(dirs, files)
|
||||
for directory in dirs:
|
||||
directoryNumer += 1
|
||||
mergeWork.append([os.path.join(root, directory)])
|
||||
@@ -269,7 +266,7 @@ def main(argv=None, qtGUI=None):
|
||||
rmtree(options.targetDir, True)
|
||||
raise RuntimeError("One of workers crashed. Cause: " + mergeWorkerOutput[0])
|
||||
print("\nSplitting images...")
|
||||
for root, dirs, files in os.walk(options.targetDir, False):
|
||||
for root, dirs, files in walk(options.targetDir, False):
|
||||
for name in files:
|
||||
if getImageFileName(name) is not None:
|
||||
pagenumber += 1
|
||||
|
||||
133
kcc/image.py
133
kcc/image.py
@@ -16,11 +16,6 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__version__ = '4.4.1'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
from io import BytesIO
|
||||
from urllib.request import Request, urlopen
|
||||
@@ -28,6 +23,7 @@ from urllib.parse import quote
|
||||
from functools import reduce
|
||||
from PIL import Image, ImageOps, ImageStat, ImageChops
|
||||
from .shared import md5Checksum
|
||||
from . import __version__
|
||||
|
||||
|
||||
class ProfileData:
|
||||
@@ -102,7 +98,7 @@ class ProfileData:
|
||||
|
||||
|
||||
class ComicPage:
|
||||
def __init__(self, source, options, fill=None):
|
||||
def __init__(self, source, options, original=None):
|
||||
try:
|
||||
self.profile_label, self.size, self.palette, self.gamma, self.panelviewsize = options.profileData
|
||||
except KeyError:
|
||||
@@ -111,18 +107,29 @@ class ComicPage:
|
||||
self.filename = os.path.basename(self.origFileName)
|
||||
self.image = Image.open(source)
|
||||
self.image = self.image.convert('RGB')
|
||||
self.opt = options
|
||||
if original:
|
||||
self.second = True
|
||||
self.rotated = original.rotated
|
||||
self.border = original.border
|
||||
self.noHPV = original.noHPV
|
||||
self.noVPV = original.noVPV
|
||||
self.noPV = original.noPV
|
||||
self.noHQ = original.noHQ
|
||||
self.fill = original.fill
|
||||
self.color = original.color
|
||||
if self.rotated:
|
||||
self.image = self.image.rotate(90, Image.BICUBIC, True)
|
||||
self.opt.quality = 0
|
||||
else:
|
||||
self.second = False
|
||||
self.rotated = None
|
||||
self.border = None
|
||||
self.noHPV = None
|
||||
self.noVPV = None
|
||||
self.noPV = None
|
||||
self.purge = False
|
||||
self.hq = False
|
||||
self.opt = options
|
||||
if fill:
|
||||
self.fill = fill
|
||||
else:
|
||||
self.fill = None
|
||||
self.noHQ = False
|
||||
if options.webtoon:
|
||||
self.color = True
|
||||
else:
|
||||
@@ -130,16 +137,12 @@ class ComicPage:
|
||||
|
||||
def saveToDir(self, targetdir):
|
||||
try:
|
||||
if not self.purge:
|
||||
flags = []
|
||||
filename = os.path.join(targetdir, os.path.splitext(self.filename)[0]) + '-KCC'
|
||||
if not self.opt.forcecolor and not self.opt.forcepng:
|
||||
self.image = self.image.convert('L')
|
||||
if self.rotated:
|
||||
flags.append('Rotated')
|
||||
if self.hq:
|
||||
flags.append('HighQuality')
|
||||
filename += '-HQ'
|
||||
if self.noPV:
|
||||
flags.append('NoPanelView')
|
||||
else:
|
||||
@@ -150,6 +153,10 @@ class ComicPage:
|
||||
if self.border:
|
||||
flags.append('Margins-' + str(self.border[0]) + '-' + str(self.border[1]) + '-'
|
||||
+ str(self.border[2]) + '-' + str(self.border[3]))
|
||||
if self.fill != 'white':
|
||||
flags.append('BlackFill')
|
||||
if self.opt.quality == 2:
|
||||
filename += '-HQ'
|
||||
if self.opt.forcepng:
|
||||
filename += '.png'
|
||||
self.image.save(filename, 'PNG', optimize=1)
|
||||
@@ -157,12 +164,10 @@ class ComicPage:
|
||||
filename += '.jpg'
|
||||
self.image.save(filename, 'JPEG', optimize=1, quality=80)
|
||||
return [md5Checksum(filename), flags]
|
||||
else:
|
||||
return None
|
||||
except IOError as e:
|
||||
raise RuntimeError('Cannot write image in directory %s: %s' % (targetdir, e))
|
||||
|
||||
def optimizeImage(self):
|
||||
def autocontrastImage(self):
|
||||
gamma = self.opt.gamma
|
||||
if gamma < 0.1:
|
||||
gamma = self.gamma
|
||||
@@ -184,80 +189,65 @@ class ComicPage:
|
||||
# Quantize is deprecated but new function call it internally anyway...
|
||||
self.image = self.image.quantize(palette=palImg)
|
||||
|
||||
def calculateBorderPercent(self, x, img, isWidth):
|
||||
if isWidth:
|
||||
return int(round(float(x)/float(img.image.size[0]), 4) * 10000 * 1.5)
|
||||
else:
|
||||
return int(round(float(x)/float(img.image.size[1]), 4) * 10000 * 1.5)
|
||||
|
||||
def calculateBorder(self, sourceImage, isHQ=False):
|
||||
if (isHQ and sourceImage.purge) or self.noPV:
|
||||
self.border = [0, 0, 0, 0]
|
||||
self.noPV = True
|
||||
def calculateBorder(self):
|
||||
if self.noPV:
|
||||
self.border = [0.0, 0.0, 0.0, 0.0]
|
||||
return
|
||||
if self.fill == 'white':
|
||||
# Only already saved files can have P mode. So we can break color quantization.
|
||||
if sourceImage.image.mode == 'P':
|
||||
sourceImage.image = sourceImage.image.convert('RGB')
|
||||
border = ImageChops.invert(sourceImage.image).getbbox()
|
||||
border = ImageChops.invert(self.image).getbbox()
|
||||
else:
|
||||
border = sourceImage.image.getbbox()
|
||||
if border is not None:
|
||||
if isHQ:
|
||||
border = self.image.getbbox()
|
||||
if self.opt.quality == 2:
|
||||
multiplier = 1.0
|
||||
else:
|
||||
multiplier = 1.5
|
||||
self.border = [self.calculateBorderPercent(border[0], sourceImage, True),
|
||||
self.calculateBorderPercent(border[1], sourceImage, False),
|
||||
self.calculateBorderPercent((sourceImage.image.size[0] - border[2]), sourceImage, True),
|
||||
self.calculateBorderPercent((sourceImage.image.size[1] - border[3]), sourceImage, False)]
|
||||
if int((border[2] - border[0]) * multiplier) < self.size[0]:
|
||||
if border is not None:
|
||||
self.border = [round(float(border[0])/float(self.image.size[0])*150, 3),
|
||||
round(float(border[1])/float(self.image.size[1])*150, 3),
|
||||
round(float(self.image.size[0]-border[2])/float(self.image.size[0])*150, 3),
|
||||
round(float(self.image.size[1]-border[3])/float(self.image.size[1])*150, 3)]
|
||||
if int((border[2] - border[0]) * multiplier) < self.size[0] + 10:
|
||||
self.noHPV = True
|
||||
if int((border[3] - border[1]) * multiplier) < self.size[1]:
|
||||
if int((border[3] - border[1]) * multiplier) < self.size[1] + 10:
|
||||
self.noVPV = True
|
||||
else:
|
||||
self.border = [0, 0, 0, 0]
|
||||
self.border = [0.0, 0.0, 0.0, 0.0]
|
||||
self.noHPV = True
|
||||
self.noVPV = True
|
||||
|
||||
def resizeImage(self, qualityMode=None):
|
||||
upscale = self.opt.upscale
|
||||
stretch = self.opt.stretch
|
||||
bordersColor = self.opt.bordersColor
|
||||
if qualityMode is None:
|
||||
qualityMode = self.opt.quality
|
||||
if bordersColor:
|
||||
fill = bordersColor
|
||||
def resizeImage(self):
|
||||
if self.opt.bordersColor:
|
||||
fill = self.opt.bordersColor
|
||||
else:
|
||||
fill = self.fill
|
||||
# Set target size
|
||||
if qualityMode == 0:
|
||||
if self.opt.quality == 0:
|
||||
size = (self.size[0], self.size[1])
|
||||
elif qualityMode == 1 and not stretch and not upscale and self.image.size[0] <=\
|
||||
elif self.opt.quality == 1 and not self.opt.stretch and not self.opt.upscale and self.image.size[0] <=\
|
||||
self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
size = (self.size[0], self.size[1])
|
||||
elif qualityMode == 1:
|
||||
elif self.opt.quality == 1:
|
||||
# Forcing upscale to make sure that margins will be not too big
|
||||
if not stretch:
|
||||
upscale = True
|
||||
if not self.opt.stretch:
|
||||
self.opt.upscale = True
|
||||
size = (self.panelviewsize[0], self.panelviewsize[1])
|
||||
elif qualityMode == 2 and not stretch and not upscale and self.image.size[0] <=\
|
||||
elif self.opt.quality == 2 and not self.opt.stretch and not self.opt.upscale and self.image.size[0] <=\
|
||||
self.size[0] and self.image.size[1] <= self.size[1]:
|
||||
self.purge = True
|
||||
return self.image
|
||||
# HQ version will not be needed
|
||||
self.noHQ = True
|
||||
return
|
||||
else:
|
||||
self.hq = True
|
||||
size = (self.panelviewsize[0], self.panelviewsize[1])
|
||||
# If stretching is on - Resize without other considerations
|
||||
if stretch:
|
||||
if self.opt.stretch:
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1]:
|
||||
method = Image.BICUBIC
|
||||
else:
|
||||
method = Image.LANCZOS
|
||||
self.image = self.image.resize(size, method)
|
||||
return self.image
|
||||
return
|
||||
# If image is smaller than target resolution and upscale is off - Just expand it by adding margins
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not upscale:
|
||||
if self.image.size[0] <= size[0] and self.image.size[1] <= size[1] and not self.opt.upscale:
|
||||
borderw = int((size[0] - self.image.size[0]) / 2)
|
||||
borderh = int((size[1] - self.image.size[1]) / 2)
|
||||
# PV is disabled when source image is smaller than device screen and upscale is off
|
||||
@@ -267,7 +257,7 @@ class ComicPage:
|
||||
# Border can't be float so sometimes image might be 1px too small/large
|
||||
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))
|
||||
return self.image
|
||||
return
|
||||
# Otherwise - Upscale/Downscale
|
||||
ratioDev = float(size[0]) / float(size[1])
|
||||
if (float(self.image.size[0]) / float(self.image.size[1])) < ratioDev:
|
||||
@@ -281,7 +271,7 @@ class ComicPage:
|
||||
else:
|
||||
method = Image.LANCZOS
|
||||
self.image = ImageOps.fit(self.image, size, method=method, centering=(0.5, 0.5))
|
||||
return self.image
|
||||
return
|
||||
|
||||
def splitPage(self, targetdir):
|
||||
width, height = self.image.size
|
||||
@@ -374,7 +364,6 @@ class ComicPage:
|
||||
else:
|
||||
diff = pageNumberCut1
|
||||
self.image = self.image.crop((0, 0, widthImg, heightImg - diff))
|
||||
return self.image
|
||||
|
||||
def cropWhiteSpace(self):
|
||||
if ImageChops.invert(self.image).getbbox() is not None:
|
||||
@@ -410,7 +399,6 @@ class ComicPage:
|
||||
diff += delta
|
||||
diff -= delta
|
||||
self.image = self.image.crop((0, 0, widthImg - diff, heightImg))
|
||||
return self.image
|
||||
|
||||
def getImageHistogram(self, image):
|
||||
histogram = image.histogram()
|
||||
@@ -512,7 +500,7 @@ class Cover:
|
||||
def processExternal(self):
|
||||
self.image = self.image.convert('RGB')
|
||||
self.image.thumbnail(self.options.profileData[1], Image.LANCZOS)
|
||||
self.save(True)
|
||||
self.save()
|
||||
|
||||
def trim(self):
|
||||
bg = Image.new(self.image.mode, self.image.size, self.image.getpixel((0, 0)))
|
||||
@@ -524,15 +512,8 @@ class Cover:
|
||||
else:
|
||||
return self.image
|
||||
|
||||
def save(self, external=False):
|
||||
if external:
|
||||
source = self.options.remoteCovers[self.tomeNumber].split('/')[-1]
|
||||
else:
|
||||
source = self.source
|
||||
def save(self):
|
||||
try:
|
||||
if os.path.splitext(source)[1].lower() == '.png':
|
||||
self.image.save(self.target, "PNG", optimize=1)
|
||||
else:
|
||||
self.image.save(self.target, "JPEG", optimize=1, quality=80)
|
||||
except IOError:
|
||||
raise RuntimeError('Failed to save cover')
|
||||
|
||||
169
kcc/metadata.py
Normal file
169
kcc/metadata.py
Normal file
@@ -0,0 +1,169 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# 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 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
|
||||
|
||||
|
||||
class MetadataParser:
|
||||
def __init__(self, source):
|
||||
self.source = source
|
||||
self.data = {'Series': '',
|
||||
'Volume': '',
|
||||
'Number': '',
|
||||
'Writers': [],
|
||||
'Pencillers': [],
|
||||
'Inkers': [],
|
||||
'Colorists': [],
|
||||
'MUid': '',
|
||||
'Bookmarks': []}
|
||||
self.rawdata = None
|
||||
self.compressor = None
|
||||
if self.source.endswith('.xml'):
|
||||
self.rawdata = parse(self.source)
|
||||
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-TMP-')
|
||||
tmpXML = os.path.join(workdir, 'ComicInfo.xml')
|
||||
output = Popen('7za e "' + self.source + '" ComicInfo.xml -o"' + workdir + '"',
|
||||
stdout=PIPE, stderr=STDOUT, 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
|
||||
if os.path.isfile(tmpXML):
|
||||
self.rawdata = parse(tmpXML)
|
||||
rmtree(workdir)
|
||||
else:
|
||||
raise OSError
|
||||
if self.rawdata:
|
||||
self.parseXML()
|
||||
|
||||
def parseXML(self):
|
||||
if len(self.rawdata.getElementsByTagName('Series')) != 0:
|
||||
self.data['Series'] = self.rawdata.getElementsByTagName('Series')[0].firstChild.nodeValue
|
||||
if len(self.rawdata.getElementsByTagName('Volume')) != 0:
|
||||
self.data['Volume'] = self.rawdata.getElementsByTagName('Volume')[0].firstChild.nodeValue
|
||||
if len(self.rawdata.getElementsByTagName('Number')) != 0:
|
||||
self.data['Number'] = self.rawdata.getElementsByTagName('Number')[0].firstChild.nodeValue
|
||||
for field in ['Writer', 'Penciller', 'Inker', 'Colorist']:
|
||||
if len(self.rawdata.getElementsByTagName(field)) != 0:
|
||||
for person in self.rawdata.getElementsByTagName(field)[0].firstChild.nodeValue.split(', '):
|
||||
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:
|
||||
self.data['Bookmarks'].append((int(page.attributes['Image'].value),
|
||||
page.attributes['Bookmark'].value))
|
||||
|
||||
def saveXML(self):
|
||||
if self.rawdata:
|
||||
root = self.rawdata.getElementsByTagName('ComicInfo')[0]
|
||||
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'])],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
if self.rawdata.getElementsByTagName(row[0]):
|
||||
node = self.rawdata.getElementsByTagName(row[0])[0]
|
||||
if row[1]:
|
||||
node.firstChild.replaceWholeText(row[1])
|
||||
else:
|
||||
root.removeChild(node)
|
||||
elif row[1]:
|
||||
main = self.rawdata.createElement(row[0])
|
||||
root.appendChild(main)
|
||||
text = self.rawdata.createTextNode(row[1])
|
||||
main.appendChild(text)
|
||||
else:
|
||||
doc = Document()
|
||||
root = doc.createElement('ComicInfo')
|
||||
root.setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema')
|
||||
root.setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
|
||||
doc.appendChild(root)
|
||||
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'])],
|
||||
['ScanInformation', 'MCD(' + self.data['MUid'] + ')' if self.data['MUid'] else '']):
|
||||
if row[1]:
|
||||
main = doc.createElement(row[0])
|
||||
root.appendChild(main)
|
||||
text = doc.createTextNode(row[1])
|
||||
main.appendChild(text)
|
||||
self.rawdata = doc
|
||||
if self.source.endswith('.xml'):
|
||||
with open(self.source, 'w', encoding='utf-8') as f:
|
||||
self.rawdata.writexml(f, encoding='utf-8')
|
||||
else:
|
||||
workdir = mkdtemp('', 'KCC-TMP-')
|
||||
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, 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
|
||||
rmtree(workdir)
|
||||
@@ -19,10 +19,6 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
from random import choice
|
||||
from string import ascii_uppercase, digits
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = '2012-2015, Ciro Mattia Gonano <ciromattia@gmail.com>, Pawel Jastrzebski <pawelj@iosphe.re>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import os
|
||||
from hashlib import md5
|
||||
from html.parser import HTMLParser
|
||||
from distutils.version import StrictVersion
|
||||
from time import sleep
|
||||
from shutil import rmtree, move
|
||||
from tempfile import mkdtemp
|
||||
from zipfile import ZipFile, ZIP_DEFLATED
|
||||
from re import split
|
||||
try:
|
||||
from scandir import walk
|
||||
except ImportError:
|
||||
walk = None
|
||||
|
||||
|
||||
class HTMLStripper(HTMLParser):
|
||||
@@ -49,11 +54,20 @@ def getImageFileName(imgfile):
|
||||
return [name, ext]
|
||||
|
||||
|
||||
def walkSort(dirnames, filenames):
|
||||
convert = lambda text: int(text) if text.isdigit() else text
|
||||
alphanum_key = lambda key: [convert(c) for c in split('([0-9]+)', key)]
|
||||
dirnames.sort(key=lambda name: alphanum_key(name.lower()))
|
||||
filenames.sort(key=lambda name: alphanum_key(name.lower()))
|
||||
return dirnames, filenames
|
||||
|
||||
|
||||
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 os.walk(some_dir):
|
||||
for root, dirs, files in walk(some_dir):
|
||||
dirs, files = walkSort(dirs, files)
|
||||
yield root, dirs, files
|
||||
num_sep_this = root.count(os.path.sep)
|
||||
if num_sep + level <= num_sep_this:
|
||||
@@ -77,6 +91,32 @@ def check7ZFile(filePath):
|
||||
return header == b"7z\xbc\xaf'\x1c"
|
||||
|
||||
|
||||
def saferReplace(old, new):
|
||||
for x in range(5):
|
||||
try:
|
||||
os.replace(old, new)
|
||||
except PermissionError:
|
||||
sleep(5)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise PermissionError
|
||||
|
||||
|
||||
def removeFromZIP(zipfname, *filenames):
|
||||
tempdir = mkdtemp('', 'KCC-TMP-')
|
||||
try:
|
||||
tempname = os.path.join(tempdir, 'KCC-TMP.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))
|
||||
move(tempname, zipfname)
|
||||
finally:
|
||||
rmtree(tempdir)
|
||||
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
def dependencyCheck(level):
|
||||
missing = []
|
||||
@@ -106,13 +146,12 @@ def dependencyCheck(level):
|
||||
missing.append('Pillow 2.7.0+')
|
||||
except ImportError:
|
||||
missing.append('Pillow 2.7.0+')
|
||||
if len(missing) > 0:
|
||||
try:
|
||||
import tkinter
|
||||
import tkinter.messagebox
|
||||
importRoot = tkinter.Tk()
|
||||
importRoot.withdraw()
|
||||
tkinter.messagebox.showerror('KCC - Error', 'ERROR: ' + ', '.join(missing) + ' is not installed!')
|
||||
from scandir import __version__ as scandirVersion
|
||||
if StrictVersion('0.9') > StrictVersion(scandirVersion):
|
||||
missing.append('scandir 0.9+')
|
||||
except ImportError:
|
||||
missing.append('scandir 0.9+')
|
||||
if len(missing) > 0:
|
||||
print('ERROR: ' + ', '.join(missing) + ' is not installed!')
|
||||
exit(1)
|
||||
8
setup.py
8
setup.py
@@ -9,12 +9,13 @@ Usage (Mac OS X):
|
||||
python setup.py py2app
|
||||
"""
|
||||
from sys import platform, version_info
|
||||
from kcc import __version__
|
||||
if version_info[0] != 3:
|
||||
print('ERROR: This is Python 3 script!')
|
||||
exit(1)
|
||||
|
||||
NAME = "KindleComicConverter"
|
||||
VERSION = "4.4.1"
|
||||
VERSION = __version__
|
||||
MAIN = "kcc.py"
|
||||
|
||||
if platform == "darwin":
|
||||
@@ -54,9 +55,9 @@ if platform == "darwin":
|
||||
elif platform == "win32":
|
||||
# noinspection PyUnresolvedReferences
|
||||
import py2exe
|
||||
import platform as arch
|
||||
import platform
|
||||
from distutils.core import setup
|
||||
if arch.architecture()[0] == '64bit':
|
||||
if platform.architecture()[0] == '64bit':
|
||||
suffix = '_64'
|
||||
else:
|
||||
suffix = ''
|
||||
@@ -70,7 +71,6 @@ elif platform == "win32":
|
||||
'C:\Python34' + suffix + '\Lib\site-packages\PyQt5\libEGL.dll'])]
|
||||
extra_options = dict(
|
||||
options={'py2exe': {"bundle_files": 1,
|
||||
"dll_excludes": ["tcl85.dll", "tk85.dll"],
|
||||
"dist_dir": "dist" + suffix,
|
||||
"compressed": True,
|
||||
"includes": ["sip"],
|
||||
|
||||
4
setup.sh
4
setup.sh
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
# Linux Python package build script
|
||||
|
||||
VERSION="4.4.1"
|
||||
VERSION="4.5"
|
||||
|
||||
cp kcc.py __main__.py
|
||||
zip kcc.zip __main__.py kcc/*.py
|
||||
@@ -21,5 +21,5 @@ echo "#!/usr/bin/env python3" > kcc-c2p-bin
|
||||
cat kcc-c2p.zip >> kcc-c2p-bin
|
||||
chmod +x kcc-c2p-bin
|
||||
|
||||
tar --xform s:^.*/:: --xform s/kcc-bin/kcc/ --xform s/kcc-c2p-bin/kcc-c2p/ --xform s/kcc-c2e-bin/kcc-c2e/ --xform s/comic2ebook/kcc/ -czf KindleComicConverter_linux_$VERSION.tar.gz kcc-bin kcc-c2e-bin kcc-c2p-bin LICENSE.txt icons/comic2ebook.png
|
||||
tar --xform s:^.*/:: --xform s/kcc-bin/kcc/ --xform s/kcc-c2p-bin/kcc-c2p/ --xform s/kcc-c2e-bin/kcc-c2e/ --xform s/comic2ebook/kcc/ -czf KindleComicConverter_linux_${VERSION}.tar.gz kcc-bin kcc-c2e-bin kcc-c2p-bin LICENSE.txt icons/comic2ebook.png
|
||||
rm __main__.py kcc.zip kcc-c2e.zip kcc-c2p.zip kcc-bin kcc-c2e-bin kcc-c2p-bin
|
||||
Reference in New Issue
Block a user