From be0eaeadb75ead1a6e5f860ceb88de3ae586ffdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Gia=20Phong?= Date: Tue, 30 Jan 2018 17:55:27 +0700 Subject: [PATCH] Give more sense to shuffle-* and *-selected modes (#8) --- comp | 18 ++-------------- omp/omp.py | 53 +++++++++++++++++++++++++++++++++++----------- setup.py | 2 +- test/playlist.json | 4 ++-- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/comp b/comp index 5e2c4de..f658692 100755 --- a/comp +++ b/comp @@ -16,7 +16,7 @@ # # Copyright (C) 2017 Nguyễn Gia Phong -__version__ = '0.4.4' +__version__ = '0.4.5' import curses import json @@ -127,8 +127,7 @@ class Comp(Omp): def setno(self, *keys): """Set all keys of each entry in entries to False.""" for entry in self.entries: - for key in keys: - entry[key] = False + for key in keys: entry[key] = False def play(self, force=False): """Play the next track.""" @@ -217,19 +216,6 @@ class Comp(Omp): def __enter__(self): return self - def idx(self, entry=None): - """Return the index of the current entry.""" - if entry is None: - return self.start + self.y - 1 - return self.entries.index(entry) - - def current(self): - """Return the current entry.""" - try: - return self.entries[self.idx()] - except: - return {} - def read_input(self, prompt): """Print the prompt string at the bottom of the screen then read from standard input. diff --git a/omp/omp.py b/omp/omp.py index 61c73d0..3b971b3 100644 --- a/omp/omp.py +++ b/omp/omp.py @@ -17,6 +17,7 @@ # Copyright (C) 2017 Nguyễn Gia Phong import json +from bisect import bisect_left as bisect from collections import deque from gettext import bindtextdomain, gettext as _, textdomain from itertools import cycle @@ -38,6 +39,15 @@ bindtextdomain('omp', resource_filename('omp', 'locale')) textdomain('omp') +def shuffle_init(a): + """Return in iterator which yield random elements from a, + and always begin with its first element. + """ + if a: + yield a[0] + while True: yield choice(a) + + class Omp(object): """Omni Media Player meta object. @@ -119,29 +129,48 @@ class Omp(object): _("Failed to cycle {} '{}'").format(direction, name), error=True) - def update_play_list(self, pick): - """Update the list of entries to be played.""" - if pick == 'current': - self.play_list = [self.current()] - elif pick == 'all': - self.play_list = deque(self.entries) - self.play_list.rotate(-self.idx()) - else: - self.play_list = [i for i in self.entries if i.get('selected')] + def idx(self, entry=None): + """Return the index of the current entry.""" + if entry is None: + return self.start + self.y - 1 + return self.entries.index(entry) + + def current(self): + """Return the current entry.""" + try: + return self.entries[self.idx()] + except: + return {} def update_playlist(self): """Update the playlist to be used by play function.""" action, pick = self.mode.split('-') - self.update_play_list(pick) + if pick == 'current': + self.play_list = deque([self.current()]) + elif pick == 'all': + self.play_list = deque(self.entries) + self.play_list.rotate(-self.idx()) + elif pick == 'selected': + self.play_list = deque([entry for entry in self.entries + if entry.get('selected')]) + indexes = [i for i, entry in enumerate(self.entries) + if entry.get('selected')] + idx = indexes[bisect(indexes, self.idx())] + self.play_list.rotate(-self.play_list.index(self.entries[idx])) + if action == 'play': self.playlist = iter(self.play_list) elif action == 'repeat': self.playlist = cycle(self.play_list) - else: - self.playlist = iter(lambda: choice(self.play_list), None) + elif action == 'shuffle': + self.playlist = shuffle_init(self.play_list) if self.playing < -1: self.played = self.played[:self.playing+1] def next(self, force=False, backward=False): + """Go forward/backward in the playlist. + + If forced, this will also unpause the player. + """ self.play_backward = backward if self.mp.idle_active: self.play(force) diff --git a/setup.py b/setup.py index eb19473..c41c14f 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open('README.rst') as f: setup( name='comp', - version='0.4.4', + version='0.4.5', description=('Curses Omni Media Player'), long_description=long_description, url='https://github.com/McSinyx/comp', diff --git a/test/playlist.json b/test/playlist.json index 191edbf..f3c68da 100644 --- a/test/playlist.json +++ b/test/playlist.json @@ -140,7 +140,7 @@ "title": "Imagine Dragons - Believer" }, { - "duration": "00:00:00", + "duration": "00:03:52", "error": false, "filename": "https://youtu.be/A-Rn0iQEpc8", "selected": false, @@ -168,7 +168,7 @@ "title": "SUSE. Yes Please. (Maroon 5 - Sugar parody)" }, { - "duration": "00:00:00", + "duration": "00:03:30", "error": false, "filename": "https://youtu.be/oHNKTlz1lps", "selected": true,