Created
December 6, 2012 20:32
-
-
Save laat/4228067 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
Copyright 2012 Sigurd Fosseng | |
You can do whatever you want with this stuff. If we meet some day, and | |
you think this stuff is worth it, you can buy me a beer or a coffee in | |
return. | |
Description: | |
Exports Spotify playlists that you own to *.xspf. | |
All files are exported to the same directory as the script. | |
Requirements: | |
pyspotify==1.9.1 | |
dexml==0.5.1 | |
Usage: | |
python spexport.py --username mee --password *mypass* | |
""" | |
from __future__ import print_function | |
from spotify.manager import SpotifySessionManager | |
from spotify import Link | |
import os | |
import threading | |
import time | |
import dexml | |
from dexml import fields | |
class Track(dexml.Model): | |
""" | |
A Track container | |
""" | |
title = fields.String(tagname="title") | |
creator = fields.String(tagname="creator") | |
album = fields.String(tagname="album", required=False) | |
track_num = fields.Integer(tagname="trackNum", required=False) | |
duration = fields.Integer(tagname="duration") | |
location = fields.String(tagname="location", required=False) | |
class meta: | |
tagname = "track" | |
class Playlist(dexml.Model): | |
""" | |
A playlist container | |
""" | |
version = fields.String() | |
title = fields.String(tagname="title") | |
creator = fields.String(tagname="creator") | |
location = fields.String(tagname="location") | |
tracks = fields.List(Track, tagname="trackList") | |
def __init__(self, *args, **kwargs): | |
super(Playlist, self).__init__(*args, **kwargs) | |
self.version = "1" | |
class meta: | |
namespace = "http://xspf.org/ns/0/" | |
tagname = "playlist" | |
def add_track(self, track): | |
self.tracks.append(track) | |
def extract_my_playlists(sm): | |
print("gathering playlists..") | |
time.sleep(10) # wait an arbitary length of time | |
playlists = [] | |
for i, playlist in enumerate(sm.ctr): | |
if (playlist.owner().canonical_name() == sm.username): | |
# the logged in user owns the playlist. | |
new_pl = generate_playlist(playlist) | |
for tr in playlist: | |
new_pl.add_track(generate_track(tr)) | |
playlists.append(new_pl) | |
write_playlists_to_file(playlists) | |
def write_playlists_to_file(playlists): | |
for playlist in playlists: | |
with open(playlist.title + ".xspf", "w") as f: | |
print(playlist.render(encoding="utf-8"), file=f) | |
print("Done.") | |
def generate_playlist(playlist): | |
name = playlist.name() | |
uri = Link.from_playlist(playlist) | |
creator = playlist.owner().display_name() # username | |
return Playlist(title=name, creator=creator, location=uri) | |
def generate_track(track): | |
name = track.name() | |
album = track.album().name() if track.album() else None | |
artists = ", ".join([artist.name() for artist in track.artists()]) | |
track_number = track.index() if track.index() > 0 else None | |
# do not include uri to local files | |
uri = str(Link.from_track(track)) | |
uri = None if uri.startswith("spotify:local") else uri | |
return Track(title=name, creator=artists, album=album, | |
track_num=track_number, duration=track.duration(), | |
location=uri) | |
class SpotifyManager(SpotifySessionManager): | |
appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key') | |
def __init__(self, *args, **kwargs): | |
SpotifySessionManager.__init__(self, *args, **kwargs) | |
print("loggin in..") | |
def logged_in(self, session, error): | |
self.session = session | |
self.ctr = session.playlist_container() | |
print("logged in") | |
t = threading.Thread(target=extract_my_playlists, args=(self, )) | |
t.start() | |
def logout(self): | |
print("logged out") | |
self.session.logout() | |
if __name__ == '__main__': | |
import optparse | |
op = optparse.OptionParser(version="%prog 0.1") | |
op.add_option("-u", "--username", help="Spotify username") | |
op.add_option("-p", "--password", help="Spotify password") | |
(options, args) = op.parse_args() | |
session = SpotifyManager(options.username, options.password, True) | |
session.connect() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment