#!/usr/bin/python3 # ex: set filetype=python import argparse from mutagen.mp3 import MP3 from mutagen.easyid3 import EasyID3 import mutagen.id3 from mutagen.id3 import ID3, TIT2, TIT3, TALB, TRCK, TYER import os from shutil importy copyfile import xml.etree.cElementTree as xml class Track(): """ Stores all the information of a track inside an object. Can be used to easily access the tracks stored in the database. """ def __init__(self, xml_doc): it = iter(xml_doc) for k, v in zip(it, it): setattr(self, k.text.replace(' ', ''), v.text) def parseXml(xml_file): """ Parses an xml file and returns the DOM tree. """ tree = xml.parse(xml_file) root = tree.getroot() tracks = [] for t in root.findall('.//dict/dict/dict'): tracks.append(Track(t)) return tracks def copy_file(track: Track, targetFolder) -> str: """ Copies a track from its source to the destination folder """ path = track.Location[7:] dst = os.path.join(targetFolder, os.path.basename(path)) if (os.path.exists(path)): print('Copying file {0}', path) copyfile(path, dst) else: print('File {0} not found.') return None return dst def tag_file(track: Track, file_name: str): """ Adds ID3 tags to a file. """ if not file_name.endswith('.mp3'): print('Skipping file {0}. It\'s not an mp3 file.'.format(file_name)) return print('Tagging file {0}'.format(file_name)) mp3file = MP3(file_name, ID3=EasyID3) if hasattr(track,'Album'): mp3file['album'] = track.Album if hasattr(track,'BPM'): mp3file['bpm'] = track.BPM if hasattr(track,'Compilation'): mp3file['compilation'] = 'true' if hasattr(track,'Composer'): mp3file['composer'] = track.Composer if hasattr(track,'TotalTime'): mp3file['length'] = track.TotalTime if hasattr(track,'Name'): mp3file['title'] = track.Name if hasattr(track,'Artist'): mp3file['artist'] = track.Artist if hasattr(track,'AlbumArtist'): mp3file['albumartist'] = track.AlbumArtist if hasattr(track,'DiscNumber'): mp3file['discnumber'] = track.DiscNumber if hasattr(track,'TrackNumber'): if hasattr(track,'TrackCount'): mp3file['tracknumber'] = '{0}/{1}'.format(track.TrackNumber, track.TrackCount) else: mp3file['tracknumber'] = track.TrackNumber if hasattr(track,'Genre'): mp3file['genre'] = track.Genre mp3file.save() def main(): """ Setup our main program """ parser = argparse.ArgumentParser() parser.add_argument('-t', '--target', type=str, help='The target path to store the scraped \ files into', default='~/itunesscrape') parser.add_argument('-l', '--logfile', type=str, help='The path to the logfile to use.', default='~/itunesscrape.log') parser.add_argument('libraryFile', help='The iTunes library file in XML format.') args = parser.parse_args() print('Parsing library file...') tracks = parseXml(args.libraryFile) print('{0} tracks found.'.format(len(tracks))) if not os.path.isdir(args.target): os.mkdir(args.target) for t in tracks: new_file = copy_file(t, args.target) if new_file is not None: tag_file(t, new_file) if __name__ == "__main__": main()