-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspotify.py
132 lines (113 loc) · 3.74 KB
/
spotify.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env python3
import sock
import socket
import spotipy
import subprocess
from sys import platform
import toplist
cmd = 'Consoleify.exe' if platform=='win32' else './Consoleify'
sp = spotipy.Spotify()
sp.max_get_retries = 1
class Client:
def __init__(self, username, password):
self._cmd = [cmd, username, password]
self._proc = None
try:
self._reset()
except:
self.quit()
raise
def popular(self):
# s = self._run('toplist')
# return self._parsesongs(s)
tracks = toplist.search()
return [Song(t['name'], t['popularity'], t['artists'][0]['name'], t['artists'], t['uri']) for t in tracks]
def search(self, song):
#s = self._run('search-song %s'%song)
#return self._parsesongs(s)
found = sp.search(song)
if not found:
return []
tracks = found['tracks']['items']
# print()
# import pprint
# pprint.pprint(tracks)
songs = [Song(t['name'], t['popularity'], t['artists'][0]['name'], t['artists'], t['uri']) for t in tracks]
return sorted(songs, key=lambda s: s.popularity, reverse=True)
def playsong(self, uri):
s = self._run('play-song %s'%uri)
return 'Playing ' in s
def isplaying(self):
s = self._run('is-playing')
return s == 'yes\n'
def stop(self):
s = self._run('stop')
return 'Stopped.'
def quit(self):
self._io('quit\n', timeout=0.5)
self._proc.kill()
self._proc.wait()
def _parsesongs(self, s):
songs = []
for song in s.split('\n'):
info = song.strip()
if info.startswith('song '):
info = info[5:]
comps = info.split('~~~')
if len(comps) == 4:
name,popularity,artists,uri = [c.strip() for c in comps]
artists = artists.split('~')
songs += [Song(name,int(popularity),artists[0],artists,uri)]
return songs
def _run(self, c):
self._io()
try:
o = self._io('%s\n'%c, timeout=5)
except socket.error:
o = 'error'
if 'error' in o.lower():
self._reset()
return ''
return o
def _reset(self):
self._sock = sock.socket()
if self._proc:
try:
self._proc.kill()
self._proc.wait()
except:
pass
self._proc = subprocess.Popen(self._cmd, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if not self._sock.connect(('localhost',55552)):
raise SystemError('Consoleify not responding.')
try:
o = self._io(timeout=15)
except socket.error:
self.quit()
o = None
if not o:
raise SystemError('Unable to login to Spotify due to timeout!')
if 'Login ok.' not in o:
self.quit()
raise NameError('Spotify login failed (user/pass incorrect?)!')
def _io(self, input=None, timeout=0.0001):
if input:
self._sock.send(input)
self._sock.settimeout(timeout)
return self._sock.recvchunk()
class Song:
def __init__(self, name, popularity, artist, artists, uri):
self.name,self.popularity,self.artist,self.artists,self.uri = name,popularity,artist,artists,uri
if __name__ == '__main__':
print('logging in and playing summat')
c = Client('your username', 'your password')
s = c.popular()[-1]
c.playsong(s.uri)
from time import sleep
sleep(5)
print('changing song')
s = c.search('Chandelier')[0]
c.playsong(s.uri)
sleep(5)
c.quit()
print('done')