From ed87ab8dd10f74ebd99b004651c0a8213527eb41 Mon Sep 17 00:00:00 2001 From: Arjun Naik Date: Mon, 28 Jul 2014 22:48:26 +0200 Subject: [PATCH 01/17] Added a playback history object to the core. --- mopidy/core/__init__.py | 1 + mopidy/core/actor.py | 7 +++++++ mopidy/core/history.py | 42 ++++++++++++++++++++++++++++++++++++++ mopidy/core/playback.py | 1 + tests/core/test_history.py | 27 ++++++++++++++++++++++++ 5 files changed, 78 insertions(+) create mode 100644 mopidy/core/history.py create mode 100644 tests/core/test_history.py diff --git a/mopidy/core/__init__.py b/mopidy/core/__init__.py index f49bbbe7..d857d4fb 100644 --- a/mopidy/core/__init__.py +++ b/mopidy/core/__init__.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals # flake8: noqa from .actor import Core +from .history import TrackHistory from .library import LibraryController from .listener import CoreListener from .playback import PlaybackController, PlaybackState diff --git a/mopidy/core/actor.py b/mopidy/core/actor.py index 66f2aa82..bb5058ee 100644 --- a/mopidy/core/actor.py +++ b/mopidy/core/actor.py @@ -7,6 +7,7 @@ import pykka from mopidy import audio, backend, mixer from mopidy.audio import PlaybackState +from mopidy.core.history import TrackHistory from mopidy.core.library import LibraryController from mopidy.core.listener import CoreListener from mopidy.core.playback import PlaybackController @@ -23,6 +24,10 @@ class Core( """The library controller. An instance of :class:`mopidy.core.LibraryController`.""" + history = None + """The playback history. An instance of + :class:`mopidy.core.TrackHistory`""" + playback = None """The playback controller. An instance of :class:`mopidy.core.PlaybackController`.""" @@ -42,6 +47,8 @@ class Core( self.library = LibraryController(backends=self.backends, core=self) + self.history = TrackHistory() + self.playback = PlaybackController( mixer=mixer, backends=self.backends, core=self) diff --git a/mopidy/core/history.py b/mopidy/core/history.py new file mode 100644 index 00000000..7f617441 --- /dev/null +++ b/mopidy/core/history.py @@ -0,0 +1,42 @@ +from __future__ import unicode_literals + +import logging + +from mopidy.models import Track + + +logger = logging.getLogger(__name__) + + +class TrackHistory(): + track_list = [] + + def add_track(self, track): + """ + :param track: track to change to + :type track: :class:`mopidy.models.Track` + """ + if type(track) is not Track: + logger.warning('Cannot add non-Track type object to TrackHistory') + return + + # Reorder the track history if the track is already present. + if track in self.track_list: + self.track_list.remove(track) + self.track_list.insert(0, track) + + def get_history_size(self): + """ + Returns the number of tracks in the history. + :returns: The number of tracks in the history. + :rtype :int + """ + return len(self.track_list) + + def get_history(self): + """ + Returns the history. + :returns: The history as a list of `mopidy.models.Track` + :rtype: L{`mopidy.models.Track`} + """ + return self.track_list diff --git a/mopidy/core/playback.py b/mopidy/core/playback.py index df48422d..f0262830 100644 --- a/mopidy/core/playback.py +++ b/mopidy/core/playback.py @@ -248,6 +248,7 @@ class PlaybackController(object): if success: self.core.tracklist.mark_playing(tl_track) # TODO: replace with stream-changed + self.core.history.add_track(tl_track.track) self._trigger_track_playback_started() else: self.core.tracklist.mark_unplayable(tl_track) diff --git a/tests/core/test_history.py b/tests/core/test_history.py new file mode 100644 index 00000000..4e9b059c --- /dev/null +++ b/tests/core/test_history.py @@ -0,0 +1,27 @@ +import unittest + +from mopidy.core import TrackHistory + +from mopidy.models import Track + + +class PlaybackHistoryTest(unittest.TestCase): + def setUp(self): + self.tracks = [ + Track(uri='dummy1:a', name='foo'), + Track(uri='dummy2:a', name='foo'), + Track(uri='dummy3:a', name='bar') + ] + self.history = TrackHistory() + + def test_add_track(self): + self.history.add_track(self.tracks[0]) + self.assertEqual(self.history.get_history_size(), 1) + + def test_track_order(self): + self.history.add_track(self.tracks[0]) + self.history.add_track(self.tracks[1]) + self.history.add_track(self.tracks[2]) + self.history.add_track(self.tracks[0]) + self.assertEqual(self.history.get_history_size(), 3) + self.assertEqual(self.history.get_history()[0], self.tracks[0]) \ No newline at end of file From 9006968f75c47428cde9f024147ab517ae5c2625 Mon Sep 17 00:00:00 2001 From: Arjun Naik Date: Mon, 4 Aug 2014 01:07:26 +0200 Subject: [PATCH 02/17] TrackHistory stores Ref instances. Timestamp as epoch in milliseconds also stored. --- mopidy/core/__init__.py | 2 +- mopidy/core/actor.py | 4 ++-- mopidy/core/history.py | 29 ++++++++++++++++++-------- mopidy/core/playback.py | 2 +- tests/core/test_history.py | 42 +++++++++++++++++++++++++------------- 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/mopidy/core/__init__.py b/mopidy/core/__init__.py index d857d4fb..302c0a74 100644 --- a/mopidy/core/__init__.py +++ b/mopidy/core/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals # flake8: noqa from .actor import Core -from .history import TrackHistory +from .history import History from .library import LibraryController from .listener import CoreListener from .playback import PlaybackController, PlaybackState diff --git a/mopidy/core/actor.py b/mopidy/core/actor.py index bb5058ee..46f94d00 100644 --- a/mopidy/core/actor.py +++ b/mopidy/core/actor.py @@ -7,7 +7,7 @@ import pykka from mopidy import audio, backend, mixer from mopidy.audio import PlaybackState -from mopidy.core.history import TrackHistory +from mopidy.core.history import History from mopidy.core.library import LibraryController from mopidy.core.listener import CoreListener from mopidy.core.playback import PlaybackController @@ -47,7 +47,7 @@ class Core( self.library = LibraryController(backends=self.backends, core=self) - self.history = TrackHistory() + self.history = History() self.playback = PlaybackController( mixer=mixer, backends=self.backends, core=self) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 7f617441..3b7b9d9f 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -1,17 +1,19 @@ from __future__ import unicode_literals +import copy +import datetime import logging -from mopidy.models import Track +from mopidy.models import Ref, Track logger = logging.getLogger(__name__) -class TrackHistory(): +class History(object): track_list = [] - def add_track(self, track): + def add(self, track): """ :param track: track to change to :type track: :class:`mopidy.models.Track` @@ -20,12 +22,21 @@ class TrackHistory(): logger.warning('Cannot add non-Track type object to TrackHistory') return - # Reorder the track history if the track is already present. - if track in self.track_list: - self.track_list.remove(track) - self.track_list.insert(0, track) + timestamp = int(datetime.datetime.now().strftime("%s")) * 1000 + name_parts = [] + if track.name is not None: + name_parts.append(track.name) + if track.artists: + name_parts.append( + ', '.join([artist.name for artist in track.artists]) + ) + ref_name = ' - '.join(name_parts) + track_ref = Ref.track(uri=track.uri, name=ref_name) - def get_history_size(self): + self.track_list.insert(0, (timestamp, track_ref)) + + @property + def size(self): """ Returns the number of tracks in the history. :returns: The number of tracks in the history. @@ -39,4 +50,4 @@ class TrackHistory(): :returns: The history as a list of `mopidy.models.Track` :rtype: L{`mopidy.models.Track`} """ - return self.track_list + return copy.copy(self.track_list) diff --git a/mopidy/core/playback.py b/mopidy/core/playback.py index f0262830..58cc1a4b 100644 --- a/mopidy/core/playback.py +++ b/mopidy/core/playback.py @@ -248,7 +248,7 @@ class PlaybackController(object): if success: self.core.tracklist.mark_playing(tl_track) # TODO: replace with stream-changed - self.core.history.add_track(tl_track.track) + self.core.history.add(tl_track.track) self._trigger_track_playback_started() else: self.core.tracklist.mark_unplayable(tl_track) diff --git a/tests/core/test_history.py b/tests/core/test_history.py index 4e9b059c..67e3ccee 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -1,27 +1,41 @@ +from __future__ import unicode_literals + import unittest -from mopidy.core import TrackHistory - -from mopidy.models import Track +from mopidy.core import History +from mopidy.models import Artist, Track class PlaybackHistoryTest(unittest.TestCase): def setUp(self): self.tracks = [ - Track(uri='dummy1:a', name='foo'), + Track(uri='dummy1:a', name='foo', + artists=[Artist(name='foober'), Artist(name='barber')]), Track(uri='dummy2:a', name='foo'), Track(uri='dummy3:a', name='bar') ] - self.history = TrackHistory() + self.history = History() def test_add_track(self): - self.history.add_track(self.tracks[0]) - self.assertEqual(self.history.get_history_size(), 1) + self.history.add(self.tracks[0]) + self.history.add(self.tracks[1]) + self.history.add(self.tracks[2]) + self.assertEqual(self.history.size, 3) - def test_track_order(self): - self.history.add_track(self.tracks[0]) - self.history.add_track(self.tracks[1]) - self.history.add_track(self.tracks[2]) - self.history.add_track(self.tracks[0]) - self.assertEqual(self.history.get_history_size(), 3) - self.assertEqual(self.history.get_history()[0], self.tracks[0]) \ No newline at end of file + def test_unsuitable_add(self): + size = self.history.size + self.history.add(self.tracks[0]) + self.history.add(object()) + self.history.add(self.tracks[1]) + self.assertEqual(self.history.size, size + 2) + + def test_history_sanity(self): + track = self.tracks[0] + self.history.add(track) + stored_history = self.history.get_history() + track_ref = stored_history[0][1] + self.assertEqual(track_ref.uri, track.uri) + self.assertTrue(track.name in track_ref.name) + if track.artists: + for artist in track.artists: + self.assertTrue(artist.name in track_ref.name) From a6370b0a671d46e9cb090848f6e56b9930d79a05 Mon Sep 17 00:00:00 2001 From: Arjun Naik Date: Sat, 23 Aug 2014 01:38:05 +0200 Subject: [PATCH 03/17] Switched track name and artist order in history object. --- mopidy/core/history.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 3b7b9d9f..24b808d2 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -24,12 +24,12 @@ class History(object): timestamp = int(datetime.datetime.now().strftime("%s")) * 1000 name_parts = [] - if track.name is not None: - name_parts.append(track.name) if track.artists: name_parts.append( ', '.join([artist.name for artist in track.artists]) ) + if track.name is not None: + name_parts.append(track.name) ref_name = ' - '.join(name_parts) track_ref = Ref.track(uri=track.uri, name=ref_name) From c38b9f378f7dbf968ee6bcb7b3f0625a1993d61d Mon Sep 17 00:00:00 2001 From: Arjun Naik Date: Sat, 23 Aug 2014 01:38:38 +0200 Subject: [PATCH 04/17] Use assertIn instead of assertTrue to test membership. --- tests/core/test_history.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/core/test_history.py b/tests/core/test_history.py index 67e3ccee..7b681d83 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -35,7 +35,7 @@ class PlaybackHistoryTest(unittest.TestCase): stored_history = self.history.get_history() track_ref = stored_history[0][1] self.assertEqual(track_ref.uri, track.uri) - self.assertTrue(track.name in track_ref.name) + self.assertIn(track.name, track_ref.name) if track.artists: for artist in track.artists: - self.assertTrue(artist.name in track_ref.name) + self.assertIn(artist.name, track_ref.name) From 718405421daae5bf882783fb633d4124c2a4f8eb Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:32:34 +0200 Subject: [PATCH 05/17] history: Rename class to HistoryController For consistency with other core controllers. --- mopidy/core/__init__.py | 2 +- mopidy/core/actor.py | 8 ++++---- mopidy/core/history.py | 2 +- tests/core/test_history.py | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/mopidy/core/__init__.py b/mopidy/core/__init__.py index 302c0a74..019034fc 100644 --- a/mopidy/core/__init__.py +++ b/mopidy/core/__init__.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals # flake8: noqa from .actor import Core -from .history import History +from .history import HistoryController from .library import LibraryController from .listener import CoreListener from .playback import PlaybackController, PlaybackState diff --git a/mopidy/core/actor.py b/mopidy/core/actor.py index 46f94d00..edf13679 100644 --- a/mopidy/core/actor.py +++ b/mopidy/core/actor.py @@ -7,7 +7,7 @@ import pykka from mopidy import audio, backend, mixer from mopidy.audio import PlaybackState -from mopidy.core.history import History +from mopidy.core.history import HistoryController from mopidy.core.library import LibraryController from mopidy.core.listener import CoreListener from mopidy.core.playback import PlaybackController @@ -25,8 +25,8 @@ class Core( :class:`mopidy.core.LibraryController`.""" history = None - """The playback history. An instance of - :class:`mopidy.core.TrackHistory`""" + """The playback history controller. An instance of + :class:`mopidy.core.HistoryController`.""" playback = None """The playback controller. An instance of @@ -47,7 +47,7 @@ class Core( self.library = LibraryController(backends=self.backends, core=self) - self.history = History() + self.history = HistoryController() self.playback = PlaybackController( mixer=mixer, backends=self.backends, core=self) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 24b808d2..38ebe74d 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -10,7 +10,7 @@ from mopidy.models import Ref, Track logger = logging.getLogger(__name__) -class History(object): +class HistoryController(object): track_list = [] def add(self, track): diff --git a/tests/core/test_history.py b/tests/core/test_history.py index 7b681d83..3592274c 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -2,11 +2,12 @@ from __future__ import unicode_literals import unittest -from mopidy.core import History +from mopidy.core import HistoryController from mopidy.models import Artist, Track class PlaybackHistoryTest(unittest.TestCase): + def setUp(self): self.tracks = [ Track(uri='dummy1:a', name='foo', @@ -14,7 +15,7 @@ class PlaybackHistoryTest(unittest.TestCase): Track(uri='dummy2:a', name='foo'), Track(uri='dummy3:a', name='bar') ] - self.history = History() + self.history = HistoryController() def test_add_track(self): self.history.add(self.tracks[0]) From f8f06f4ec4cc7c8de9f2787689a1145daa40a6a8 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:33:24 +0200 Subject: [PATCH 06/17] playback: Move comment so its next to the line it applies to --- mopidy/core/playback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mopidy/core/playback.py b/mopidy/core/playback.py index 58cc1a4b..4c968d81 100644 --- a/mopidy/core/playback.py +++ b/mopidy/core/playback.py @@ -247,8 +247,8 @@ class PlaybackController(object): if success: self.core.tracklist.mark_playing(tl_track) - # TODO: replace with stream-changed self.core.history.add(tl_track.track) + # TODO: replace with stream-changed self._trigger_track_playback_started() else: self.core.tracklist.mark_unplayable(tl_track) From 1f9c5c609aa552fbcf4fc5d7c618e6bebe34a79e Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:34:50 +0200 Subject: [PATCH 07/17] history: Use time.time() to get time since epoch --- mopidy/core/history.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 38ebe74d..da7d298a 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -1,8 +1,8 @@ from __future__ import unicode_literals import copy -import datetime import logging +import time from mopidy.models import Ref, Track @@ -22,7 +22,8 @@ class HistoryController(object): logger.warning('Cannot add non-Track type object to TrackHistory') return - timestamp = int(datetime.datetime.now().strftime("%s")) * 1000 + timestamp = int(time.time() * 1000) + name_parts = [] if track.artists: name_parts.append( From f3a6c10188d9a86ec7c603c059ba5fa35d0d1758 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:37:18 +0200 Subject: [PATCH 08/17] history: Import entire modules For concistency with other code. --- mopidy/core/history.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index da7d298a..787d55d7 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -4,7 +4,7 @@ import copy import logging import time -from mopidy.models import Ref, Track +from mopidy import models logger = logging.getLogger(__name__) @@ -18,7 +18,7 @@ class HistoryController(object): :param track: track to change to :type track: :class:`mopidy.models.Track` """ - if type(track) is not Track: + if type(track) is not models.Track: logger.warning('Cannot add non-Track type object to TrackHistory') return @@ -32,7 +32,7 @@ class HistoryController(object): if track.name is not None: name_parts.append(track.name) ref_name = ' - '.join(name_parts) - track_ref = Ref.track(uri=track.uri, name=ref_name) + track_ref = models.Ref.track(uri=track.uri, name=ref_name) self.track_list.insert(0, (timestamp, track_ref)) From ded43039bf15e8d46c49caf5f762686be019d9e1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:38:38 +0200 Subject: [PATCH 09/17] history: Keep history in private attribute So it is not accessible directly from other actors. --- mopidy/core/history.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 787d55d7..23f5d74f 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -11,7 +11,9 @@ logger = logging.getLogger(__name__) class HistoryController(object): - track_list = [] + + def __init__(self): + self._history = [] def add(self, track): """ @@ -34,7 +36,7 @@ class HistoryController(object): ref_name = ' - '.join(name_parts) track_ref = models.Ref.track(uri=track.uri, name=ref_name) - self.track_list.insert(0, (timestamp, track_ref)) + self._history.insert(0, (timestamp, track_ref)) @property def size(self): @@ -43,7 +45,7 @@ class HistoryController(object): :returns: The number of tracks in the history. :rtype :int """ - return len(self.track_list) + return len(self._history) def get_history(self): """ @@ -51,4 +53,4 @@ class HistoryController(object): :returns: The history as a list of `mopidy.models.Track` :rtype: L{`mopidy.models.Track`} """ - return copy.copy(self.track_list) + return copy.copy(self._history) From d30cf68efd1ac34273edb780c2f56497bac7d878 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:42:26 +0200 Subject: [PATCH 10/17] history: Raise TypeError if non-Tracks are added --- mopidy/core/history.py | 5 ++--- tests/core/test_history.py | 11 +++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 23f5d74f..b66cd078 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -20,9 +20,8 @@ class HistoryController(object): :param track: track to change to :type track: :class:`mopidy.models.Track` """ - if type(track) is not models.Track: - logger.warning('Cannot add non-Track type object to TrackHistory') - return + if not isinstance(track, models.Track): + raise TypeError('Only Track objects can be added to the history') timestamp = int(time.time() * 1000) diff --git a/tests/core/test_history.py b/tests/core/test_history.py index 3592274c..ed918c1f 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -23,12 +23,11 @@ class PlaybackHistoryTest(unittest.TestCase): self.history.add(self.tracks[2]) self.assertEqual(self.history.size, 3) - def test_unsuitable_add(self): - size = self.history.size - self.history.add(self.tracks[0]) - self.history.add(object()) - self.history.add(self.tracks[1]) - self.assertEqual(self.history.size, size + 2) + def test_non_tracks_are_rejected(self): + with self.assertRaises(TypeError): + self.history.add(object()) + + self.assertEqual(self.history.size, 0) def test_history_sanity(self): track = self.tracks[0] From 1f1e86023b9970ec0d61cf6c9934c1c5d618d05c Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:44:17 +0200 Subject: [PATCH 11/17] history: Cleanup docstrings --- mopidy/core/history.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index b66cd078..16a5208f 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -16,8 +16,9 @@ class HistoryController(object): self._history = [] def add(self, track): - """ - :param track: track to change to + """Add track to the playback history. + + :param track: track to add :type track: :class:`mopidy.models.Track` """ if not isinstance(track, models.Track): @@ -39,17 +40,17 @@ class HistoryController(object): @property def size(self): - """ - Returns the number of tracks in the history. - :returns: The number of tracks in the history. - :rtype :int + """Get the number of tracks in the history. + + :returns: the history length + :rtype: int """ return len(self._history) def get_history(self): - """ - Returns the history. - :returns: The history as a list of `mopidy.models.Track` - :rtype: L{`mopidy.models.Track`} + """Get the track history. + + :returns: the track history + :rtype: list of (timestamp, mopidy.models.Ref) tuples """ return copy.copy(self._history) From 177f91fb274ee4b358d304b1080bfdc6dea37b3f Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:45:24 +0200 Subject: [PATCH 12/17] history: Tweaking formatting and variable names --- mopidy/core/history.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 16a5208f..021ee34d 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -29,14 +29,13 @@ class HistoryController(object): name_parts = [] if track.artists: name_parts.append( - ', '.join([artist.name for artist in track.artists]) - ) + ', '.join([artist.name for artist in track.artists])) if track.name is not None: name_parts.append(track.name) - ref_name = ' - '.join(name_parts) - track_ref = models.Ref.track(uri=track.uri, name=ref_name) + name = ' - '.join(name_parts) + ref = models.Ref.track(uri=track.uri, name=name) - self._history.insert(0, (timestamp, track_ref)) + self._history.insert(0, (timestamp, ref)) @property def size(self): From 5a67339855c5a400cfebf1a64fe606c999501aa0 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:47:28 +0200 Subject: [PATCH 13/17] history: Cleanup history entry test --- tests/core/test_history.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/core/test_history.py b/tests/core/test_history.py index ed918c1f..e0f607f9 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -29,13 +29,15 @@ class PlaybackHistoryTest(unittest.TestCase): self.assertEqual(self.history.size, 0) - def test_history_sanity(self): + def test_history_entry_contents(self): track = self.tracks[0] self.history.add(track) - stored_history = self.history.get_history() - track_ref = stored_history[0][1] - self.assertEqual(track_ref.uri, track.uri) - self.assertIn(track.name, track_ref.name) - if track.artists: - for artist in track.artists: - self.assertIn(artist.name, track_ref.name) + + result = self.history.get_history() + (timestamp, ref) = result[0] + + self.assertIsInstance(timestamp, int) + self.assertEqual(track.uri, ref.uri) + self.assertIn(track.name, ref.name) + for artist in track.artists: + self.assertIn(artist.name, ref.name) From 5317834baf62d04e3a844a1804af1ea5782ddbf1 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:47:54 +0200 Subject: [PATCH 14/17] history: Change size property to get_length() method For consistency with tracklist.get_length() and our goal of aligning Python and JS APIs by using less properties in the core API. --- mopidy/core/history.py | 3 +-- tests/core/test_history.py | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mopidy/core/history.py b/mopidy/core/history.py index 021ee34d..6711bcf4 100644 --- a/mopidy/core/history.py +++ b/mopidy/core/history.py @@ -37,8 +37,7 @@ class HistoryController(object): self._history.insert(0, (timestamp, ref)) - @property - def size(self): + def get_length(self): """Get the number of tracks in the history. :returns: the history length diff --git a/tests/core/test_history.py b/tests/core/test_history.py index e0f607f9..75b4dc76 100644 --- a/tests/core/test_history.py +++ b/tests/core/test_history.py @@ -19,15 +19,19 @@ class PlaybackHistoryTest(unittest.TestCase): def test_add_track(self): self.history.add(self.tracks[0]) + self.assertEqual(self.history.get_length(), 1) + self.history.add(self.tracks[1]) + self.assertEqual(self.history.get_length(), 2) + self.history.add(self.tracks[2]) - self.assertEqual(self.history.size, 3) + self.assertEqual(self.history.get_length(), 3) def test_non_tracks_are_rejected(self): with self.assertRaises(TypeError): self.history.add(object()) - self.assertEqual(self.history.size, 0) + self.assertEqual(self.history.get_length(), 0) def test_history_entry_contents(self): track = self.tracks[0] From 39bee603fa3f1da21b23f2f891ddcd8296875a6d Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:55:37 +0200 Subject: [PATCH 15/17] docs: Add HistoryController to core API --- docs/api/core.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/api/core.rst b/docs/api/core.rst index 38cc0f0a..21ff79f5 100644 --- a/docs/api/core.rst +++ b/docs/api/core.rst @@ -37,6 +37,15 @@ Manages everything related to the tracks we are currently playing. :members: +History controller +================== + +Keeps record of what tracks have been played. + +.. autoclass:: mopidy.core.HistoryController + :members: + + Playlists controller ==================== From d655be10334d58dfea8feb805abac4b31417f200 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 18:55:57 +0200 Subject: [PATCH 16/17] docs: Update changelog --- docs/changelog.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index ad83e0c0..e8f03d50 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,11 @@ This changelog is used to track all major changes to Mopidy. v0.20.0 (UNRELEASED) ==================== +**Core API** + +- Added :class:`mopidy.core.HistoryController` which keeps track of what + tracks have been played. (Fixes: :issue:`423`, PR: :issue:`803`) + **Commands** - Make the ``mopidy`` command print a friendly error message if the From 542cd3a3bbc4843eefce70c71586ed9d7b23d57e Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Tue, 23 Sep 2014 19:02:58 +0200 Subject: [PATCH 17/17] http: Add history controller to JSON-RPC API --- mopidy/http/handlers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mopidy/http/handlers.py b/mopidy/http/handlers.py index 3ef10c3b..3bfc1eff 100644 --- a/mopidy/http/handlers.py +++ b/mopidy/http/handlers.py @@ -41,6 +41,7 @@ def make_jsonrpc_wrapper(core_actor): objects={ 'core.get_uri_schemes': core.Core.get_uri_schemes, 'core.get_version': core.Core.get_version, + 'core.history': core.HistoryController, 'core.library': core.LibraryController, 'core.playback': core.PlaybackController, 'core.playlists': core.PlaylistsController, @@ -51,6 +52,7 @@ def make_jsonrpc_wrapper(core_actor): 'core.describe': inspector.describe, 'core.get_uri_schemes': core_actor.get_uri_schemes, 'core.get_version': core_actor.get_version, + 'core.history': core_actor.history, 'core.library': core_actor.library, 'core.playback': core_actor.playback, 'core.playlists': core_actor.playlists,