Got basic tag save via CLI working

git-svn-id: http://comictagger.googlecode.com/svn/trunk@59 6c5673fe-1810-88d6-992b-cd32ca31540c
This commit is contained in:
beville@gmail.com 2012-11-19 03:55:40 +00:00
parent f45e7b887f
commit fb6d6a42b9
6 changed files with 186 additions and 51 deletions

View File

@ -561,5 +561,5 @@ class ComicArchive:
metadata.publicationYear = fnp.year
metadata.isEmpty = False
return metadata

View File

@ -36,7 +36,7 @@ from genericmetadata import GenericMetadata
class ComicVineTalker(QObject):
def __init__(self, api_key):
def __init__(self, api_key=""):
QObject.__init__(self)
# key that is registered to comictagger
@ -142,7 +142,6 @@ class ComicVineTalker(QObject):
volume_url = "http://api.comicvine.com/volume/" + str(series_id) + "/?api_key=" + self.api_key + "&format=json"
#print "search_url = : ", volume_url
resp = urllib2.urlopen(volume_url)
content = resp.read()

View File

@ -97,6 +97,59 @@ class GenericMetadata:
self.tags = list()
self.pages = list()
def overlay( self, new_md ):
# Overlay a metadata object on this one
# that is, when the new object has non-None
# values, over-write them to this one
def assign( cur, new ):
if new is not None:
setattr(self, cur, new)
if not new_md.isEmpty:
self.isEmpty = False
assign( 'series', new_md.series )
assign( "issueNumber", new_md.issueNumber )
assign( "issueCount", new_md.issueCount )
assign( "title", new_md.title )
assign( "publisher", new_md.publisher )
assign( "publicationMonth", new_md.publicationMonth )
assign( "publicationYear", new_md.publicationYear )
assign( "volumeNumber", new_md.volumeNumber )
assign( "volumeCount", new_md.volumeCount )
assign( "genre", new_md.genre )
assign( "language", new_md.language )
assign( "country", new_md.country )
assign( "alternateSeries", new_md.criticalRating )
assign( "alt. series", new_md.alternateSeries )
assign( "alternateNumber", new_md.alternateNumber )
assign( "alternateCount", new_md.alternateCount )
assign( "imprint", new_md.imprint )
assign( "web", new_md.webLink )
assign( "format", new_md.format )
assign( "manga", new_md.manga )
assign( "blackAndWhite", new_md.blackAndWhite )
assign( "maturityRating", new_md.maturityRating )
assign( "scanInfo", new_md.scanInfo )
assign( "scanInfo", new_md.scanInfo )
assign( "scanInfo", new_md.scanInfo )
assign( "characters", new_md.characters )
assign( "teams", new_md.teams )
assign( "locations", new_md.locations )
assign( "comments", new_md.comments )
assign( "notes", new_md.notes )
# TODO
# not sure if the tags, credits, and pages should broken down, or treated
# as whole lists.... For now, go the easy route, where any overlay
# value wipes out the whole list
assign( "tags", new_md.tags )
assign( "credits", new_md.credits )
assign( "pages", new_md.pages )
def addCredit( self, person, role, primary = False ):
credit = dict()
@ -114,7 +167,7 @@ class GenericMetadata:
return "No metadata"
def add( tag, val ):
if val is not None and str(val) != "":
if val is not None and u"{0}".format(val) != "":
vals.append( (tag, val) )
add( "series", self.series )
@ -148,10 +201,10 @@ class GenericMetadata:
add( "comments", self.comments )
add( "notes", self.notes )
add( "tags", utils.listToString( self.tags ) )
for c in self.credits:
add( "credit", c['role']+": "+c['person'] )
# find the longest field name
flen = 0
for i in vals:
@ -160,7 +213,8 @@ class GenericMetadata:
#format the data nicely
outstr = ""
fmt_str = u"{0: <" + str(flen) + "}: {1}\n"
for i in vals:
outstr += ("{0: <" + str(flen) + "}: {1}\n").format( i[0], i[1] )
outstr += fmt_str.format( i[0], i[1] )
return outstr

View File

@ -56,7 +56,7 @@ If no options are given, {0} will run in windowed mode
year
-o, --online Search online and attempt to identify file using
existing metadata and images in archive. May be used
in conjuntion with -p and -m
in conjuntion with -f and -m
-m, --metadata=LIST Explicity define some tags to be used as a list
....TBD........
....TBD........
@ -72,11 +72,11 @@ If no options are given, {0} will run in windowed mode
self.no_gui = False
self.filename = None
self.verbose = False
self.md_settings = None
self.metadata = None
self.print_tags = False
self.delete_tags = False
self.search_online = False
self.dryrun = True # keep this true for now!
self.dryrun = False
self.save_tags = False
self.parse_filename = False
self.rename_file = False
@ -87,10 +87,12 @@ If no options are given, {0} will run in windowed mode
print( msg )
print self.help_text.format(appname)
sys.exit(code)
def parseMetadataFromString( self, mdstr ):
print "TBD!!!!!!!!!!!!!!!!!!!!!"
return None
def parseCmdLineArgs(self):
# mac no likey this from .app bundle
if platform.system() == "Darwin" and getattr(sys, 'frozen', None):
@ -121,7 +123,7 @@ If no options are given, {0} will run in windowed mode
if o in ("-n", "--dryrun"):
self.dryrun = True
if o in ("-m", "--metadata"):
self.md_settings = a
self.metadata = self.parseMetadataFromString(a)
if o in ("-s", "--save"):
self.save_tags = True
if o in ("-r", "--rename"):

142
tagger.py
View File

@ -33,6 +33,8 @@ from taggerwindow import TaggerWindow
from options import Options, MetaDataStyle
from comicarchive import ComicArchive
from issueidentifier import IssueIdentifier
from genericmetadata import GenericMetadata
from comicvinetalker import ComicVineTalker
import utils
@ -49,6 +51,11 @@ def cli_mode( opts, settings ):
if not ca.seemsToBeAComicArchive():
print "Sorry, but "+ opts.filename + " is not a comic archive!"
return
if not ca.isWritable() and ( opts.delete_tags or opts.save_tags or opts.rename_file ):
print "This archive is not writable."
return
cix = False
cbi = False
@ -81,61 +88,128 @@ def cli_mode( opts, settings ):
if opts.data_style is None or opts.data_style == MetaDataStyle.CIX:
if cix:
print "------ComicRack tags--------"
print ca.readCIX()
print u"{0}".format(ca.readCIX())
if opts.data_style is None or opts.data_style == MetaDataStyle.CBI:
if cbi:
print "------ComicBookLover tags--------"
print ca.readCBI()
print u"{0}".format(ca.readCBI())
elif opts.delete_tags:
if not ca.isWritable():
print "This archive is not writable."
return
elif opts.delete_tags:
if opts.data_style == MetaDataStyle.CIX:
if cix:
ca.removeCIX()
print "Removed ComicRack tags."
if not opts.dryrun:
ca.removeCIX()
print "Removed ComicRack tags."
else:
print "dry-run. ComicRack tags not removed"
else:
print "This archive doesn't have ComicRack tags."
if opts.data_style == MetaDataStyle.CBI:
if cbi:
ca.removeCBI()
print "Removed ComicBookLover tags."
if not opts.dryrun:
ca.removeCBI()
print "Removed ComicBookLover tags."
else:
print "dry-run. ComicBookLover tags not removed"
else:
print "This archive doesn't have ComicBookLover tags."
#elif opt.rename:
# print "Gonna rename file"
elif opts.save_tags:
if opts.data_style == MetaDataStyle.CIX:
print "Gonna save ComicRack tags"
if opts.data_style == MetaDataStyle.CBI:
print "Gonna save ComicBookLover tags"
"""
ii = IssueIdentifier( ca, settings.cv_api_key )
matches = ii.search()
# OK we're gonna do a save of some new data
md = GenericMetadata()
if len(matches) == 1:
# First read in existing data, if it's there
if opts.data_style == MetaDataStyle.CIX and cix:
md = ca.readCIX()
elif opts.data_style == MetaDataStyle.CBI and cbi:
md = ca.readCBI()
# now, overlay the new data onto the old, in order
if opts.parse_filename:
md.overlay( ca.metadataFromFilename() )
if opts.metadata is not None:
md.overlay( opts.metadata )
# finally, search online
if opts.search_online:
ii = IssueIdentifier( ca, "" )
if md is None or md.isEmpty:
print "No metadata given to search online with!"
return
def myoutput( text ):
if opts.verbose:
IssueIdentifier.defaultWriteOutput( text )
# use our overlayed MD struct to search
ii.setAdditionalMetadata( md )
ii.onlyUseAdditionalMetaData = True
ii.setOutputFunction( myoutput )
matches = ii.search()
result = ii.search_result
found_match = False
choices = False
low_confidence = False
if result == ii.ResultNoMatches:
pass
elif result == ii.ResultFoundMatchButBadCoverScore:
low_confidence = False
found_match = True
elif result == ii.ResultFoundMatchButNotFirstPage :
found_match = True
elif result == ii.ResultMultipleMatchesWithBadImageScores:
low_confidence = False
choices = True
elif result == ii.ResultOneGoodMatch:
found_match = True
elif result == ii.ResultMultipleGoodMatches:
choices = True
if choices:
print "Online search: Multiple matches. Save aborted"
return
if low_confidence:
print "Online search: Low confidence match. Save aborted"
return
if not found_match:
print "Online search: No match found. Save aborted"
return
# we got here, so we have a single match
# 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
cv_md = ComicVineTalker().fetchIssueData( matches[0]['volume_id'], matches[0]['issue_number'] )
md.overlay( cv_md )
# ok, done building our metadata. time to save
elif len(matches) == 0:
# print match options, with CV issue ID's
pass
"""
#HACK
opts.dryrun = True
#HACK
if not opts.dryrun:
# write out the new data
ca.writeMetadata( md, opts.data_style )
else:
print "dry-run option was set, so nothing was written, but here is the final set of tags:"
print u"{0}".format(md)
elif opt.rename_file:
print "File renaming TBD"
#-----------------------------
def main():

View File

@ -2,8 +2,14 @@
Features
----------------
CLI
rename
save
save log
abort flag
explicit metadata settings option format
just series, issue, year??
multiple files?
verbose settings for identifier
interactive for choices option?
--- or defer choices to end, by keeping special log of those files
Settings/Preferences Dialog
Remove API Key
@ -34,13 +40,11 @@ Bugs
SERIOUS BUG: rebuilding zips!
http://stackoverflow.com/questions/11578443/trigger-io-errno-18-cross-device-link
Test ComicRack android
OSX:
toolbar
weird unrar complaints
Page browser sizing
Override curson is not beachball
Override cursor is not beachball
Other settings possibilities:
Last tag style
@ -50,6 +54,8 @@ Other settings possibilities:
Filename parsing:
Rework how series name is separated from issue
Test ComicRack android
Form type validation Ints vs strings for month, year. etc
Check all HTTP responses for errors