def run(self, release): """Gather track-specific data and find a consensus.""" results = [] for track in release.tracks: with logSection("Attempting to determine %s for %s." % (self.fieldName, quote(track.fileName))): data = [] for (getter, weight) in self.getters: flowcontrol.checkpoint() log(" ") data.append((getter(track), weight, getter.__name__, quote(track.fileName))) self.logResults(data) consensus = self.findConsensus(data) log("\n\n\n") if consensus: results.append((track, consensus)) else: return False log(" ") for (track, consensus) in results: track.storeData(self.fieldName, consensus) return True
def writeResults(self): """After tags have been found, write tags and filenames for all tracks.""" flowcontrol.checkpoint() for track in self.release.tracks: flowcontrol.checkpoint(pauseOnly=True) track.writeTags() track.rename() log(" ")
def findConsensus(self, data): """Take data from getters and find the value with the highest score. Candidates that differ by only capitalization and punctuation are grouped together for scoring. Example: If the scores come back 5 Chick Corea 4 Song of Singing 3 Song Of Singing then the "song of singing" group will win with 7 points and the "Song of Singing" candidate will be chosen because it is the highest scoring candidate of that group.""" flowcontrol.checkpoint() # Create a dict of values to sums of weights while removing null results. scores = {} groupScores = {} for (candidate, weight, name, track) in data: if candidate: group = restrictChars(candidate, punctuation=False).lower() scores[candidate] = scores.get(candidate, 0) + weight groupScores[group] = groupScores.get(group, 0) + weight # Ensure that we have data, otherwise return None indicating failure if not scores: log("Unable to find consensus -- no getters returned valid results.") return None # Rank the groups and the candidates groups = [(score, group) for group, score in groupScores.items()] groups.sort(reverse=True) candidates = [(score, candidate) for candidate, score in scores.items()] candidates.sort(reverse=True) # Display candidates (and groups, if different). log("Candidates:") for score, candidate in candidates: log(" %s %s" % (str(score).rjust(4), candidate)) if len(groups) != len(candidates): log("\nGroups:") for score, group in groups: log(" %s %s" % (str(score).rjust(4), group)) # Pick the highest member of the winning group. topGroupScore, topGroup = groups[0] for score, candidate in candidates: if restrictChars(candidate, punctuation=False).lower() == topGroup: return candidate return winningCandidate
def traverse(directoryPath): """Recursively traverse directories.""" flowcontrol.checkpoint(cleanStopPoint=True) if not functions.validatePath(directoryPath, isDirectory=True): return subdirectoryPaths = functions.getValidSubdirectories(directoryPath) # If appropriate, rename and recurse into subdirectories if subdirectoryPaths: for subdirectoryPath in clean.standardizeFilenames(subdirectoryPaths): traverse(subdirectoryPath) # We are now in a leaf directory with no subdirectories. with logSection("\nHandling %s." % quote(directoryPath)): handleDirectory(directoryPath)
def run(self, release): """Gather release data and find a consensus.""" data = [] for track in release.tracks: with logSection("\nActing on track %s." % quote(track.fileName)): for (getter, weight) in self.getters: flowcontrol.checkpoint() log(" ") data.append((getter(track), weight, getter.__name__, quote(track.fileName))) self.logResults(data) consenus = self.findConsensus(data) log("\n\n\n") if consenus: release.storeData(self.fieldName, consenus) return True else: return False