commit f1ead763fba163407c16d3ee0e2a2a8cd8081fc4
parent e567ef4b528738568334d3db6c6166431c38f768
Author: Paco Esteban <paco@e1e0.net>
Date: Thu, 10 Jun 2021 12:40:14 +0200
basic interface, no play
Diffstat:
5 files changed, 110 insertions(+), 30 deletions(-)
diff --git a/requirements.txt b/requirements.txt
@@ -1 +1,2 @@
py-sonic==0.7.9
+py-cui==0.1.3
diff --git a/setup.py b/setup.py
@@ -5,6 +5,9 @@ here = pathlib.Path(__file__).parent.resolve()
long_description = (here / 'README.md').read_text(encoding='utf-8')
+with open('requirements.txt', 'r') as req_fp:
+ required_packages = req_fp.readlines()
+
setup(
name='subclient',
version='0.1.0',
@@ -27,7 +30,7 @@ setup(
keywords='subsonic, client, music',
packages=find_packages(where='.'),
python_requires='>=3.6, <4',
- install_requires=['py-sonic'],
+ install_requires=required_packages,
entry_points={
'console_scripts': [
'subclient=subclient.subclient:main',
diff --git a/subclient/subclient.py b/subclient/subclient.py
@@ -1,43 +1,63 @@
#!/usr/bin/env python3
import configparser
-import libsonic
-import mpv
+from subclient.subsonic import Subsonic
+import py_cui
-from helpers import format_duration
+__version__ = 'v0.0.1'
-player = mpv.MPV(input_default_bindings=True, input_vo_keyboard=True,
- vo='gpu', ytdl=True)
-stream = None
+class SubClient:
-@player.python_stream('subclient')
-def stream_reader():
- while True:
- yield stream.read(1024*1024)
+ def __init__(self, master: py_cui.PyCUI):
+
+ self.config = configparser.ConfigParser()
+ self.config.read('config.ini')
+ self.subsonic = Subsonic(self.config['subclient'])
+ self.master = master
+ # The scrolled list cells that will contain our tasks in each of the
+ # three categories
+ self.artist_scroll_cell = self.master.add_scroll_menu(
+ 'Artists', 0, 0, row_span=1, column_span=1)
+ self.album_scroll_cell = self.master.add_scroll_menu(
+ 'Albums', 0, 1, row_span=1, column_span=1)
+ self.song_scroll_cell = self.master.add_scroll_menu(
+ 'Songs', 0, 2, row_span=1, column_span=1)
+
+ self.artist_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER,
+ self.update_albums)
+ self.album_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER,
+ self.update_songs)
+ # self.song_scroll_cell.add_key_command(py_cui.keys.KEY_ENTER,
+ # self.play_song)
+
+ self.update_artists()
+
+ def update_artists(self):
+ artists = self.subsonic.get_artists()
+ self.artist_scroll_cell.add_item_list(artists)
+
+ def update_albums(self):
+ self.album_scroll_cell.clear()
+ artist = self.artist_scroll_cell.get()
+ albums = self.subsonic.get_albums_from_artist(artist)
+ self.album_scroll_cell.add_item_list(albums)
+
+ def update_songs(self):
+ self.song_scroll_cell.clear()
+ album = self.album_scroll_cell.get()
+ songs = self.subsonic.get_songs_from_album(album)
+ self.song_scroll_cell.add_item_list(songs)
def main():
- config = configparser.ConfigParser()
- config.read('config.ini')
-
- url = config['subclient']['url']
- user = config['subclient']['username']
- pwd = config['subclient']['password']
- random_list_size = config['subclient']['randomListSize']
-
- subsonic = libsonic.Connection(url, user, pwd, port=443)
-
- # Let's get X completely random songs
- songs = subsonic.getRandomSongs(size=random_list_size)
- for song in songs['randomSongs']['song']:
- print(f"Playing: {song['title']} by {song['artist']}"
- f"({format_duration(song['duration'])})")
- global stream
- stream = subsonic.stream(song['id'], tformat='raw')
- player.play('python://subclient')
- player.wait_for_playback()
+ root = py_cui.PyCUI(1, 3)
+ # enable unicode box chars
+ root.toggle_unicode_borders()
+ root.set_title('SubsonicClient')
+ wrapper = SubClient(root)
+ root.start()
if __name__ == "__main__":
diff --git a/subclient/subsonic.py b/subclient/subsonic.py
@@ -0,0 +1,56 @@
+import libsonic
+
+
+class Artist:
+ def __init__(self, id: str, name: str, albumCount: int, **kwargs):
+ self.id = id
+ self.name = name
+ self.album_count = albumCount
+
+ def __str__(self):
+ return f'{self.name} ({self.album_count})'
+
+
+class Album:
+ def __init__(self, id: str, title: str, year: int, **kwargs):
+ self.id = id
+ self.title = title
+ self.year = year
+
+ def __str__(self):
+ return f'{self.title} ({self.year})'
+
+
+class Song:
+ def __init__(self, id: str, title: str, track: int, duration: int,
+ **kwargs):
+ self.id = id
+ self.title = title
+ self.track = track
+ self.duration = duration
+
+ def __str__(self):
+ return f'{self.title}'
+
+
+class Subsonic:
+
+ def __init__(self, config):
+ self.s = libsonic.Connection(config['url'], config['username'],
+ config['password'], port=443)
+
+ def get_artists(self):
+ artists = []
+ artists_idx = self.s.getIndexes()['indexes']['index']
+ for i in artists_idx:
+ for a in i['artist']:
+ artists.append(Artist(**a))
+ return artists
+
+ def get_albums_from_artist(self, artist):
+ albums = self.s.getArtist(artist.id)['artist']['album']
+ return [Album(**a) for a in albums]
+
+ def get_songs_from_album(self, album):
+ songs = self.s.getAlbum(album.id)['album']['song']
+ return [Song(**s) for s in songs]
diff --git a/subclient/tests/__init__.py b/subclient/tests/__init__.py