Skip to content
This repository was archived by the owner on Apr 8, 2025. It is now read-only.

Commit 0c245bc

Browse files
authored
Merge pull request #137 from sindrig/show-length-of-playlist
Show length of playlist
2 parents 372e066 + db2a346 commit 0c245bc

File tree

6 files changed

+57
-13
lines changed

6 files changed

+57
-13
lines changed

spoppy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
def get_version():
13-
return '1.6.0'
13+
return '1.6.1'
1414

1515

1616
if click:

spoppy/players.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,12 @@ def get_ui(self):
242242

243243
])
244244
right_side_items = [
245-
'Shuffle on' if self.shuffle else '',
245+
'%d of %d' % (
246+
self.current_track_idx + 1, len(self.song_order)
247+
),
248+
'Total playlist length: %s' % self.get_total_playlist_length(),
246249
'Repeat: %s' % self.repeat,
247-
'%d of %d' % (self.current_track_idx + 1, len(self.song_order))
250+
'Shuffle on' if self.shuffle else '',
248251
]
249252
songs_to_show = (
250253
list(range(
@@ -259,13 +262,13 @@ def get_ui(self):
259262
)
260263
for song_idx in songs_to_show:
261264
song = self.get_track_by_idx(song_idx)
262-
right_side = right_side_items and right_side_items.pop()
265+
right_side = right_side_items and right_side_items.pop(0)
263266
if song_idx == self.current_track_idx:
264267
if song_idx != songs_to_show[0]:
265268
# Small spacing around current...
266269
res.append(('', right_side or ''))
267270
right_side = (
268-
right_side_items and right_side_items.pop()
271+
right_side_items and right_side_items.pop(0)
269272
)
270273
formatted_song = '>>>%s' % format_track(
271274
song,
@@ -292,6 +295,10 @@ def get_ui(self):
292295

293296
return res
294297

298+
def get_total_playlist_length(self):
299+
total_seconds = sum([song.duration for song in self.song_list]) / 1000
300+
return get_duration_from_s(total_seconds, max_length=None)
301+
295302
def trigger_redraw(self):
296303
'''
297304
Tell the player to trigger a full redraw in the next loop.

spoppy/util.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,28 @@ def sorted_menu_items(items):
9696
yield key, value
9797

9898

99-
def get_duration_from_s(s):
99+
def get_duration_from_s(s, max_length=59 * 60 + 59):
100100
'''
101101
Formats seconds as "%M:%S"
102+
If max_length exceed 60, give format in "%H:%M:%S"
102103
:param s: Seconds in int/float
104+
:param max_length: Max length in seconds. Default is 59 minutes, 59 seconds
103105
:returns: s formatted as "%M:%S"
104106
'''
105-
# Max length is 59 minutes, 59 seconds
106-
MAX_LENGTH = 59 * 60 + 59
107107
if not isinstance(s, (int, float)):
108108
raise TypeError('Seconds must be int/float')
109109
elif s < 0:
110110
raise TypeError('Seconds must be positive')
111-
elif s > MAX_LENGTH:
112-
s = MAX_LENGTH
113-
return '%s:%s' % (
114-
str(int(s / 60)).zfill(2),
111+
elif max_length and s > max_length:
112+
s = max_length
113+
m = s / 60
114+
h = ''
115+
if m > 60:
116+
h = ('%s:' % int(m / 60)).zfill(3)
117+
m = m % 60
118+
return '%s%s:%s' % (
119+
h,
120+
str(int(m)).zfill(2),
115121
str(int(s % 60)).zfill(2)
116122
)
117123

tests/test_players.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,19 @@ def test_save_as_playlist(self, patched_saveplaylist):
520520
SavePlaylist.callback(playlist)
521521
self.assertEqual(self.player.playlist, playlist)
522522
self.assertEqual(self.player.original_playlist_name, 'foobar')
523+
524+
@patch('spoppy.players.get_duration_from_s')
525+
def test_get_total_playlist_length(self, patched_get_duration_from_s):
526+
# total length of list is 71000 ms = 71 s
527+
expected_duration = 'Expected this duration message'
528+
patched_get_duration_from_s.return_value = expected_duration
529+
self.player.song_list = [
530+
utils.Track('', '', duration=1000),
531+
utils.Track('', '', duration=10000),
532+
utils.Track('', '', duration=60000),
533+
]
534+
result = self.player.get_total_playlist_length()
535+
patched_get_duration_from_s.assert_called_once_with(
536+
71, max_length=None
537+
)
538+
self.assertEquals(result, expected_duration)

tests/test_utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ def test_get_duration_from_s(self):
1616
self.assertEqual(
1717
util.get_duration_from_s(seconds), expected
1818
)
19+
two_hours_minus_second = 2 * 60 * 60 - 1
20+
self.assertEqual(
21+
util.get_duration_from_s(
22+
two_hours_minus_second, max_length=None
23+
),
24+
'01:59:59'
25+
)
26+
one_hour_one_minute_one_second = 1 * 60 * 60 + 60 + 1
27+
self.assertEqual(
28+
util.get_duration_from_s(
29+
one_hour_one_minute_one_second, max_length=None
30+
),
31+
'01:01:01'
32+
)
1933

2034
def test_get_duration_from_s_raises(self):
2135
with self.assertRaises(TypeError):

tests/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77

88

99
class Track(object):
10-
def __init__(self, name, artists, available=True):
10+
def __init__(self, name, artists, available=True, duration=0):
1111
self.artists = [Artist(artist) for artist in artists]
1212
self.name = name
1313
if available:
1414
self.availability = TrackAvailability.AVAILABLE
1515
else:
1616
self.availability = TrackAvailability.UNAVAILABLE
17+
self.duration = duration
1718

1819

1920
class Playlist(object):

0 commit comments

Comments
 (0)