Files
iTunesScraper/scraper.py
2022-05-10 22:26:57 +02:00

129 lines
3.8 KiB
Python
Executable File

#!/usr/bin/python3
# ex: set filetype=python
import argparse
import os
import urllib.parse
import xml.etree.cElementTree as xml
from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
from shutil import copyfile
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, cnt, max) -> str:
"""
Copies a track from its source to the destination folder
"""
path = urllib.parse.unquote(track.Location[7:])
dst = os.path.join(targetFolder, os.path.basename(path))
if (os.path.exists(path)):
print('Copying file {0} [{1}/{2}]'.format(path,cnt,max))
copyfile(path, dst)
else:
print('File {0} not found.'.format(path))
return None
return dst
def tag_file(track: Track, file_name: str, cnt, max):
"""
Adds ID3 tags to a file.
"""
if not file_name.endswith('.mp3'):
print('Skipping file {0}. It\'s not an mp3 file. [{1}/{2}]'
.format(file_name, cnt, max))
return
print('Tagging file {0} [{1}/{2}]'.format(file_name, cnt, max))
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)
count = 0
maxcount = len(tracks)
for t in tracks:
count += 1
new_file = copy_file(t, args.target)
if new_file is not None:
tag_file(t, new_file)
print('Done. Copied {0} of {1} files.'.format(count, maxcount))
if __name__ == "__main__":
main()