forked from mopidy/mopidy
/
session_manager.py
128 lines (109 loc) · 4.55 KB
/
session_manager.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
import logging
import os
import threading
import spotify.manager
from mopidy import get_version, settings
from mopidy.backends.spotify.translator import SpotifyTranslator
from mopidy.models import Playlist
from mopidy.utils.process import BaseThread
logger = logging.getLogger('mopidy.backends.spotify.session_manager')
# pylint: disable = R0901
# SpotifySessionManager: Too many ancestors (9/7)
class SpotifySessionManager(spotify.manager.SpotifySessionManager, BaseThread):
cache_location = settings.SPOTIFY_CACHE_PATH
settings_location = settings.SPOTIFY_CACHE_PATH
appkey_file = os.path.join(os.path.dirname(__file__), 'spotify_appkey.key')
user_agent = 'Mopidy %s' % get_version()
def __init__(self, username, password, core_queue, output):
spotify.manager.SpotifySessionManager.__init__(
self, username, password)
BaseThread.__init__(self, core_queue)
self.name = 'SpotifySMThread'
self.output = output
self.connected = threading.Event()
self.session = None
def run_inside_try(self):
self.connect()
def logged_in(self, session, error):
"""Callback used by pyspotify"""
if error:
logger.error(u'Spotify login error: %s', error)
return
logger.info(u'Connected to Spotify')
self.session = session
if settings.SPOTIFY_HIGH_BITRATE:
logger.debug(u'Preferring high bitrate from Spotify')
self.session.set_preferred_bitrate(1)
else:
logger.debug(u'Preferring normal bitrate from Spotify')
self.session.set_preferred_bitrate(0)
self.connected.set()
def logged_out(self, session):
"""Callback used by pyspotify"""
logger.info(u'Disconnected from Spotify')
def metadata_updated(self, session):
"""Callback used by pyspotify"""
logger.debug(u'Metadata updated')
self.refresh_stored_playlists()
def connection_error(self, session, error):
"""Callback used by pyspotify"""
logger.error(u'Spotify connection error: %s', error)
def message_to_user(self, session, message):
"""Callback used by pyspotify"""
logger.debug(u'User message: %s', message.strip())
def notify_main_thread(self, session):
"""Callback used by pyspotify"""
logger.debug(u'notify_main_thread() called')
def music_delivery(self, session, frames, frame_size, num_frames,
sample_type, sample_rate, channels):
"""Callback used by pyspotify"""
# pylint: disable = R0913
# Too many arguments (8/5)
assert sample_type == 0, u'Expects 16-bit signed integer samples'
capabilites = """
audio/x-raw-int,
endianness=(int)1234,
channels=(int)%(channels)d,
width=(int)16,
depth=(int)16,
signed=(boolean)true,
rate=(int)%(sample_rate)d
""" % {
'sample_rate': sample_rate,
'channels': channels,
}
self.output.deliver_data(capabilites, bytes(frames))
def play_token_lost(self, session):
"""Callback used by pyspotify"""
logger.debug(u'Play token lost')
self.core_queue.put({'command': 'stop_playback'})
def log_message(self, session, data):
"""Callback used by pyspotify"""
logger.debug(u'System message: %s' % data.strip())
def end_of_track(self, session):
"""Callback used by pyspotify"""
logger.debug(u'End of data stream reached')
self.output.end_of_data_stream()
def refresh_stored_playlists(self):
"""Refresh the stored playlists in the backend with fresh meta data
from Spotify"""
playlists = []
for spotify_playlist in self.session.playlist_container():
playlists.append(
SpotifyTranslator.to_mopidy_playlist(spotify_playlist))
playlists = filter(None, playlists)
self.core_queue.put({
'command': 'set_stored_playlists',
'playlists': playlists,
})
logger.debug(u'Refreshed %d stored playlist(s)', len(playlists))
def search(self, query, connection):
"""Search method used by Mopidy backend"""
def callback(results, userdata=None):
# TODO Include results from results.albums(), etc. too
playlist = Playlist(tracks=[
SpotifyTranslator.to_mopidy_track(t)
for t in results.tracks()])
connection.send(playlist)
self.connected.wait()
self.session.search(query, callback)