예제 #1
0
def playlist_list(playlist_name, itunes_xml):
    lib = Library(itunes_xml)
    playlist = lib.getPlaylist(playlist_name)
    track_locations = []
    for song in playlist.tracks:
        # print("{a} - {n} - {p}".format(a=song.artist, n=song.name, p=song.location))
        track_locations.append(song.location)
    return track_locations
예제 #2
0
def get_tracks(lib_fn):
    lib = Library(lib_fn)
    tracks = []
    for id, song in lib.songs.items():
        if song.location:
            tracks.append(song)
    return tracks
 def __init__(self, path):
     library = Library(path)
     albums = {}
     for id, song in library.songs.items():
         if song and song.album:
             albums[song.album + (song.album_artist or "")] = song
     DiffableCollection.__init__(self, albums)
 def __init__(self, path):
     library = Library(path)
     songs = {}
     for id, song in library.songs.items():
         if song:
             songs[(song.artist or "") + song.name] = song
     DiffableCollection.__init__(self, songs)
예제 #5
0
    def __generate(self, **kwargs):
        """ Generate xml with **kwargs, save to tmp file, init parser

        :return: <iTunes xml parser object>
        """
        xml = generate_xml(**kwargs)
        tmp_file(path=self.path, text=tostring(xml))
        return Library(itunesxml=self.path)
예제 #6
0
class TestLibrary(unittest.TestCase):

    def setUp(self):
        self.it_library = Library(os.path.join(os.path.dirname(__file__), "Test Library.xml"))

    def test_songs(self):

        for id, song in self.it_library.songs.items():
            assert(hasattr(song, 'name') == True)

    def test_playlists(self):

        playlists = self.it_library.getPlaylistNames()

        for song in self.it_library.getPlaylist(playlists[0]).tracks:
            assert(hasattr(song, 'track_number'))
            assert(hasattr(song, 'artist'))
            assert(hasattr(song, 'name'))
def parse_xml(settings):
    """Parse the XML file for the wanted playlists and write the data to a file."""
    data = Library(settings['xmlFile'])
    playlists = data.getPlaylistNames()
    for name in playlists:
        if name in settings['whiteList']:
            playlist = data.getPlaylist(name)
            handle = open(settings['outputDir'] +
                          '/' + name, 'w')
            handle.write('[')
            first = True
            for song in playlist.tracks:
                if first:
                    first = False
                else:
                    handle.write(',')
                path = converttobytestr(song.location).replace(
                    settings['pattern'], settings['replacement'])
                handle.write(
                    '\n  {\n    "service": "mpd",\n    "type": "song",\n    "title" : "')
                if song.name:
                    handle.write(converttobytestr(song.name))
                handle.write('",\n    "artist": "')
                if song.artist:
                    handle.write(converttobytestr(song.artist))
                handle.write('",\n    "album": "')
                if song.album:
                    handle.write(converttobytestr(song.album))
                handle.write('",\n    "albumart": "')
                album_path = os.path.dirname(path)
                short_path = album_path.replace(settings['replacement'], '')
                # handle.write('/albumart?web=none')
                handle.write('/albumart?web=' + urllib.quote(short_path) +
                             '/large&path=' + urllib.quote(album_path) + '&icon=fa-dot-circle-o')
                handle.write('",\n    "uri": "')
                handle.write(path + '"\n  }')
                if path == song.location:
                    print 'Did not match: ' + song.location
            handle.write('\n]\n')
            handle.close()
 def _refresh_lib(self):
     if not os.path.isfile(self._pf) or os.path.getmtime(
             self._pf) + self._pf_exp < int(time.time()):
         itl_source = Library(self.lib_path)
         pickle.dump(itl_source, open(self._pf, "wb"))
     self.lib = pickle.load(open(self._pf, "rb"))
     self.songs_by_type = {}
     self.song_type_report = {}
     self.songs_by_type, self.song_type_report = self._group_songs(
         self.lib.songs.values(), 'kind')
     #self.itunes_base_dir = self.lib.il.get('Music Folder', '').replace('file:///', '').replace('%20', ' ')
     self.itunes_base_dir = urlparse.unquote(
         urlparse.urlparse(self.lib.il.get('Music Folder')).path[1:])
예제 #9
0
 def get_itunes_lib(self):
     path = self.backup_file(Config.ITUNES_PATH, Config.BACKUP_PATH)
     l = Library(path)
     songs = l.songs.items()
     song_list = []
     for id, song in songs:
         song_model = None
         song_model = Song(artist=song.artist,
                           title=song.name,
                           genre=song.genre,
                           album=song.album)
         song_list.append(song_model)
     return song_list
예제 #10
0
def process(path, user_id) -> dict:
    clogger.info('process file: %s for user %s', path, user_id)

    # no need for try-except because
    # on any Exception celery task will be marked as failed
    lib = Library(itunesxml=path)
    playlist_deleted, track_delete = clear_user_itunes_data(user_id)
    insert_tracks(lib, user_id)
    playlists_created = insert_playlists(lib, user_id)

    return dict(
        playlists_deleted=playlist_deleted,
        tracks_deleted=track_delete,
        playlists_created=playlists_created,
        tracks_created=len(lib.songs.values()),
    )
예제 #11
0
def get_itunes_lib():
    path = backup_file(ITUNES_PATH, BACKUP_PATH)
    l = Library(path)
    songs = l.songs.items()
    dict_list = []
    for id, song in songs:
        song_dict = {}
        song_dict['artist'] = song.artist
        song_dict['title'] = song.name
        song_dict['genre'] = song.genre
        song_dict['album'] = song.album
        dict_list.append(song_dict)
    itunes_lib = pd.DataFrame(dict_list)
    itunes_lib['artist_stripped'] = itunes_lib.artist.apply(strip_ft)
    itunes_lib['title_stripped'] = itunes_lib.title.apply(strip_ft)
    itunes_lib['full_title_stripped'] = itunes_lib[
        'artist_stripped'] + ' - ' + itunes_lib['title_stripped']
    return itunes_lib
예제 #12
0
def run_export():
    library = Library('/Users/ruu/Music/iTunes/iTunes Music Library.xml')

    library_data = {}

    for song_id, song_data in library.songs.items():
        if song_data.album_artist not in library_data:
            library_data[song_data.album_artist] = {}

        if song_data.album not in library_data[song_data.album_artist]:
            library_data[song_data.album_artist][song_data.album] = []

        library_data[song_data.album_artist][song_data.album].append(song_data)

    for i in range(8):
        Process(target=process_enclosure, args=(album_queue, )).start()

    for album_artist, albums in library_data.items():
        for album, songs in albums.items():
            album_queue.put((
                album_artist,
                album,
                songs,
            ))
예제 #13
0
from libpytunes import Library


class Song:
    def __init__(self, artist, name):
        self.Artist = artist
        self.Name = name


SongList = []

l = Library("C:/Users/Admin/Desktop/Library.xml")

for id, song in l.songs.items():
    SongList.append(Song(song.artist, song.name))
예제 #14
0
		print("[ERROR] Please respond with 'yes' or 'no'. Exiting...")
		quit()

	choiceRatings = input("Do you want to sync 1 star ratings? (yes/no): ").lower()
	if choiceRatings in choiceyes:
		print("[INFO] Syncing 1 star ratings")
		choiceRatings = 10
	elif choiceRatings in choiceno:
		print("[INFO] Skipping 1 star ratings")
		choiceRatings = 20
	else:
		print("[ERROR] Please respond with 'yes' or 'no'. Exiting...")
		quit()

	print("[INFO] Loading iTunes library...")
	itunesLibrary = Library(itunesLibraryName)
	itunesLibraryCount = len(itunesLibrary.songs.items())
	print("[INFO] Total number of iTunes tracks: ", itunesLibraryCount)
	time.sleep(2)

	print("[INFO] Optimizing iTunes library...")
	itunesRatingList = { }
	counter = 0
	for x, song in itunesLibrary.songs.items():
		counter += 1
		print("\r[", counter, "/", itunesLibraryCount, "] ")
		import sys
		sys.stdout.flush()
		if song and song.rating and song.rating > choiceRatings :
			songFullName = str(song.name) + ' - ' + str(song.album_artist) + ' - ' + str(song.album)
			songRating = song.rating/10
def main():
    """Main script"""
    num_cores = multiprocessing.cpu_count()

    l = Library(FILEPATH)
    playlists = l.getPlaylistNames()

    PLEX = PlexServer(PLEX_URL, PLEX_TOKEN)
    PLEX_USERS = get_user_tokens(PLEX.machineIdentifier)
    PLEX_MUSIC = PLEX.library.section('Music')
    PLEX_TRACK_LIST = PLEX_MUSIC.searchTracks()
    PLEX_ARTIST_LIST = PLEX_MUSIC.searchArtists()

    for playlist in playlists:
        playlist_items = []
        DATA_FILE = playlist + '.pickle'

        if playlist not in PLAYLISTS:
            continue

        # Check if .pickle exists
        try:
            print("Loading the '{title}' playlist from disk...".format(title=playlist))

            with open(DATA_FILE, 'rb') as fp:
                playlist_items = pickle.load(fp)
                fp.close()

            # HACK
            playlist_items = [playlist_item for playlist_item in playlist_items if playlist_item]

        except FileNotFoundError:
            print("Building the '{title}' playlist...".format(title=playlist))

            PLAYLIST_TRACKS = l.getPlaylist(playlist).tracks

            # Multiprocessing implementation
            # playlist_items = Parallel(n_jobs=num_cores, prefer='processes')(
            #     delayed(match_track)(PLAYLIST_TRACK, PLEX_MUSIC, PLEX_ARTIST_LIST, PLEX_TRACK_LIST) for PLAYLIST_TRACK in PLAYLIST_TRACKS)

            # Standard implementation
            for PLAYLIST_TRACK in PLAYLIST_TRACKS:
                track_match = match_track(PLAYLIST_TRACK, PLEX_MUSIC, PLEX_ARTIST_LIST, PLEX_TRACK_LIST)
                if track_match:
                    playlist_items.append(track_match)

            # Save data (just in case)
            with open(DATA_FILE, 'wb') as fp:
                pickle.dump(playlist_items, fp)
                fp.close()

        # Create playlist (per user)
        for user in USERS:
            user_token = PLEX_USERS.get(user)
            if not user_token:
                print("...User '{user}' not found in shared users. Skipping.".format(user=user))
                continue

            user_plex = PlexServer(PLEX_URL, user_token)

            # Delete the old playlist
            try:
                user_playlist = user_plex.playlist(playlist)
                user_playlist.delete()
            except:
                pass

            # Create a new playlist
            user_plex.createPlaylist(playlist, playlist_items)
            print("...Created playlist for '{user}'.".format(user=user))
    return
예제 #16
0
from libpytunes import Library

l = Library("/path/to/iTunes Library.xml")

for id, song in l.songs.items():
    if song and song.rating:
        if song.rating > 80:
            print(song.name, song.rating)

playlists = l.getPlaylistNames()

for song in l.getPlaylist(playlists[0]).tracks:
    print("[{t}] {a} - {n}".format(t=song.track_number,
                                   a=song.artist,
                                   n=song.name))
예제 #17
0
                    playlistContent += os.path.relpath(track.location,
                                                       start=parentPath) + "\n"
                except ValueError:
                    print("Warning: Could not add the track \"" +
                          track.location +
                          "\" as relative path to the playlist \"" +
                          playlistName +
                          "\"; added the track as absolute path instead.")
                    playlistContent += track.location + "\n"

        playlistPath = parentPath.joinpath(
            cleanupPlaylistName(playlist.name) + ".m3u")
        playlistPath.write_text(playlistContent, encoding="utf8")


playlists = {}

library = Library(libraryPath)
for playlistName in library.getPlaylistNames(ignoreList=[
        "Library", "Music", "Movies", "TV Shows", "Purchased", "iTunes DJ",
        "Podcasts", "Audiobooks", "Downloaded", "Bibliotheek", "Muziek",
        "Films", "TV-programma's", "Aangekocht", "iTunes DJ", "Podcasts",
        "Audioboeken", "Gedownload"
] + ignoreList):
    playlist = library.getPlaylist(playlistName)
    playlists[playlist.playlist_persistent_id] = playlist

for playlist in playlists.values():
    if (playlist.parent_persistent_id == None):
        exportPlaylist(playlist, playlistRootPath)
예제 #18
0
parser = argparse.ArgumentParser(
    description=
    'Parse iTunes XML library and output useful things because Apple won\'t help you'
)
parser.add_argument('file', help='iTunes XML library file to process')
parser.add_argument('--lists',
                    help='file with newline delimited lists to output')
parser.add_argument('--playlist',
                    help='output playlist names only',
                    action='store_true')
parser.add_argument('--spotify',
                    help='transfer playlists to a spotify account')
args = parser.parse_args()

l = Library(args.file)
playlists = l.getPlaylistNames()

# remove first element; by default it's a list of all songs
del playlists[0]

if args.playlist == True:
    for listname in playlists:
        print(listname)
else:
    # if specific playlists desired, prepare array
    lists = []
    if args.lists:
        # lists = open(args.lists).readlines()
        listfile = open(args.lists)
        for line in listfile:
예제 #19
0
            n_p * section_length:(n_p + 1) * section_length,
            0] = beat_mfcc_delta[0][para_init_locs[n_p]:para_init_locs[n_p] +
                                    section_length] / 250
        all_features[n_p * section_length:(n_p + 1) * section_length,
                     1] = np.argmax(
                         beat_chroma[:,
                                     para_init_locs[n_p]:para_init_locs[n_p] +
                                     section_length],
                         axis=0) / 11

    return all_features.reshape((n_paras * section_length * 2))


pickle_file = "itl.p"
xmlPath = '/Users/vidursatija/Music/iTunes/iTunes Music Library.xml'  #your dir here
l = Library(xmlPath)
pickle.dump(l, open(pickle_file, "wb"))

itl = pickle.load(open(pickle_file, "rb"))

song_dict = {}
count = 0
for id, song in itl.songs.items():
    if song and song.kind:
        if song.kind[-10:] == 'audio file':
            songPath = song.location
            try:
                song_dict["-".join([
                    str(song.name)[:5],
                    str(song.album)[:5],
                    str(song.artist)[:5],
예제 #20
0
import xml.etree.ElementTree as ET
from libpytunes import Library
from collections import Counter
import musicbrainzngs
import requests
from urllib.parse import urlparse
import boto3
import botocore

musicbrainzngs.set_useragent("Artist Nationality Sorter", "a0.0.2",
                             "alexchow.me")

s3 = boto3.resource('s3')

# l = Library('/Users/alexchow/Music/iTunes/iTunes Music Library.xml')
l = Library('iTunes Music Library.xml')
artists = []
xmls = []
countries = []
cities = []


def findArtist(library):

    for id, song in l.songs.items():
        if song.artist is None:
            continue
        if song.artist in artists:
            continue
        else:
            test = musicbrainzngs.search_artists(query=song.artist, limit=1)
예제 #21
0
            currentPath.mkdir()

        for childPlaylist in playlists.values():
            if (childPlaylist.parent_persistent_id ==
                    playlist.playlist_persistent_id):
                exportPlaylist(childPlaylist, currentPath)
    else:
        playlistContent = ""
        for track in playlist.tracks:
            if track.location != None:
                playlistContent += os.path.relpath(track.location,
                                                   start=parentPath) + "\n"

        playlistPath = parentPath.joinpath(
            cleanupPlaylistName(playlist.name) + ".m3u")
        playlistPath.write_text(playlistContent, encoding="utf8")


playlists = {}

library = Library(libraryPath)
for playlistName in library.getPlaylistNames(ignoreList=[
        "Library", "Music", "Movies", "TV Shows", "Purchased", "iTunes DJ",
        "Podcasts", "Audiobooks", "Downloaded"
] + ignoreList):
    playlist = library.getPlaylist(playlistName)
    playlists[playlist.playlist_persistent_id] = playlist

for playlist in playlists.values():
    if (playlist.parent_persistent_id == None):
        exportPlaylist(playlist, playlistRootPath)
예제 #22
0
    def __init__(self, configuration):
        itunesLibraryPath = configuration.get('iTunes', 'itunesLibraryPath')

        self.library = Library(itunesLibraryPath)
        itunesLibraryCount = len(self.library.songs.items())
        print("[INFO] Total number of iTunes tracks: ", itunesLibraryCount)
예제 #23
0
 def setUp(self):
     self.it_library = Library(os.path.join(os.path.dirname(__file__), "Test Library.xml"))
예제 #24
0
from libpytunes import Library
import pandas as pd
import datetime
import matplotlib.pyplot as plt

l = Library("C:\Python34\music_Library.xml")

new_list = []
counter = 0

new_list = [
    song.__dict__ for id, song in l.songs.items() if song and song.kind
]

df = pd.DataFrame(new_list)
##print(df.head())
#writer = pd.ExcelWriter('c:\\Users\\cdonohu\\Documents\\python\\music_output_test.xlsx', engine='xlsxwriter')
#df.to_excel(writer, sheet_name='Sheet1')
#writer.save()

df['genre'].plot()
plt.show()
            song_info = get_song_details_using_id3(file)
            if song_info is not None:
                lookup_song_info(song_info['artist'], song_info['api_path'],
                                 song_info['track_name'],
                                 song_info['track_length'],
                                 song_info['mp3_path'])
    else:
        print(Fore.BLUE + 'Searching through iTunes library')
        lib_path = itunes_library
        pickle_file = "itl.p"
        expiry = 60 * 60
        epoch_time = int(time.time())

        if not os.path.isfile(pickle_file) or os.path.getmtime(
                pickle_file) + expiry < epoch_time:
            itl_source = Library(lib_path)
            pickle.dump(itl_source, open(pickle_file, "wb"))

        itl = pickle.load(open(pickle_file, "rb"))

        for id, song in itl.songs.items():
            if song:
                song_info = get_song_details_using_itunes(song)
                if song_info is not None:
                    lookup_song_info(song_info['artist'],
                                     song_info['api_path'],
                                     song_info['track_name'],
                                     song_info['track_length'],
                                     song_info['mp3_path'])

    print(Style.RESET_ALL)
예제 #26
0
def build_dbs(itunes_xml_path):
    itunes_media_path = re.sub(r'.*iTunes/.*', 'iTunes Media/Music/',
                               itunes_xml_path)
    library = Library(itunes_xml_path).songs.values(
    )  # Récupère toutes les musiques de la bibliothèque
    genres_list = list_of_genre(
        library
    )  # Récupère tous les genres musicaux existant dans la bibliothèque
    track_db_col = [
        "Name", "Album", "Artist", "Album_Artist", "Genre", "Year",
        "Date_Added", "Group", "Play_Count", "Location", "All_Artists",
        "Comments"
    ]
    artist_db = pandas.DataFrame(columns=["Artist_Name"] +
                                 genres_list)  # un DF vide pour les artistes
    track_db = pandas.DataFrame(
        columns=track_db_col)  # un DF vide pour les titres
    artist_already_added = set(
    )  # Ensemble des artistes ajoutés au DF (de base, vide)
    # song : Objet de "type dictionnaire" conservant toutes les musiques avec toutes les métadonnées associées.
    for song in library:

        # Appel des fonctions de formatage
        artist_org = formating_artist(song.artist)
        remixer_lst = formating_remixer(song)
        all_artist = sorted(list(set(artist_org + remixer_lst)))
        if song.composer is not None:
            all_artist.append(song.composer)
            track_composer = song.composer
        else:
            track_composer = ""
        all_artist = formating_with_alias(all_artist)

        if song.play_count is None:
            count = 0
        else:
            count = song.play_count

        track_location = re.sub(r".*{}".format(itunes_media_path),
                                itunes_media_path, song.location)
        track_artists = ", ".join(all_artist)

        track_new_entry = {
            "Name": song.name,
            "Album": song.album,
            "Artist": song.artist,
            "Album_Artist": song.album_artist,
            "Genre": re.sub(r".*> ", "", song.genre),
            "Year": song.year,
            "Composer": track_composer,
            "Date_Added": datetime.fromtimestamp(mktime(song.date_added)),
            "Group": song.grouping,
            "Play_Count": count,
            "Location": track_location,
            "All_Artists": track_artists,
            "Comments": song.comments
        }

        track_db = track_db.append(track_new_entry, ignore_index=True)

        for an_artist in all_artist:

            if an_artist not in artist_already_added:

                # Création d'une pour l'artiste
                artist_new_entry = {"Artist_Name": an_artist}
                artist_new_entry.update({genres: 0 for genres in genres_list})
                artist_db = artist_db.append(artist_new_entry,
                                             ignore_index=True)
                artist_db.loc[artist_db.Artist_Name == an_artist,
                              song.genre] += 1

                # L'artiste existe désormais dans la DB :
                artist_already_added.update({an_artist})

            else:

                # Pour les artistes existants dans la DB, +1 pour le genre musicale de la musique traitée.
                artist_db.loc[artist_db.Artist_Name == an_artist,
                              song.genre] += 1

    # Re-formatage des noms de colonne (plus d'infos prochainement).
    col_names = [re.sub(r".*> ", "", col_name) for col_name in list(artist_db)]
    artist_db.columns = col_names

    # Mise en ordre alphabétique des colonnes des genres musicaux
    genres = sorted(col_names[1:])
    new_col_names = ["Artist_Name"] + genres
    artist_db = artist_db[new_col_names]

    # Transtypage en vue de la sommation
    artist_db = artist_db.astype({genre: int for genre in genres})
    artist_db["TOTAL"] = artist_db.sum(axis=1, numeric_only=True, skipna=True)

    # Normalisation des noms d'artistes pour la mise ordre des lignes
    artist_db["NameNorm"] = artist_db.Artist_Name.str.normalize(
        'NFKD').str.encode('ascii',
                           errors='ignore').str.decode('utf-8').str.upper()

    # Mise en ordre des lignes et suppression de la colonne de tri "NameNorm"
    artist_db = artist_db.sort_values(by=["TOTAL", "NameNorm"],
                                      ascending=[0, 1]).reset_index(drop=True)
    artist_db = artist_db.drop(labels="NameNorm", axis=1)

    dbs = {"A_DB": artist_db, "T_DB": track_db}

    return dbs