diff --git a/issueidentifier.py b/issueidentifier.py
index 8927220..6bc186e 100644
--- a/issueidentifier.py
+++ b/issueidentifier.py
@@ -39,6 +39,7 @@ class IssueIdentifier:
self.min_score_distance = 2
self.additional_metadata = GenericMetadata()
self.cv_api_key = cv_api_key
+ self.output_function = IssueIdentifier.defaultWriteOutput
def setScoreMinThreshold( self, thresh ):
self.min_score_thresh = thresh
@@ -52,6 +53,10 @@ class IssueIdentifier:
def setHasherAlgorithm( self, algo ):
self.image_hasher = algo
pass
+
+ def setOutputFunction( self, func ):
+ self.output_function = func
+ pass
def calculateHash( self, image_data ):
if self.image_hasher == '3':
@@ -118,57 +123,60 @@ class IssueIdentifier:
search_keys['month'] = md_from_filename.publicationMonth
return search_keys
-
+
@staticmethod
- def log_msg( msg , newline=True ):
- sys.stdout.write(msg)
- if newline:
- sys.stdout.write("\n")
+ def defaultWriteOutput( text ):
+ sys.stdout.write(text)
sys.stdout.flush()
+ def log_msg( self, msg , newline=True ):
+ self.output_function(msg)
+ if newline:
+ self.output_function("\n")
+
def search( self ):
ca = self.comic_archive
if not ca.seemsToBeAComicArchive():
- IssueIdentifier.log_msg( "Sorry, but "+ opts.filename + " is not a comic archive!")
- return
+ self.log_msg( "Sorry, but "+ opts.filename + " is not a comic archive!")
+ return []
cover_image_data = ca.getCoverPage()
cover_hash = self.calculateHash( cover_image_data )
- #IssueIdentifier.log_msg( "Cover hash = {0:016x}".format(cover_hash) )
+ #self.log_msg( "Cover hash = {0:016x}".format(cover_hash) )
keys = self.getSearchKeys()
# we need, at minimum, a series and issue number
if keys['series'] is None or keys['issue_number'] is None:
- IssueIdentifier.log_msg("Not enough info for a search!")
- return None
+ self.log_msg("Not enough info for a search!")
+ return []
"""
- IssueIdentifier.log_msg( "Going to search for:" )
- IssueIdentifier.log_msg( "Series: " + keys['series'] )
- IssueIdentifier.log_msg( "Issue : " + keys['issue_number'] )
+ self.log_msg( "Going to search for:" )
+ self.log_msg( "Series: " + keys['series'] )
+ self.log_msg( "Issue : " + keys['issue_number'] )
if keys['year'] is not None:
- IssueIdentifier.log_msg( "Year : " + keys['year'] )
+ self.log_msg( "Year : " + keys['year'] )
if keys['month'] is not None:
- IssueIdentifier.log_msg( "Month : " + keys['month'] )
+ self.log_msg( "Month : " + keys['month'] )
"""
comicVine = ComicVineTalker( self.cv_api_key )
- #IssueIdentifier.log_msg( ( "Searching for " + keys['series'] + "...")
- IssueIdentifier.log_msg( "Searching for {0} #{1} ...".format( keys['series'], keys['issue_number']) )
+ #self.log_msg( ( "Searching for " + keys['series'] + "...")
+ self.log_msg( "Searching for {0} #{1} ...".format( keys['series'], keys['issue_number']) )
keys['series'] = utils.removearticles( keys['series'] )
cv_search_results = comicVine.searchForSeries( keys['series'] )
- #IssueIdentifier.log_msg( "Found " + str(len(cv_search_results)) + " initial results" )
+ #self.log_msg( "Found " + str(len(cv_search_results)) + " initial results" )
series_shortlist = []
- #IssueIdentifier.log_msg( "Removing results with too long names" )
+ #self.log_msg( "Removing results with too long names" )
for item in cv_search_results:
#assume that our search name is close to the actual name, say within 5 characters
if len( utils.removearticles(item['name'])) < len( keys['series'] ) + 5:
@@ -176,10 +184,10 @@ class IssueIdentifier:
# if we don't think it's an issue number 1, remove any series' that are one-shots
if keys['issue_number'] != '1':
- #IssueIdentifier.log_msg( "Removing one-shots" )
+ #self.log_msg( "Removing one-shots" )
series_shortlist[:] = [x for x in series_shortlist if not x['count_of_issues'] == 1]
- IssueIdentifier.log_msg( "Searching in " + str(len(series_shortlist)) +" series" )
+ self.log_msg( "Searching in " + str(len(series_shortlist)) +" series" )
# now sort the list by name length
series_shortlist.sort(key=lambda x: len(x['name']), reverse=False)
@@ -189,14 +197,14 @@ class IssueIdentifier:
match_list = []
- IssueIdentifier.log_msg( "Fetching issue data", newline=False)
+ self.log_msg( "Fetching issue data", newline=False)
for series in series_shortlist:
- #IssueIdentifier.log_msg( "Fetching info for ID: {0} {1} ({2}) ...".format(
+ #self.log_msg( "Fetching info for ID: {0} {1} ({2}) ...".format(
# series['id'],
# series['name'],
# series['start_year']) )
- IssueIdentifier.log_msg( ".", newline=False)
+ self.log_msg( ".", newline=False)
cv_series_results = comicVine.fetchVolumeData( series['id'] )
issue_list = cv_series_results['issues']
@@ -224,14 +232,16 @@ class IssueIdentifier:
match['url_image_hash'] = url_image_hash
match['issue_title'] = issue['name']
match['img_url'] = thumb_url
+ match['issue_id'] = issue['id']
+ match['volume_id'] = series['id']
match_list.append(match)
break
- IssueIdentifier.log_msg( "done!" )
+ self.log_msg( "done!" )
if len(match_list) == 0:
- IssueIdentifier.log_msg( ":-( no matches!" )
- return
+ self.log_msg( ":-( no matches!" )
+ return match_list
# sort list by image match scores
match_list.sort(key=lambda k: k['distance'])
@@ -240,11 +250,11 @@ class IssueIdentifier:
for i in match_list:
l.append( i['distance'] )
- IssueIdentifier.log_msg( "Compared {0} covers".format(len(match_list)), newline=False)
- IssueIdentifier.log_msg( str(l))
+ self.log_msg( "Compared {0} covers".format(len(match_list)), newline=False)
+ self.log_msg( str(l))
def print_match(item):
- IssueIdentifier.log_msg( u"-----> {0} #{1} {2} -- score: {3}\n-------> url:{4}".format(
+ self.log_msg( u"-----> {0} #{1} {2} -- score: {3}\n-------> url:{4}".format(
item['series'],
item['issue_number'],
item['issue_title'],
@@ -255,13 +265,13 @@ class IssueIdentifier:
if len(match_list) == 1:
if best_score > self.min_score_thresh:
- IssueIdentifier.log_msg( "!!!! Very weak score for the cover. Maybe it's not the cover?" )
+ self.log_msg( "!!!! Very weak score for the cover. Maybe it's not the cover?" )
print_match(match_list[0])
- return
+ return match_list
elif best_score > self.min_score_thresh and len(match_list) > 1:
- IssueIdentifier.log_msg( "No good image matches! Need to use other info..." )
- return
+ self.log_msg( "No good image matches! Need to use other info..." )
+ return match_list
#now pare down list, remove any item more than specified distant from the top scores
for item in reversed(match_list):
@@ -270,15 +280,14 @@ class IssueIdentifier:
if len(match_list) == 1:
print_match(match_list[0])
- return
elif len(match_list) == 0:
- IssueIdentifier.log_msg( "No matches found :(" )
- return
-
+ self.log_msg( "No matches found :(" )
else:
print
- IssueIdentifier.log_msg( "More than one likley candiate. Maybe a lexical comparison??" )
+ self.log_msg( "More than one likley candiate. Maybe a lexical comparison??" )
for item in match_list:
print_match(item)
-
+
+ return match_list
+
\ No newline at end of file
diff --git a/tagger.py b/tagger.py
index 9bc2602..c80acde 100755
--- a/tagger.py
+++ b/tagger.py
@@ -35,7 +35,7 @@ from issueidentifier import IssueIdentifier
import utils
#-----------------------------
-def cliProcedure( opts, settings ):
+def cli_mode( opts, settings ):
ca = ComicArchive(opts.filename)
if not ca.seemsToBeAComicArchive():
@@ -43,17 +43,23 @@ def cliProcedure( opts, settings ):
return
ii = IssueIdentifier( ca, settings.cv_api_key )
- ii.search()
+ matches = ii.search()
"""
- # now get the particular issue data
- metadata = comicVine.fetchIssueData( series_id, opts.issue_number )
-
- #pprint( cv_volume_data, indent=4 )
-
- ca = ComicArchive(opts.filename)
- ca.writeMetadata( metadata, opts.data_style )
+ if len(matches) == 1:
+
+ # now get the particular issue data
+ metadata = comicVine.fetchIssueData( match[0]['series'], match[0]['issue_number'] )
+
+ # write out the new data
+ ca.writeMetadata( metadata, opts.data_style )
+
+ elif len(matches) == 0:
+ pass
+ elif len(matches) == 0:
+ # print match options, with CV issue ID's
+ pass
"""
#-----------------------------
@@ -69,7 +75,7 @@ def main():
if opts.no_gui:
- cliProcedure( opts, settings )
+ cli_mode( opts, settings )
else:
diff --git a/taggerwindow.py b/taggerwindow.py
index f5c76fa..31c04dc 100644
--- a/taggerwindow.py
+++ b/taggerwindow.py
@@ -555,7 +555,7 @@ class TaggerWindow( QtGui.QMainWindow):
issue_number = str(self.leIssueNum.text()).strip()
- selector = VolumeSelectionWindow( self, self.settings.cv_api_key, series_name, issue_number )
+ selector = VolumeSelectionWindow( self, self.settings.cv_api_key, series_name, issue_number, self.comic_archive )
selector.setModal(True)
selector.exec_()
diff --git a/volumeselectionwindow.py b/volumeselectionwindow.py
index 2f03312..72f4f11 100644
--- a/volumeselectionwindow.py
+++ b/volumeselectionwindow.py
@@ -26,12 +26,14 @@ from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest
from comicvinetalker import ComicVineTalker
from issueselectionwindow import IssueSelectionWindow
+from issueidentifier import IssueIdentifier
+from genericmetadata import GenericMetadata
class VolumeSelectionWindow(QtGui.QDialog):
volume_id = 0
- def __init__(self, parent, cv_api_key, series_name, issue_number):
+ def __init__(self, parent, cv_api_key, series_name, issue_number, comic_archive):
super(VolumeSelectionWindow, self).__init__(parent)
uic.loadUi('volumeselectionwindow.ui', self)
@@ -39,6 +41,7 @@ class VolumeSelectionWindow(QtGui.QDialog):
self.series_name = series_name
self.issue_number = issue_number
self.cv_api_key = cv_api_key
+ self.comic_archive = comic_archive
self.performQuery()
@@ -47,6 +50,7 @@ class VolumeSelectionWindow(QtGui.QDialog):
self.twList.cellDoubleClicked.connect(self.cellDoubleClicked)
self.btnRequery.clicked.connect(self.requery)
self.btnIssues.clicked.connect(self.showIssues)
+ self.btnAutoSelect.clicked.connect(self.autoSelect)
self.twList.selectRow(0)
@@ -54,6 +58,22 @@ class VolumeSelectionWindow(QtGui.QDialog):
self.performQuery()
self.twList.selectRow(0)
+ def autoSelect( self ):
+ ii = IssueIdentifier( self.comic_archive, self.cv_api_key )
+
+ md = GenericMetadata()
+ md.series = self.series_name
+ md.issue_number = self.issue_number
+ ii.setAdditionalMetadata( md )
+
+ matches = ii.search()
+ if len(matches) == 1:
+ print "VolumeSelectionWindow found a match!!", matches[0]['volume_id'], matches[0]['issue_number']
+ self.volume_id = matches[0]['volume_id']
+ self.issue_number = matches[0]['issue_number']
+ self.selectByID()
+ self.showIssues()
+
def showIssues( self ):
selector = IssueSelectionWindow( self, self.cv_api_key, self.volume_id, self.issue_number )
selector.setModal(True)
@@ -64,6 +84,13 @@ class VolumeSelectionWindow(QtGui.QDialog):
self.accept()
return
+ def selectByID( self ):
+ for r in range(0, self.twList.rowCount()):
+ volume_id, b = self.twList.item( r, 0 ).data( QtCore.Qt.UserRole ).toInt()
+ if (volume_id == self.volume_id):
+ self.twList.selectRow( r )
+ break
+
def performQuery( self ):
while self.twList.rowCount() > 0:
diff --git a/volumeselectionwindow.ui b/volumeselectionwindow.ui
index e744b1a..be0e902 100644
--- a/volumeselectionwindow.ui
+++ b/volumeselectionwindow.ui
@@ -44,14 +44,14 @@
272
430
611
- 29
+ 32
-
-
+
- Show Issues
+ Auto-Select
@@ -62,6 +62,13 @@
+ -
+
+
+ Show Issues
+
+
+
-