Files
iTunesScraper/scraper.py
2022-05-07 20:18:06 +02:00

119 lines
3.5 KiB
Python
Executable File

#!/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 import copyfile
import urllib
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 = urllib.parse.unquote(track.Location[7:])
dst = os.path.join(targetFolder, os.path.basename(path))
if (os.path.exists(path)):
print('Copying file {0}'.format(path))
copyfile(path, dst)
else:
print('File {0} not found.'.format(path))
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()