Added use of IssueIdentifier in the GUI

git-svn-id: http://comictagger.googlecode.com/svn/trunk@28 6c5673fe-1810-88d6-992b-cd32ca31540c
This commit is contained in:
beville@gmail.com 2012-11-10 20:29:07 +00:00
parent d8a8355f5b
commit a58442b8f6
5 changed files with 104 additions and 55 deletions

View File

@ -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

View File

@ -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:

View File

@ -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_()

View File

@ -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:

View File

@ -44,14 +44,14 @@
<x>272</x>
<y>430</y>
<width>611</width>
<height>29</height>
<height>32</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="btnIssues">
<widget class="QPushButton" name="btnAutoSelect">
<property name="text">
<string>Show Issues</string>
<string>Auto-Select</string>
</property>
</widget>
</item>
@ -62,6 +62,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnIssues">
<property name="text">
<string>Show Issues</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">