full backend entity management is ok

This commit is contained in:
jr-k 2024-06-03 00:30:21 +02:00
parent 175bcda7e9
commit 8e63d53ef4
17 changed files with 88 additions and 21 deletions

View File

@ -43,19 +43,25 @@ jQuery(document).ready(function ($) {
showModal('modal-node-player-group-edit');
$('.modal-node-player-group-edit input:visible:eq(0)').focus().select();
$('#node-player-group-edit-name').val(nodePlayerGroup.name);
$('#node-player-group-edit-playlist-id').val(nodePlayerGroup.playlist_id);
$('#node-player-group-edit-id').val(nodePlayerGroup.id);
});
$(document).on('click', '.node-player-group-delete', function () {
if (confirm(l.js_fleet_node_player_delete_confirmation)) {
const $tr = $(this).parents('tr:eq(0)');
$tr.remove();
updateTable();
$.ajax({
method: 'DELETE',
url: '/fleet/node-player-group/delete',
headers: {'Content-Type': 'application/json'},
data: JSON.stringify({id: getId($(this))}),
success: function(data) {
$tr.remove();
updateTable();
},
error: function(data) {
$('.alert-error').html(data.responseJSON.message).removeClass('hidden');
}
});
}
});

View File

@ -4,7 +4,6 @@
"slideshow_refresh_player": "Refresh player",
"slideshow_refresh_player_success": "Player refresh signal has been sent, it should happen soon enough (%time% seconds maximum)",
"slideshow_playlist_panel_title": "Playlists",
"slideshow_playlist_panel_item_default": "Default Playlist",
"slideshow_slide_button_add": "Add a slide",
"slideshow_slide_panel_active": "Active slides",
"slideshow_slide_panel_inactive": "Inactive slides",
@ -59,7 +58,7 @@
"playlist_form_button_cancel": "Cancel",
"js_playlist_delete_confirmation": "Are you sure?",
"playlist_delete_has_slides": "Playlist has slides, please remove them before and retry",
"playlist_delete_has_node_player_groups": "Playlist has player groups, please remove them before and retry",
"playlist_delete_has_node_player_groups": "Playlist is linked to a player group",
"fleet_node_studio_page_title": "Studios",
"fleet_node_studio_button_add": "Add a studio",
@ -105,12 +104,14 @@
"fleet_node_player_group_panel_active": "Active player groups",
"fleet_node_player_group_panel_empty": "Currently, there are no player groups. %link% now.",
"fleet_node_player_group_panel_th_name": "Name",
"fleet_node_player_group_panel_th_playlist": "Playlist",
"fleet_node_player_group_panel_th_activity": "Activity",
"fleet_node_player_group_form_add_title": "Add Player Group",
"fleet_node_player_group_form_add_submit": "Add",
"fleet_node_player_group_form_edit_title": "Edit Player Group",
"fleet_node_player_group_form_edit_submit": "Save",
"fleet_node_player_group_form_label_name": "Name",
"fleet_node_player_group_form_label_playlist_id": "Playlist",
"fleet_node_player_group_form_button_cancel": "Cancel",
"js_fleet_node_player_group_delete_confirmation": "Are you sure?",
"node_player_group_delete_has_node_player": "Player group has players, please remove or unassign them before and retry",
@ -197,8 +198,9 @@
"basic_month_9": "September",
"basic_month_10": "October",
"basic_month_11": "November",
"basic_month_12": "Décember",
"basic_month_12": "December",
"common_default_playlist": "Default playlist",
"common_unknown_ipaddr": "Unknown IP address",
"common_empty": "[Empty]",
"common_are_you_sure": "Are you sure?",

View File

@ -4,7 +4,6 @@
"slideshow_refresh_player": "Rafraîchir le lecteur",
"slideshow_refresh_player_success": "Un rafraîchissement du lecteur a été programmé, il devrait avoir lieu sous peu (%time% secondes maximum)",
"slideshow_playlist_panel_title": "Playlists",
"slideshow_playlist_panel_item_default": "Playlist par défaut",
"slideshow_slide_button_add": "Ajouter une slide",
"slideshow_slide_panel_active": "Slides actives",
"slideshow_slide_panel_inactive": "Slides inactives",
@ -59,7 +58,7 @@
"playlist_form_button_cancel": "Annuler",
"js_playlist_delete_confirmation": "Êtes-vous sûr ?",
"playlist_delete_has_slides": "La liste de lecture contient des slides, supprimez-les avant et réessayez",
"playlist_delete_has_node_player_groups": "La liste de lecture contient des groupes de lecteur, supprimez-les avant et réessayez",
"playlist_delete_has_node_player_groups": "La liste de lecture est attribuée à un groupe de lecteur",
"fleet_node_studio_page_title": "Studios",
"fleet_node_studio_button_add": "Ajouter un studio",
@ -105,12 +104,14 @@
"fleet_node_player_group_panel_active": "Groupes de lecteur",
"fleet_node_player_group_panel_empty": "Actuellement, il n'y a pas de groupes de lecteur. %link% maintenant.",
"fleet_node_player_group_panel_th_name": "Nom",
"fleet_node_player_group_panel_th_playlist": "Liste de lecture",
"fleet_node_player_group_panel_th_activity": "Options",
"fleet_node_player_group_form_add_title": "Ajout d'un groupe de lecteur",
"fleet_node_player_group_form_add_submit": "Ajouter",
"fleet_node_player_group_form_edit_title": "Modification d'un groupe de lecteur",
"fleet_node_player_group_form_edit_submit": "Enregistrer",
"fleet_node_player_group_form_label_name": "Nom",
"fleet_node_player_group_form_label_playlist_id": "Liste de lecture",
"fleet_node_player_group_form_button_cancel": "Annuler",
"js_fleet_node_player_group_delete_confirmation": "Êtes-vous sûr ?",
"node_player_group_delete_has_node_player": "Le groupe de lecteur a des lecteurs, supprimez-les ou réassignez-les avant de le supprimer",
@ -199,6 +200,7 @@
"basic_month_11": "Novembre",
"basic_month_12": "Décembre",
"common_default_playlist": "Playlist par défaut",
"common_unknown_ipaddr": "Adresse IP inconnue",
"common_empty": "[Vide]",
"common_are_you_sure": "Êtes-vous sûr ?",

View File

@ -81,7 +81,7 @@ class AuthController(ObController):
self._model_store.user().update_form(
id=request.form['id'],
username=request.form['username'],
password=request.form['password'] if 'password' in request.form else None
password=request.form['password'] if 'password' in request.form and request.form['password'] else None
)
return redirect(url_for('auth_user_list'))

View File

@ -26,17 +26,20 @@ class FleetNodePlayerGroupController(ObController):
return render_template(
'fleet/player-group/list.jinja.html',
node_player_groups=self._model_store.node_player_group().get_all(),
playlists=self._model_store.playlist().get_all_labels_indexed()
)
def fleet_node_player_group_add(self):
playlist_id = request.form['playlist_id'] if 'playlist_id' in request.form and request.form['playlist_id'] else None
self._model_store.node_player_group().add_form(NodePlayerGroup(
name=request.form['name'],
playlist_id=request.form['playlist_id'],
playlist_id=playlist_id,
))
return redirect(url_for('fleet_node_player_group_list'))
def fleet_node_player_group_edit(self):
self._model_store.node_player_group().update_form(request.form['id'], request.form['name'], request.form['playlist_id'])
playlist_id = request.form['playlist_id'] if 'playlist_id' in request.form and request.form['playlist_id'] else None
self._model_store.node_player_group().update_form(request.form['id'], request.form['name'], playlist_id)
return redirect(url_for('fleet_node_player_group_list'))
def fleet_node_player_group_delete(self):
@ -46,5 +49,5 @@ class FleetNodePlayerGroupController(ObController):
if self._model_store.node_player().count_node_players_for_group(id) > 0:
return jsonify({'status': 'error', 'message': self.t('node_player_group_delete_has_node_player')}), 400
self._model_store.playlist().delete(id)
self._model_store.node_player_group().delete(id)
return jsonify({'status': 'ok'})

View File

@ -47,7 +47,7 @@ class SlideshowController(ObController):
name=request.form['name'],
type=str_to_enum(request.form['type'], SlideType),
duration=request.form['duration'],
playlist_id=request.form['playlist_id'] if 'playlist_id' in request.form else None,
playlist_id=request.form['playlist_id'] if 'playlist_id' in request.form and request.form['playlist_id'] else None,
cron_schedule=get_optional_string(request.form['cron_schedule']),
cron_schedule_end=get_optional_string(request.form['cron_schedule_end']),
)
@ -84,7 +84,7 @@ class SlideshowController(ObController):
duration=request.form['duration'],
cron_schedule=request.form['cron_schedule'],
cron_schedule_end=request.form['cron_schedule_end'],
location=request.form['location'] if 'location' in request.form else None
location=request.form['location'] if 'location' in request.form and request.form['location'] else None
)
self._post_update()

View File

@ -77,6 +77,9 @@ class FolderManager(ModelManager):
def post_update(self, folder_id: str) -> str:
return folder_id
def post_delete(self, folder_id: str) -> str:
return folder_id
def update_form(self, id: int, name: str) -> None:
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update({"name": name}))
self.post_update(id)

View File

@ -52,7 +52,7 @@ class NodePlayerGroupManager(ModelManager):
return self.hydrate_list(self._db.get_all(self.TABLE_NAME, "name" if sort else None))
def get_node_players_groups(self, playlist_id: Optional[int] = None) -> List[NodePlayerGroup]:
query = ""
query = " 1=1 "
if playlist_id:
query = "{} {}".format(query, "AND playlist_id = {}".format(playlist_id))
else:
@ -85,6 +85,9 @@ class NodePlayerGroupManager(ModelManager):
def post_update(self, node_player_group_id: str) -> str:
return node_player_group_id
def post_delete(self, node_player_group_id: str) -> str:
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.post_update(id)

View File

@ -54,7 +54,7 @@ class NodePlayerManager(ModelManager):
def get_all(self, sort: bool = False) -> List[NodePlayer]:
return self.hydrate_list(self._db.get_all(self.TABLE_NAME, "position" if sort else None))
def get_node_players(self, group_id: Optional[int] = None) -> List[NodePlayer]:
def get_node_players(self, group_id: Optional[int] = None, enabled: bool = True) -> List[NodePlayer]:
query = "enabled = {}".format("1" if enabled else "0")
if group_id:
query = "{} {}".format(query, "AND group_id = {}".format(group_id))
@ -88,6 +88,9 @@ class NodePlayerManager(ModelManager):
def post_update(self, node_player_id: str) -> str:
return node_player_id
def post_delete(self, node_player_id: str) -> str:
return node_player_id
def get_enabled_node_players(self) -> List[NodePlayer]:
return self.get_by(query="enabled = 1", sort="position")

View File

@ -79,6 +79,9 @@ class NodeStudioManager(ModelManager):
def post_update(self, node_studio_id: str) -> str:
return node_studio_id
def post_delete(self, node_studio_id: str) -> str:
return node_studio_id
def get_enabled_node_studios(self) -> List[NodeStudio]:
return self.get_by(query="enabled = 1", sort="position")

View File

@ -62,15 +62,23 @@ class PlaylistManager(ModelManager):
return self.hydrate_object(object)
def get_durations_by_playlists(self):
durations = self._db.execute_read_query("select playlist, sum(duration) as total_duration from slideshow where cron_schedule is null group by playlist")
durations = self._db.execute_read_query("select playlist_id, sum(duration) as total_duration from slideshow where cron_schedule is null group by playlist_id")
map = {}
for duration in durations:
map[duration['playlist']] = duration['total_duration']
map[duration['playlist_id']] = duration['total_duration']
return map
def get_all(self) -> List[Playlist]:
return self.hydrate_list(self._db.get_all(self.TABLE_NAME))
def get_all_labels_indexed(self) -> Dict:
index = {}
for item in self.get_all():
index[item.id] = item.name
return index
def get_enabled_playlists(self, with_default: bool = False) -> List[Playlist]:
playlists = self.get_by(query="enabled = 1")
@ -80,7 +88,7 @@ class PlaylistManager(ModelManager):
return [Playlist(
id=None,
time_sync=self.variable_manager.map().get('playlist_default_time_sync').as_bool(),
name=self.t('slideshow_playlist_panel_item_default'))
name=self.t('common_default_playlist'))
] + playlists
def get_disabled_playlists(self) -> List[Playlist]:

View File

@ -7,6 +7,7 @@
<i class="fa fa-user"></i>
</th>
{% endif %}
<th class="tac">{{ l.fleet_node_player_group_panel_th_playlist }}</th>
<th class="tac">{{ l.fleet_node_player_group_panel_th_activity }}</th>
</tr>
</thead>
@ -19,6 +20,7 @@
) }}
</td>
</tr>
{% for node_player_group in node_player_groups %}
<tr class="node-player-group-item" data-level="{{ node_player_group.id }}" data-entity="{{ node_player_group.to_json({"created_by": track_created(node_player_group).username, "updated_by": track_updated(node_player_group).username}) }}">
<td class="infos">
@ -29,7 +31,7 @@
<div class="badge"><i class="fa fa-key icon-left"></i> {{ node_player_group.id }}</div>
<i class="fa fa-server icon-left"></i>
<i class="fa fa-group icon-left"></i>
{{ node_player_group.name }}
</div>
</td>
@ -41,6 +43,13 @@
</a>
</td>
{% endif %}
<td class="tac">
{% if node_player_group.playlist_id and playlists[node_player_group.playlist_id] %}
{{ playlists[node_player_group.playlist_id] }}
{% else %}
{{ l.common_default_playlist }}
{% endif %}
</td>
<td class="actions tac">
<a href="javascript:void(0);" class="item-edit node-player-group-edit">
<i class="fa fa-pencil"></i>

View File

@ -24,6 +24,9 @@
</div>
</div>
<div class="alert alert-error hidden">
</div>
<div class="panel">
<div class="panel-body">

View File

@ -11,6 +11,17 @@
</div>
</div>
<div class="form-group">
<label for="node-player-group-add-playlist-id">{{ l.fleet_node_player_group_form_label_playlist_id }}</label>
<div class="widget">
<select name="playlist_id" id="node-player-group-add-playlist-id">
<option value="">{{ l.common_default_playlist }}</option>
{% for playlist_id, playlist_name in playlists.items() %}
<option value="{{ playlist_id }}">{{ playlist_name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="actions">
<button type="button" class="btn-normal modal-close">

View File

@ -13,6 +13,17 @@
</div>
</div>
<div class="form-group">
<label for="node-player-group-edit-playlist-id">{{ l.fleet_node_player_group_form_label_playlist_id }}</label>
<div class="widget">
<select name="playlist_id" id="node-player-group-edit-playlist-id">
<option value="">{{ l.common_default_playlist }}</option>
{% for playlist_id, playlist_name in playlists.items() %}
<option value="{{ playlist_id }}">{{ playlist_name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="actions">
<button type="button" class="btn-normal modal-close">

View File

@ -31,7 +31,7 @@
<div class="badge"><i class="fa fa-key icon-left"></i> {{ node_player.id }}</div>
<i class="fa fa-server icon-left"></i>
<i class="fa fa-tv icon-left"></i>
{{ node_player.name }}
</div>
</td>

View File

@ -41,7 +41,7 @@
{% if PLAYLIST_ENABLED %}
<select class="playlist-picker">
<option value="{{ url_for('slideshow_slide_list') }}" {% if not current_playlist %}selected="selected"{% endif %}>
{{ l.slideshow_playlist_panel_item_default }}
{{ l.common_default_playlist }}
</option>
{% for playlist in playlists %}
{% set is_active_playlist = str(current_playlist.id) == str(playlist.id) %}