models: Make Playlist.last_modified milliseconds since Unix epoch
This commit is contained in:
parent
981c4e4b81
commit
38d3c6ccf9
@ -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.
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import division, unicode_literals
|
||||
|
||||
import datetime as dt
|
||||
import datetime
|
||||
|
||||
from mopidy.mpd.exceptions import MpdNoExistError, MpdNotImplemented
|
||||
from mopidy.mpd.protocol import handle_request
|
||||
@ -80,16 +80,26 @@ def listplaylists(context):
|
||||
continue
|
||||
name = context.lookup_playlist_name_from_uri(playlist.uri)
|
||||
result.append(('playlist', name))
|
||||
last_modified = (
|
||||
playlist.last_modified or dt.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
|
||||
|
||||
|
||||
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()
|
||||
|
||||
|
||||
@handle_request(
|
||||
r'load\ "(?P<name>[^"]+)"(\ "(?P<start>\d+):(?P<end>\d+)*")*$')
|
||||
def load(context, name, start=None, end=None):
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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)]
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user