split jinja views + add sysinfo page

This commit is contained in:
jr-k 2024-02-27 10:51:21 +01:00
parent bab018232a
commit 886bac5de1
14 changed files with 348 additions and 313 deletions

View File

@ -1,7 +1,5 @@
{
"manage_page_title": "Schedule Overview",
"settings_page_title": "Settings",
"sysinfo_page_title": "System info",
"manage_slide_button_add": "Add a slide",
"manage_slide_panel_active": "Active slides",
"manage_slide_panel_inactive": "Inactive slides",
@ -25,5 +23,15 @@
"manage_slide_form_label_duration": "Duration",
"manage_slide_form_label_duration_unit": "seconds",
"manage_slide_form_button_cancel": "Cancel",
"manage_slide_delete_confirmation": "Are you sure?"
"js_manage_slide_delete_confirmation": "Are you sure?",
"sysinfo_page_title": "System infos",
"sysinfo_panel_title": "Infos",
"sysinfo_panel_th_attribute": "Attribute",
"sysinfo_panel_th_value": "Value",
"sysinfo_panel_td_ipaddr": "IP Address",
"settings_page_title": "Settings"
}

View File

@ -1,7 +1,5 @@
{
"manage_page_title": "Vue Planning",
"settings_page_title": "Paramètres",
"sysinfo_page_title": "Système",
"manage_slide_button_add": "Ajouter une slide",
"manage_slide_panel_active": "Slides actives",
"manage_slide_panel_inactive": "Slides inactives",
@ -25,5 +23,13 @@
"manage_slide_form_label_duration": "Durée",
"manage_slide_form_label_duration_unit": "secondes",
"manage_slide_form_button_cancel": "Annuler",
"manage_slide_delete_confirmation": "Êtes-vous sûr ?"
"js_manage_slide_delete_confirmation": "Êtes-vous sûr ?",
"sysinfo_page_title": "Système",
"sysinfo_panel_title": "Informations",
"sysinfo_panel_th_attribute": "Attribut",
"sysinfo_panel_th_value": "Valeur",
"sysinfo_panel_td_ipaddr": "Adresse IP",
"settings_page_title": "Paramètres"
}

View File

@ -82,9 +82,16 @@ def get_ip_address():
# </utils>
# <web>
@app.context_processor
def inject_global_vars():
return dict(
LANG=config['lang'],
STATIC_PREFIX='/data/www/'
)
@app.route('/')
def index():
return render_template('player.jinja.html', items=json.dumps(slide_manager.to_dict(slide_manager.get_enabled_slides())))
return render_template('player/player.jinja.html', items=json.dumps(slide_manager.to_dict(slide_manager.get_enabled_slides())))
@app.route('/playlist')
def playlist():
@ -92,16 +99,23 @@ def playlist():
@app.route('/slide/default')
def slide_default():
return render_template('default.jinja.html', ipaddr=get_ip_address())
return render_template('player/default.jinja.html', ipaddr=get_ip_address())
@app.route('/manage')
def manage():
return render_template(
'manage.jinja.html',
ipaddr=get_ip_address(),
'manager/manage.jinja.html',
l=LANGDICT,
enabled_slides=slide_manager.get_enabled_slides(),
disabled_slides=slide_manager.get_disabled_slides()
disabled_slides=slide_manager.get_disabled_slides(),
)
@app.route('/manage/sysinfo')
def manage_sysinfo():
return render_template(
'manager/sysinfo.jinja.html',
ipaddr=get_ip_address(),
l=LANGDICT,
)
@app.route('/manage/slide/add', methods=['GET', 'POST'])
@ -158,7 +172,7 @@ def manage_slide_position():
@app.errorhandler(404)
def not_found(e):
return send_from_directory('views', 'error404.html'), 404
return send_from_directory('views', 'core/error404.html'), 404
# </web>
if __name__ == '__main__':

View File

@ -1,301 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<title>
Obscreen - {{ l.manage_page_title }}
</title>
<meta name="robots" content="noindex, nofollow">
<meta name="google" content="notranslate">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="data/www/css/manage.css" />
</head>
<body>
<div class="container">
<header>
<h1 class="logo">
<img src="data/www/img/logo.png" />
Obscreen
</h1>
<menu>
<ul>
<li class="active">
<a href="#">
<i class="fa-regular fa-clock"></i> {{ l.manage_page_title }}
</a>
</li>
<li>
<a href="#">
<i class="fa-solid fa-gear"></i> {{ l.settings_page_title }}
</a>
</li>
<li>
<a href="#">
<i class="fa-solid fa-list-check"></i> {{ l.sysinfo_page_title }}
</a>
</li>
</ul>
</menu>
</header>
<div class="toolbar">
<h2>{{ l.manage_page_title }}</h2>
<div class="toolbar-actions">
<button class="purple slide-add"><i class="fa fa-plus icon-left"></i>{{ l.manage_slide_button_add }}</button>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h3>{{ l.manage_slide_panel_active }}</h3>
<table class="active-slides">
<thead>
<tr>
<th>{{ l.manage_slide_panel_th_name }}</th>
<th class="tac">{{ l.manage_slide_panel_th_duration }}</th>
<th class="tac">{{ l.manage_slide_panel_th_enabled }}</th>
<th class="tac">{{ l.manage_slide_panel_th_activity }}</th>
</tr>
</thead>
<tbody>
<tr class="empty-tr {% if enabled_slides|length != 0 %}hidden{% endif %}">
<td colspan="4">
{{
l.manage_slide_panel_empty|replace(
'%link%',
('<a href="javascript:void(0);" class="slide-add">'~l.manage_slide_button_add~'</a>')|safe
)
}}
</td>
</tr>
{% for slide in enabled_slides %}
<tr class="slide-item" data-level="{{ slide.id }}" data-entity="{{ slide.to_json() }}">
<td class="infos">
<div class="inner">
<a href="javascript:void(0);" class="slide-sort">
<i class="fa fa-sort icon-left"></i>
</a>
{% set icon_type = 'globe' %}
{% if slide.type == 'video' %}
{% set icon_type = 'video' %}
{% elif slide.type == 'picture' %}
{% set icon_type = 'image' %}
{% endif %}
<i class="fa fa-{{ icon_type }} icon-left"></i>
{{ slide.name }}
</div>
</td>
<td class="tac">
{{ slide.duration }} {{ l.manage_slide_panel_th_duration_unit }}
</td>
<td class="tac">
<label class="pure-material-switch">
<input type="checkbox" {% if slide.enabled %}checked="checked"{% endif %}><span></span>
</label>
</td>
<td class="actions tac">
<a href="javascript:void(0);" class="slide-edit">
<i class="fa fa-pencil"></i>
</a>
<a href="{{ slide.location }}" class="slide-download" target="_blank">
<i class="fa fa-eye"></i>
</a>
<a href="javascript:void(0);" class="slide-delete">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-inactive">
<div class="panel-body">
<h3>{{ l.manage_slide_panel_inactive }}</h3>
<table class="inactive-slides">
<thead>
<tr>
<th>{{ l.manage_slide_panel_th_name }}</th>
<th class="tac">{{ l.manage_slide_panel_th_duration }}</th>
<th class="tac">{{ l.manage_slide_panel_th_enabled }}</th>
<th class="tac">{{ l.manage_slide_panel_th_activity }}</th>
</tr>
</thead>
<tbody>
<tr class="empty-tr {% if disabled_slides|length != 0 %}hidden{% endif %}">
<td colspan="4">
{{
l.manage_slide_panel_empty|replace(
'%link%',
('<a href="javascript:void(0);" class="slide-add">'~l.manage_slide_button_add~'</a>')|safe
)
}}
</td>
</tr>
{% for slide in disabled_slides %}
<tr class="slide-item" data-level="{{ slide.id }}" data-entity="{{ slide.to_json() }}">
<td class="infos">
<div class="inner">
<a href="javascript:void(0);" class="slide-sort">
<i class="fa fa-sort icon-left"></i>
</a>
{% set icon_type = 'globe' %}
{% if slide.type == 'video' %}
{% set icon_type = 'video' %}
{% elif slide.type == 'picture' %}
{% set icon_type = 'image' %}
{% endif %}
<i class="fa fa-{{ icon_type }} icon-left"></i>
{{ slide.name }}
</div>
</td>
<td class="tac">
{{ slide.duration }} {{ l.manage_slide_panel_th_duration_unit }}
</td>
<td class="tac">
<label class="pure-material-switch">
<input type="checkbox" {% if slide.enabled %}checked="checked"{% endif %}><span></span>
</label>
</td>
<td class="actions tac">
<a href="javascript:void(0);" class="slide-edit">
<i class="fa fa-pencil"></i>
</a>
<a href="{{ slide.location }}" class="slide-download" target="_blank">
<i class="fa fa-eye"></i>
</a>
<a href="javascript:void(0);" class="slide-delete">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="footer">
</div>
<div class="modals hidden">
<div class="modals-outer">
<a href="javascript:void(0);" class="modal-close">
<i class="fa fa-close"></i>
</a>
<div class="modals-inner">
<div class="modal modal-slide-add">
<h2>
{{ l.manage_slide_form_add_title }}
</h2>
<form action="/manage/slide/add" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="slide-add-name">{{ l.manage_slide_form_label_name }}</label>
<div class="widget">
<input name="name" type="text" id="slide-add-name" required="required" />
</div>
</div>
<div class="form-group">
<label for="slide-add-type">{{ l.manage_slide_form_label_type }}</label>
<div class="widget">
<select name="type" id="slide-add-type">
<option value="url" data-input="text">{{ l.manage_slide_form_label_type_url }}</option>
<option value="video" data-input="upload">{{ l.manage_slide_form_label_type_video }}</option>
<option value="picture" data-input="upload">{{ l.manage_slide_form_label_type_picture }}</option>
</select>
</div>
</div>
<div class="form-group object-input">
<label for="slide-add-duration">{{ l.manage_slide_form_label_object }}</label>
<div class="widget">
<input type="text" name="object" id="slide-add-object-input-text" class="slide-add-object-input" />
<input type="file" name="object" id="slide-add-object-input-upload" class="slide-add-object-input hidden" disabled="disabled" />
</div>
</div>
<div class="form-group">
<label for="slide-add-duration">{{ l.manage_slide_form_label_duration }}</label>
<div class="widget">
<input type="number" name="duration" id="slide-add-duration" required="required" />
<span>{{ l.manage_slide_form_label_duration_unit }}</span>
</div>
</div>
<div class="actions">
<button type="button" class="modal-close">
{{ l.manage_slide_form_button_cancel }}
</button>
<button type="submit" class="green">
<i class="fa fa-plus icon-left"></i> {{ l.manage_slide_form_add_submit }}
</button>
</div>
</form>
</div>
<div class="modal modal-slide-edit hidden">
<h2>
{{ l.manage_slide_form_edit_submit }}
</h2>
<form action="/manage/slide/edit" method="POST">
<input type="hidden" name="id" id="slide-edit-id" />
<div class="form-group">
<label for="slide-edit-name">{{ l.manage_slide_form_label_name }}</label>
<div class="widget">
<input type="text" name="name" id="slide-edit-name" required="required" />
</div>
</div>
<div class="form-group">
<label for="slide-edit-type">{{ l.manage_slide_form_label_type }}</label>
<div class="widget">
<select id="slide-edit-type" name="type" disabled="disabled">
<option value="url" data-input="text">{{ l.manage_slide_form_label_type_url }}</option>
<option value="video" data-input="upload">{{ l.manage_slide_form_label_type_video }}</option>
<option value="picture" data-input="upload">{{ l.manage_slide_form_label_type_picture }}</option>
</select>
</div>
</div>
<div class="form-group">
<label for="slide-edit-location">{{ l.manage_slide_form_label_location }}</label>
<div class="widget">
<input type="text" name="location" id="slide-edit-location" disabled="disabled" />
</div>
</div>
<div class="form-group">
<label for="slide-edit-duration">{{ l.manage_slide_form_label_duration }}</label>
<div class="widget">
<input type="number" name="duration" id="slide-edit-duration" required="required" />
<span>{{ l.manage_slide_form_label_duration_unit }}</span>
</div>
</div>
<div class="actions">
<button type="button" class="modal-close">
{{ l.manage_slide_form_button_cancel }}
</button>
<button type="submit" class="green">
<i class="fa fa-save icon-left"></i>{{ l.manage_slide_form_edit_submit }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
var l = {'manage_slide_delete_confirmation': '{{ l.manage_slide_delete_confirmation }}'};
</script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="data/www/js/tablednd-fixed.js"></script>
<script src="data/www/js/manage.js"></script>
</body>
</html>

62
views/manager/base.jinja.html Executable file
View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="{{ LANG }}">
<head>
<title>
Obscreen - {% block page_title %}{% endblock %}
</title>
<meta name="robots" content="noindex, nofollow">
<meta name="google" content="notranslate">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="{{ STATIC_PREFIX }}css/main.css" />
{% block add_css %}{% endblock %}
</head>
<body>
<div class="container">
{% block header %}
<header>
<h1 class="logo">
<img src="{{ STATIC_PREFIX }}img/logo.png" />
Obscreen
</h1>
<menu>
<ul>
<li class="{{ 'active' if request.url_rule.endpoint == 'manage' }}">
<a href="{{ url_for('manage') }}">
<i class="fa-regular fa-clock"></i> {{ l.manage_page_title }}
</a>
</li>
{# <li class="{{ 'active' if request.url_rule.endpoint == 'manage_settings' }}">#}
{# <a href="#">#}
{# <i class="fa-solid fa-gear"></i> {{ l.settings_page_title }}#}
{# </a>#}
{# </li>#}
<li class="{{ 'active' if request.url_rule.endpoint == 'manage_sysinfo' }}">
<a href="{{ url_for('manage_sysinfo') }}">
<i class="fa-solid fa-list-check"></i> {{ l.sysinfo_page_title }}
</a>
</li>
</ul>
</menu>
</header>
{% endblock %}
{% block page %}
{% endblock %}
{% block footer %}
<footer></footer>
{% endblock %}
</div>
<script>
var l = {'js_manage_slide_delete_confirmation': '{{ l.manage_slide_delete_confirmation }}'};
</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 %}
</body>
</html>

View File

@ -0,0 +1,59 @@
<table class="{{ tclass }}-slides">
<thead>
<tr>
<th>{{ l.manage_slide_panel_th_name }}</th>
<th class="tac">{{ l.manage_slide_panel_th_duration }}</th>
<th class="tac">{{ l.manage_slide_panel_th_enabled }}</th>
<th class="tac">{{ l.manage_slide_panel_th_activity }}</th>
</tr>
</thead>
<tbody>
<tr class="empty-tr {% if slides|length != 0 %}hidden{% endif %}">
<td colspan="4">
{{ l.manage_slide_panel_empty|replace(
'%link%',
('<a href="javascript:void(0);" class="slide-add">'~l.manage_slide_button_add~'</a>')|safe
) }}
</td>
</tr>
{% for slide in slides %}
<tr class="slide-item" data-level="{{ slide.id }}" data-entity="{{ slide.to_json() }}">
<td class="infos">
<div class="inner">
<a href="javascript:void(0);" class="slide-sort">
<i class="fa fa-sort icon-left"></i>
</a>
{% set icon_type = 'globe' %}
{% if slide.type == 'video' %}
{% set icon_type = 'video' %}
{% elif slide.type == 'picture' %}
{% set icon_type = 'image' %}
{% endif %}
<i class="fa fa-{{ icon_type }} icon-left"></i>
{{ slide.name }}
</div>
</td>
<td class="tac">
{{ slide.duration }} {{ l.manage_slide_panel_th_duration_unit }}
</td>
<td class="tac">
<label class="pure-material-switch">
<input type="checkbox" {% if slide.enabled %}checked="checked"{% endif %}><span></span>
</label>
</td>
<td class="actions tac">
<a href="javascript:void(0);" class="slide-edit">
<i class="fa fa-pencil"></i>
</a>
<a href="{{ slide.location }}" class="slide-download" target="_blank">
<i class="fa fa-eye"></i>
</a>
<a href="javascript:void(0);" class="slide-delete">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,52 @@
{% extends 'manager/base.jinja.html' %}
{% block page_title %}
{{ l.manage_page_title }}
{% endblock %}
{% block add_js %}
<script src="{{ STATIC_PREFIX }}js/tablednd-fixed.js"></script>
<script src="{{ STATIC_PREFIX }}js/manage.js"></script>
{% endblock %}
{% block page %}
<div class="toolbar">
<h2>{{ l.manage_page_title }}</h2>
<div class="toolbar-actions">
<button class="purple slide-add"><i class="fa fa-plus icon-left"></i>{{ l.manage_slide_button_add }}</button>
</div>
</div>
<div class="panel">
<div class="panel-body">
<h3>{{ l.manage_slide_panel_active }}</h3>
{% with tclass='active', slides=enabled_slides %}
{% include 'manager/manage-table.jinja.html' %}
{% endwith %}
</div>
</div>
<div class="panel panel-inactive">
<div class="panel-body">
<h3>{{ l.manage_slide_panel_inactive }}</h3>
{% with tclass='inactive', slides=disabled_slides %}
{% include 'manager/manage-table.jinja.html' %}
{% endwith %}
</div>
</div>
<div class="modals hidden">
<div class="modals-outer">
<a href="javascript:void(0);" class="modal-close">
<i class="fa fa-close"></i>
</a>
<div class="modals-inner">
{% include 'manager/modal/slide-add.jinja.html' %}
{% include 'manager/modal/slide-edit.jinja.html' %}
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,50 @@
<div class="modal modal-slide-add">
<h2>
{{ l.manage_slide_form_add_title }}
</h2>
<form action="/manage/slide/add" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="slide-add-name">{{ l.manage_slide_form_label_name }}</label>
<div class="widget">
<input name="name" type="text" id="slide-add-name" required="required"/>
</div>
</div>
<div class="form-group">
<label for="slide-add-type">{{ l.manage_slide_form_label_type }}</label>
<div class="widget">
<select name="type" id="slide-add-type">
<option value="url" data-input="text">{{ l.manage_slide_form_label_type_url }}</option>
<option value="video" data-input="upload">{{ l.manage_slide_form_label_type_video }}</option>
<option value="picture" data-input="upload">{{ l.manage_slide_form_label_type_picture }}</option>
</select>
</div>
</div>
<div class="form-group object-input">
<label for="slide-add-duration">{{ l.manage_slide_form_label_object }}</label>
<div class="widget">
<input type="text" name="object" id="slide-add-object-input-text" class="slide-add-object-input"/>
<input type="file" name="object" id="slide-add-object-input-upload"
class="slide-add-object-input hidden" disabled="disabled"/>
</div>
</div>
<div class="form-group">
<label for="slide-add-duration">{{ l.manage_slide_form_label_duration }}</label>
<div class="widget">
<input type="number" name="duration" id="slide-add-duration" required="required"/>
<span>{{ l.manage_slide_form_label_duration_unit }}</span>
</div>
</div>
<div class="actions">
<button type="button" class="modal-close">
{{ l.manage_slide_form_button_cancel }}
</button>
<button type="submit" class="green">
<i class="fa fa-plus icon-left"></i> {{ l.manage_slide_form_add_submit }}
</button>
</div>
</form>
</div>

View File

@ -0,0 +1,50 @@
<div class="modal modal-slide-edit hidden">
<h2>
{{ l.manage_slide_form_edit_submit }}
</h2>
<form action="/manage/slide/edit" method="POST">
<input type="hidden" name="id" id="slide-edit-id"/>
<div class="form-group">
<label for="slide-edit-name">{{ l.manage_slide_form_label_name }}</label>
<div class="widget">
<input type="text" name="name" id="slide-edit-name" required="required"/>
</div>
</div>
<div class="form-group">
<label for="slide-edit-type">{{ l.manage_slide_form_label_type }}</label>
<div class="widget">
<select id="slide-edit-type" name="type" disabled="disabled">
<option value="url" data-input="text">{{ l.manage_slide_form_label_type_url }}</option>
<option value="video" data-input="upload">{{ l.manage_slide_form_label_type_video }}</option>
<option value="picture" data-input="upload">{{ l.manage_slide_form_label_type_picture }}</option>
</select>
</div>
</div>
<div class="form-group">
<label for="slide-edit-location">{{ l.manage_slide_form_label_location }}</label>
<div class="widget">
<input type="text" name="location" id="slide-edit-location" disabled="disabled"/>
</div>
</div>
<div class="form-group">
<label for="slide-edit-duration">{{ l.manage_slide_form_label_duration }}</label>
<div class="widget">
<input type="number" name="duration" id="slide-edit-duration" required="required"/>
<span>{{ l.manage_slide_form_label_duration_unit }}</span>
</div>
</div>
<div class="actions">
<button type="button" class="modal-close">
{{ l.manage_slide_form_button_cancel }}
</button>
<button type="submit" class="green">
<i class="fa fa-save icon-left"></i>{{ l.manage_slide_form_edit_submit }}
</button>
</div>
</form>
</div>

View File

@ -0,0 +1,35 @@
{% extends 'manager/base.jinja.html' %}
{% block page_title %}
{{ l.sysinfo_page_title }}
{% endblock %}
{% block add_js %}
{% endblock %}
{% block page %}
<div class="toolbar">
<h2>{{ l.sysinfo_page_title }}</h2>
</div>
<div class="panel">
<div class="panel-body">
<h3>{{ l.sysinfo_panel_title }}</h3>
<table class="active-slides">
<thead>
<tr>
<th>{{ l.sysinfo_panel_th_attribute }}</th>
<th>{{ l.sysinfo_panel_th_value }}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ l.sysinfo_panel_td_ipaddr }}</td>
<td>{{ ipaddr }}</td>
</tr>
</tbody>
</table>
</div>
</div>
{% endblock %}