diff --git a/libremsonic/config.py b/libremsonic/config.py index d6382c6..47b829d 100644 --- a/libremsonic/config.py +++ b/libremsonic/config.py @@ -1,6 +1,6 @@ import os -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List import json from libremsonic.from_json import from_json @@ -38,7 +38,7 @@ class ServerConfiguration: class AppConfiguration: servers: List[ServerConfiguration] - current_server: Optional[int] + current_server: int def to_json(self): return { @@ -57,7 +57,7 @@ def get_config(filename: str) -> AppConfiguration: if not response_json: default_configuration = AppConfiguration() default_configuration.servers = [] - default_configuration.current_server = None + default_configuration.current_server = -1 return default_configuration return from_json(AppConfiguration, response_json) diff --git a/libremsonic/from_json.py b/libremsonic/from_json.py index 2737ccd..424979a 100644 --- a/libremsonic/from_json.py +++ b/libremsonic/from_json.py @@ -58,7 +58,7 @@ def from_json(cls, data): instance[key] = value else: raise Exception( - 'Trying to deserialize an unsupported type: {cls._name}') + f'Trying to deserialize an unsupported type: {cls._name}') # Handle everything else by first instantiating the class, then adding # all of the sub-elements, recursively calling from_json on them. diff --git a/libremsonic/ui/app.py b/libremsonic/ui/app.py index 9731eb5..8508ece 100644 --- a/libremsonic/ui/app.py +++ b/libremsonic/ui/app.py @@ -21,16 +21,26 @@ class LibremsonicApp(Gtk.Application): self.window = None self.add_main_option( - 'config', ord('c'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, + 'config', ord('c'), GLib.OptionFlags.NONE, GLib.OptionArg.FILENAME, 'Specify a configuration file. Defaults to ~/.config/libremsonic/config.json', None) - # TODO load this from the config file + self.config_file = None self.config = None def do_command_line(self, command_line): - options = command_line.get_options_dict().end().unpack() - print(options) + options = command_line.get_options_dict() + self.config_file = options.lookup_value('config') + + if self.config_file: + self.config_file = self.config_file.get_bytestring().decode( + 'utf-8') + else: + config_folder = (os.environ.get('XDG_CONFIG_HOME') + or os.environ.get('APPDATA') or os.path.join( + os.environ.get('HOME'), '.config')) + config_folder = os.path.join(config_folder, 'visplay') + self.config_file = os.path.join(config_folder, 'config.yaml') self.activate() return 0 @@ -56,25 +66,33 @@ class LibremsonicApp(Gtk.Application): if self.config.current_server is None: self.show_configure_servers_dialog() - - print('current config', self.config) + else: + self.on_connected_server_changed(None, self.config.current_server) def on_configure_servers(self, action, param): self.show_configure_servers_dialog() def on_server_list_changed(self, action, params): - server_config, *_ = params - + self.config.servers = params self.save_settings() + def on_connected_server_changed(self, action, params): + self.config.current_server = params + self.save_settings() + + # Update the window according to the new server configuration. + self.window.update(self.config) + def show_configure_servers_dialog(self): - dialog = ConfigureServersDialog(self.window, self.config.servers) + dialog = ConfigureServersDialog(self.window, self.config) dialog.connect('server-list-changed', self.on_server_list_changed) + dialog.connect('connected-server-changed', + self.on_connected_server_changed) dialog.run() dialog.destroy() def load_settings(self): - self.config = get_config(os.path.expanduser('~/tmp/test.json')) + self.config = get_config(self.config_file) def save_settings(self): - save_config(self.config, os.path.expanduser('~/tmp/test.json')) + save_config(self.config, self.config_file) diff --git a/libremsonic/ui/configure_servers.py b/libremsonic/ui/configure_servers.py index 1b5d53b..4acedd1 100644 --- a/libremsonic/ui/configure_servers.py +++ b/libremsonic/ui/configure_servers.py @@ -21,7 +21,7 @@ class EditServerDialog(Gtk.Dialog): existing_config = ServerConfiguration() # Create the two columns for the labels and corresponding entry fields. - self.set_default_size(400, 250) + self.set_default_size(450, 250) content_area = self.get_content_area() flowbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) label_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) @@ -99,22 +99,23 @@ class EditServerDialog(Gtk.Dialog): class ConfigureServersDialog(Gtk.Dialog): __gsignals__ = { 'server-list-changed': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, - (object, )) + (object, )), + 'connected-server-changed': (GObject.SIGNAL_RUN_FIRST, + GObject.TYPE_NONE, (object, )), } - def __init__(self, parent, server_configs): - Gtk.Dialog.__init__(self, 'Configure Servers', parent, 0, ()) + def __init__(self, parent, config): + Gtk.Dialog.__init__(self, 'Connect to Server', parent, 0, ()) - # TODO: DEBUG DATA - self.server_configs = server_configs - self.set_default_size(400, 250) + self.server_configs = config.servers + self.selected_server_index = config.current_server + self.set_default_size(450, 300) flowbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.server_list = Gtk.ListBox() self.server_list.connect('selected-rows-changed', self.server_list_on_selected_rows_changed) - self.refresh_server_list() flowbox.pack_start(self.server_list, True, True, 10) @@ -128,6 +129,7 @@ class ConfigureServersDialog(Gtk.Dialog): (Gtk.Button('Add...'), lambda e: self.on_edit_clicked(e, True), 'start', False), (Gtk.Button('Remove'), self.on_remove_clicked, 'start', True), + (Gtk.Button('Connect'), self.on_connect_clicked, 'end', False), (Gtk.Button('Close'), lambda _: self.close(), 'end', False), ] for button_cfg in self.buttons: @@ -145,8 +147,9 @@ class ConfigureServersDialog(Gtk.Dialog): content_area = self.get_content_area() content_area.pack_start(flowbox, True, True, 10) - self.server_list_on_selected_rows_changed(None) self.show_all() + self.refresh_server_list() + self.server_list_on_selected_rows_changed(None) def refresh_server_list(self): for el in self.server_list: @@ -160,6 +163,9 @@ class ConfigureServersDialog(Gtk.Dialog): self.server_list.add(row) self.show_all() + if self.selected_server_index is not None and self.selected_server_index >= 0: + self.server_list.select_row( + self.server_list.get_row_at_index(self.selected_server_index)) def on_remove_clicked(self, event): selected = self.server_list.get_selected_row() @@ -196,11 +202,15 @@ class ConfigureServersDialog(Gtk.Dialog): else: self.server_configs[selected_index] = new_config - self.refresh_server_list() self.emit('server-list-changed', self.server_configs) dialog.destroy() + def on_connect_clicked(self, event): + selected_index = self.server_list.get_selected_row().get_index() + self.emit('connected-server-changed', selected_index) + self.close() + def server_list_on_selected_rows_changed(self, event): has_selection = self.server_list.get_selected_row() diff --git a/libremsonic/ui/main.py b/libremsonic/ui/main.py index 21e06ff..2d654f1 100644 --- a/libremsonic/ui/main.py +++ b/libremsonic/ui/main.py @@ -3,6 +3,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gio, Gtk from .albums import AlbumsPanel +from libremsonic.config import AppConfiguration class MainWindow(Gtk.ApplicationWindow): @@ -10,7 +11,7 @@ class MainWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.set_default_size(400, 200) + self.set_default_size(1024, 768) artists = Gtk.Label('Artists') playlists = Gtk.Label('Playlists') @@ -29,6 +30,10 @@ class MainWindow(Gtk.ApplicationWindow): self.set_titlebar(titlebar) self.add(stack) + def update(self, config: AppConfiguration): + server_name = config.servers[config.current_server].name + self.connected_to_label.set_markup(f'Connected to {server_name}') + def create_stack(self, **kwargs): stack = Gtk.Stack() for name, child in kwargs.items(): @@ -68,13 +73,21 @@ class MainWindow(Gtk.ApplicationWindow): def create_menu(self): self.menu = Gtk.PopoverMenu() + self.connected_to_label = Gtk.Label() + self.connected_to_label.set_markup( + f'Not Connected to a Server') + self.connected_to_label.set_margin_left(10) + self.connected_to_label.set_margin_right(10) + menu_items = [ - ('app.configure_servers', Gtk.ModelButton('Configure Servers')), + (None, self.connected_to_label), + ('app.configure_servers', Gtk.ModelButton('Connect to Server')), ] vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) for name, item in menu_items: - item.set_action_name(name) + if name: + item.set_action_name(name) vbox.pack_start(item, False, True, 10) self.menu.add(vbox)