Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,4 @@ spotify_appkey.key
*.m4a
tmp/*
*~
.cache-*
2 changes: 1 addition & 1 deletion spotify_ripper/post_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import spotify
import codecs
import shutil
from spotify_ripper.remove_all_from_playlist import remove_all_from_playlist
from spotify_ripper.spotipy_integration import remove_all_from_playlist


class PostActions(object):
Expand Down
45 changes: 0 additions & 45 deletions spotify_ripper/remove_all_from_playlist.py

This file was deleted.

28 changes: 19 additions & 9 deletions spotify_ripper/ripper.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from spotify_ripper.sync import Sync
from spotify_ripper.eventloop import EventLoop
from datetime import datetime
from spotify_ripper.remove_all_from_playlist import get_playlist_tracks
from spotify_ripper.spotipy_integration import get_playlist_tracks, init_spotipy
import os
import sys
import time
Expand Down Expand Up @@ -189,12 +189,16 @@ def run(self):
self.ripper_continue.wait()
if self.abort.is_set():
return
#set session to provate

# set session to private
self.session.social.private_session = True

# list of spotify URIs
uris = args.uri

# init spotipy api
init_spotipy(self.session.user.canonical_name)

def get_tracks_from_uri(uri):
self.current_playlist = None
self.current_album = None
Expand Down Expand Up @@ -225,18 +229,24 @@ def get_tracks_from_uri(uri):

# calculate total size and time
all_tracks = []
all_uris = {}
for uri in uris:
tracks = list(get_tracks_from_uri(uri))
if uri not in all_uris:
all_uris[uri] = list(get_tracks_from_uri(uri))
tracks = all_uris[uri]

# TODO: remove dependency on current_album, ...
for idx, track in enumerate(tracks):
print('Loading track {}/{}...'.format(idx, len(tracks)), end='\r')
sys.stdout.flush()

# ignore local tracks
if track.is_local:
continue

audio_file = self.format_track_path(idx, track)
all_tracks.append((track, audio_file))
print('Loading track {}/{}...'.format(len(tracks), len(tracks)))

self.progress.calc_total(all_tracks)

Expand All @@ -250,7 +260,9 @@ def get_tracks_from_uri(uri):
if self.abort.is_set():
break

tracks = list(get_tracks_from_uri(uri))
if uri not in all_uris:
all_uris[uri] = list(get_tracks_from_uri(uri))
tracks = all_uris[uri]

if args.playlist_sync and self.current_playlist:
self.sync = Sync(args, self)
Expand All @@ -269,8 +281,8 @@ def get_tracks_from_uri(uri):
track.load(args.timeout)
if track.availability != 1 or track.is_local:
print(
Fore.RED + 'Track is not available, '
'skipping...' + Fore.RESET)
Fore.RED + 'Track {} - {} is not available, skipping...'
.format(track.artists[0].name, track.name) + Fore.RESET)
self.post.log_failure(track)
continue

Expand Down Expand Up @@ -363,7 +375,7 @@ def get_tracks_from_uri(uri):
self.post.create_playlist_wpl(tracks)

# actually removing the tracks from playlist
self.post.remove_tracks_from_playlist()
# self.post.remove_tracks_from_playlist()

# remove libspotify's offline storage cache
self.post.remove_offline_cache()
Expand Down Expand Up @@ -427,7 +439,6 @@ def load_link(self, uri):
track = link.as_track()
return iter([track])
elif link.type == spotify.LinkType.PLAYLIST:
print('get playlist tracks')
self.playlist_uri = uri
tracks = get_playlist_tracks(self.session.user.canonical_name, uri)
track_list = tracks.get('items')
Expand All @@ -438,7 +449,6 @@ def load_link(self, uri):
tracksIter = iter(uriList)
for i in tracksIter:
trackList.append(self.session.get_link(i).as_track())
print('Loading playlist...')
return iter(trackList)
elif link.type == spotify.LinkType.STARRED:
link_user = link.as_user()
Expand Down
79 changes: 79 additions & 0 deletions spotify_ripper/spotipy_integration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import sys

import spotipy.util as util
import spotipy.client
import spotipy.oauth2 as oauth2
import os

redirect_uri = 'http://www.purple.com'
client_id = ''
client_secret = ''
scope = 'playlist-modify-public playlist-modify-private playlist-read-collaborative'

# client_id = os.environ["SPOTIPY_CLIENT_ID"]
# client_secret = os.environ["SPOTIPY_CLIENT_SECRET"]
# redirect_uri = os.environ["SPOTIPY_REDIRECT_URI"]

token = None
spotInstance = None
spotAuthUsername = None


def init_spotipy(username):
global spotAuthUsername
spotAuthUsername = username

global token
token = util.prompt_for_user_token(username, scope)

global spotInstance
spotInstance = spotipy.Spotify(auth=token)
spotInstance.trace = False


def refresh_access_token():
global token
token = util.prompt_for_user_token(spotAuthUsername, scope)

global spotInstance
spotInstance = spotipy.Spotify(auth=token)
spotInstance.trace = False


def remove_all_from_playlist(username, playlistURI):
refresh_access_token()
tracks = get_playlist_tracks(username, playlistURI)

track_ids = []
for i, item in enumerate(tracks['items']):
track = item['track']
tid = track['id']
track_ids.append(tid)
results = spotInstance.user_playlist_remove_all_occurrences_of_tracks(username, rPlaylistID, track_ids)


def get_playlist_tracks(username, playlistURI):
refresh_access_token()
global rPlaylistID
p1, p2, p3, p4, rPlaylistID = playlistURI.split(':', 5)

# the spotify api limits the number of tracks which can be retrieved from a playlist in a single request
# make multiple requests to collect all playlist tracks before continuing
print('Collecting tracks from playlist', end='\r')
tracks = spotInstance.user_playlist(username, rPlaylistID, fields='tracks,next')['tracks']
sys.stdout.flush()
print('Collecting tracks from playlist ({}/{})'.format(len(tracks['items']), tracks['total']), end='\r')
paged_tracks = tracks
while paged_tracks['next']:
paged_tracks = spotInstance.next(paged_tracks)
tracks['items'].extend(paged_tracks['items'])
sys.stdout.flush()
print('Collecting tracks from playlist ({}/{})'.format(len(tracks['items']), tracks['total']), end='\r')
print('Collecting tracks from playlist ({}/{})'.format(len(tracks['items']), tracks['total']))

return tracks


def get_track_json(track_uri):
refresh_access_token()
return spotInstance.track(track_uri)
15 changes: 4 additions & 11 deletions spotify_ripper/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from colorama import Fore
from spotify_ripper.utils import *
from spotify_ripper.spotipy_integration import get_track_json
import os
import time
import spotify
Expand Down Expand Up @@ -233,12 +234,7 @@ def sanity_check_date(val):
self.cache_result("charts", uri, charts_obj)
return charts_obj


def get_large_coverart(self, uri):
def get_track_json(track_id):
url = self.api_url('tracks/' + track_id)
return self.request_json(url, "track")

def get_image_data(url):
response = self.request_url(url, "cover art")
return response.content
Expand All @@ -248,18 +244,15 @@ def get_image_data(url):
if cached_result is not None:
return get_image_data(cached_result)

# extract album id from uri
uri_tokens = uri.split(':')
if len(uri_tokens) != 3:
return None

track = get_track_json(uri_tokens[2])
track = get_track_json(uri)
if track is None:
print(Fore.RED + "Failed to retrieve track information, cover art cannot be set" + Fore.RESET)
return None

try:
images = track['album']['images']
except KeyError:
print(Fore.RED + "Album art not found in track JSON, cover art cannot be set" + Fore.RESET)
return None

for image in images:
Expand Down