resolved conflict
This commit is contained in:
commit
73c26903d1
@ -1,4 +1,5 @@
|
||||
from mopidy.backends.base import BaseBackend
|
||||
|
||||
class DummyBackend(BaseBackend):
|
||||
pass
|
||||
def url_handlers(self):
|
||||
return [u'dummy:']
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import sys
|
||||
|
||||
import spytify
|
||||
|
||||
from mopidy import settings
|
||||
@ -6,13 +8,25 @@ from mopidy.backends.base import BaseBackend
|
||||
class SpotifyBackend(BaseBackend):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SpotifyBackend, self).__init__(*args, **kwargs)
|
||||
self.spotify = spytify.Spytify(
|
||||
settings.SPOTIFY_USERNAME.encode('utf-8'),
|
||||
settings.SPOTIFY_PASSWORD.encode('utf-8'))
|
||||
self.spotify = spytify.Spytify(self.username, self.password)
|
||||
self._playlist_load_cache = None
|
||||
self.current_playlist = []
|
||||
self.current_playlist_version = 0
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
username = settings.SPOTIFY_USERNAME.encode('utf-8')
|
||||
if not username:
|
||||
sys.exit('Setting SPOTIFY_USERNAME is not set.')
|
||||
return username
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
password = settings.SPOTIFY_PASSWORD.encode('utf-8')
|
||||
if not password:
|
||||
sys.exit('Setting SPOTIFY_PASSWORD is not set.')
|
||||
return password
|
||||
|
||||
def playlist_load(self, name):
|
||||
for playlist in self.spotify.stored_playlists:
|
||||
if playlist.name == name:
|
||||
@ -58,3 +72,6 @@ class SpotifyBackend(BaseBackend):
|
||||
|
||||
def status_playlist(self):
|
||||
return self.current_playlist_version
|
||||
|
||||
def url_handlers(self):
|
||||
return [u'spotify:', u'http://open.spotify.com/']
|
||||
|
||||
@ -21,9 +21,9 @@ def register(pattern):
|
||||
return decorator
|
||||
|
||||
class MpdHandler(object):
|
||||
def __init__(self, session=None, backend=SpotifyBackend):
|
||||
def __init__(self, session=None, backend=None):
|
||||
self.session = session
|
||||
self.register_backend(backend())
|
||||
self.backend = backend
|
||||
|
||||
def handle_request(self, request):
|
||||
for pattern in _request_handlers:
|
||||
@ -34,9 +34,6 @@ class MpdHandler(object):
|
||||
logger.warning(u'Unhandled request: %s', request)
|
||||
return False
|
||||
|
||||
def register_backend(self, backend):
|
||||
self.backend = backend
|
||||
|
||||
@register(r'^add "(?P<uri>[^"]*)"$')
|
||||
def _add(self, uri):
|
||||
pass # TODO
|
||||
@ -66,6 +63,10 @@ class MpdHandler(object):
|
||||
else:
|
||||
pass # TODO
|
||||
|
||||
@register(r'^count (?P<tag>\S+) (?P<needle>\S+)$')
|
||||
def _count(self, tag, needle):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^crossfade "(?P<seconds>\d+)"$')
|
||||
def _crossfade(self, seconds):
|
||||
seconds = int(seconds)
|
||||
@ -87,6 +88,16 @@ class MpdHandler(object):
|
||||
def _empty(self):
|
||||
pass
|
||||
|
||||
@register(r'^find (?P<type>(album|artist|title)) (?P<what>.*)$')
|
||||
def _find(self, type, what):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^findadd (?P<type>(album|artist|title)) (?P<what>.*)$')
|
||||
def _findadd(self, type, what):
|
||||
result = self._find(type, what)
|
||||
# TODO Add result to current playlist
|
||||
return result
|
||||
|
||||
@register(r'^idle( (?P<subsystems>.+))*$')
|
||||
def _idle(self, subsystems=None):
|
||||
pass # TODO
|
||||
@ -95,6 +106,20 @@ class MpdHandler(object):
|
||||
def _kill(self):
|
||||
self.session.do_kill()
|
||||
|
||||
@register(r'^list (?P<type>(artist|album))( (?P<artist>.*))*$')
|
||||
def _list(self, type, artist=None):
|
||||
if type == u'artist' and artist is not None:
|
||||
return False
|
||||
pass # TODO
|
||||
|
||||
@register(r'^listall "(?P<uri>[^"]+)"')
|
||||
def _listall(self, uri):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^listallinfo "(?P<uri>[^"]+)"')
|
||||
def _listallinfo(self, uri):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^listplaylist (?P<name>.+)$')
|
||||
def _listplaylist(self, name):
|
||||
pass # TODO
|
||||
@ -115,8 +140,7 @@ class MpdHandler(object):
|
||||
def _lsinfo(self, uri):
|
||||
if uri == u'/':
|
||||
return self._listplaylists()
|
||||
# TODO
|
||||
return self._listplaylists()
|
||||
pass # TODO
|
||||
|
||||
@register(r'^move ((?P<songpos>\d+)|(?P<start>\d+):(?P<end>\d+)*) (?P<to>\d+)$')
|
||||
def _move(self, songpos=None, start=None, end=None, to=None):
|
||||
@ -226,6 +250,10 @@ class MpdHandler(object):
|
||||
def _replay_gain_status(self):
|
||||
return u'off' # TODO
|
||||
|
||||
@register(r'^rescan( "(?P<uri>[^"]+)")*$')
|
||||
def _update(self, uri=None):
|
||||
return self._update(uri, rescan_unmodified_files=True)
|
||||
|
||||
@register(r'^rm (?P<name>\S+)$')
|
||||
def _rm(self, name):
|
||||
pass # TODO
|
||||
@ -234,6 +262,10 @@ class MpdHandler(object):
|
||||
def _save(self, name):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^search (?P<type>(album|artist|filename|title)) (?P<what>.+)$')
|
||||
def _search(self, type, what):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^seek (?P<songpos>.+) (?P<seconds>\d+)$')
|
||||
def _seek(self, songpos, seconds):
|
||||
pass # TODO
|
||||
@ -301,3 +333,11 @@ class MpdHandler(object):
|
||||
@register(r'^swapid (?P<songid1>\S+) (?P<songid2>\S+)$')
|
||||
def _swapid(self, songid1, songid2):
|
||||
pass # TODO
|
||||
|
||||
@register(r'^update( "(?P<uri>[^"]+)")*$')
|
||||
def _update(self, uri=None, rescan_unmodified_files=False):
|
||||
return u'updating_db: 0' # TODO
|
||||
|
||||
@register(r'^urlhandlers$')
|
||||
def _urlhandlers(self):
|
||||
return self.backend.url_handlers()
|
||||
|
||||
@ -5,13 +5,15 @@ import sys
|
||||
|
||||
from mopidy import settings
|
||||
from mopidy.session import MpdSession
|
||||
from mopidy.backends.spotify import SpotifyBackend
|
||||
|
||||
logger = logging.getLogger(u'server')
|
||||
|
||||
class MpdServer(asyncore.dispatcher):
|
||||
def __init__(self, handler_class=MpdSession):
|
||||
def __init__(self, session_class=MpdSession, backend=SpotifyBackend):
|
||||
asyncore.dispatcher.__init__(self)
|
||||
self.handler_class = handler_class
|
||||
self.session_class = session_class
|
||||
self.backend = SpotifyBackend()
|
||||
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.set_reuse_addr()
|
||||
self.bind((settings.MPD_SERVER_HOSTNAME, settings.MPD_SERVER_PORT))
|
||||
@ -20,7 +22,8 @@ class MpdServer(asyncore.dispatcher):
|
||||
def handle_accept(self):
|
||||
(client_socket, client_address) = self.accept()
|
||||
logger.info(u'Connection from: [%s]:%s', *client_address)
|
||||
self.handler_class(self, client_socket, client_address)
|
||||
self.session_class(self, client_socket, client_address,
|
||||
backend=self.backend)
|
||||
|
||||
def handle_close(self):
|
||||
self.close()
|
||||
|
||||
@ -7,14 +7,14 @@ from mopidy.handler import MpdHandler
|
||||
logger = logging.getLogger(u'session')
|
||||
|
||||
class MpdSession(asynchat.async_chat):
|
||||
def __init__(self, server, client_socket, client_address,
|
||||
handler=MpdHandler):
|
||||
def __init__(self, server, client_socket, client_address, backend,
|
||||
handler_class=MpdHandler):
|
||||
asynchat.async_chat.__init__(self, sock=client_socket)
|
||||
self.server = server
|
||||
self.client_address = client_address
|
||||
self.input_buffer = []
|
||||
self.set_terminator(settings.MPD_LINE_TERMINATOR)
|
||||
self.handler = handler(session=self)
|
||||
self.handler = handler_class(session=self, backend=backend)
|
||||
self.send_response(u'OK MPD %s' % get_mpd_version())
|
||||
|
||||
def do_close(self):
|
||||
@ -51,4 +51,3 @@ class MpdSession(asynchat.async_chat):
|
||||
output = u'%s%s' % (output, settings.MPD_LINE_TERMINATOR)
|
||||
data = output.encode(settings.MPD_LINE_ENCODING)
|
||||
self.push(data)
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ from mopidy.backends.dummy import DummyBackend
|
||||
|
||||
class RequestHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_register_same_pattern_twice_fails(self):
|
||||
func = lambda: None
|
||||
@ -26,15 +26,10 @@ class RequestHandlerTest(unittest.TestCase):
|
||||
result = self.h.handle_request('known request')
|
||||
self.assertEquals(expected, result)
|
||||
|
||||
def test_register_backend(self):
|
||||
expected = 'magic'
|
||||
self.h.register_backend(expected)
|
||||
self.assertEquals(expected, self.h.backend)
|
||||
|
||||
|
||||
class StatusHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_clearerror(self):
|
||||
result = self.h.handle_request(u'clearerror')
|
||||
@ -93,7 +88,7 @@ class StatusHandlerTest(unittest.TestCase):
|
||||
|
||||
class PlaybackOptionsHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_consume_off(self):
|
||||
result = self.h.handle_request(u'consume "0"')
|
||||
@ -189,7 +184,7 @@ class PlaybackOptionsHandlerTest(unittest.TestCase):
|
||||
|
||||
class PlaybackControlHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_next(self):
|
||||
result = self.h.handle_request(u'next')
|
||||
@ -230,7 +225,7 @@ class PlaybackControlHandlerTest(unittest.TestCase):
|
||||
|
||||
class CurrentPlaylistHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_add(self):
|
||||
result = self.h.handle_request(u'add "file:///dev/urandom"')
|
||||
@ -348,7 +343,7 @@ class CurrentPlaylistHandlerTest(unittest.TestCase):
|
||||
|
||||
class StoredPlaylistsHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_listplaylist(self):
|
||||
result = self.h.handle_request(u'listplaylist name')
|
||||
@ -398,9 +393,55 @@ class StoredPlaylistsHandlerTest(unittest.TestCase):
|
||||
|
||||
class MusicDatabaseHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
pass # TODO
|
||||
def test_count(self):
|
||||
result = self.h.handle_request(u'count tag needle')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_find_album(self):
|
||||
result = self.h.handle_request(u'find album what')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_find_artist(self):
|
||||
result = self.h.handle_request(u'find artist what')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_find_title(self):
|
||||
result = self.h.handle_request(u'find title what')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_find_else_should_fail(self):
|
||||
result = self.h.handle_request(u'find somethingelse what')
|
||||
self.assert_(result is False)
|
||||
|
||||
def test_findadd(self):
|
||||
result = self.h.handle_request(u'findadd album what')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_list_artist(self):
|
||||
result = self.h.handle_request(u'list artist')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_list_artist_with_artist_should_fail(self):
|
||||
result = self.h.handle_request(u'list artist anartist')
|
||||
self.assert_(result is False)
|
||||
|
||||
def test_list_album_without_artist(self):
|
||||
result = self.h.handle_request(u'list album')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_list_album_with_artist(self):
|
||||
result = self.h.handle_request(u'list album anartist')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_listall(self):
|
||||
result = self.h.handle_request(u'listall "file:///dev/urandom"')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_listallinfo(self):
|
||||
result = self.h.handle_request(u'listallinfo "file:///dev/urandom"')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_lsinfo_for_root_returns_same_as_listplaylists(self):
|
||||
lsinfo_result = self.h.handle_request(u'lsinfo "/"')
|
||||
@ -411,10 +452,58 @@ class MusicDatabaseHandlerTest(unittest.TestCase):
|
||||
result = self.h.handle_request(u'lsinfo ""')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_search_album(self):
|
||||
result = self.h.handle_request(u'search album analbum')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_search_artist(self):
|
||||
result = self.h.handle_request(u'search artist anartist')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_search_filename(self):
|
||||
result = self.h.handle_request(u'search filename afilename')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_search_title(self):
|
||||
result = self.h.handle_request(u'search title atitle')
|
||||
self.assert_(result is None)
|
||||
|
||||
def test_search_else_should_fail(self):
|
||||
result = self.h.handle_request(u'search sometype something')
|
||||
self.assert_(result is False)
|
||||
|
||||
def test_update_without_uri(self):
|
||||
result = self.h.handle_request(u'update')
|
||||
(label, jobid) = result.split(':', 1)
|
||||
self.assertEquals(u'updating_db', label)
|
||||
self.assert_(jobid.strip().isdigit())
|
||||
self.assert_(int(jobid) >= 0)
|
||||
|
||||
def test_update_with_uri(self):
|
||||
result = self.h.handle_request(u'update "file:///dev/urandom"')
|
||||
(label, jobid) = result.split(':', 1)
|
||||
self.assertEquals(u'updating_db', label)
|
||||
self.assert_(jobid.strip().isdigit())
|
||||
self.assert_(int(jobid) >= 0)
|
||||
|
||||
def test_rescan_without_uri(self):
|
||||
result = self.h.handle_request(u'rescan')
|
||||
(label, jobid) = result.split(':', 1)
|
||||
self.assertEquals(u'updating_db', label)
|
||||
self.assert_(jobid.strip().isdigit())
|
||||
self.assert_(int(jobid) >= 0)
|
||||
|
||||
def test_rescan_with_uri(self):
|
||||
result = self.h.handle_request(u'rescan "file:///dev/urandom"')
|
||||
(label, jobid) = result.split(':', 1)
|
||||
self.assertEquals(u'updating_db', label)
|
||||
self.assert_(jobid.strip().isdigit())
|
||||
self.assert_(int(jobid) >= 0)
|
||||
|
||||
|
||||
class StickersHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
pass # TODO
|
||||
|
||||
@ -430,7 +519,7 @@ class DummySession(object):
|
||||
class ConnectionHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(session=DummySession(),
|
||||
backend=DummyBackend)
|
||||
backend=DummyBackend())
|
||||
|
||||
def test_close(self):
|
||||
result = self.h.handle_request(u'close')
|
||||
@ -454,13 +543,17 @@ class ConnectionHandlerTest(unittest.TestCase):
|
||||
|
||||
class AudioOutputHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
pass # TODO
|
||||
|
||||
|
||||
class ReflectionHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.h = handler.MpdHandler(backend=DummyBackend)
|
||||
self.h = handler.MpdHandler(backend=DummyBackend())
|
||||
|
||||
def test_urlhandlers(self):
|
||||
result = self.h.handle_request(u'urlhandlers')
|
||||
self.assert_('dummy:' in result)
|
||||
|
||||
pass # TODO
|
||||
|
||||
Loading…
Reference in New Issue
Block a user