Skip to content

Commit

Permalink
Merge pull request #14 from Mrokkk/devel
Browse files Browse the repository at this point in the history
Resolve #12 and #13
  • Loading branch information
Mrokkk authored May 7, 2018
2 parents 41bc50c + fb9ce30 commit 78dee2a
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 32 deletions.
14 changes: 12 additions & 2 deletions playerlib/backends/mplayer/arguments_builder.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#!/usr/bin/env python3

from urwim import rdb

class ArgumentsBuilder:

def __init__(self, config):
self._config = config

def _get_audio_output(self):
try: self._config.audio_output
except: return 'pulse'

def _get_cache(self):
try: return self._config.cache
except: return 0
Expand All @@ -17,18 +23,22 @@ def _get_cdrom_device(self):
try: return self._config.cdrom_device
except: return '/dev/sr0'

def _get_volume(self):
try: return rdb['volume']
except: return 100

def build(self, track):
args = [
self._config.path,
'-ao', self._config.audio_output,
'-ao', self._get_audio_output(),
'-noquiet',
'-slave',
'-novideo',
'-cdrom-device', self._get_cdrom_device(),
'-vo', 'null',
'-cache', str(self._get_cache()),
'-ss', str(track.offset),
'-volume', '100',
'-volume', str(self._get_volume()),
]
demuxer = self._get_demuxer(track)
if demuxer:
Expand Down
3 changes: 2 additions & 1 deletion playerlib/track/readers/cue_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ def read(self, path):
for t in cuesheet.tracks:
new_track = Track()
new_track.path = os.path.join(os.path.dirname(path), t.file)
new_track.artist = cuesheet.title
new_track.artist = cuesheet.performer
new_track.album = cuesheet.title
new_track.title = t.title
new_track.index = str(t.index)
new_track.length = t.length
Expand Down
2 changes: 2 additions & 0 deletions playerlib/track/readers/file_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def read(self, path):
except KeyError: track.title = os.path.basename(path)
try: track.artist = ', '.join(tags.tags['ARTIST'])
except KeyError: pass
try: track.album = ', '.join(tags.tags['ALBUM'])
except KeyError: pass
try: track.index = tags.tags['TRACKNUMBER'][0]
except KeyError: pass
track.length = tags.length
Expand Down
1 change: 1 addition & 0 deletions playerlib/track/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def __init__(self, dictionary=None):
self.index = 0
self.title = None
self.artist = None
self.album = None
self.performer = None
self.state = self.State.STOPPED
self.playlist_entry = None
Expand Down
1 change: 1 addition & 0 deletions playerlib/track_info/track_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def _update(self, track):
if track == None: return self._no_track_playing()
self.content[:] = [
urwim.Text('Artist: {}'.format(track.artist)),
urwim.Text('Album: {}'.format(track.album)),
urwim.Text('Title: {}'.format(track.title)),
urwim.Text('Index: {}'.format(track.index)),
urwim.Text('Length: {}'.format(
Expand Down
64 changes: 64 additions & 0 deletions test/mplayer_backend_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from unittest import TestCase
from unittest.mock import Mock, MagicMock, patch
from playerlib.backends.mplayer.backend import Backend as MplayerBackend
from playerlib.backends.mplayer.arguments_builder import *

class MplayerBackendTests(TestCase):

Expand Down Expand Up @@ -214,3 +215,66 @@ def test_loadfile_and_seek_commands_should_be_sent_if_track_playing_and_paths_di
popen_mock.assert_not_called()
mplayer_mock.stdin.write.has_calls(['loadfile \"file2.mp3\"\n', 'seek 20 2 1\n'])


class ArgumentsBuilderTests(TestCase):

class Config(object):
def __init__(self):
pass


def setUp(self):
self.config_mock = self.Config()
self.track_mock = Mock()
self.track_mock.path = 'some_file.mp3'
self.track_mock.offset = 0


def assertHasPair(self, data, a, b):
for i, e in enumerate(data):
if e == a:
if b:
self.assertEqual(data[i + 1], b)
return
raise RuntimeError('cannot find pair of {}, {}'.format(a, b))


def assertHasItem(self, data, a):
self.assertTrue(a in data)


def assertDoesntHaveItem(self, data, a):
self.assertFalse(a in data)


def test_should_choose_default_values_if_no_config(self):
self.config_mock.path = 'mplayer'
sut = ArgumentsBuilder(self.config_mock)
expected_args = ['mplayer', '-ao', 'pulse', '-noquiet', '-slave',
'-novideo', '-cdrom-device', '/dev/sr0', '-vo', 'null', '-cache', '0', '-ss',
'0', '-volume', '100', 'some_file.mp3']
args = sut.build(self.track_mock)
self.assertEqual(sorted(args), sorted(expected_args))


def test_should_choose_proper_demuxer(self):
self.config_mock.path = 'mplayer'
self.config_mock.demuxer = {
"mp3": "audio",
"flac": "lavf",
"ape": "ape"
}
sut = ArgumentsBuilder(self.config_mock)

self.track_mock.path = 'some_file.mp3'
args = sut.build(self.track_mock)
self.assertHasPair(args, '-demuxer', 'audio')

self.track_mock.path = 'some_file.flac'
args = sut.build(self.track_mock)
self.assertHasPair(args, '-demuxer', 'lavf')

self.track_mock.path = 'some_file.eee'
args = sut.build(self.track_mock)
self.assertDoesntHaveItem(args, '-demuxer')

4 changes: 4 additions & 0 deletions test/track_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def test_can_be_converted_to_dict(self):
track.length = 21
track.index = 1
track.title = 'title'
track.album = 'album'
track.artist = 'Artist'
track.state = Track.State.PLAYING
track.playlist_entry = Mock()
Expand All @@ -22,6 +23,7 @@ def test_can_be_converted_to_dict(self):
self.assertEqual(dict_track['length'], 21)
self.assertEqual(dict_track['index'], 1)
self.assertEqual(dict_track['title'], 'title')
self.assertEqual(dict_track['album'], 'album')
self.assertEqual(dict_track['artist'], 'Artist')
self.assertFalse('state' in dict_track)
self.assertFalse('playlist_entry' in dict_track)
Expand All @@ -34,13 +36,15 @@ def test_can_be_created_from_dict(self):
'index': 98,
'title': 'Some Title',
'artist': 'Random Artist',
'album': 'Super Album',
}
track = Track(dict_track)
self.assertEqual(track.path, 'some_path')
self.assertEqual(track.offset, 23)
self.assertEqual(track.length, 315)
self.assertEqual(track.index, 98)
self.assertEqual(track.title, 'Some Title')
self.assertEqual(track.album, 'Super Album')
self.assertEqual(track.artist, 'Random Artist')

def test_play_sets_proper_state_and_triggers_playlist_entry(self):
Expand Down
57 changes: 28 additions & 29 deletions test/tracks_reader_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ def test_can_handle_music_file_with_full_tags(self):
with patch('os.path.isfile') as isfile_mock, patch('taglib.File') as taglib_file_mock:
isfile_mock.return_value = True
track_tags = Mock()
track_tags.tags = {'TITLE': ['some title'], 'ARTIST': ['some artist'], 'TRACKNUMBER': ['1']}
track_tags.tags = {'TITLE': ['some title'], 'ARTIST': ['some artist'], 'ALBUM': ['some album'], 'TRACKNUMBER': ['1']}
track_tags.length = 22
taglib_file_mock.return_value = track_tags
tracks = self.sut.read('some_file.mp3')
self.assertEqual(len(tracks), 1)
self.assertEqual(tracks[0].path, 'some_file.mp3')
self.assertEqual(tracks[0].title, 'some title')
self.assertEqual(tracks[0].album, 'some album')
self.assertEqual(tracks[0].artist, 'some artist')
self.assertEqual(tracks[0].index, '1')
self.assertEqual(tracks[0].length, 22)
Expand Down Expand Up @@ -111,34 +112,32 @@ def test_can_handle_dir_with_empty_cue_sheet(self):
tracks = self.sut.read('some_dir')
self.assertEqual(len(tracks), 0)

# FIXME
# def test_can_handle_cuesheet(self):
# with patch('os.path.isdir') as isdir_mock, \
# patch('os.path.isfile') as isfile_mock, \
# patch('playerlib.tracks_reader.CueReader') as cueparser_class_mock, \
# patch('builtins.open') as open_mock:
# self.sut = TracksReader()
# isdir_mock.return_value = False
# isfile_mock.return_value = True
# track = Mock()
# track.file = 'some_file.flac'
# track.title = ['Title']
# track.index = 1
# track.length = 203
# track.offset = 0
# cuesheet_mock = Mock()
# cuesheet_mock.title = ['Album Title']
# cuesheet_mock.tracks = [track]
# cuereader_mock = Mock()
# cuereader_mock.read.return_value = [track]
# cueparser_class_mock.return_value = cuereader_mock
# tracks = self.sut.read('some_cue.cue')
# self.assertEqual(len(tracks), 1)
# self.assertEqual(tracks[0].path, 'some_file.flac')
# self.assertEqual(tracks[0].title, 'Title')
# self.assertEqual(tracks[0].index, '1')
# self.assertEqual(tracks[0].length, 203)
# self.assertEqual(tracks[0].offset, 0)
def test_can_handle_cuesheet(self):
with patch('os.path.isdir') as isdir_mock, \
patch('os.path.isfile') as isfile_mock, \
patch('builtins.open') as open_mock:
cueparser_mock = Mock()
self.sut = TracksReader()
self.sut._cue_reader._parser = cueparser_mock # FIXME
isdir_mock.return_value = False
isfile_mock.return_value = True
track = Mock()
track.file = 'some_file.flac'
track.title = 'Title'
track.index = 1
track.length = 203
track.offset = 0
cuesheet_mock = Mock()
cuesheet_mock.title = 'Album Title'
cuesheet_mock.tracks = [track]
cueparser_mock.parse.return_value = cuesheet_mock
tracks = self.sut.read('some_cue.cue')
self.assertEqual(len(tracks), 1)
self.assertEqual(tracks[0].path, 'some_file.flac')
self.assertEqual(tracks[0].title, 'Title')
self.assertEqual(tracks[0].index, '1')
self.assertEqual(tracks[0].length, 203)
self.assertEqual(tracks[0].offset, 0)

def test_can_handle_empty_cdaudio(self):
import sys
Expand Down

0 comments on commit 78dee2a

Please sign in to comment.