def newSongsInOther(self, other, artist, album=None, title=None, command='compare'): for album in (album,) if album else self.artists[artist]['albums']: for title in (title,) if title else self.artists[artist]['albums'][album]['songs']: song = self.artists[artist]['albums'][album]['songs'][title] otherSong = other.findSong(song) if otherSong: if song.compare(otherSong): if options['fix'] and takeAction("move %s to %s" % (otherSong.getPath(), otherSong.getPath(song.filePath))): otherSong.move(song.filePath) # Relies on filePath being the relative path song.syncModTime(otherSong) return info("Song %s has the same audio as song %s" %(song.getPath(), otherSong.getPath())); elif command == "backup" or command == "restore": otherPath = os.path.join(other.library, song.filePath) if takeAction("%s %s to %s" % (command, song.getPath(), otherPath)): song.copy(otherPath)
def diff(self, backup, command='compare'): libArtists = self.getArtists() bakArtists = backup.getArtists() while len(libArtists) > 0 or len(bakArtists) > 0: if len(bakArtists) == 0 or (len(libArtists) >0 and libArtists[-1] > bakArtists[-1]): artist = libArtists.pop() info("Library artist %s not found in backup" % artist) self.newSongsInOther(backup, artist, command=command) continue if len(libArtists) == 0 or (len(bakArtists) > 0 and bakArtists[-1] > libArtists[-1]): artist = bakArtists.pop() info("Backup artist %s not found in library" % artist) continue artist = libArtists.pop() bakArtists.pop() libAlbums = self.getAlbums(artist) bakAlbums = backup.getAlbums(artist) while len(libAlbums) > 0 or len(bakAlbums) > 0: if len(bakAlbums) == 0 or (len(libAlbums) > 0 and libAlbums[-1] > bakAlbums[-1]): album = libAlbums.pop() info("Library artist %s album %s not found in backup" % (artist, album)) self.newSongsInOther(backup, artist, album, command=command) continue if len(libAlbums) == 0 or (len(bakAlbums) > 0 and bakAlbums[-1] > libAlbums[-1]): album = bakAlbums.pop() info("Backup artist %s album %s not found in library" % (artist, album)) continue album = libAlbums.pop() bakAlbums.pop() libTitles = self.getTitles(artist, album) bakTitles = backup.getTitles(artist, album) while len(libTitles) > 0 or len(bakTitles) > 0: if len(bakTitles) == 0 or (len(libTitles) > 0 and libTitles[-1] > bakTitles[-1]): title = libTitles.pop() info("Library artist %s album %s title %s not found in backup" % (artist, album, title)) self.newSongsInOther(backup, artist, album, title, command=command) continue if len(libTitles) == 0 or (len(bakTitles) > 0 and bakTitles[-1] > libTitles[-1]): title = bakTitles.pop() info("Backup artist %s album %s title %s not found in library" % (artist, album, title)) continue libTitles.pop() bakTitles.pop()
def __init__(self, filePath, rootPath=None): MuseFile.__init__(self, filePath, rootPath) self.artist = None self.album = None self.md5 = None self.frames = {} # Determine meta-data from file path match = AudioFile.splitPattern.match(filePath) if not match: raise AudioFileError(filePath, "Failed to parse file path") (dirName, fileName, fileExt) = match.group(1, 2, 3) match = AudioFile.dirPattern.match(dirName) if not match: raise AudioFileError(filePath, "Failed to parse directory name " + dirName) (dirLetter, dirArtist, dirAlbum) = match.group(1, 2, 3) if not match.group(2) and match.group(3): dirAlbum = None if dirLetter or len(match.group(3)) > 1: dirArtist = match.group(3) else: dirLetter = match.group(3) #print "Directory: Letter %s Artist %s Album %s" % (dirLetter, dirArtist, dirAlbum) match = AudioFile.filePattern.match(fileName) if not match: raise AudioFileError(filePath, "Failed to parse file name " + fileName) (fileArtist, fileAlbum, self.track, self.title) = match.group(1, 2, 3, 4) #print ("File name: Letter %s Artist %s Album %s Track %s Song %s Ext %s" % # (dirLetter, fileArtist, fileAlbum, self.track, self.title, fileExt)) self.artist = reconcileStrings(dirArtist, fileArtist, default="Unknown") if self.artist == "Unknown": warn("Failed to determine an artist from the filepath", filePath) elif self.artist == None: self.artist = dirArtist match = AudioFile.numericPattern.match(fileArtist) if match and self.track == None: self.track = match.group(1) fileArtist = match.group(2) fileAlbum = None if fileArtist: match = AudioFile.artistAlbumPattern.match(fileArtist) if match and reconcileStrings(dirArtist, match.group(1)) and reconcileStrings(dirAlbum, match.group(2)): fileAlbum = match.group(2) else: match = AudioFile.withArtistPattern.match(fileArtist) if (not (match and (reconcileStrings(match.group(1), dirArtist) or reconcileStrings(match.group(2), dirArtist))) and not simpleString(dirArtist) == simpleString(fileArtist).replace("_", " ")): error("Directory artist '%s' differs from file name artist '%s'" % (dirArtist, fileArtist), filePath) self.album = reconcileStrings(dirAlbum, fileAlbum, default="Unknown") if self.album == "Unknown": info("Failed to determine an album from the filepath", filePath) # Too common to warn on elif self.album == None: self.album = dirAlbum if fileArtist.isdigit() and reconcileStrings(fileAlbum, dirArtist): self.track = fileArtist elif not reconcileStrings(fileAlbum, dirAlbum): match = AudioFile.yearAlbumPattern.match(dirAlbum) if match and reconcileStrings(fileAlbum, match.group(2)): self.year = match.group(1) self.album = match.group(2) else: error("Directory album '%s' differs from file name album '%s'" % (dirAlbum, fileAlbum), filePath) newPath = ("%s/%s%s%s%s.%s" % (dirName, safeAppend(self.artist, " - ", suppress="Unknown"), safeAppend(self.album, " - ", suppress="Unknown"), safeAppend(self.track, " - "), self.title, fileExt)) if getOption("fix", default=False) and newPath != filePath and takeAction("rename %s to %s" % (filePath, newPath)): os.rename(filePath, newPath) os.utime(newPath, None)