Skip to content

Commit

Permalink
Merge branch 'release/v0.19.x' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
jodal committed Aug 29, 2014
2 parents b404091 + 69c3e10 commit c506412
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 18 deletions.
11 changes: 11 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ Bug fix release.

- Configuration: :option:`mopidy --config` now supports directories.

- Network: Fix a race condition where two threads could try to free the same
data simultaneously. (Fixes: :issue:`781`)

- Backend API: Update :meth:`mopidy.backend.LibraryProvider.browse` signature
and docs to match how the core use the backend's browse method. (Fixes:
:issue:`833`)

- Local library API: Add :attr:`mopidy.local.ROOT_DIRECTORY_URI` constant for
use by implementors of :method:`mopidy.local.Library.browse`. (Related to:
:issue:`833`)


v0.19.3 (2014-08-03)
====================
Expand Down
4 changes: 2 additions & 2 deletions mopidy/backend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ class LibraryProvider(object):
def __init__(self, backend):
self.backend = backend

def browse(self, path):
def browse(self, uri):
"""
See :meth:`mopidy.core.LibraryController.browse`.
If you implement this method, make sure to also set
:attr:`root_directory_name`.
:attr:`root_directory`.
*MAY be implemented by subclass.*
"""
Expand Down
18 changes: 15 additions & 3 deletions mopidy/local/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ def get_command(self):
return LocalCommand()


ROOT_DIRECTORY_URI = 'local:directory'
"""
URI of the local backend's root directory.
This constant should be used by libraries implementing the
:meth:`Library.browse` method.
"""


class Library(object):
"""
Local library interface.
Expand All @@ -64,11 +73,14 @@ class Library(object):
def __init__(self, config):
self._config = config

def browse(self, path):
def browse(self, uri):
"""
Browse directories and tracks at the given path.
Browse directories and tracks at the given URI.
The URI for the root directory is a constant available at
:attr:`ROOT_DIRECTORY_URI`.
:param string path: path to browse or None for root.
:param string path: URI to browse.
:rtype: List of :class:`~mopidy.models.Ref` tracks and directories.
"""
raise NotImplementedError
Expand Down
7 changes: 3 additions & 4 deletions mopidy/local/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ class _BrowseCache(object):
splitpath_re = re.compile(r'([^/]+)')

def __init__(self, uris):
# TODO: local.ROOT_DIRECTORY_URI
self._cache = {'local:directory': collections.OrderedDict()}
self._cache = {local.ROOT_DIRECTORY_URI: collections.OrderedDict()}

for track_uri in uris:
path = translator.local_track_uri_to_path(track_uri, b'/')
Expand Down Expand Up @@ -97,10 +96,10 @@ def __init__(self, uris):
else:
# Loop completed, so final child needs to be added to root.
if child:
self._cache['local:directory'][child.uri] = child
self._cache[local.ROOT_DIRECTORY_URI][child.uri] = child
# If no parent was set we belong in the root.
if not parent_uri:
parent_uri = 'local:directory'
parent_uri = local.ROOT_DIRECTORY_URI

self._cache[parent_uri][track_uri] = track_ref

Expand Down
10 changes: 5 additions & 5 deletions mopidy/local/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

import logging

from mopidy import backend, models
from mopidy import backend, local, models

logger = logging.getLogger(__name__)


class LocalLibraryProvider(backend.LibraryProvider):
"""Proxy library that delegates work to our active local library."""

root_directory = models.Ref.directory(uri=b'local:directory',
name='Local media')
root_directory = models.Ref.directory(
uri=local.ROOT_DIRECTORY_URI, name='Local media')

def __init__(self, backend, library):
super(LocalLibraryProvider, self).__init__(backend)
self._library = library
self.refresh()

def browse(self, path):
def browse(self, uri):
if not self._library:
return []
return self._library.browse(path)
return self._library.browse(uri)

def refresh(self, uri=None):
if not self._library:
Expand Down
2 changes: 1 addition & 1 deletion mopidy/utils/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ def recv_callback(self, fd, flags):
return True

if not data:
self.actor_ref.tell({'close': True})
self.disable_recv()
self.actor_ref.tell({'close': True})
return True

try:
Expand Down
9 changes: 6 additions & 3 deletions tests/utils/network/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import gobject

from mock import Mock, patch, sentinel
from mock import Mock, call, patch, sentinel

import pykka

Expand Down Expand Up @@ -418,8 +418,11 @@ def test_recv_callback_gets_no_data(self):

self.assertTrue(network.Connection.recv_callback(
self.mock, sentinel.fd, gobject.IO_IN))
self.mock.actor_ref.tell.assert_called_once_with({'close': True})
self.mock.disable_recv.assert_called_once_with()
self.assertEqual(self.mock.mock_calls, [
call.sock.recv(any_int),
call.disable_recv(),
call.actor_ref.tell({'close': True}),
])

def test_recv_callback_recoverable_error(self):
self.mock.sock = Mock(spec=socket.SocketType)
Expand Down

0 comments on commit c506412

Please sign in to comment.