resolved conflict

This commit is contained in:
Johannes Knutsen 2009-12-25 16:15:08 +01:00
commit 73c26903d1
6 changed files with 188 additions and 35 deletions

View File

@ -1,4 +1,5 @@
from mopidy.backends.base import BaseBackend
class DummyBackend(BaseBackend):
pass
def url_handlers(self):
return [u'dummy:']

View File

@ -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/']

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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