Merge branch 'develop' into feature/mpd-tokenized-requests

Conflicts:
	mopidy/mpd/protocol/stored_playlists.py
This commit is contained in:
Thomas Adamcik 2014-01-30 22:48:28 +01:00
commit 2e6f716b72
6 changed files with 47 additions and 31 deletions

View File

@ -8,6 +8,13 @@ This changelog is used to track all major changes to Mopidy.
v0.19.0 (unreleased)
====================
**Models**
- The type of :attr:`mopidy.models.Playlist.last_modified` has been redefined
from a :class:`datetime.datetime` instance to the number of milliseconds
since Unix epoch as an integer. This makes serialization of the time stamp
simpler.
**MPD**
- Minor refactor of context such that it stores password instead of config.

View File

@ -418,8 +418,9 @@ class Playlist(ImmutableObject):
:type name: string
:param tracks: playlist's tracks
:type tracks: list of :class:`Track` elements
:param last_modified: playlist's modification time in UTC
:type last_modified: :class:`datetime.datetime`
:param last_modified:
playlist's modification time in milliseconds since Unix epoch
:type last_modified: int
"""
#: The playlist URI. Read-only.
@ -431,9 +432,10 @@ class Playlist(ImmutableObject):
#: The playlist's tracks. Read-only.
tracks = tuple()
#: The playlist modification time in UTC. Read-only.
#: The playlist modification time in milliseconds since Unix epoch.
#: Read-only.
#:
#: :class:`datetime.datetime`, or :class:`None` if unknown.
#: Integer, or :class:`None` if unknown.
last_modified = None
def __init__(self, *args, **kwargs):

View File

@ -1,4 +1,4 @@
from __future__ import unicode_literals
from __future__ import division, unicode_literals
import datetime
@ -78,16 +78,27 @@ def listplaylists(context):
continue
name = context.lookup_playlist_name_from_uri(playlist.uri)
result.append(('playlist', name))
last_modified = (
playlist.last_modified or datetime.datetime.utcnow()).isoformat()
# Remove microseconds
last_modified = last_modified.split('.')[0]
# Add time zone information
last_modified = last_modified + 'Z'
result.append(('Last-Modified', last_modified))
result.append(('Last-Modified', _get_last_modified(playlist)))
return result
# TODO: move to translators?
def _get_last_modified(playlist):
"""Formats last modified timestamp of a playlist for MPD.
Time in UTC with second precision, formatted in the ISO 8601 format, with
the "Z" time zone marker for UTC. For example, "1970-01-01T00:00:00Z".
"""
if playlist.last_modified is None:
# If unknown, assume the playlist is modified
dt = datetime.datetime.utcnow()
else:
dt = datetime.datetime.utcfromtimestamp(
playlist.last_modified / 1000.0)
dt = dt.replace(microsecond=0)
return '%sZ' % dt.isoformat()
@protocol.commands.add('load', playlist_slice=protocol.RANGE)
def load(context, name, playlist_slice=slice(0, None)):
"""

View File

@ -1,6 +1,5 @@
from __future__ import unicode_literals
import datetime
import unittest
from mopidy.mpd.protocol import music_db
@ -237,7 +236,7 @@ class MusicDatabaseHandlerTest(protocol.BaseTestCase):
self.assertEqual(response1, response2)
def test_lsinfo_without_path_returns_same_as_for_root(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
last_modified = 1390942873222
self.backend.playlists.playlists = [
Playlist(name='a', uri='dummy:/a', last_modified=last_modified)]
@ -246,7 +245,7 @@ class MusicDatabaseHandlerTest(protocol.BaseTestCase):
self.assertEqual(response1, response2)
def test_lsinfo_with_empty_path_returns_same_as_for_root(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
last_modified = 1390942873222
self.backend.playlists.playlists = [
Playlist(name='a', uri='dummy:/a', last_modified=last_modified)]
@ -255,14 +254,14 @@ class MusicDatabaseHandlerTest(protocol.BaseTestCase):
self.assertEqual(response1, response2)
def test_lsinfo_for_root_includes_playlists(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
last_modified = 1390942873222
self.backend.playlists.playlists = [
Playlist(name='a', uri='dummy:/a', last_modified=last_modified)]
self.sendRequest('lsinfo "/"')
self.assertInResponse('playlist: a')
# Date without microseconds and with time zone information
self.assertInResponse('Last-Modified: 2001-03-17T13:41:17Z')
# Date without milliseconds and with time zone information
self.assertInResponse('Last-Modified: 2014-01-28T21:01:13Z')
self.assertInResponse('OK')
def test_lsinfo_for_root_includes_dirs_for_each_lib_with_content(self):

View File

@ -1,7 +1,5 @@
from __future__ import unicode_literals
import datetime
from mopidy.models import Track, Playlist
from tests.mpd import protocol
@ -78,14 +76,14 @@ class PlaylistsHandlerTest(protocol.BaseTestCase):
self.assertInResponse('OK')
def test_listplaylists(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
last_modified = 1390942873222
self.backend.playlists.playlists = [
Playlist(name='a', uri='dummy:a', last_modified=last_modified)]
self.sendRequest('listplaylists')
self.assertInResponse('playlist: a')
# Date without microseconds and with time zone information
self.assertInResponse('Last-Modified: 2001-03-17T13:41:17Z')
# Date without milliseconds and with time zone information
self.assertInResponse('Last-Modified: 2014-01-28T21:01:13Z')
self.assertInResponse('OK')
def test_listplaylists_duplicate(self):
@ -99,7 +97,7 @@ class PlaylistsHandlerTest(protocol.BaseTestCase):
self.assertInResponse('OK')
def test_listplaylists_ignores_playlists_without_name(self):
last_modified = datetime.datetime(2001, 3, 17, 13, 41, 17, 12345)
last_modified = 1390942873222
self.backend.playlists.playlists = [
Playlist(name='', uri='dummy:', last_modified=last_modified)]

View File

@ -1,6 +1,5 @@
from __future__ import unicode_literals
import datetime
import json
import unittest
@ -842,7 +841,7 @@ class PlaylistTest(unittest.TestCase):
self.assertEqual(playlist.length, 3)
def test_last_modified(self):
last_modified = datetime.datetime.utcnow()
last_modified = 1390942873000
playlist = Playlist(last_modified=last_modified)
self.assertEqual(playlist.last_modified, last_modified)
self.assertRaises(
@ -850,7 +849,7 @@ class PlaylistTest(unittest.TestCase):
def test_with_new_uri(self):
tracks = [Track()]
last_modified = datetime.datetime.utcnow()
last_modified = 1390942873000
playlist = Playlist(
uri='an uri', name='a name', tracks=tracks,
last_modified=last_modified)
@ -862,7 +861,7 @@ class PlaylistTest(unittest.TestCase):
def test_with_new_name(self):
tracks = [Track()]
last_modified = datetime.datetime.utcnow()
last_modified = 1390942873000
playlist = Playlist(
uri='an uri', name='a name', tracks=tracks,
last_modified=last_modified)
@ -874,7 +873,7 @@ class PlaylistTest(unittest.TestCase):
def test_with_new_tracks(self):
tracks = [Track()]
last_modified = datetime.datetime.utcnow()
last_modified = 1390942873000
playlist = Playlist(
uri='an uri', name='a name', tracks=tracks,
last_modified=last_modified)
@ -887,8 +886,8 @@ class PlaylistTest(unittest.TestCase):
def test_with_new_last_modified(self):
tracks = [Track()]
last_modified = datetime.datetime.utcnow()
new_last_modified = last_modified + datetime.timedelta(1)
last_modified = 1390942873000
new_last_modified = last_modified + 1000
playlist = Playlist(
uri='an uri', name='a name', tracks=tracks,
last_modified=last_modified)