From 5a0a51b349575ff935a1e990827cc27510a117f8 Mon Sep 17 00:00:00 2001 From: jr-k Date: Mon, 3 Jun 2024 01:22:38 +0200 Subject: [PATCH] backend ok, frontend ok, ready to use host and route playlists --- data/www/css/main.css | 4 +-- data/www/js/fleet/node-players.js | 5 +++ lang/en.json | 5 +++ lang/fr.json | 5 +++ src/controller/FleetNodePlayerController.py | 32 +++++++++++++++---- .../FleetNodePlayerGroupController.py | 2 +- src/controller/SettingsController.py | 27 +++++++++++++--- src/manager/NodePlayerGroupManager.py | 21 +++++++++++- src/manager/NodePlayerManager.py | 16 ++++++++-- src/manager/VariableManager.py | 2 +- views/base.jinja.html | 10 +++--- .../player-group/component/table.jinja.html | 26 ++++++++------- views/fleet/player/list.jinja.html | 13 ++++++++ views/fleet/player/modal/add.jinja.html | 12 +++++++ views/fleet/player/modal/edit.jinja.html | 12 +++++++ views/settings/list.jinja.html | 5 +++ views/slideshow/list.jinja.html | 2 +- 17 files changed, 164 insertions(+), 35 deletions(-) diff --git a/data/www/css/main.css b/data/www/css/main.css index d08d4c1..ed251b3 100644 --- a/data/www/css/main.css +++ b/data/www/css/main.css @@ -175,7 +175,7 @@ header nav ul li.active a { align-items: center; } -select.playlist-picker, +select.select-item-picker, a.btn, button { background-color: #fff; @@ -200,7 +200,7 @@ button:hover { color: #bc48ff; } -select.playlist-picker, +select.select-item-picker, button.purple { font-weight: bold; border: 1px solid #692fbd; diff --git a/data/www/js/fleet/node-players.js b/data/www/js/fleet/node-players.js index 378287f..36c5884 100644 --- a/data/www/js/fleet/node-players.js +++ b/data/www/js/fleet/node-players.js @@ -38,6 +38,10 @@ jQuery(document).ready(function ($) { }); }; + $(document).on('change', 'select.group-picker', function () { + document.location.href = $(this).val(); + }); + $(document).on('change', 'input[type=checkbox]', function () { $.ajax({ url: '/fleet/node-player/toggle', @@ -83,6 +87,7 @@ jQuery(document).ready(function ($) { showModal('modal-node-player-edit'); $('.modal-node-player-edit input:visible:eq(0)').focus().select(); $('#node-player-edit-name').val(nodePlayer.name); + $('#node-player-edit-group-id').val(nodePlayer.group_id); $('#node-player-edit-host').val(nodePlayer.host); $('#node-player-edit-id').val(nodePlayer.id); }); diff --git a/lang/en.json b/lang/en.json index 8dd44f6..2265a1a 100644 --- a/lang/en.json +++ b/lang/en.json @@ -88,6 +88,7 @@ "fleet_node_player_panel_empty": "Currently, there are no players. %link% now.", "fleet_node_player_panel_th_name": "Name", "fleet_node_player_panel_th_host": "Host", + "fleet_node_player_panel_th_group_id": "Group", "fleet_node_player_panel_th_enabled": "Enabled", "fleet_node_player_panel_th_activity": "Activity", "fleet_node_player_form_add_title": "Add Player", @@ -95,6 +96,7 @@ "fleet_node_player_form_edit_title": "Edit Player", "fleet_node_player_form_edit_submit": "Save", "fleet_node_player_form_label_name": "Name", + "fleet_node_player_form_label_group_id": "Group", "fleet_node_player_form_label_host": "Host", "fleet_node_player_form_button_cancel": "Cancel", "js_fleet_node_player_delete_confirmation": "Are you sure?", @@ -146,10 +148,12 @@ "settings_variable_form_label_name": "Name", "settings_variable_form_label_value": "Value", "settings_variable_form_button_cancel": "Cancel", + "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "You can't disable playlists while fleet player management is on", "settings_variable_desc_lang": "Server language", "settings_variable_desc_playlist_enabled": "Enable playlist management", "settings_variable_desc_fleet_studio_enabled": "Enable fleet studio management", "settings_variable_desc_fleet_player_enabled": "Enable fleet player management", + "settings_variable_desc_edition_fleet_player_enabled": "Playlist management will also be enabled", "settings_variable_desc_auth_enabled": "Enable auth management", "settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin", "settings_variable_desc_external_url": "External url (i.e: https://studio-01.company.com or http://10.10.3.100)", @@ -200,6 +204,7 @@ "basic_month_11": "November", "basic_month_12": "December", + "common_default_node_player_group": "Default player group", "common_default_playlist": "Default playlist", "common_unknown_ipaddr": "Unknown IP address", "common_empty": "[Empty]", diff --git a/lang/fr.json b/lang/fr.json index 3a8d718..d343af4 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -88,6 +88,7 @@ "fleet_node_player_panel_empty": "Actuellement, il n'y a pas de lecteurs. %link% maintenant.", "fleet_node_player_panel_th_name": "Nom", "fleet_node_player_panel_th_host": "Hôte", + "fleet_node_player_panel_th_group_id": "Groupe", "fleet_node_player_panel_th_enabled": "Activé", "fleet_node_player_panel_th_activity": "Options", "fleet_node_player_form_add_title": "Ajout d'un lecteur", @@ -95,6 +96,7 @@ "fleet_node_player_form_edit_title": "Modification d'un lecteur", "fleet_node_player_form_edit_submit": "Enregistrer", "fleet_node_player_form_label_name": "Nom", + "fleet_node_player_form_label_group_id": "Groupe", "fleet_node_player_form_label_host": "Hôte", "fleet_node_player_form_button_cancel": "Annuler", "js_fleet_node_player_delete_confirmation": "Êtes-vous sûr ?", @@ -146,10 +148,12 @@ "settings_variable_form_label_name": "Nom", "settings_variable_form_label_value": "Valeur", "settings_variable_form_button_cancel": "Annuler", + "settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled": "Vous ne pouvez pas désactiver les listes de lecture tant que la gestion de flotte de lecteurs est activée", "settings_variable_desc_lang": "Langage de l'application", "settings_variable_desc_playlist_enabled": "Activer la gestion des playlists", "settings_variable_desc_fleet_studio_enabled": "Activer la gestion de flotte des studios", "settings_variable_desc_fleet_player_enabled": "Activer la gestion de flotte des players", + "settings_variable_desc_edition_fleet_player_enabled": "Les listes de lecture seront également activées", "settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification", "settings_variable_desc_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin", "settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)", @@ -200,6 +204,7 @@ "basic_month_11": "Novembre", "basic_month_12": "Décembre", + "common_default_node_player_group": "Groupe de lecteur par défaut", "common_default_playlist": "Playlist par défaut", "common_unknown_ipaddr": "Adresse IP inconnue", "common_empty": "[Vide]", diff --git a/src/controller/FleetNodePlayerController.py b/src/controller/FleetNodePlayerController.py index 26ceb61..55bf882 100644 --- a/src/controller/FleetNodePlayerController.py +++ b/src/controller/FleetNodePlayerController.py @@ -18,28 +18,48 @@ class FleetNodePlayerController(ObController): def register(self): self._app.add_url_rule('/fleet/node-player/list', 'fleet_node_player_list', self.guard_fleet(self._auth(self.fleet_node_player_list)), methods=['GET']) + self._app.add_url_rule('/fleet/node-player/group/set/', 'fleet_node_player_list_group_use', self._auth(self.fleet_node_player_list), methods=['GET']) self._app.add_url_rule('/fleet/node-player/add', 'fleet_node_player_add', self.guard_fleet(self._auth(self.fleet_node_player_add)), methods=['POST']) self._app.add_url_rule('/fleet/node-player/edit', 'fleet_node_player_edit', self.guard_fleet(self._auth(self.fleet_node_player_edit)), methods=['POST']) self._app.add_url_rule('/fleet/node-player/toggle', 'fleet_node_player_toggle', self.guard_fleet(self._auth(self.fleet_node_player_toggle)), methods=['POST']) self._app.add_url_rule('/fleet/node-player/delete', 'fleet_node_player_delete', self.guard_fleet(self._auth(self.fleet_node_player_delete)), methods=['DELETE']) self._app.add_url_rule('/fleet/node-player/position', 'fleet_node_player_position', self.guard_fleet(self._auth(self.fleet_node_player_position)), methods=['POST']) - def fleet_node_player_list(self): + def fleet_node_player_list(self, group_id: int = 0): + current_group = self._model_store.node_player_group().get(group_id) + group_id = current_group.id if current_group else None return render_template( 'fleet/player/list.jinja.html', - enabled_node_players=self._model_store.node_player().get_enabled_node_players(), - disabled_node_players=self._model_store.node_player().get_disabled_node_players(), + current_group=current_group, + groups=self._model_store.node_player_group().get_all_labels_indexed(), + enabled_node_players=self._model_store.node_player().get_node_players(group_id=group_id, enabled=True), + disabled_node_players=self._model_store.node_player().get_node_players(group_id=group_id, enabled=False) ) def fleet_node_player_add(self): - self._model_store.node_player().add_form(NodePlayer( + node_player = NodePlayer( name=request.form['name'], host=request.form['host'], - )) + group_id=request.form['group_id'] if 'group_id' in request.form and request.form['group_id'] else None, + ) + self._model_store.node_player().add_form(node_player) + + if node_player.group_id: + return redirect(url_for('fleet_node_player_list_group_use', group_id=node_player.group_id)) + return redirect(url_for('fleet_node_player_list')) def fleet_node_player_edit(self): - self._model_store.node_player().update_form(request.form['id'], request.form['name'], request.form['host']) + node_player = self._model_store.node_player().update_form( + request.form['id'], + request.form['name'], + request.form['host'], + request.form['group_id'] + ) + + if node_player.group_id: + return redirect(url_for('fleet_node_player_list_group_use', group_id=node_player.group_id)) + return redirect(url_for('fleet_node_player_list')) def fleet_node_player_toggle(self): diff --git a/src/controller/FleetNodePlayerGroupController.py b/src/controller/FleetNodePlayerGroupController.py index 39d1d5c..ec4ff17 100644 --- a/src/controller/FleetNodePlayerGroupController.py +++ b/src/controller/FleetNodePlayerGroupController.py @@ -25,7 +25,7 @@ class FleetNodePlayerGroupController(ObController): def fleet_node_player_group_list(self): return render_template( 'fleet/player-group/list.jinja.html', - node_player_groups=self._model_store.node_player_group().get_all(), + node_player_groups=self._model_store.node_player_group().get_groups(with_default=True), playlists=self._model_store.playlist().get_all_labels_indexed() ) diff --git a/src/controller/SettingsController.py b/src/controller/SettingsController.py index 76226dc..ef8165e 100644 --- a/src/controller/SettingsController.py +++ b/src/controller/SettingsController.py @@ -2,6 +2,7 @@ import time import json from flask import Flask, render_template, redirect, request, url_for +from typing import Optional from src.service.ModelStore import ModelStore from src.interface.ObController import ObController @@ -23,10 +24,25 @@ class SettingsController(ObController): ) def settings_variable_edit(self): + error = self._pre_update(request.form['id']) + + if error: + return redirect(url_for('settings_variable_list', error=error)) + self._model_store.variable().update_form(request.form['id'], request.form['value']) self._post_update(request.form['id']) return redirect(url_for('settings_variable_list')) + def _pre_update(self, id: int) -> Optional[str]: + variable = self._model_store.variable().get(id) + + if variable.name == 'playlist_enabled': + fleet_player_enabled = self._model_store.variable().get_one_by_name(name='fleet_player_enabled') + if variable.as_bool() and fleet_player_enabled.as_bool(): + return self.t('settings_variable_form_error_not_playlist_enabled_while_fleet_player_enabled') + + return None + def _post_update(self, id: int) -> None: variable = self._model_store.variable().get(id) @@ -39,11 +55,12 @@ class SettingsController(ObController): if variable.name == 'fleet_studio_enabled': self.reload_web_server() - # if variable.name == 'fleet_player_enabled': - # if variable.as_bool() and self._model_store.node_player_group().count_all_enabled() == 0: - # self._model_store.user().add_form(NodePlayerGroup(name="default", enabled=True)) - # - # self.reload_web_server() + if variable.name == 'fleet_player_enabled': + playlist_enabled = self._model_store.variable().get_one_by_name(name='playlist_enabled') + if variable.as_bool() and not playlist_enabled.as_bool(): + self._model_store.variable().update_by_name(name='playlist_enabled', value=True) + + self.reload_web_server() if variable.name == 'auth_enabled': if variable.as_bool() and self._model_store.user().count_all_enabled() == 0: diff --git a/src/manager/NodePlayerGroupManager.py b/src/manager/NodePlayerGroupManager.py index 6215d53..869b2be 100644 --- a/src/manager/NodePlayerGroupManager.py +++ b/src/manager/NodePlayerGroupManager.py @@ -51,6 +51,25 @@ class NodePlayerGroupManager(ModelManager): def get_all(self, sort: bool = False) -> List[NodePlayerGroup]: return self.hydrate_list(self._db.get_all(self.TABLE_NAME, "name" if sort else None)) + def get_all_labels_indexed(self, with_default: bool = False) -> Dict: + index = {} + + for item in self.get_groups(with_default=with_default): + index[item.id] = item.name + + return index + + def get_groups(self, with_default: bool = False): + node_player_groups = self.get_all(sort=True) + + if not with_default: + return node_player_groups + + return [NodePlayerGroup( + id=None, + name=self.t('common_default_node_player_group')) + ] + node_player_groups + def get_node_players_groups(self, playlist_id: Optional[int] = None) -> List[NodePlayerGroup]: query = " 1=1 " if playlist_id: @@ -89,7 +108,7 @@ class NodePlayerGroupManager(ModelManager): return node_player_group_id def update_form(self, id: int, name: str, playlist_id: Optional[int]) -> None: - self._db.update_by_id(self.TABLE_NAME, id, self.pre_update({"name": name, "playlist_id": playlist_id})) + self._db.update_by_id(self.TABLE_NAME, id, self.pre_update({"name": name, "playlist_id": playlist_id if playlist_id else None})) self.post_update(id) def add_form(self, node_player_group: Union[NodePlayerGroup, Dict]) -> None: diff --git a/src/manager/NodePlayerManager.py b/src/manager/NodePlayerManager.py index f4b2735..6f1e1f5 100644 --- a/src/manager/NodePlayerManager.py +++ b/src/manager/NodePlayerManager.py @@ -105,9 +105,21 @@ class NodePlayerManager(ModelManager): for node_player_id, node_player_position in positions.items(): self._db.update_by_id(self.TABLE_NAME, node_player_id, {"position": node_player_position}) - def update_form(self, id: int, name: str, host: str) -> None: - self._db.update_by_id(self.TABLE_NAME, id, self.pre_update({"name": name, "host": host})) + def update_form(self, id: int, name: str, host: str, group_id: Optional[int]) -> NodePlayer: + node_player = self.get(id) + + if not node_player: + return + + form = { + "name": name, + "host": host, + "group_id": group_id if group_id else None + } + + self._db.update_by_id(self.TABLE_NAME, id, self.pre_update(form)) self.post_update(id) + return self.get(id) def add_form(self, node_player: Union[NodePlayer, Dict]) -> None: form = node_player diff --git a/src/manager/VariableManager.py b/src/manager/VariableManager.py index abbea8a..58a2c44 100644 --- a/src/manager/VariableManager.py +++ b/src/manager/VariableManager.py @@ -125,7 +125,7 @@ class VariableManager: {"name": "playlist_default_time_sync", "section": self.t(VariableSection.PLAYLIST), "value": True, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_playlist_default_time_sync'), "refresh_player": True}, ### Fleet Management - {"name": "fleet_player_enabled", "section": self.t(VariableSection.FLEET), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_fleet_player_enabled'), "refresh_player": False}, + {"name": "fleet_player_enabled", "section": self.t(VariableSection.FLEET), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_fleet_player_enabled'), "description_edition": self.t('settings_variable_desc_edition_fleet_player_enabled'), "refresh_player": False}, {"name": "fleet_studio_enabled", "section": self.t(VariableSection.FLEET), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_fleet_studio_enabled'), "refresh_player": False}, ### Security diff --git a/views/base.jinja.html b/views/base.jinja.html index 716b153..b713194 100755 --- a/views/base.jinja.html +++ b/views/base.jinja.html @@ -71,16 +71,16 @@ {% endif %} {% if FLEET_PLAYER_ENABLED %} -
  • - - {{ l.fleet_node_player_page_title }} - -
  • {{ l.fleet_node_player_group_page_title }}
  • +
  • + + {{ l.fleet_node_player_page_title }} + +
  • {% endif %} {% if AUTH_ENABLED %}
  • diff --git a/views/fleet/player-group/component/table.jinja.html b/views/fleet/player-group/component/table.jinja.html index 35aca28..a3c2e7e 100644 --- a/views/fleet/player-group/component/table.jinja.html +++ b/views/fleet/player-group/component/table.jinja.html @@ -7,7 +7,9 @@ {% endif %} - {{ l.fleet_node_player_group_panel_th_playlist }} + {% if PLAYLIST_ENABLED %} + {{ l.fleet_node_player_group_panel_th_playlist }} + {% endif %} {{ l.fleet_node_player_group_panel_th_activity }} @@ -25,11 +27,11 @@
    - - - - -
    {{ node_player_group.id }}
    + {% if node_player_group.id %} +
    {{ node_player_group.id }}
    + {% else %} +
    + {% endif %} {{ node_player_group.name }} @@ -37,11 +39,13 @@ {% if AUTH_ENABLED %} - {% set creator = track_created(node_player_group) %} - {% if creator.username %} - - {{ creator.username }} - + {% if node_player_group.id %} + {% set creator = track_created(node_player_group) %} + {% if creator.username %} + + {{ creator.username }} + + {% endif %} {% endif %} {% endif %} diff --git a/views/fleet/player/list.jinja.html b/views/fleet/player/list.jinja.html index 7c96c3c..44dd3c3 100644 --- a/views/fleet/player/list.jinja.html +++ b/views/fleet/player/list.jinja.html @@ -21,6 +21,19 @@
    {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_START) }} + + + {{ HOOK(H_FLEET_NODE_PLAYER_TOOLBAR_ACTIONS_END) }}
    diff --git a/views/fleet/player/modal/add.jinja.html b/views/fleet/player/modal/add.jinja.html index 4e0d183..3c384f5 100644 --- a/views/fleet/player/modal/add.jinja.html +++ b/views/fleet/player/modal/add.jinja.html @@ -11,6 +11,18 @@ +
    + +
    + +
    +
    +
    diff --git a/views/fleet/player/modal/edit.jinja.html b/views/fleet/player/modal/edit.jinja.html index 0c6def9..ed89ecc 100644 --- a/views/fleet/player/modal/edit.jinja.html +++ b/views/fleet/player/modal/edit.jinja.html @@ -13,6 +13,18 @@
    +
    + +
    + +
    +
    +
    diff --git a/views/settings/list.jinja.html b/views/settings/list.jinja.html index 2a35245..b90e063 100644 --- a/views/settings/list.jinja.html +++ b/views/settings/list.jinja.html @@ -13,6 +13,11 @@

    {{ l.settings_page_title }}

    + + {% if request.args.get('error') %} +
    {{ request.args.get('error') }}
    + {% endif %} +

    {{ l.settings_variable_panel_system_variables }}

    diff --git a/views/slideshow/list.jinja.html b/views/slideshow/list.jinja.html index 0005148..f5a4944 100644 --- a/views/slideshow/list.jinja.html +++ b/views/slideshow/list.jinja.html @@ -39,7 +39,7 @@ {% if PLAYLIST_ENABLED %} -