some fixes + type variables

This commit is contained in:
jr-k 2024-02-28 17:38:29 +01:00
parent 637b6197cb
commit 7648518c28
15 changed files with 146 additions and 23 deletions

View File

@ -61,6 +61,10 @@
"settings_variable_help_bind": "Application server bind (restart needed)",
"settings_variable_help_lang": "Server language [fr,en] (restart needed)",
"settings_variable_help_fleet_enabled": "Enable fleet screen management view (restart needed)",
"settings_variable_help_external_url": "External url (i.e: https://screen-01.company.com or http://10.10.3.100)",
"settings_variable_help_ro_editable": "Last application reboot datetime",
"settings_variable_help_ro_last_slide_update": "Last slide update datetime",
"sysinfo_page_title": "System infos",
"sysinfo_panel_button_restart": "Restart",

View File

@ -61,6 +61,10 @@
"settings_variable_help_bind": "Hôte d'attache du serveur d'application (redémarrage nécessaire)",
"settings_variable_help_lang": "Langage de l'application [fr,en] (redémarrage nécessaire)",
"settings_variable_help_fleet_enabled": "Activer la gestion de flotte des écrans (redémarrage nécessaire)",
"settings_variable_help_external_url": "URL externe (i.e: https://screen-01.company.com or http://10.10.3.100)",
"settings_variable_help_ro_editable": "Date de dernier redémarrage de l'application",
"settings_variable_help_ro_last_slide_update": "Date de dernière modification d'une slide",
"sysinfo_page_title": "Système",
"sysinfo_panel_button_restart": "Redémarrer",

View File

@ -5,6 +5,7 @@ import re
import shutil
import subprocess
import sys
import time
from flask import Flask, send_from_directory
@ -87,10 +88,16 @@ def inject_global_vars():
)
@app.template_filter('ctime')
def time_ctime(s):
return time.ctime(s)
PlayerController(app, LANGDICT, slide_manager)
SlideshowController(app, LANGDICT, slide_manager)
SlideshowController(app, LANGDICT, slide_manager, variable_manager)
SettingsController(app, LANGDICT, variable_manager)
SysinfoController(app, LANGDICT, config)
SysinfoController(app, LANGDICT, config, variable_manager)
if vars['fleet_enabled'].as_bool():
FleetController(app, LANGDICT, screen_manager)

View File

@ -19,7 +19,7 @@ class SettingsController:
return render_template(
'settings/list.jinja.html',
l=self._lang_dict,
variables=self._variable_manager.get_all(),
variables=self._variable_manager.get_editable_variables(),
)
def settings_variable_edit(self):

View File

@ -1,5 +1,6 @@
import json
import os
import time
from flask import Flask, render_template, redirect, request, url_for, send_from_directory, jsonify
from werkzeug.utils import secure_filename
@ -10,10 +11,11 @@ from src.utils import str_to_enum
class SlideshowController:
def __init__(self, app, lang_dict, slide_manager):
def __init__(self, app, lang_dict, slide_manager, variable_manager):
self._app = app
self._lang_dict = lang_dict
self._slide_manager = slide_manager
self._variable_manager = variable_manager
self.register()
def register(self):
@ -34,6 +36,8 @@ class SlideshowController:
l=self._lang_dict,
enabled_slides=self._slide_manager.get_enabled_slides(),
disabled_slides=self._slide_manager.get_disabled_slides(),
var_last_restart=self._variable_manager.get_one_by_name('last_restart'),
var_external_url=self._variable_manager.get_one_by_name('external_url')
)
def slideshow_slide_add(self):
@ -61,24 +65,33 @@ class SlideshowController:
slide.location = request.form['object']
self._slide_manager.add_form(slide)
self._post_update()
return redirect(url_for('slideshow_slide_list'))
def slideshow_slide_edit(self):
self._slide_manager.update_form(request.form['id'], request.form['name'], request.form['duration'])
self._post_update()
return redirect(url_for('slideshow_slide_list'))
def slideshow_slide_toggle(self):
data = request.get_json()
self._slide_manager.update_enabled(data.get('id'), data.get('enabled'))
self._post_update()
return jsonify({'status': 'ok'})
def slideshow_slide_delete(self):
data = request.get_json()
self._slide_manager.delete(data.get('id'))
self._post_update()
return jsonify({'status': 'ok'})
def slideshow_slide_position(self):
data = request.get_json()
self._slide_manager.update_positions(data)
self._post_update()
return jsonify({'status': 'ok'})
def _post_update(self):
self._variable_manager.update_by_name("last_slide_update", time.time())

View File

@ -9,15 +9,17 @@ from src.utils import get_ip_address
class SysinfoController:
def __init__(self, app, lang_dict, config):
def __init__(self, app, lang_dict, config, variable_manager):
self._app = app
self._lang_dict = lang_dict
self._config = config
self._variable_manager = variable_manager
self.register()
def register(self):
self._app.add_url_rule('/sysinfo', 'sysinfo_attribute_list', self.sysinfo, methods=['GET'])
self._app.add_url_rule('/sysinfo/restart', 'sysinfo_restart', self.sysinfo_restart, methods=['POST'])
self._app.add_url_rule('/sysinfo/restart/needed', 'sysinfo_restart_needed', self.sysinfo_restart_needed, methods=['GET'])
def sysinfo(self):
ipaddr = get_ip_address()
@ -25,6 +27,7 @@ class SysinfoController:
'sysinfo/list.jinja.html',
ipaddr=ipaddr if ipaddr else self._lang_dict['common_unknown_ipaddr'],
l=self._lang_dict,
ro_variables=self._variable_manager.get_readonly_variables(),
)
def sysinfo_restart(self):
@ -43,3 +46,12 @@ class SysinfoController:
return jsonify({'status': 'ok'})
def sysinfo_restart_needed(self):
var_last_slide_update = self._variable_manager.get_one_by_name('last_slide_update')
var_last_restart = self._variable_manager.get_one_by_name('last_restart')
if var_last_slide_update.value <= var_last_restart.value:
return jsonify({'status': False})
return jsonify({'status': True})

View File

@ -1,7 +1,9 @@
from typing import Dict, Optional, List, Tuple, Union
from src.model.Variable import Variable
from src.model.VariableType import VariableType
from pysondb import PysonDB
from pysondb.errors import IdDoesNotExistError
import time
class VariableManager:
@ -14,20 +16,27 @@ class VariableManager:
def init(self, lang_dict: Optional[Dict] = None) -> None:
default_vars = [
{"name": "port", "value": 5000, "description": lang_dict['settings_variable_help_port'] if lang_dict else ""},
{"name": "bind", "value": '0.0.0.0', "description": lang_dict['settings_variable_help_bind'] if lang_dict else ""},
{"name": "lang", "value": "en", "description": lang_dict['settings_variable_help_lang'] if lang_dict else ""},
{"name": "fleet_enabled", "value": "0", "description": lang_dict['settings_variable_help_fleet_enabled'] if lang_dict else ""},
{"name": "port", "value": 5000, "type": VariableType.INT.value, "editable": True, "description": lang_dict['settings_variable_help_port'] if lang_dict else ""},
{"name": "bind", "value": '0.0.0.0', "type": VariableType.STRING.value, "editable": True, "description": lang_dict['settings_variable_help_bind'] if lang_dict else ""},
{"name": "lang", "value": "en", "type": VariableType.STRING.value, "editable": True, "description": lang_dict['settings_variable_help_lang'] if lang_dict else ""},
{"name": "fleet_enabled", "value": "0", "type": VariableType.BOOL.value, "editable": True, "description": lang_dict['settings_variable_help_fleet_enabled'] if lang_dict else ""},
{"name": "external_url", "value": "", "type": VariableType.STRING.value, "editable": True, "description": lang_dict['settings_variable_help_external_url'] if lang_dict else ""},
{"name": "last_restart", "value": time.time(), "type": VariableType.TIMESTAMP.value, "editable": False, "description": lang_dict['settings_variable_help_ro_editable'] if lang_dict else ""},
{"name": "last_slide_update", "value": time.time(), "type": VariableType.TIMESTAMP.value, "editable": False, "description": lang_dict['settings_variable_help_ro_last_slide_update'] if lang_dict else ""},
]
for default_var in default_vars:
variable = self.get_one_by(query=lambda v: v['name'] == default_var['name'])
variable = self.get_one_by_name(default_var['name'])
if not variable:
self.add_form(default_var)
variable = self.get_one_by_name(default_var['name'])
elif variable.description != default_var['description']:
self._db.update_by_id(variable.id, {"description": default_var['description']})
if variable.name == 'last_restart':
self._db.update_by_id(variable.id, {"value": time.time()})
def get_variable_map(self) -> Dict[str, Variable]:
var_map = {}
@ -60,6 +69,9 @@ class VariableManager:
def get_by(self, query) -> List[Variable]:
return self.hydrate_dict(self._db.get_by_query(query=query))
def get_one_by_name(self, name: str) -> Optional[Variable]:
return self.get_one_by(query=lambda v: v['name'] == name)
def get_one_by(self, query) -> Optional[Variable]:
variables = self.hydrate_dict(self._db.get_by_query(query=query))
if len(variables) == 1:
@ -76,9 +88,18 @@ class VariableManager:
return VariableManager.hydrate_list(raw_variables)
def get_editable_variables(self) -> List[Variable]:
return [variable for variable in self.get_all() if variable.editable]
def get_readonly_variables(self) -> List[Variable]:
return [variable for variable in self.get_all() if not variable.editable]
def update_form(self, id: str, value: Union[int, bool, str]) -> None:
self._db.update_by_id(id, {"value": value})
def update_by_name(self, name: str, value) -> Optional[Variable]:
return self._db.update_by_query(query=lambda v: v['name'] == name, new_data={"value": value})
def add_form(self, variable: Union[Variable, Dict]) -> None:
db_variable = variable

View File

@ -1,15 +1,19 @@
import json
import time
from typing import Optional, Union
from src.model.VariableType import VariableType
from src.utils import str_to_enum
class Variable:
def __init__(self, name: str = '', description: str = '', value: Union[int, bool, str] = '', id: Optional[str] = None):
def __init__(self, name: str = '', description: str = '', type: Union[VariableType, str] = VariableType.STRING, value: Union[int, bool, str] = '', editable: bool = True, id: Optional[str] = None):
self._id = id if id else None
self._name = name
self._type = str_to_enum(type, VariableType) if isinstance(type, str) else type
self._description = description
self._value = value
self._editable = editable
@property
def id(self) -> Union[int, str]:
@ -23,6 +27,14 @@ class Variable:
def name(self, value: str):
self._name = value
@property
def type(self) -> VariableType:
return self._type
@type.setter
def type(self, value: VariableType):
self._type = value
@property
def description(self) -> str:
return self._description
@ -31,6 +43,14 @@ class Variable:
def description(self, value: str):
self._description = value
@property
def editable(self) -> bool:
return self._editable
@editable.setter
def editable(self, value: bool):
self._editable = value
@property
def value(self) -> Union[int, bool, str]:
return self._value
@ -44,7 +64,9 @@ class Variable:
f"id='{self.id}',\n" \
f"name='{self.name}',\n" \
f"value='{self.value}',\n" \
f"type='{self.type}',\n" \
f"description='{self.description}',\n" \
f"editable='{self.editable}',\n" \
f")"
def to_json(self) -> str:
@ -55,14 +77,30 @@ class Variable:
"id": self.id,
"name": self.name,
"value": self.value,
"type": self.type.value,
"description": self.description,
"editable": self.editable,
}
def as_bool(self):
def as_bool(self) -> bool:
return bool(int(self._value))
def as_string(self):
def as_string(self) -> str:
return str(self._value)
def as_int(self):
return int(self._value)
def as_int(self) -> int:
return int(self._value)
def as_ctime(self):
return time.ctime(self._value)
def display(self):
if self.type == VariableType.INT:
return self.as_int()
elif self.type == VariableType.BOOL:
return self.as_bool()
elif self.type == VariableType.TIMESTAMP:
return self.as_ctime()
return self.as_string()

View File

@ -0,0 +1,9 @@
from enum import Enum
class VariableType(Enum):
BOOL = 'bool'
STRING = 'string'
INT = 'int'
TIMESTAMP = 'timestamp'

View File

@ -64,10 +64,12 @@
{% endblock %}
</div>
<script>
var l = {'js_slideshow_slide_delete_confirmation': '{{ l.slideshow_slide_delete_confirmation }}'};
var l = {'js_fleet_screen_delete_confirmation': '{{ l.js_fleet_screen_delete_confirmation }}'};
var l = {'js_sysinfo_restart_confirmation': '{{ l.js_sysinfo_restart_confirmation }}'};
var l = {'js_sysinfo_restart_loading': '{{ l.js_sysinfo_restart_loading }}'};
var l = {
'js_slideshow_slide_delete_confirmation': '{{ l.slideshow_slide_delete_confirmation }}',
'js_fleet_screen_delete_confirmation': '{{ l.js_fleet_screen_delete_confirmation }}',
'js_sysinfo_restart_confirmation': '{{ l.js_sysinfo_restart_confirmation }}',
'js_sysinfo_restart_loading': '{{ l.js_sysinfo_restart_loading }}'
};
</script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
{% block add_js %}{% endblock %}

View File

@ -34,7 +34,6 @@
items = data;
}).catch(function(err) {
console.error(err);
document.location.reload();
});
}, playlistCheck);

View File

@ -50,6 +50,10 @@
<a href="{{ slide.location }}" class="item-download slide-download" target="_blank">
<i class="fa fa-eye"></i>
</a>
{% elif var_external_url.value|length > 0 %}
<a href="{{ var_external_url.value }}/{{ slide.location }}" class="item-download slide-download" target="_blank">
<i class="fa fa-eye"></i>
</a>
{% endif %}
<a href="javascript:void(0);" class="item-delete slide-delete">
<i class="fa fa-trash"></i>

View File

@ -8,6 +8,7 @@
{% block add_js %}
<script src="{{ STATIC_PREFIX }}js/tablednd-fixed.js"></script>
<script src="{{ STATIC_PREFIX }}js/slideshow.js"></script>
<script src="{{ STATIC_PREFIX }}js/restart.js"></script>
{% endblock %}
{% block page %}
@ -15,6 +16,10 @@
<h2>{{ l.slideshow_page_title }}</h2>
<div class="toolbar-actions">
{% if fleet_mode %}
<button class="normal sysinfo-restart"><i class="fa fa-refresh icon-left"></i>{{ l.sysinfo_panel_button_restart }}</button>
{% endif %}
<button class="purple slide-add item-add"><i class="fa fa-plus icon-left"></i>{{ l.slideshow_slide_button_add }}</button>
</div>
</div>
@ -37,7 +42,6 @@
</div>
</div>
<div class="modals hidden">
<div class="modals-outer">
<a href="javascript:void(0);" class="modal-close">

View File

@ -6,7 +6,7 @@
{% endblock %}
{% block add_js %}
<script src="{{ STATIC_PREFIX }}js/sysinfo.js"></script>
<script src="{{ STATIC_PREFIX }}js/restart.js"></script>
{% endblock %}
{% block page %}
@ -31,6 +31,12 @@
<td>{{ l.sysinfo_panel_td_ipaddr }}</td>
<td>{{ ipaddr }}</td>
</tr>
{% for ro_variable in ro_variables %}
<tr>
<td>{{ ro_variable.description }}</td>
<td>{{ ro_variable.display() }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>