diff --git a/autotagprogresswindow.py b/autotagprogresswindow.py
new file mode 100644
index 0000000..ad0b36b
--- /dev/null
+++ b/autotagprogresswindow.py
@@ -0,0 +1,60 @@
+"""
+A PyQT4 dialog to show ID log and progress
+"""
+
+"""
+Copyright 2012 Anthony Beville
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import sys
+from PyQt4 import QtCore, QtGui, uic
+import os
+from settings import ComicTaggerSettings
+
+
+class AutoTagProgressWindow(QtGui.QDialog):
+
+
+ def __init__(self, parent):
+ super(AutoTagProgressWindow, self).__init__(parent)
+
+ uic.loadUi(os.path.join(ComicTaggerSettings.baseDir(), 'autotagprogresswindow.ui' ), self)
+ self.lblTest.setPixmap(QtGui.QPixmap(os.path.join(ComicTaggerSettings.baseDir(), 'graphics/nocover.png' )))
+ self.lblArchive.setPixmap(QtGui.QPixmap(os.path.join(ComicTaggerSettings.baseDir(), 'graphics/nocover.png' )))
+ self.isdone = False
+
+ def setArchiveImage( self, img_data):
+ self.setCoverImage( img_data, self.lblArchive )
+
+ def setTestImage( self, img_data):
+ self.setCoverImage( img_data, self.lblTest )
+
+ def setCoverImage( self, img_data , label):
+ if img_data is not None:
+ img = QtGui.QImage()
+ img.loadFromData( img_data )
+ label.setPixmap(QtGui.QPixmap(img))
+ label.setScaledContents(True)
+ else:
+ label.setPixmap(QtGui.QPixmap(os.path.join(ComicTaggerSettings.baseDir(), 'graphics/nocover.png' )))
+ label.setScaledContents(True)
+ QtCore.QCoreApplication.processEvents()
+ QtCore.QCoreApplication.processEvents()
+
+ def reject(self):
+ QtGui.QDialog.reject(self)
+ self.isdone = True
+
+
\ No newline at end of file
diff --git a/autotagprogresswindow.ui b/autotagprogresswindow.ui
new file mode 100644
index 0000000..13cf566
--- /dev/null
+++ b/autotagprogresswindow.ui
@@ -0,0 +1,152 @@
+
+
+ dialogIssueSelect
+
+
+
+ 0
+ 0
+ 865
+ 413
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ Issue Identification Progress
+
+
+ -
+
+
-
+
+
+ 0
+
+
+ false
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ Courier New
+ 75
+ true
+
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel
+
+
+ true
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 110
+ 165
+
+
+
+
+ 110
+ 165
+
+
+
+ TextLabel
+
+
+
+ -
+
+
+
+ 110
+ 165
+
+
+
+
+ 110
+ 165
+
+
+
+ TextLabel
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ dialogIssueSelect
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ dialogIssueSelect
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/autotagstartwindow.py b/autotagstartwindow.py
index 3daca55..bfbe3df 100644
--- a/autotagstartwindow.py
+++ b/autotagstartwindow.py
@@ -38,12 +38,15 @@ class AutoTagStartWindow(QtGui.QDialog):
self.settings = settings
self.cbxNoAutoSaveOnLow.setCheckState( QtCore.Qt.Unchecked )
+ self.cbxDontUseYear.setCheckState( QtCore.Qt.Unchecked )
self.noAutoSaveOnLow = False
+ self.dontUseYear = False
def accept( self ):
QtGui.QDialog.accept(self)
self.noAutoSaveOnLow = self.cbxNoAutoSaveOnLow.isChecked()
+ self.dontUseYear = self.cbxDontUseYear.isChecked()
\ No newline at end of file
diff --git a/autotagstartwindow.ui b/autotagstartwindow.ui
index f43489e..3b46aed 100644
--- a/autotagstartwindow.ui
+++ b/autotagstartwindow.ui
@@ -50,6 +50,13 @@
+ -
+
+
+ Don't use publication year in indentification process
+
+
+
-
diff --git a/comictagger.py b/comictagger.py
index 5890320..04e6b4e 100755
--- a/comictagger.py
+++ b/comictagger.py
@@ -294,7 +294,7 @@ def process_file_cli( filename, opts, settings, match_results ):
if not opts.dryrun:
md = ca.readMetadata( opts.copy_source )
- if settings.apply_cbl_transform_on_bulk_operation:
+ if settings.apply_cbl_transform_on_bulk_operation and opts.data_style == MetaDataStyle.CBI:
md = CBLTransformer( md, settings ).apply()
if not ca.writeMetadata( md, opts.data_style ):
diff --git a/filerenamer.py b/filerenamer.py
index 417002c..644fdd5 100644
--- a/filerenamer.py
+++ b/filerenamer.py
@@ -106,7 +106,10 @@ class FileRenamer:
new_name += ext
+ # some tweaks to keep various filesystems happy
new_name = new_name.replace("/", "-")
+ new_name = new_name.replace(":", "-")
+
return new_name
diff --git a/fileselectionlist.ui b/fileselectionlist.ui
index 1b69370..0770453 100644
--- a/fileselectionlist.ui
+++ b/fileselectionlist.ui
@@ -41,13 +41,19 @@
File
+
+ File Name
+
+
+ AlignHCenter|AlignVCenter|AlignCenter
+
CR
-
+ Has ComicRack Tags
AlignHCenter|AlignVCenter|AlignCenter
@@ -57,6 +63,9 @@
CBL
+
+ Has ComicBookLover Tags
+
AlignHCenter|AlignVCenter|AlignCenter
@@ -65,16 +74,34 @@
Type
+
+ Archive Type
+
+
+ AlignHCenter|AlignVCenter|AlignCenter
+
R/O
+
+ Read-Only
+
+
+ AlignHCenter|AlignVCenter|AlignCenter
+
Folder
+
+ File Location
+
+
+ AlignHCenter|AlignVCenter|AlignCenter
+
diff --git a/issueidentifier.py b/issueidentifier.py
index 2ad08a9..42e7874 100644
--- a/issueidentifier.py
+++ b/issueidentifier.py
@@ -72,6 +72,7 @@ class IssueIdentifier:
self.additional_metadata = GenericMetadata()
self.output_function = IssueIdentifier.defaultWriteOutput
self.callback = None
+ self.coverUrlCallback = None
self.search_result = self.ResultNoMatches
self.cover_page_index = 0
@@ -97,7 +98,7 @@ class IssueIdentifier:
def setOutputFunction( self, func ):
self.output_function = func
pass
-
+
def calculateHash( self, image_data ):
if self.image_hasher == '3':
return ImageHasher( data=image_data ).dct_average_hash()
@@ -130,6 +131,9 @@ class IssueIdentifier:
def setProgressCallback( self, cb_func ):
self.callback = cb_func
+
+ def setCoverURLCallback( self, cb_func ):
+ self.coverUrlCallback = cb_func
def getSearchKeys( self ):
@@ -306,7 +310,6 @@ class IssueIdentifier:
if self.callback is not None:
self.callback( 0, len(series_shortlist))
-
# now sort the list by name length
series_shortlist.sort(key=lambda x: len(x['name']), reverse=False)
@@ -358,6 +361,9 @@ class IssueIdentifier:
self.match_list = []
return self.match_list
+ if self.coverUrlCallback is not None:
+ self.coverUrlCallback( url_image_data )
+
url_image_hash = self.calculateHash( url_image_data )
score = ImageHasher.hamming_distance(cover_hash, url_image_hash)
@@ -387,7 +393,6 @@ class IssueIdentifier:
break
self.log_msg( "" )
-
if len(self.match_list) == 0:
self.log_msg( ":-( no matches!" )
diff --git a/renamewindow.py b/renamewindow.py
index b7b4f6b..5d5b4dc 100644
--- a/renamewindow.py
+++ b/renamewindow.py
@@ -23,6 +23,8 @@ from PyQt4 import QtCore, QtGui, uic
from settings import ComicTaggerSettings
from settingswindow import SettingsWindow
from filerenamer import FileRenamer
+from options import MetaDataStyle
+
import os
import utils
@@ -32,6 +34,7 @@ class RenameWindow(QtGui.QDialog):
super(RenameWindow, self).__init__(parent)
uic.loadUi(os.path.join(ComicTaggerSettings.baseDir(), 'renamewindow.ui' ), self)
+ self.label.setText("Preview (based on {0} tags):".format(MetaDataStyle.name[data_style]))
self.settings = settings
self.comic_archive_list = comic_archive_list
diff --git a/settingswindow.ui b/settingswindow.ui
index 827815d..b4d85b1 100644
--- a/settingswindow.ui
+++ b/settingswindow.ui
@@ -334,7 +334,7 @@
-
- Apply CBL Transforms on Batch/CLI Operations
+ Apply CBL Transforms on Batch Copy Operations to CBL Tags
diff --git a/taggerwindow.py b/taggerwindow.py
index 92529d6..2613127 100644
--- a/taggerwindow.py
+++ b/taggerwindow.py
@@ -51,6 +51,7 @@ from exportwindow import ExportWindow, ExportConflictOpts
from pageloader import PageLoader
from issueidentifier import IssueIdentifier
from autotagstartwindow import AutoTagStartWindow
+from autotagprogresswindow import AutoTagProgressWindow
import utils
import ctversion
@@ -489,7 +490,6 @@ class TaggerWindow( QtGui.QMainWindow):
self.lblCover.setPixmap(QtGui.QPixmap(img))
self.lblCover.setScaledContents(True)
-
def updateMenus( self ):
# First just disable all the questionable items
@@ -1468,7 +1468,7 @@ class TaggerWindow( QtGui.QMainWindow):
print "Network error while getting issue details. Save aborted"
if cv_md is not None:
- if self.settings.apply_cbl_transform_on_bulk_operation:
+ if self.settings.apply_cbl_transform_on_cv_import:
cv_md = CBLTransformer( cv_md, self.settings ).apply()
QtGui.QApplication.restoreOverrideCursor()
@@ -1476,7 +1476,7 @@ class TaggerWindow( QtGui.QMainWindow):
return cv_md
- def identifyAndTagSingleArchive( self, ca, match_results, abortOnLowConfidence ):
+ def identifyAndTagSingleArchive( self, ca, match_results, abortOnLowConfidence, dontUseYear ):
success = False
ii = IssueIdentifier( ca, self.settings )
@@ -1491,14 +1491,20 @@ class TaggerWindow( QtGui.QMainWindow):
def myoutput( text ):
IssueIdentifier.defaultWriteOutput( text )
+ self.atprogdialog.textEdit.ensureCursorVisible()
+ self.atprogdialog.textEdit.insertPlainText(text)
QtCore.QCoreApplication.processEvents()
QtCore.QCoreApplication.processEvents()
QtCore.QCoreApplication.processEvents()
+ if dontUseYear:
+ md.year = None
ii.setAdditionalMetadata( md )
ii.onlyUseAdditionalMetaData = True
ii.setOutputFunction( myoutput )
ii.cover_page_index = md.getCoverPageIndexList()[0]
+ ii.setCoverURLCallback( self.atprogdialog.setTestImage )
+
matches = ii.search()
result = ii.search_result
@@ -1569,41 +1575,66 @@ class TaggerWindow( QtGui.QMainWindow):
dlg.setModal( True )
if not dlg.exec_():
return
-
- progdialog = QtGui.QProgressDialog("", "Cancel", 0, len(ca_list), self)
- progdialog.setWindowTitle( "Auto-Tagging" )
- progdialog.setWindowModality(QtCore.Qt.WindowModal)
- progdialog.show()
+
+
+ self.atprogdialog = AutoTagProgressWindow( self)
+ self.atprogdialog.setModal(True)
+ #self.progdialog.rejected.connect( self.identifyCancel )
+ self.atprogdialog.show()
+ self.atprogdialog.progressBar.setMaximum( len(ca_list) )
+ self.atprogdialog.setWindowTitle( "Auto-Tagging" )
+
prog_idx = 0
match_results = OnlineMatchResults()
for ca in ca_list:
+ cover_idx = ca.readMetadata(style).getCoverPageIndexList()[0]
+ image_data = ca.getPage( cover_idx )
+ self.atprogdialog.setArchiveImage( image_data )
+ self.atprogdialog.setTestImage( None )
+
QtCore.QCoreApplication.processEvents()
- if progdialog.wasCanceled():
+ if self.atprogdialog.isdone:
break
- progdialog.setValue(prog_idx)
+ self.atprogdialog.progressBar.setValue( prog_idx )
prog_idx += 1
- progdialog.setLabelText( ca.path )
- progdialog.setAutoClose( False )
+ self.atprogdialog.label.setText( ca.path )
QtCore.QCoreApplication.processEvents()
if ca.isWritable():
- success, match_results = self.identifyAndTagSingleArchive( ca, match_results, dlg.noAutoSaveOnLow )
+ success, match_results = self.identifyAndTagSingleArchive( ca, match_results, dlg.noAutoSaveOnLow, dlg.dontUseYear )
- #if not success:
- # QtGui.QMessageBox.warning(self, self.tr("Auto-Tag failed"),
- # self.tr("The tagging operation seemed to fail for {0} Operation aborted!".format(ca.path)))
- # break
-
- print "Good", match_results.goodMatches
- print "multipleMatches", match_results.multipleMatches
- print "noMatches", match_results.noMatches
- print "fetchDataFailures", match_results.fetchDataFailures
- print "writeFailures", match_results.writeFailures
-
- progdialog.close()
+ self.atprogdialog.close()
self.fileSelectionList.updateSelectedRows()
self.loadArchive( self.fileSelectionList.getCurrentArchive() )
+ self.atprogdialog = None
+
+ summary = ""
+ summary += "Successfully tagged archives: {0}\n".format( len(match_results.goodMatches))
+
+ if len ( match_results.multipleMatches ) > 0:
+ summary += "Archives with multiple matches: {0}\n".format( len(match_results.multipleMatches))
+ if len ( match_results.noMatches ) > 0:
+ summary += "Archives with no matches: {0}\n".format( len(match_results.noMatches))
+ if len ( match_results.fetchDataFailures ) > 0:
+ summary += "Archives that failed due to data fetch errors: {0}\n".format( len(match_results.fetchDataFailures))
+ if len ( match_results.writeFailures ) > 0:
+ summary += "Archives that failed due to file writing errors: {0}\n".format( len(match_results.writeFailures))
+
+ if len ( match_results.multipleMatches ) > 0:
+ summary += "\n\nDo you want to manually select the ones with multiple matches now?"
+
+ reply = QtGui.QMessageBox.question(self,
+ self.tr("Auto-Tag Summary"),
+ self.tr(summary),
+ QtGui.QMessageBox.Yes, QtGui.QMessageBox.No )
+
+ if reply == QtGui.QMessageBox.Yes:
+ print "TBD"
+ else:
+ QtGui.QMessageBox.information(self, self.tr("Auto-Tag Summary"), self.tr(summary))
+
+
diff --git a/todo.txt b/todo.txt
index 42752f7..4b34cec 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,36 +2,34 @@
Features
-----------------------------------------------------
+Re-arrange main form layout
+
+New menu graphics
+ auto tag
+ open folder vs file
+
Multi-file:
File list:
-
Delete archive function??
+ change menu order
+
Batch Functions:
-
- Batch Auto-Select
- Start/Options Dialog
- Progress Dialog - maybe reuse
- -Show compared images to show progress in a sexy way
+ Auto-Tag
Interactive dialog at end
Summary Dialog
Rename
check-box for rows?
-
- Batch Tag Copy
- Disallow overwrites?
-
+ manual edit the preview?
-----------------------------------------------------
Bugs
-----------------------------------------------------
-Ultimate Spider-Man files can't be read
- square bracket in folder name
-
(python:4401): GLib-ERROR **: Creating pipes for GWakeup: Too many open files
+
-----------------------------------------------------
Big Future Features
-----------------------------------------------------