def testParseTxtReturnsDictionaryWithAllFoundMetadata(self): txtParser = TxtParser(sampleTxt) metadata = txtParser.parseTxt() self.assertTrue(isinstance(metadata, dict)) self.assertTrue('artist' in metadata.keys()) self.assertEquals('The Foo Bars', metadata['artist']) self.assertEquals('1980-12-01', metadata['date'].isoformat()) self.assertEquals('Topeka, KS', metadata['location']) self.assertEquals('Venue', metadata['venue']) self.assertEquals(['First Song', 'Second Song', 'Third Song'], metadata['tracklist']) self.assertEquals(sampleTxt, metadata['comments'])
def getMetadataFromDir(self, dirName): """ Search dirName for a txt file and supported audio files. If found, return a tuple of parameters to be passed to self.addToQueue(). If not found, raises QueueDialogError. @type dirName: QString @param dirName: Full path of the directory @rtype: dict @return: Metadata suitable as a parameter for self.addToQueue() @raise QueueDialogError: For various errors. Error message contained in first argument. """ parent = self.parent() qDir = QDir(dirName) if getSettings()['verifyMd5Hashes']: md5s = self.getMd5s(qDir) else: md5s = [] qDir.setNameFilters(['*.txt']) if not qDir.entryList(): raise QueueDialogError( "No txt file found in the specified directory" ) # If at least three fields not found (not counting comments, which # is set to the full contents of the file), and there are more txt # files, keep trying. for index, txtFile in enumerate(qDir.entryList()): isTheFinalTxt = (index == len(qDir.entryList()) - 1) textFilePath = unicode(qDir.filePath(txtFile)) try: fileHandle = parent.openFileOfUnknownEncoding(textFilePath) txt = fileHandle.read() metadata = TxtParser(txt).parseTxt() fileHandle.close() foundCount = 0 for k, v in metadata.iteritems(): if v: foundCount += 1 if foundCount < 4 and not isTheFinalTxt: continue # Must contain valid audio files validExtensions = ['*.flac', '*.shn', '*.m4a'] qDir.setNameFilters(validExtensions) filePaths = parent.getFilePaths(qDir) filePaths = parent.getSortedFiles(filePaths) filePaths = [ unicode(filePath) for filePath in filePaths ] if len(filePaths) == 0: raise QueueDialogError( "Directory does not contain any supported audio " + "files (FLAC, SHN, ALAC)" ); if metadata['tracklist'] == None: metadata['tracklist'] = ['' for x in filePaths] # Otherwise, leave titles for remaining files blank if (len(filePaths) > len(metadata['tracklist'])): numOfBlankTracks = ( len(filePaths) - len(metadata['tracklist']) ) for i in range(0, numOfBlankTracks): metadata['tracklist'].append('') # If more tracks detected than files exist, # assume the extra tracks are an error del metadata['tracklist'][len(filePaths):] nonParsedMetadata = {} nonParsedMetadata['audioFiles'] = filePaths nonParsedMetadata['dir'] = qDir # Hash used for identicons and temp directory names nonParsedMetadata['hash'] = hashlib.md5(metadata['comments'] \ .encode('utf-8')).hexdigest() # The dir where all temp files for this show will be stored nonParsedMetadata['tempDir'] = QDir( getSettings().settingsDir + '/' + nonParsedMetadata['hash'] ) if not nonParsedMetadata['tempDir'].exists(): nonParsedMetadata['tempDir'].mkpath( nonParsedMetadata['tempDir'].absolutePath() ) # Check for MD5 mismatches nonParsedMetadata['md5_mismatches'] = [] tempDir = unicode(nonParsedMetadata['tempDir'].absolutePath()) if md5s: nonParsedMetadata['md5_mismatches'] = self.checkMd5s( md5s, filePaths ) try: audioFile = audiotools.open(filePaths[0]) isBroken = isinstance( audioFile, tracklint.BrokenFlacAudio ) if isBroken: metadata.update(nonParsedMetadata) self.fixBadFlacFiles(metadata) else: # Assume that an artist name found in the actual file # metadata is more accurate unless that title is # "Unknown Artist" audioFileMetadata = audioFile.get_metadata() artistFoundInFileMetadata = ( audioFileMetadata and audioFileMetadata.artist_name and audioFileMetadata.artist_name != \ 'Unknown Artist' ) if artistFoundInFileMetadata: txtParser = TxtParser(metadata['comments']) txtParser.artist = audioFileMetadata.artist_name # Don't lose values added to tracklist # since last parsing it tracklist = metadata['tracklist'] metadata = txtParser.parseTxt() metadata['tracklist'] = tracklist except audiotools.UnsupportedFile as e: raise QueueDialogError( os.path.basename(filePaths[0]) + " is an unsupported file: " ) nonParsedMetadata['cover'] = CoverArtRetriever \ .getCoverImageChoices(nonParsedMetadata, True)[0] metadata.update(nonParsedMetadata) if self.stopped: return None else: return metadata except IOError as e: raise QueueDialogError( "Could not read file: %s<br /><br />%s" % \ (txtFile, e.args[1]) ) except UnicodeDecodeError as e: raise QueueDialogError( "Could not read file: %s<br /><br />%s" % \ (txtFile, e.args[4]) )