Reworked the credit writing in CIX
Added credit editing UI git-svn-id: http://comictagger.googlecode.com/svn/trunk@4 6c5673fe-1810-88d6-992b-cd32ca31540c
This commit is contained in:
parent
52ad4790e7
commit
9c5cf74dab
122
comicinfoxml.py
122
comicinfoxml.py
@ -7,7 +7,7 @@ import zipfile
|
||||
from pprint import pprint
|
||||
import xml.etree.ElementTree as ET
|
||||
from genericmetadata import GenericMetadata
|
||||
|
||||
import utils
|
||||
|
||||
class ComicInfoXml:
|
||||
|
||||
@ -83,71 +83,67 @@ class ComicInfoXml:
|
||||
ET.SubElement(root, 'BlackAndWhite').text = "Yes"
|
||||
|
||||
# need to specially process the credits, since they are structured differently than CIX
|
||||
credit_writer = None
|
||||
credit_penciller = None
|
||||
credit_inker = None
|
||||
credit_colorist = None
|
||||
credit_letterer = None
|
||||
credit_cover = None
|
||||
credit_editor = None
|
||||
|
||||
credit_writer_list = list()
|
||||
credit_penciller_list = list()
|
||||
credit_inker_list = list()
|
||||
credit_colorist_list = list()
|
||||
credit_letterer_list = list()
|
||||
credit_cover_list = list()
|
||||
credit_editor_list = list()
|
||||
|
||||
# first, loop thru credits, and build a list for each role that CIX supports
|
||||
for credit in metadata.credits:
|
||||
if credit['role'].title() in set( ['Writer', 'Plotter'] ):
|
||||
if credit_writer == None:
|
||||
credit_writer = ET.SubElement(root, 'Writer')
|
||||
credit_writer.text = ""
|
||||
if len(credit_writer.text) > 0:
|
||||
credit_writer.text += ", "
|
||||
credit_writer.text += credit['person']
|
||||
|
||||
if credit['role'].lower() in set( ['writer', 'plotter', 'scripter'] ):
|
||||
credit_writer_list.append(credit['person'])
|
||||
|
||||
if credit['role'].lower() in set( [ 'artist', 'penciller', 'penciler', 'breakdowns' ] ):
|
||||
credit_penciller_list.append(credit['person'])
|
||||
|
||||
if credit['role'].title() in set( [ 'Inker', 'Artist', 'Finishes' ] ):
|
||||
if credit_inker == None:
|
||||
credit_inker = ET.SubElement(root, 'Inker')
|
||||
credit_inker.text = ""
|
||||
if len(credit_inker.text) > 0:
|
||||
credit_inker.text += ", "
|
||||
credit_inker.text += credit['person']
|
||||
|
||||
if credit['role'].title() in set( [ 'Artist', 'Penciller', 'Penciler', 'Breakdowns' ] ):
|
||||
if credit_penciller == None:
|
||||
credit_penciller = ET.SubElement(root, 'Penciller')
|
||||
credit_penciller.text = ""
|
||||
if len(credit_penciller.text) > 0:
|
||||
credit_penciller.text += ", "
|
||||
credit_penciller.text += credit['person']
|
||||
|
||||
if credit['role'].title() in set( [ 'Colorist', 'Colourist' ]):
|
||||
if credit_colorist == None:
|
||||
credit_colorist = ET.SubElement(root, 'Colorist')
|
||||
credit_colorist.text = ""
|
||||
if len(credit_colorist.text) > 0:
|
||||
credit_colorist.text += ", "
|
||||
credit_colorist.text += credit['person']
|
||||
|
||||
if credit['role'].title() == 'Letterer':
|
||||
if credit_letterer == None:
|
||||
credit_letterer = ET.SubElement(root, 'Letterer')
|
||||
credit_letterer.text = ""
|
||||
if len(credit_letterer.text) > 0:
|
||||
credit_letterer.text += ", "
|
||||
credit_letterer.text += credit['person']
|
||||
|
||||
if credit['role'].title() in set( [ 'Cover', 'Covers', 'CoverArtist', 'Cover Artist' ] ):
|
||||
if credit_cover == None:
|
||||
credit_cover = ET.SubElement(root, 'CoverArtist')
|
||||
credit_cover.text = ""
|
||||
if len(credit_cover.text) > 0:
|
||||
credit_cover.text += ", "
|
||||
credit_cover.text += credit['person']
|
||||
|
||||
if credit['role'].title() in set( [ 'Editor'] ):
|
||||
if credit_editor == None:
|
||||
credit_editor = ET.SubElement(root, 'Editor')
|
||||
credit_editor.text = ""
|
||||
if len(credit_editor.text) > 0:
|
||||
credit_editor.text += ", "
|
||||
credit_editor.text += credit['person']
|
||||
if credit['role'].lower() in set( [ 'inker', 'artist', 'finishes' ] ):
|
||||
credit_inker_list.append(credit['person'])
|
||||
|
||||
if credit['role'].lower() in set( [ 'colorist', 'colourist', 'colorer', 'colourer' ]):
|
||||
credit_colorist_list.append(credit['person'])
|
||||
|
||||
if credit['role'].lower() in set( [ 'letterer'] ):
|
||||
credit_letterer_list.append(credit['person'])
|
||||
|
||||
if credit['role'].lower() in set( [ 'cover', 'covers', 'coverartist', 'cover artist' ] ):
|
||||
credit_cover_list.append(credit['person'])
|
||||
|
||||
if credit['role'].lower() in set( [ 'editor'] ):
|
||||
credit_editor_list.append(credit['person'])
|
||||
|
||||
# second, convert each list to string, and add to XML struct
|
||||
if len( credit_writer_list ) > 0:
|
||||
node = ET.SubElement(root, 'Writer')
|
||||
node.text = utils.listToString( credit_writer_list )
|
||||
|
||||
if len( credit_penciller_list ) > 0:
|
||||
node = ET.SubElement(root, 'Penciller')
|
||||
node.text = utils.listToString( credit_penciller_list )
|
||||
|
||||
if len( credit_inker_list ) > 0:
|
||||
node = ET.SubElement(root, 'Inker')
|
||||
node.text = utils.listToString( credit_inker_list )
|
||||
|
||||
if len( credit_colorist_list ) > 0:
|
||||
node = ET.SubElement(root, 'Colorist')
|
||||
node.text = utils.listToString( credit_colorist_list )
|
||||
|
||||
if len( credit_letterer_list ) > 0:
|
||||
node = ET.SubElement(root, 'Letterer')
|
||||
node.text = utils.listToString( credit_letterer_list )
|
||||
|
||||
if len( credit_cover_list ) > 0:
|
||||
node = ET.SubElement(root, 'CoverArtist')
|
||||
node.text = utils.listToString( credit_cover_list )
|
||||
|
||||
if len( credit_editor_list ) > 0:
|
||||
node = ET.SubElement(root, 'Editor')
|
||||
node.text = utils.listToString( credit_editor_list )
|
||||
|
||||
# !!!ATB todo: loop and add the page entries under pages node
|
||||
#pages = ET.SubElement(root, 'Pages')
|
||||
|
||||
|
55
crediteditorwindow.py
Normal file
55
crediteditorwindow.py
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui, uic
|
||||
|
||||
|
||||
class CreditEditorWindow(QtGui.QDialog):
|
||||
|
||||
|
||||
ModeEdit = 0
|
||||
ModeNew = 1
|
||||
|
||||
|
||||
def __init__(self, parent, mode, role, name ):
|
||||
super(CreditEditorWindow, self).__init__(parent)
|
||||
|
||||
uic.loadUi('crediteditorwindow.ui', self)
|
||||
|
||||
self.mode = mode
|
||||
|
||||
if self.mode == self.ModeEdit:
|
||||
self.setWindowTitle("Edit Credit")
|
||||
else:
|
||||
self.setWindowTitle("New Credit")
|
||||
|
||||
# Add the entries to the role combobox
|
||||
self.cbRole.addItem( "" )
|
||||
self.cbRole.addItem( "Writer" )
|
||||
self.cbRole.addItem( "Artist" )
|
||||
self.cbRole.addItem( "Penciller" )
|
||||
self.cbRole.addItem( "Inker" )
|
||||
self.cbRole.addItem( "Colorist" )
|
||||
self.cbRole.addItem( "Letterer" )
|
||||
self.cbRole.addItem( "Cover Artist" )
|
||||
self.cbRole.addItem( "Editor" )
|
||||
self.cbRole.addItem( "Other" )
|
||||
self.cbRole.addItem( "Plotter" )
|
||||
self.cbRole.addItem( "Scripter" )
|
||||
|
||||
self.leName.setText( name )
|
||||
|
||||
if role is not None and role != "":
|
||||
i = self.cbRole.findText( role )
|
||||
if i == -1:
|
||||
self.cbRole.setEditText( role )
|
||||
else:
|
||||
self.cbRole.setCurrentIndex( i )
|
||||
|
||||
def getCredits( self ):
|
||||
return self.cbRole.currentText(), self.leName.text()
|
||||
|
||||
|
||||
def accept( self ):
|
||||
if self.cbRole.currentText() == "" or self.leName.text() == "":
|
||||
QtGui.QMessageBox.warning(self, self.tr("Whoops"), self.tr("You need to enter both role and name for a credit."))
|
||||
else:
|
||||
QtGui.QDialog.accept(self)
|
107
crediteditorwindow.ui
Normal file
107
crediteditorwindow.ui
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>dialogCreditEditor</class>
|
||||
<widget class="QDialog" name="dialogCreditEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>196</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Modify Credit</string>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>140</y>
|
||||
<width>191</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="formLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>30</y>
|
||||
<width>341</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Role</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cbRole">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="leName"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>dialogCreditEditor</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>dialogCreditEditor</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -1,6 +1,9 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# This is horrible, and needs to be re-written, but, well, it mostly works!
|
||||
# This should probably be re-written, but, well, it mostly works!
|
||||
|
||||
# Some portions of this code were modified from pyComicMetaThis project
|
||||
# http://code.google.com/p/pycomicmetathis/
|
||||
|
||||
import re
|
||||
import os
|
||||
|
135
taggerwindow.py
135
taggerwindow.py
@ -1,13 +1,15 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui, uic
|
||||
import locale
|
||||
|
||||
from volumeselectionwindow import VolumeSelectionWindow
|
||||
from options import Options, MetaDataStyle
|
||||
from genericmetadata import GenericMetadata
|
||||
from comicvinetalker import ComicVineTalker
|
||||
from comicarchive import ComicArchive
|
||||
from crediteditorwindow import CreditEditorWindow
|
||||
import utils
|
||||
import locale
|
||||
|
||||
# this reads the environment and inits the right locale
|
||||
locale.setlocale(locale.LC_ALL, "")
|
||||
|
||||
@ -43,7 +45,11 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
|
||||
# hook up the callbacks
|
||||
self.cbDataStyle.currentIndexChanged.connect(self.setDataStyle)
|
||||
|
||||
self.btnEditCredit.clicked.connect(self.editCredit)
|
||||
self.btnAddCredit.clicked.connect(self.addCredit)
|
||||
self.btnRemoveCredit.clicked.connect(self.removeCredit)
|
||||
self.twCredits.cellDoubleClicked.connect(self.editCredit)
|
||||
|
||||
self.updateStyleTweaks()
|
||||
|
||||
|
||||
@ -232,36 +238,40 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
|
||||
row = 0
|
||||
for credit in md.credits:
|
||||
|
||||
# before we add the credit, see if the role-person pair already exists:
|
||||
r = 0
|
||||
while r < self.twCredits.rowCount():
|
||||
if ( self.twCredits.item(r, 0).text() == credit['role'].title() and
|
||||
self.twCredits.item(r, 1).text() == credit['person'] ):
|
||||
break
|
||||
r = r + 1
|
||||
|
||||
# if we didn't make it through the table, it's there alread, so continue without adding
|
||||
if ( r != self.twCredits.rowCount() ):
|
||||
# if the role-person pair already exists, just skip adding it to the list
|
||||
if self.isDupeCredit( credit['role'].title(), credit['person']):
|
||||
continue
|
||||
|
||||
self.twCredits.insertRow(row)
|
||||
|
||||
item_text = credit['role'].title()
|
||||
item = QtGui.QTableWidgetItem(item_text)
|
||||
#item.setData( QtCore.Qt.UserRole ,record['id'])
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable| QtCore.Qt.ItemIsEnabled)
|
||||
self.twCredits.setItem(row, 0, item)
|
||||
|
||||
item_text = credit['person']
|
||||
item = QtGui.QTableWidgetItem(item_text)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable| QtCore.Qt.ItemIsEnabled)
|
||||
self.twCredits.setItem(row, 1, item)
|
||||
|
||||
self.addNewCreditEntry( row, credit['role'].title(), credit['person'] )
|
||||
|
||||
row += 1
|
||||
|
||||
self.twCredits.setSortingEnabled( True )
|
||||
|
||||
def addNewCreditEntry( self, row, role, name ):
|
||||
self.twCredits.insertRow(row)
|
||||
|
||||
item_text = role
|
||||
item = QtGui.QTableWidgetItem(item_text)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable| QtCore.Qt.ItemIsEnabled)
|
||||
self.twCredits.setItem(row, 0, item)
|
||||
|
||||
item_text = name
|
||||
item = QtGui.QTableWidgetItem(item_text)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable| QtCore.Qt.ItemIsEnabled)
|
||||
self.twCredits.setItem(row, 1, item)
|
||||
|
||||
|
||||
def isDupeCredit( self, role, name ):
|
||||
r = 0
|
||||
while r < self.twCredits.rowCount():
|
||||
if ( self.twCredits.item(r, 0).text() == role and
|
||||
self.twCredits.item(r, 1).text() == name ):
|
||||
return True
|
||||
r = r + 1
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def formToMetadata( self ):
|
||||
|
||||
@ -326,6 +336,16 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
else:
|
||||
md.blackAndWhite = False
|
||||
|
||||
# get the credits from the table
|
||||
md.credits = list()
|
||||
row = 0
|
||||
while row < self.twCredits.rowCount():
|
||||
role = str(self.twCredits.item(row, 0).text())
|
||||
name = str(self.twCredits.item(row, 1).text())
|
||||
md.addCredit( name, role, False )
|
||||
print name, role, row
|
||||
row += 1
|
||||
|
||||
|
||||
def useFilename( self ):
|
||||
self.metadata = self.comic_archive.metadataFromFilename( )
|
||||
@ -443,6 +463,69 @@ class TaggerWindow( QtGui.QMainWindow):
|
||||
for item in cix_only:
|
||||
enableWidget(item, False )
|
||||
|
||||
def cellDoubleClicked( self, r, c ):
|
||||
self.editCredit()
|
||||
|
||||
def addCredit( self ):
|
||||
self.modifyCredits( "add" )
|
||||
|
||||
def editCredit( self ):
|
||||
if ( self.twCredits.currentRow() > -1 ):
|
||||
self.modifyCredits( "edit" )
|
||||
|
||||
def modifyCredits( self , action ):
|
||||
|
||||
if action == "edit":
|
||||
row = self.twCredits.currentRow()
|
||||
role = self.twCredits.item( row, 0 ).text()
|
||||
name = self.twCredits.item( row, 1 ).text()
|
||||
else:
|
||||
role = ""
|
||||
name = ""
|
||||
|
||||
editor = CreditEditorWindow( self, CreditEditorWindow.ModeEdit, role, name )
|
||||
editor.setModal(True)
|
||||
editor.exec_()
|
||||
if editor.result():
|
||||
new_role, new_name = editor.getCredits()
|
||||
|
||||
if new_name == name and new_role == role:
|
||||
#nothing has changed, just quit
|
||||
return
|
||||
|
||||
# check for dupes
|
||||
ok_to_mod = True
|
||||
if self.isDupeCredit( new_role, new_name):
|
||||
# delete the dupe credit from list
|
||||
#TODO warn user!!
|
||||
reply = QtGui.QMessageBox.question(self,
|
||||
self.tr("Duplicate Credit!"),
|
||||
self.tr("This will create a duplicate credit entry. Would you like to merge the entries, or create a duplicate?"),
|
||||
self.tr("Merge"), self.tr("Duplicate" ))
|
||||
|
||||
if reply == 0:
|
||||
# merge
|
||||
if action == "edit":
|
||||
# just remove the row that would be same
|
||||
self.twCredits.removeRow( row )
|
||||
|
||||
ok_to_mod = False
|
||||
|
||||
|
||||
if ok_to_mod:
|
||||
#modify it
|
||||
if action == "edit":
|
||||
self.twCredits.item(row, 0).setText( new_role )
|
||||
self.twCredits.item(row, 1).setText( new_name )
|
||||
else:
|
||||
# add new entry
|
||||
row = self.twCredits.rowCount()
|
||||
self.addNewCreditEntry( row, new_role, new_name)
|
||||
|
||||
def removeCredit( self ):
|
||||
row = self.twCredits.currentRow()
|
||||
if row != -1 :
|
||||
self.twCredits.removeRow( row )
|
||||
|
||||
|
||||
def center(self):
|
||||
|
12
todo.txt
12
todo.txt
@ -1,4 +1,3 @@
|
||||
Add more CIX tags:
|
||||
|
||||
|
||||
ComicArchive support for folders
|
||||
@ -8,20 +7,15 @@ API Key config
|
||||
|
||||
Toolbar icons
|
||||
|
||||
Consolidate Credit Roles for english variants : Penciler vs Penciller
|
||||
Consolidate Credit Roles for english variants? : Penciler vs Penciller
|
||||
|
||||
TaggerWindow entry fields
|
||||
General layout
|
||||
Special Dialogs needed for:
|
||||
Credits
|
||||
Pages Info
|
||||
|
||||
Some entry fields should/could be combobox:
|
||||
Format
|
||||
Language
|
||||
Country
|
||||
Manga?? CIX: "Yes", "No", "YesAndRightToLeft"
|
||||
|
||||
CR has editable dropdowns/comboboxes for Format, Publisher, Imprint
|
||||
-----------
|
||||
|
||||
Form type validation Ints vs strings for month, year. etc
|
||||
@ -72,4 +66,4 @@ Some that seem library only:
|
||||
Tags
|
||||
Proposed Values
|
||||
|
||||
Community Rating
|
||||
Community Rating
|
||||
|
Loading…
Reference in New Issue
Block a user