First cut at real CLI feature
git-svn-id: http://comictagger.googlecode.com/svn/trunk@58 6c5673fe-1810-88d6-992b-cd32ca31540c
This commit is contained in:
parent
ea6b2d1e9e
commit
f45e7b887f
@ -23,6 +23,8 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
import utils
|
||||
|
||||
# These page info classes are exactly the same as the CIX scheme, since it's unique
|
||||
class PageType:
|
||||
FrontCover = "FrontCover"
|
||||
@ -68,7 +70,7 @@ class GenericMetadata:
|
||||
self.comments = None # use same way as Summary in CIX
|
||||
|
||||
self.volumeCount = None
|
||||
self.criticalRating = None
|
||||
self.criticalRating = None
|
||||
self.country = None
|
||||
|
||||
self.alternateSeries = None
|
||||
@ -94,8 +96,7 @@ class GenericMetadata:
|
||||
self.credits = list()
|
||||
self.tags = list()
|
||||
self.pages = list()
|
||||
|
||||
|
||||
|
||||
def addCredit( self, person, role, primary = False ):
|
||||
|
||||
credit = dict()
|
||||
@ -105,5 +106,61 @@ class GenericMetadata:
|
||||
credit['primary'] = primary
|
||||
|
||||
self.credits.append(credit)
|
||||
|
||||
|
||||
|
||||
|
||||
def __str__( self ):
|
||||
vals = []
|
||||
if self.isEmpty:
|
||||
return "No metadata"
|
||||
|
||||
def add( tag, val ):
|
||||
if val is not None and str(val) != "":
|
||||
vals.append( (tag, val) )
|
||||
|
||||
add( "series", self.series )
|
||||
add( "issue number", self.issueNumber )
|
||||
add( "issue count", self.issueCount )
|
||||
add( "title", self.title )
|
||||
add( "publisher", self.publisher )
|
||||
add( "month", self.publicationMonth )
|
||||
add( "year", self.publicationYear )
|
||||
add( "volume number", self.volumeNumber )
|
||||
add( "volume count", self.volumeCount )
|
||||
add( "genre", self.genre )
|
||||
add( "language", self.language )
|
||||
add( "country", self.country )
|
||||
add( "user rating", self.criticalRating )
|
||||
add( "alt. series", self.alternateSeries )
|
||||
add( "alt. number", self.alternateNumber )
|
||||
add( "alt. count", self.alternateCount )
|
||||
add( "imprint", self.imprint )
|
||||
add( "web", self.webLink )
|
||||
add( "format", self.format )
|
||||
add( "manga", self.manga )
|
||||
add( "B&W", self.blackAndWhite )
|
||||
add( "age rating", self.maturityRating )
|
||||
add( "story arc", self.storyArc )
|
||||
add( "series group", self.seriesGroup )
|
||||
add( "scan info", self.scanInfo )
|
||||
add( "characters", self.characters )
|
||||
add( "teams", self.teams )
|
||||
add( "locations", self.locations )
|
||||
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:
|
||||
flen = max( flen, len(i[0]) )
|
||||
flen += 1
|
||||
|
||||
#format the data nicely
|
||||
outstr = ""
|
||||
for i in vals:
|
||||
outstr += ("{0: <" + str(flen) + "}: {1}\n").format( i[0], i[1] )
|
||||
|
||||
return outstr
|
||||
|
@ -261,7 +261,6 @@ class IssueIdentifier:
|
||||
|
||||
# remove any series that starts after the issue year
|
||||
if keys['year'] is not None and keys['year'].isdigit():
|
||||
print "ATB", keys['year'] , item['start_year']
|
||||
if int(keys['year']) < item['start_year']:
|
||||
date_approved = False
|
||||
|
||||
|
138
options.py
138
options.py
@ -21,6 +21,7 @@ limitations under the License.
|
||||
import sys
|
||||
import getopt
|
||||
import platform
|
||||
import os
|
||||
|
||||
class Enum(set):
|
||||
def __getattr__(self, name):
|
||||
@ -35,57 +36,128 @@ class MetaDataStyle:
|
||||
|
||||
|
||||
class Options:
|
||||
help_text = """
|
||||
Usage: {0} [OPTION]... [FILE]
|
||||
|
||||
A utility for read and writing metadata to comic archives.
|
||||
|
||||
If no options are given, {0} will run in windowed mode
|
||||
|
||||
-p, --print Print out tag info from file. Specify type
|
||||
(via -t) to get only info of that tag type
|
||||
-d, --delete Deletes the tag block of specified type (via -t)
|
||||
-s, --save Save out tags as specified type (via -t)
|
||||
Must specify also at least -o, -p, or -m
|
||||
-n, --dryrun Don't actually modify file (only relevent for -d, -s, or -r)
|
||||
-t, --type=TYPE Specify TYPE as either "CR" or "CBL", (as either
|
||||
ComicRack or ComicBookLover style tags, respectivly)
|
||||
-f, --parsefilename Parse the filename to get some info, specifically
|
||||
series name, issue number, volume, and publication
|
||||
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
|
||||
-m, --metadata=LIST Explicity define some tags to be used as a list
|
||||
....TBD........
|
||||
....TBD........
|
||||
-r, --rename Rename the file based on metadata as indicated. TBD!
|
||||
-a, --abort Abort save operation when online match is of low confidence TBD!
|
||||
-v, --verbose Be noisy when doing what it does
|
||||
-h, --help Display this message
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.data_style = MetaDataStyle.CIX
|
||||
self.data_style = None
|
||||
self.no_gui = False
|
||||
self.filename = None
|
||||
self.verbose = False
|
||||
self.md_settings = None
|
||||
self.print_tags = False
|
||||
self.delete_tags = False
|
||||
self.search_online = False
|
||||
self.dryrun = True # keep this true for now!
|
||||
self.save_tags = False
|
||||
self.parse_filename = False
|
||||
self.rename_file = False
|
||||
|
||||
def display_help_and_quit( self, msg, code ):
|
||||
appname = os.path.basename(sys.argv[0])
|
||||
if msg is not None:
|
||||
print( msg )
|
||||
print self.help_text.format(appname)
|
||||
sys.exit(code)
|
||||
|
||||
|
||||
self.series_name = ''
|
||||
self.issue_number = ''
|
||||
self.filename = ''
|
||||
self.image_hasher = 1
|
||||
|
||||
def parseCmdLineArgs(self):
|
||||
|
||||
|
||||
# mac no likey this from .app bundle
|
||||
if platform.system() == "Darwin" and getattr(sys, 'frozen', None):
|
||||
return
|
||||
|
||||
|
||||
# parse command line options
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "cht:s:i:vf:m:", ["cli", "help", "type=", "series=", "issue=", "verbose", "file", "imagehasher=" ])
|
||||
except (getopt.error, msg):
|
||||
print( msg )
|
||||
print( "for help use --help" )
|
||||
sys.exit(2)
|
||||
opts, args = getopt.getopt(sys.argv[1:],
|
||||
"hpdt:fm:vonsr",
|
||||
[ "help", "print", "delete", "type=", "parsefilename", "metadata=", "verbose", "online", "dryrun", "save", "rename" ])
|
||||
|
||||
except getopt.GetoptError as err:
|
||||
self.display_help_and_quit( str(err), 2 )
|
||||
|
||||
# process options
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print( __doc__ )
|
||||
sys.exit(0)
|
||||
self.display_help_and_quit( None, 0 )
|
||||
if o in ("-v", "--verbose"):
|
||||
print( "Verbose output!" )
|
||||
if o in ("-c", "--cli"):
|
||||
self.no_gui = True
|
||||
if o in ("-m", "--imagehasher"):
|
||||
self.image_hasher = a
|
||||
if o in ("-s", "--series"):
|
||||
self.series_name = a
|
||||
if o in ("-i", "--issue"):
|
||||
self.issue_number = a
|
||||
if o in ("-f", "--file"):
|
||||
self.filename = a
|
||||
self.verbose = True
|
||||
if o in ("-p", "--print"):
|
||||
self.print_tags = True
|
||||
if o in ("-d", "--delete"):
|
||||
self.delete_tags = True
|
||||
if o in ("-o", "--online"):
|
||||
self.search_online = True
|
||||
if o in ("-n", "--dryrun"):
|
||||
self.dryrun = True
|
||||
if o in ("-m", "--metadata"):
|
||||
self.md_settings = a
|
||||
if o in ("-s", "--save"):
|
||||
self.save_tags = True
|
||||
if o in ("-r", "--rename"):
|
||||
self.rename_file = True
|
||||
if o in ("-f", "--parsefilename"):
|
||||
self.parse_filename = True
|
||||
if o in ("-t", "--type"):
|
||||
if a == "cr":
|
||||
if a.lower() == "cr":
|
||||
self.data_style = MetaDataStyle.CIX
|
||||
elif a == "cbl":
|
||||
elif a.lower() == "cbl":
|
||||
self.data_style = MetaDataStyle.CBI
|
||||
else:
|
||||
print( __doc__ )
|
||||
sys.exit(0)
|
||||
|
||||
if self.filename == "" and len(args) > 0:
|
||||
self.filename = args[0]
|
||||
self.display_help_and_quit( "Invalid tag type", 1 )
|
||||
|
||||
return opts
|
||||
|
||||
if self.print_tags or self.delete_tags or self.save_tags or self.rename_file:
|
||||
self.no_gui = True
|
||||
|
||||
count = 0
|
||||
if self.print_tags: count += 1
|
||||
if self.delete_tags: count += 1
|
||||
if self.save_tags: count += 1
|
||||
if self.rename_file: count += 1
|
||||
|
||||
if count > 1:
|
||||
self.display_help_and_quit( "Must choose only one action of print, delete, save, or rename", 1 )
|
||||
|
||||
if len(args) > 0:
|
||||
self.filename = args[0]
|
||||
|
||||
if self.no_gui and self.filename is None:
|
||||
self.display_help_and_quit( "Command requires a filename!", 1 )
|
||||
|
||||
if self.delete_tags and self.data_style is None:
|
||||
self.display_help_and_quit( "Please specify the type to delete with -t", 1 )
|
||||
|
||||
if self.save_tags and self.data_style is None:
|
||||
self.display_help_and_quit( "Please specify the type to save with -t", 1 )
|
||||
|
||||
|
||||
|
@ -26,7 +26,6 @@ from settings import ComicTaggerSettings
|
||||
|
||||
class PageBrowserWindow(QtGui.QDialog):
|
||||
|
||||
|
||||
def __init__(self, parent):
|
||||
super(PageBrowserWindow, self).__init__(parent)
|
||||
|
||||
|
126
tagger.py
126
tagger.py
@ -40,30 +40,102 @@ import utils
|
||||
#-----------------------------
|
||||
def cli_mode( opts, settings ):
|
||||
|
||||
if opts.filename is None:
|
||||
return
|
||||
ca = ComicArchive(opts.filename)
|
||||
if settings.rar_exe_path != "":
|
||||
ca.setExternalRarProgram( settings.rar_exe_path )
|
||||
|
||||
if not ca.seemsToBeAComicArchive():
|
||||
print "Sorry, but "+ opts.filename + " is not a comic archive!"
|
||||
return
|
||||
|
||||
ii = IssueIdentifier( ca, settings.cv_api_key )
|
||||
matches = ii.search()
|
||||
|
||||
"""
|
||||
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
|
||||
"""
|
||||
cix = False
|
||||
cbi = False
|
||||
if ca.hasCIX(): cix = True
|
||||
if ca.hasCBI(): cbi = True
|
||||
|
||||
if opts.print_tags:
|
||||
|
||||
if opts.data_style is None:
|
||||
page_count = ca.getNumberOfPages()
|
||||
|
||||
brief = ""
|
||||
if ca.isZip(): brief = "ZIP archive "
|
||||
elif ca.isRar(): brief = "RAR archive "
|
||||
elif ca.isFolder(): brief = "Folder archive "
|
||||
|
||||
brief += "({0: >3} pages)".format(page_count)
|
||||
brief += " tags:[ "
|
||||
|
||||
if not (cbi or cix):
|
||||
brief += "none"
|
||||
else:
|
||||
if cbi: brief += "CBL "
|
||||
if cix: brief += "CR "
|
||||
brief += "]"
|
||||
|
||||
print brief
|
||||
print
|
||||
|
||||
if opts.data_style is None or opts.data_style == MetaDataStyle.CIX:
|
||||
if cix:
|
||||
print "------ComicRack tags--------"
|
||||
print ca.readCIX()
|
||||
if opts.data_style is None or opts.data_style == MetaDataStyle.CBI:
|
||||
if cbi:
|
||||
print "------ComicBookLover tags--------"
|
||||
print ca.readCBI()
|
||||
|
||||
|
||||
elif opts.delete_tags:
|
||||
if not ca.isWritable():
|
||||
print "This archive is not writable."
|
||||
return
|
||||
|
||||
if opts.data_style == MetaDataStyle.CIX:
|
||||
if cix:
|
||||
ca.removeCIX()
|
||||
print "Removed ComicRack tags."
|
||||
else:
|
||||
print "This archive doesn't have ComicRack tags."
|
||||
|
||||
if opts.data_style == MetaDataStyle.CBI:
|
||||
if cbi:
|
||||
ca.removeCBI()
|
||||
print "Removed ComicBookLover tags."
|
||||
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()
|
||||
|
||||
|
||||
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
|
||||
"""
|
||||
#-----------------------------
|
||||
|
||||
def main():
|
||||
@ -90,22 +162,8 @@ def main():
|
||||
splash.raise_()
|
||||
app.processEvents()
|
||||
|
||||
"""
|
||||
lw = QtGui.QListWidget()
|
||||
icon = QtGui.QIcon('app.png')
|
||||
for i in range(10):
|
||||
lw.addItem( QtGui.QListWidgetItem( icon, "Item {0}".format(i) ) )
|
||||
|
||||
lw.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
|
||||
#lw.setViewMode(QtGui.QListView.IconMode)
|
||||
lw.setMovement(QtGui.QListView.Snap)
|
||||
lw.setGridSize(QtCore.QSize(100,100))
|
||||
lw.show()
|
||||
sys.exit(app.exec_())
|
||||
"""
|
||||
|
||||
try:
|
||||
tagger_window = TaggerWindow( opts, settings )
|
||||
tagger_window = TaggerWindow( opts.filename, settings )
|
||||
tagger_window.show()
|
||||
splash.finish( tagger_window )
|
||||
sys.exit(app.exec_())
|
||||
|
175
taggerwindow.py
175
taggerwindow.py
@ -27,7 +27,7 @@ import platform
|
||||
import os
|
||||
|
||||
from volumeselectionwindow import VolumeSelectionWindow
|
||||
from options import Options, MetaDataStyle
|
||||
from options import MetaDataStyle
|
||||
from comicinfoxml import ComicInfoXml
|
||||
from genericmetadata import GenericMetadata
|
||||
from comicvinetalker import ComicVineTalker
|
||||
@ -64,162 +64,6 @@ def clickable(widget):
|
||||
widget.installEventFilter(filter)
|
||||
return filter.dblclicked
|
||||
|
||||
"""
|
||||
class PageTableModel(QtCore.QAbstractTableModel):
|
||||
|
||||
def __init__(self, comic_archive, parent=None, *args):
|
||||
QtCore.QAbstractTableModel.__init__(self, parent, *args)
|
||||
|
||||
self.comic_archive = comic_archive
|
||||
page_list = comic_archive.getPageNameList()
|
||||
|
||||
self.page_model = []
|
||||
i = 0
|
||||
for page in page_list:
|
||||
item = dict()
|
||||
item['number'] = i
|
||||
item['filename'] = page
|
||||
item['thumb'] = None
|
||||
|
||||
self.page_model.append( item )
|
||||
i +=1
|
||||
|
||||
|
||||
def rowCount(self, parent):
|
||||
return len(self.page_model)
|
||||
|
||||
def columnCount(self, parent):
|
||||
return 3
|
||||
|
||||
def data(self, index, role):
|
||||
|
||||
if not index.isValid():
|
||||
return QtCore.QVariant()
|
||||
|
||||
elif role == QtCore.Qt.DisplayRole:
|
||||
# page num
|
||||
if index.column() == 0:
|
||||
return QtCore.QVariant(self.page_model[index.row()]['number'])
|
||||
|
||||
# page filename
|
||||
if index.column() == 1:
|
||||
return QtCore.QVariant(self.page_model[index.row()]['filename'])
|
||||
|
||||
elif role == QtCore.Qt.DecorationRole:
|
||||
|
||||
if index.column() == 2:
|
||||
if self.page_model[index.row()]['thumb'] is None:
|
||||
|
||||
image_data = self.comic_archive.getPage( self.page_model[index.row()]['number'] )
|
||||
img = QtGui.QImage()
|
||||
img.loadFromData( image_data )
|
||||
pixmap = QtGui.QPixmap(QtGui.QPixmap(img))
|
||||
#scaled_pixmap = pixmap.scaled(100, 150, QtCore.Qt.KeepAspectRatio)
|
||||
|
||||
self.page_model[index.row()]['thumb'] = pixmap #scaled_pixmap
|
||||
|
||||
return QtCore.QVariant(self.page_model[index.row()]['thumb'])
|
||||
|
||||
else:
|
||||
return QtCore.QVariant()
|
||||
"""
|
||||
class PageListModel(QtCore.QAbstractListModel):
|
||||
|
||||
def __init__(self, comic_archive, parent=None, *args):
|
||||
QtCore.QAbstractTableModel.__init__(self, parent, *args)
|
||||
|
||||
self.comic_archive = comic_archive
|
||||
page_list = comic_archive.getPageNameList()
|
||||
|
||||
self.page_model = []
|
||||
i = 0
|
||||
for page in page_list:
|
||||
item = dict()
|
||||
item['number'] = i
|
||||
item['filename'] = page
|
||||
item['thumb'] = None
|
||||
|
||||
self.page_model.append( item )
|
||||
i +=1
|
||||
|
||||
def rowCount(self, parent):
|
||||
return len(self.page_model)
|
||||
|
||||
def data(self, index, role):
|
||||
|
||||
if not index.isValid():
|
||||
return QtCore.QVariant()
|
||||
|
||||
elif role == QtCore.Qt.DisplayRole:
|
||||
# page num
|
||||
return QtCore.QVariant(self.page_model[index.row()]['number'])
|
||||
|
||||
elif role == QtCore.Qt.DecorationRole:
|
||||
|
||||
if self.page_model[index.row()]['thumb'] is None:
|
||||
|
||||
#timestamp = datetime.datetime.now()
|
||||
|
||||
image_data = self.comic_archive.getPage( self.page_model[index.row()]['number'] )
|
||||
img = QtGui.QImage()
|
||||
img.loadFromData( image_data )
|
||||
pixmap = QtGui.QPixmap(QtGui.QPixmap(img))
|
||||
scaled_pixmap = pixmap.scaled(100, 150, QtCore.Qt.KeepAspectRatio)
|
||||
|
||||
self.page_model[index.row()]['thumb'] = scaled_pixmap
|
||||
|
||||
return QtCore.QVariant(self.page_model[index.row()]['thumb'])
|
||||
|
||||
else:
|
||||
return QtCore.QVariant()
|
||||
|
||||
def flags( self, index):
|
||||
defaultFlags = QtCore.QAbstractTableModel.flags(self, index)
|
||||
if index.isValid():
|
||||
return QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled | defaultFlags
|
||||
else:
|
||||
return QtCore.Qt.ItemIsDropEnabled | defaultFlags
|
||||
|
||||
def removeRows(self, row, count, parent=QtCore.QModelIndex()):
|
||||
|
||||
print "removeRows", row, count
|
||||
return True
|
||||
|
||||
def insertRows(self, row, count, parent=QtCore.QModelIndex()):
|
||||
|
||||
print "insertRows", row, count
|
||||
return False
|
||||
|
||||
def beginRemoveRows(self, sourceParent, start, end, destinationParent, dest):
|
||||
print "beginRemoveRows"
|
||||
|
||||
def dropMimeData(self,data, action, row, col, parent):
|
||||
print "dropMimeData", action, row, col
|
||||
|
||||
|
||||
if (row != -1):
|
||||
beginRow = row
|
||||
|
||||
elif (parent.isValid()):
|
||||
beginRow = parent.row()
|
||||
|
||||
print beginRow
|
||||
|
||||
return True
|
||||
if (action == QtCore.Qt.IgnoreAction):
|
||||
return True
|
||||
|
||||
#if ( not data.hasFormat("application/vnd.text.list"))
|
||||
# return False
|
||||
|
||||
if (column > 0):
|
||||
return False
|
||||
#def beginMoveRows(self, sourceParent, start, end, destinationParent, dest):
|
||||
# print "rowsMoved"
|
||||
|
||||
def supportedDropActions(self):
|
||||
#print "supportedDropActions"
|
||||
return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction
|
||||
|
||||
|
||||
class TaggerWindow( QtGui.QMainWindow):
|
||||
@ -227,7 +71,7 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
appName = "ComicTagger"
|
||||
version = ctversion.version
|
||||
|
||||
def __init__(self, opts, settings, parent = None):
|
||||
def __init__(self, filename, settings, parent = None):
|
||||
super(TaggerWindow, self).__init__(parent)
|
||||
|
||||
uic.loadUi(os.path.join(ComicTaggerSettings.baseDir(), 'taggerwindow.ui' ), self)
|
||||
@ -240,9 +84,8 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
|
||||
#print platform.system(), platform.release()
|
||||
self.dirtyFlag = False
|
||||
self.opts = opts
|
||||
self.settings = settings
|
||||
self.data_style = opts.data_style
|
||||
self.data_style = MetaDataStyle.CIX
|
||||
|
||||
#set up a default metadata object
|
||||
self.metadata = GenericMetadata()
|
||||
@ -270,16 +113,8 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
|
||||
self.updateStyleTweaks()
|
||||
|
||||
|
||||
self.openArchive( opts.filename )
|
||||
|
||||
# fill in some explicit metadata stuff from our options
|
||||
# this overrides what we just read in
|
||||
if self.metadata.series is None:
|
||||
self.metadata.series = opts.series_name
|
||||
if self.metadata.issueNumber is None:
|
||||
self.metadata.issueNumber = opts.issue_number
|
||||
|
||||
if filename is not None:
|
||||
self.openArchive( filename )
|
||||
|
||||
def updateAppTitle( self ):
|
||||
|
||||
|
18
todo.txt
18
todo.txt
@ -1,11 +1,9 @@
|
||||
-----------------
|
||||
Features
|
||||
----------------
|
||||
Stand-alone CLI
|
||||
Info dump
|
||||
optionless args
|
||||
remove tags
|
||||
copy tags
|
||||
CLI
|
||||
rename
|
||||
save
|
||||
|
||||
Settings/Preferences Dialog
|
||||
Remove API Key
|
||||
@ -13,6 +11,7 @@ Settings/Preferences Dialog
|
||||
Add reset settings
|
||||
Tab w/Identifier Settings
|
||||
Add publisher blacklist
|
||||
other Identifier tunings
|
||||
|
||||
Add class for warning/info messages with "Don't show again" checkbox.
|
||||
Add list of these flags to settings
|
||||
@ -22,18 +21,21 @@ TaggerWindow entry fields
|
||||
Pages Info - maybe a custom painted widget
|
||||
At minimum, preserve the page data
|
||||
|
||||
File rename
|
||||
-Dialog??
|
||||
|
||||
Style sheets for windows/mac/linux
|
||||
|
||||
Better stripping of html from CV text
|
||||
|
||||
-----------------
|
||||
Bugs
|
||||
----------------
|
||||
|
||||
SQLite chokes on "Batman\ Li'l Gotham 001.cbr" name -- Doesn't like single quote '
|
||||
|
||||
SERIOUS BUG: rebuilding zips!
|
||||
http://stackoverflow.com/questions/11578443/trigger-io-errno-18-cross-device-link
|
||||
|
||||
Test ComicRack android
|
||||
|
||||
OSX:
|
||||
toolbar
|
||||
weird unrar complaints
|
||||
|
Loading…
x
Reference in New Issue
Block a user