diff --git a/comet.py b/comet.py index d28bb8f..3a29cab 100644 --- a/comet.py +++ b/comet.py @@ -1,5 +1,5 @@ """ -A python class to encapsulate CoMets's data and file handling +A python class to encapsulate CoMet data """ """ @@ -84,25 +84,37 @@ class CoMet: md.title = "" assign( 'title', md.title ) assign( 'series', md.series ) - assign( 'issue', md.issue ) #must be int... + assign( 'issue', md.issue ) #must be int?? assign( 'volume', md.volume ) assign( 'description', md.comments ) - #assign( 'date', md.year ) #need to make a date from month, year assign( 'publisher', md.publisher ) - assign( 'genre', md.genre ) assign( 'pages', md.pageCount ) assign( 'format', md.format ) assign( 'language', md.language ) - #assign( 'readingDirection', md.??? ) - - assign( 'character', md.characters ) assign( 'rating', md.maturityRating ) - #assign( 'price', md.??? ) - #assign( 'isVersionOf', md.??? ) - #assign( 'rights', md.??? ) - #assign( 'identifier', md.??? ) - #assign( 'coverImage', md.??? ) - #assign( 'lastMark', md.??? ) + assign( 'price', md.price ) + assign( 'isVersionOf', md.isVersionOf ) + assign( 'rights', md.rights ) + assign( 'identifier', md.identifier ) + assign( 'lastMark', md.lastMark ) + assign( 'genre', md.genre ) # TODO repeatable + + if md.characters is not None: + char_list = [ c.strip() for c in md.characters.split(',') ] + for c in char_list: + assign( 'character', c ) + + if md.manga is not None and md.manga == "YesAndRightToLeft": + assign( 'readingDirection', "rtl") + + date_str = "" + if md.year is not None: + date_str = md.year.zfill(4) + if md.month is not None: + date_str += "-" + md.month.zfill(2) + assign( 'date', date_str ) + + #assign( 'coverImage', md.??? ) #TODO Need to use pages list, eventually... # need to specially process the credits, since they are structured differently than CIX credit_writer_list = list() @@ -171,16 +183,38 @@ class CoMet: md.issue = xlate( 'issue' ) md.volume = xlate( 'volume' ) md.comments = xlate( 'description' ) - #md.year = xlate( 'Year' ) - #md.month = xlate( 'Month' ) md.publisher = xlate( 'publisher' ) - md.genre = xlate( 'genre' ) md.language = xlate( 'language' ) md.format = xlate( 'format' ) - #md.manga = xlate( 'readingDirection' ) - #md.characters = xlate( 'character' ) md.pageCount = xlate( 'pages' ) md.maturityRating = xlate( 'rating' ) + md.price = xlate( 'price' ) + md.isVersionOf = xlate( 'isVersionOf' ) + md.rights = xlate( 'rights' ) + md.identifier = xlate( 'identifier' ) + md.lastMark = xlate( 'lastMark' ) + md.genre = xlate( 'genre' ) # TODO - repeatable field + + date = xlate( 'date' ) + if date is not None: + parts = date.split('-') + if len( parts) > 0: + md.year = parts[0] + if len( parts) > 1: + md.month = parts[1] + + coverImage = xlate( 'coverImage' ) # TODO - do something with this! + + readingDirection = xlate( 'readingDirection' ) + if readingDirection is not None and readingDirection == "rtl": + md.manga = "YesAndRightToLeft" + + # loop for character tags + char_list = [] + for n in root: + if n.tag == 'character': + char_list.append(n.text.strip()) + md.characters = utils.listToString( char_list ) # Now extract the credit info for n in root: @@ -201,6 +235,19 @@ class CoMet: return metadata + #verify that the string actually contains CoMet data in XML format + def validateString( self, string ): + try: + tree = ET.ElementTree(ET.fromstring( string )) + root = tree.getroot() + if root.tag != 'comet': + raise Exception + except: + return False + + return True + + def writeToExternalFile( self, filename, metadata ): tree = self.convertMetadataToXML( self, metadata ) diff --git a/comicarchive.py b/comicarchive.py index b96bd7f..54ec272 100644 --- a/comicarchive.py +++ b/comicarchive.py @@ -386,7 +386,8 @@ class ComicArchive: def __init__( self, path ): self.path = path self.ci_xml_filename = 'ComicInfo.xml' - self.comet_filename = 'CoMet.xml' + self.comet_default_filename = 'CoMet.xml' + self.comet_filename = None if self.zipTest(): self.archive_type = self.ArchiveType.Zip @@ -597,6 +598,7 @@ class ComicArchive: def writeCIX(self, metadata): if metadata is not None: + metadata.pageCount = self.getNumberOfPages() cix_string = ComicInfoXml().stringFromMetadata( metadata ) return self.archiver.writeArchiveFile( self.ci_xml_filename, cix_string ) else: @@ -632,24 +634,43 @@ class ComicArchive: def writeCoMet(self, metadata): if metadata is not None: + if not self.hasCoMet(): + self.comet_filename = self.comet_default_filename + + metadata.pageCount = self.getNumberOfPages() comet_string = CoMet().stringFromMetadata( metadata ) return self.archiver.writeArchiveFile( self.comet_filename, comet_string ) else: return False def removeCoMet( self ): - - return self.archiver.removeArchiveFile( self.comet_filename ) + if self.hasCoMet(): + retcode = self.archiver.removeArchiveFile( self.comet_filename ) + self.comet_filename = None + return retcode + return True def hasCoMet(self): if not self.seemsToBeAComicArchive(): return False - #TODO look at all xml files in root, and search for CoMet data, get first - #TODO if doesn't exist, use default - elif self.comet_filename in self.archiver.getArchiveFilenameList(): - return True - else: + + #Use the existence of self.comet_filename as a cue that the tag block exists + if self.comet_filename is None: + #TODO look at all xml files in root, and search for CoMet data, get first + for n in self.archiver.getArchiveFilenameList(): + if ( os.path.dirname(n) == "" and + os.path.splitext(n)[1].lower() == '.xml'): + # read in XML file, and validate it + data = self.archiver.readArchiveFile( n ) + if CoMet().validateString( data ): + # since we found it, save it! + self.comet_filename = n + return True + # if we made it through the loop, no CoMet here... return False + + else: + return True def metadataFromFilename( self ): diff --git a/genericmetadata.py b/genericmetadata.py index b5ae4e4..145942c 100644 --- a/genericmetadata.py +++ b/genericmetadata.py @@ -93,11 +93,19 @@ class GenericMetadata: self.characters = None self.teams = None self.locations = None - + self.credits = list() self.tags = list() self.pages = list() + # Some CoMet-only items + self.price = None + self.isVersionOf = None + self.rights = None + self.identifier = None + self.lastMark = None + + def overlay( self, new_md ): # Overlay a metadata object on this one # that is, when the new object has non-None @@ -130,7 +138,7 @@ class GenericMetadata: assign( "alternateNumber", new_md.alternateNumber ) assign( "alternateCount", new_md.alternateCount ) assign( "imprint", new_md.imprint ) - assign( "webLink", new_md.webLink ) + assign( "webLink", new_md.webLink ) assign( "format", new_md.format ) assign( "manga", new_md.manga ) assign( "blackAndWhite", new_md.blackAndWhite ) @@ -143,6 +151,12 @@ class GenericMetadata: assign( "locations", new_md.locations ) assign( "comments", new_md.comments ) assign( "notes", new_md.notes ) + + assign( "price", new_md.price ) + assign( "isVersionOf", new_md.isVersionOf ) + assign( "rights", new_md.rights ) + assign( "identifier", new_md.identifier ) + assign( "lastMark", new_md.lastMark ) self.overlayCredits( new_md.credits ) # TODO @@ -229,6 +243,13 @@ class GenericMetadata: add_attr_string( "webLink" ) add_attr_string( "format" ) add_attr_string( "manga" ) + + add_attr_string( "price" ) + add_attr_string( "isVersionOf" ) + add_attr_string( "rights" ) + add_attr_string( "identifier" ) + add_attr_string( "lastMark" ) + if self.blackAndWhite: add_attr_string( "blackAndWhite" ) add_attr_string( "maturityRating" )