Esempio n. 1
0
 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'])
Esempio n. 2
0
    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])
                )