rename manager > composer > studio

This commit is contained in:
jr-k 2024-05-23 10:39:15 +02:00
parent 389b6ad717
commit f5af0e34d9
28 changed files with 205 additions and 205 deletions

View File

@ -6,7 +6,7 @@
**⭐️ You liked it ? Give this repository a star, it's free :)** **⭐️ You liked it ? Give this repository a star, it's free :)**
## About ## About
Use a RaspberryPi (Lite OS) to show a full-screen slideshow (Kiosk-mode) Use a RaspberryPi (Lite OS) to show a fullscreen slideshow (Kiosk-mode)
[![Docker Pulls](https://badgen.net/docker/pulls/jierka/obscreen?icon=docker&label=docker%20pulls)](https://hub.docker.com/r/jierka/obscreen/) [![Docker Pulls](https://badgen.net/docker/pulls/jierka/obscreen?icon=docker&label=docker%20pulls)](https://hub.docker.com/r/jierka/obscreen/)

View File

@ -1,6 +1,6 @@
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
const $tableActive = $('table.active-screens'); const $tableActive = $('table.active-studios');
const $tableInactive = $('table.inactive-screens'); const $tableInactive = $('table.inactive-studios');
const $modalsRoot = $('.modals'); const $modalsRoot = $('.modals');
const getId = function ($el) { const getId = function ($el) {
@ -9,7 +9,7 @@ jQuery(document).ready(function ($) {
const updateTable = function () { const updateTable = function () {
$('table').each(function () { $('table').each(function () {
if ($(this).find('tbody tr.screen-item:visible').length === 0) { if ($(this).find('tbody tr.studio-item:visible').length === 0) {
$(this).find('tr.empty-tr').removeClass('hidden'); $(this).find('tr.empty-tr').removeClass('hidden');
} else { } else {
$(this).find('tr.empty-tr').addClass('hidden'); $(this).find('tr.empty-tr').addClass('hidden');
@ -30,13 +30,13 @@ jQuery(document).ready(function ($) {
const updatePositions = function (table, row) { const updatePositions = function (table, row) {
const positions = {}; const positions = {};
$('.screen-item').each(function (index) { $('.studio-item').each(function (index) {
positions[getId($(this))] = index; positions[getId($(this))] = index;
}); });
$.ajax({ $.ajax({
method: 'POST', method: 'POST',
url: '/fleet/screen/position', url: '/fleet/studio/position',
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},
data: JSON.stringify(positions), data: JSON.stringify(positions),
}); });
@ -44,14 +44,14 @@ jQuery(document).ready(function ($) {
const main = function () { const main = function () {
$("table").tableDnD({ $("table").tableDnD({
dragHandle: 'td a.screen-sort', dragHandle: 'td a.studio-sort',
onDrop: updatePositions onDrop: updatePositions
}); });
}; };
$(document).on('change', 'input[type=checkbox]', function () { $(document).on('change', 'input[type=checkbox]', function () {
$.ajax({ $.ajax({
url: '/fleet/screen/toggle', url: '/fleet/studio/toggle',
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},
data: JSON.stringify({id: getId($(this)), enabled: $(this).is(':checked')}), data: JSON.stringify({id: getId($(this)), enabled: $(this).is(':checked')}),
method: 'POST', method: 'POST',
@ -68,16 +68,16 @@ jQuery(document).ready(function ($) {
updateTable(); updateTable();
}); });
$(document).on('change', '#screen-add-type', function () { $(document).on('change', '#studio-add-type', function () {
const value = $(this).val(); const value = $(this).val();
const inputType = $(this).find('option').filter(function (i, el) { const inputType = $(this).find('option').filter(function (i, el) {
return $(el).val() === value; return $(el).val() === value;
}).data('input'); }).data('input');
$('.screen-add-object-input') $('.studio-add-object-input')
.addClass('hidden') .addClass('hidden')
.prop('disabled', true) .prop('disabled', true)
.filter('#screen-add-object-input-' + inputType) .filter('#studio-add-object-input-' + inputType)
.removeClass('hidden') .removeClass('hidden')
.prop('disabled', false) .prop('disabled', false)
; ;
@ -87,29 +87,29 @@ jQuery(document).ready(function ($) {
hideModal(); hideModal();
}); });
$(document).on('click', '.screen-add', function () { $(document).on('click', '.studio-add', function () {
showModal('modal-screen-add'); showModal('modal-studio-add');
$('.modal-screen-add input:eq(0)').focus().select(); $('.modal-studio-add input:eq(0)').focus().select();
}); });
$(document).on('click', '.screen-edit', function () { $(document).on('click', '.studio-edit', function () {
const screen = JSON.parse($(this).parents('tr:eq(0)').attr('data-entity')); const studio = JSON.parse($(this).parents('tr:eq(0)').attr('data-entity'));
showModal('modal-screen-edit'); showModal('modal-studio-edit');
$('.modal-screen-edit input:visible:eq(0)').focus().select(); $('.modal-studio-edit input:visible:eq(0)').focus().select();
$('#screen-edit-name').val(screen.name); $('#studio-edit-name').val(studio.name);
$('#screen-edit-host').val(screen.host); $('#studio-edit-host').val(studio.host);
$('#screen-edit-port').val(screen.port); $('#studio-edit-port').val(studio.port);
$('#screen-edit-id').val(screen.id); $('#studio-edit-id').val(studio.id);
}); });
$(document).on('click', '.screen-delete', function () { $(document).on('click', '.studio-delete', function () {
if (confirm(l.js_fleet_screen_delete_confirmation)) { if (confirm(l.js_fleet_studio_delete_confirmation)) {
const $tr = $(this).parents('tr:eq(0)'); const $tr = $(this).parents('tr:eq(0)');
$tr.remove(); $tr.remove();
updateTable(); updateTable();
$.ajax({ $.ajax({
method: 'DELETE', method: 'DELETE',
url: '/fleet/screen/delete', url: '/fleet/studio/delete',
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},
data: JSON.stringify({id: getId($(this))}), data: JSON.stringify({id: getId($(this))}),
}); });

View File

@ -73,16 +73,16 @@ python ./obscreen.py
#### Start server forever with systemctl #### Start server forever with systemctl
```bash ```bash
cat "$(pwd)/system/obscreen-composer.service" | sed "s#/home/pi#$HOME#g" | sed "s#=pi#=$USER#g" | sudo tee /etc/systemd/system/obscreen-composer.service cat "$(pwd)/system/obscreen-studio.service" | sed "s#/home/pi#$HOME#g" | sed "s#=pi#=$USER#g" | sudo tee /etc/systemd/system/obscreen-studio.service
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl enable obscreen-composer.service sudo systemctl enable obscreen-studio.service
sudo systemctl start obscreen-composer.service sudo systemctl start obscreen-studio.service
``` ```
#### Troubleshoot #### Troubleshoot
```bash ```bash
# Watch logs with following command # Watch logs with following command
sudo journalctl -u obscreen-composer -f sudo journalctl -u obscreen-studio -f
``` ```
--- ---
## 👌 Usage ## 👌 Usage

View File

@ -87,16 +87,16 @@ python ./obscreen.py
#### Start server forever with systemctl #### Start server forever with systemctl
```bash ```bash
cat "$(pwd)/system/obscreen-composer.service" | sed "s#/home/pi#$HOME#g" | sed "s#=pi#=$USER#g" | sudo tee /etc/systemd/system/obscreen-composer.service cat "$(pwd)/system/obscreen-studio.service" | sed "s#/home/pi#$HOME#g" | sed "s#=pi#=$USER#g" | sudo tee /etc/systemd/system/obscreen-studio.service
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl enable obscreen-composer.service sudo systemctl enable obscreen-studio.service
sudo systemctl start obscreen-composer.service sudo systemctl start obscreen-studio.service
``` ```
#### Troubleshoot #### Troubleshoot
```bash ```bash
# Watch logs with following command # Watch logs with following command
sudo journalctl -u obscreen-composer -f sudo journalctl -u obscreen-studio -f
``` ```
--- ---
## 🏁 Finally ## 🏁 Finally

View File

@ -57,26 +57,26 @@
"js_playlist_delete_confirmation": "Are you sure?", "js_playlist_delete_confirmation": "Are you sure?",
"playlist_delete_has_slides": "Playlist has slides, please remove them before and retry", "playlist_delete_has_slides": "Playlist has slides, please remove them before and retry",
"fleet_page_title": "Composers", "fleet_page_title": "Studios",
"fleet_screen_button_add": "Add a screen", "fleet_studio_button_add": "Add a studio",
"fleet_screen_button_fleetview": "Fleet view", "fleet_studio_button_fleetview": "Fleet view",
"fleet_screen_panel_active": "Active screens", "fleet_studio_panel_active": "Active studios",
"fleet_screen_panel_inactive": "Inactive screens", "fleet_studio_panel_inactive": "Inactive studios",
"fleet_screen_panel_empty": "Currently, there are no screens. %link% now.", "fleet_studio_panel_empty": "Currently, there are no studios. %link% now.",
"fleet_screen_panel_th_name": "Name", "fleet_studio_panel_th_name": "Name",
"fleet_screen_panel_th_host": "Host", "fleet_studio_panel_th_host": "Host",
"fleet_screen_panel_th_port": "Port", "fleet_studio_panel_th_port": "Port",
"fleet_screen_panel_th_enabled": "Enabled", "fleet_studio_panel_th_enabled": "Enabled",
"fleet_screen_panel_th_activity": "Activity", "fleet_studio_panel_th_activity": "Activity",
"fleet_screen_form_add_title": "Add Screen", "fleet_studio_form_add_title": "Add Studio",
"fleet_screen_form_add_submit": "Add", "fleet_studio_form_add_submit": "Add",
"fleet_screen_form_edit_title": "Edit Screen", "fleet_studio_form_edit_title": "Edit Studio",
"fleet_screen_form_edit_submit": "Save", "fleet_studio_form_edit_submit": "Save",
"fleet_screen_form_label_name": "Name", "fleet_studio_form_label_name": "Name",
"fleet_screen_form_label_host": "Host", "fleet_studio_form_label_host": "Host",
"fleet_screen_form_label_port": "Port", "fleet_studio_form_label_port": "Port",
"fleet_screen_form_button_cancel": "Cancel", "fleet_studio_form_button_cancel": "Cancel",
"js_fleet_screen_delete_confirmation": "Are you sure?", "js_fleet_studio_delete_confirmation": "Are you sure?",
"login_page_title": "Login", "login_page_title": "Login",
"auth_page_title": "Users", "auth_page_title": "Users",
@ -110,10 +110,10 @@
"settings_variable_form_button_cancel": "Cancel", "settings_variable_form_button_cancel": "Cancel",
"settings_variable_desc_lang": "Server language", "settings_variable_desc_lang": "Server language",
"settings_variable_desc_playlist_enabled": "Enable playlist management", "settings_variable_desc_playlist_enabled": "Enable playlist management",
"settings_variable_desc_fleet_composer_enabled": "Enable fleet composer management", "settings_variable_desc_fleet_studio_enabled": "Enable fleet studio management",
"settings_variable_desc_auth_enabled": "Enable auth management", "settings_variable_desc_auth_enabled": "Enable auth management",
"settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin", "settings_variable_desc_edition_auth_enabled": "Default user credentials will be admin/admin",
"settings_variable_desc_external_url": "External url (i.e: https://screen-01.company.com or http://10.10.3.100)", "settings_variable_desc_external_url": "External url (i.e: https://studio-01.company.com or http://10.10.3.100)",
"settings_variable_desc_slide_upload_limit": "Slide upload limit (in megabytes)", "settings_variable_desc_slide_upload_limit": "Slide upload limit (in megabytes)",
"settings_variable_desc_default_slide_duration": "Intro slide duration (in seconds)", "settings_variable_desc_default_slide_duration": "Intro slide duration (in seconds)",
"settings_variable_desc_polling_interval": "Refresh interval applied for settings to the player (in seconds)", "settings_variable_desc_polling_interval": "Refresh interval applied for settings to the player (in seconds)",

View File

@ -57,26 +57,26 @@
"js_playlist_delete_confirmation": "Êtes-vous sûr ?", "js_playlist_delete_confirmation": "Êtes-vous sûr ?",
"playlist_delete_has_slides": "La liste de lecture contient des sldies, supprimez-les avant et réessayez", "playlist_delete_has_slides": "La liste de lecture contient des sldies, supprimez-les avant et réessayez",
"fleet_page_title": "Composeurs", "fleet_page_title": "Studios",
"fleet_screen_button_add": "Ajouter un écran", "fleet_studio_button_add": "Ajouter un studio",
"fleet_screen_button_fleetview": "Vue flotte", "fleet_studio_button_fleetview": "Vue flotte",
"fleet_screen_panel_active": "Écrans actifs", "fleet_studio_panel_active": "Studios actifs",
"fleet_screen_panel_inactive": "Écrans inactifs", "fleet_studio_panel_inactive": "Studios inactifs",
"fleet_screen_panel_empty": "Actuellement, il n'y a pas d'écrans. %link% maintenant.", "fleet_studio_panel_empty": "Actuellement, il n'y a pas de studios. %link% maintenant.",
"fleet_screen_panel_th_name": "Nom", "fleet_studio_panel_th_name": "Nom",
"fleet_screen_panel_th_host": "Hôte", "fleet_studio_panel_th_host": "Hôte",
"fleet_screen_panel_th_port": "Port", "fleet_studio_panel_th_port": "Port",
"fleet_screen_panel_th_enabled": "Activé", "fleet_studio_panel_th_enabled": "Activé",
"fleet_screen_panel_th_activity": "Options", "fleet_studio_panel_th_activity": "Options",
"fleet_screen_form_add_title": "Ajout d'un écran", "fleet_studio_form_add_title": "Ajout d'un studio",
"fleet_screen_form_add_submit": "Ajouter", "fleet_studio_form_add_submit": "Ajouter",
"fleet_screen_form_edit_title": "Modification d'un écran", "fleet_studio_form_edit_title": "Modification d'un studio",
"fleet_screen_form_edit_submit": "Enregistrer", "fleet_studio_form_edit_submit": "Enregistrer",
"fleet_screen_form_label_name": "Nom", "fleet_studio_form_label_name": "Nom",
"fleet_screen_form_label_host": "Hôte", "fleet_studio_form_label_host": "Hôte",
"fleet_screen_form_label_port": "Port", "fleet_studio_form_label_port": "Port",
"fleet_screen_form_button_cancel": "Annuler", "fleet_studio_form_button_cancel": "Annuler",
"js_fleet_screen_delete_confirmation": "Êtes-vous sûr ?", "js_fleet_studio_delete_confirmation": "Êtes-vous sûr ?",
"login_page_title": "Connexion", "login_page_title": "Connexion",
"auth_page_title": "Utilisateurs", "auth_page_title": "Utilisateurs",
@ -110,10 +110,10 @@
"settings_variable_form_button_cancel": "Annuler", "settings_variable_form_button_cancel": "Annuler",
"settings_variable_desc_lang": "Langage de l'application", "settings_variable_desc_lang": "Langage de l'application",
"settings_variable_desc_playlist_enabled": "Activer la gestion des playlists", "settings_variable_desc_playlist_enabled": "Activer la gestion des playlists",
"settings_variable_desc_fleet_composer_enabled": "Activer la gestion de flotte des composeurs", "settings_variable_desc_fleet_studio_enabled": "Activer la gestion de flotte des studios",
"settings_variable_desc_auth_enabled": "Activer la gestion de l'authentification", "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_edition_auth_enabled": "Les identifiants de l'utilisateur par défaut seront admin/admin",
"settings_variable_desc_external_url": "URL externe (i.e: https://screen-01.company.com or http://10.10.3.100)", "settings_variable_desc_external_url": "URL externe (i.e: https://studio-01.company.com or http://10.10.3.100)",
"settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)", "settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en mégaoctets)",
"settings_variable_desc_default_slide_duration": "Durée de la slide d'introduction (en secondes)", "settings_variable_desc_default_slide_duration": "Durée de la slide d'introduction (en secondes)",
"settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)", "settings_variable_desc_polling_interval": "Intervalle de rafraîchissement des paramètres à appliquer au lecteur (en secondes)",

View File

@ -7,13 +7,13 @@ from src.model.enum.HookType import HookType
from src.model.hook.HookRegistration import HookRegistration from src.model.hook.HookRegistration import HookRegistration
class FleetmodeScreenRestart(ObPlugin): class FleetmodeStudioRestart(ObPlugin):
def use_id(self): def use_id(self):
return 'fleetmode_screen_restart' return 'fleetmode_studio_restart'
def use_title(self): def use_title(self):
return 'Fleetmode Screen Restart' return 'Fleetmode Studio Restart'
def use_variables(self) -> List[Variable]: def use_variables(self) -> List[Variable]:
return [ return [

View File

@ -1,2 +1,2 @@
<button class="normal sysinfo-restart"><i class="fa fa-refresh icon-left"></i>{{ l.fleetmode_screen_restart_button_restart }}</button> <button class="normal sysinfo-restart"><i class="fa fa-refresh icon-left"></i>{{ l.fleetmode_studio_restart_button_restart }}</button>

View File

@ -2,7 +2,7 @@ import json
from flask import Flask, render_template, redirect, request, url_for, jsonify from flask import Flask, render_template, redirect, request, url_for, jsonify
from src.service.ModelStore import ModelStore from src.service.ModelStore import ModelStore
from src.model.entity.Screen import Screen from src.model.entity.Studio import Studio
from src.interface.ObController import ObController from src.interface.ObController import ObController
@ -10,7 +10,7 @@ class FleetController(ObController):
def guard_fleet(self, f): def guard_fleet(self, f):
def decorated_function(*args, **kwargs): def decorated_function(*args, **kwargs):
if not self._model_store.variable().map().get('fleet_composer_enabled').as_bool(): if not self._model_store.variable().map().get('fleet_studio_enabled').as_bool():
return redirect(url_for('manage')) return redirect(url_for('manage'))
return f(*args, **kwargs) return f(*args, **kwargs)
@ -18,49 +18,49 @@ class FleetController(ObController):
def register(self): def register(self):
self._app.add_url_rule('/fleet', 'fleet', self.guard_fleet(self._auth(self.fleet)), methods=['GET']) self._app.add_url_rule('/fleet', 'fleet', self.guard_fleet(self._auth(self.fleet)), methods=['GET'])
self._app.add_url_rule('/fleet/screen/list', 'fleet_screen_list', self.guard_fleet(self._auth(self.fleet_screen_list)), methods=['GET']) self._app.add_url_rule('/fleet/studio/list', 'fleet_studio_list', self.guard_fleet(self._auth(self.fleet_studio_list)), methods=['GET'])
self._app.add_url_rule('/fleet/screen/add', 'fleet_screen_add', self.guard_fleet(self._auth(self.fleet_screen_add)), methods=['POST']) self._app.add_url_rule('/fleet/studio/add', 'fleet_studio_add', self.guard_fleet(self._auth(self.fleet_studio_add)), methods=['POST'])
self._app.add_url_rule('/fleet/screen/edit', 'fleet_screen_edit', self.guard_fleet(self._auth(self.fleet_screen_edit)), methods=['POST']) self._app.add_url_rule('/fleet/studio/edit', 'fleet_studio_edit', self.guard_fleet(self._auth(self.fleet_studio_edit)), methods=['POST'])
self._app.add_url_rule('/fleet/screen/toggle', 'fleet_screen_toggle', self.guard_fleet(self._auth(self.fleet_screen_toggle)), methods=['POST']) self._app.add_url_rule('/fleet/studio/toggle', 'fleet_studio_toggle', self.guard_fleet(self._auth(self.fleet_studio_toggle)), methods=['POST'])
self._app.add_url_rule('/fleet/screen/delete', 'fleet_screen_delete', self.guard_fleet(self._auth(self.fleet_screen_delete)), methods=['DELETE']) self._app.add_url_rule('/fleet/studio/delete', 'fleet_studio_delete', self.guard_fleet(self._auth(self.fleet_studio_delete)), methods=['DELETE'])
self._app.add_url_rule('/fleet/screen/position', 'fleet_screen_position', self.guard_fleet(self._auth(self.fleet_screen_position)), methods=['POST']) self._app.add_url_rule('/fleet/studio/position', 'fleet_studio_position', self.guard_fleet(self._auth(self.fleet_studio_position)), methods=['POST'])
def fleet(self): def fleet(self):
return render_template( return render_template(
'fleet/fleet.jinja.html', 'fleet/fleet.jinja.html',
screens=self._model_store.screen().get_enabled_screens(), studios=self._model_store.studio().get_enabled_studios(),
) )
def fleet_screen_list(self): def fleet_studio_list(self):
return render_template( return render_template(
'fleet/list.jinja.html', 'fleet/list.jinja.html',
enabled_screens=self._model_store.screen().get_enabled_screens(), enabled_studios=self._model_store.studio().get_enabled_studios(),
disabled_screens=self._model_store.screen().get_disabled_screens(), disabled_studios=self._model_store.studio().get_disabled_studios(),
) )
def fleet_screen_add(self): def fleet_studio_add(self):
self._model_store.screen().add_form(Screen( self._model_store.studio().add_form(Studio(
name=request.form['name'], name=request.form['name'],
host=request.form['host'], host=request.form['host'],
port=request.form['port'], port=request.form['port'],
)) ))
return redirect(url_for('fleet_screen_list')) return redirect(url_for('fleet_studio_list'))
def fleet_screen_edit(self): def fleet_studio_edit(self):
self._model_store.screen().update_form(request.form['id'], request.form['name'], request.form['host'], request.form['port']) self._model_store.studio().update_form(request.form['id'], request.form['name'], request.form['host'], request.form['port'])
return redirect(url_for('fleet_screen_list')) return redirect(url_for('fleet_studio_list'))
def fleet_screen_toggle(self): def fleet_studio_toggle(self):
data = request.get_json() data = request.get_json()
self._model_store.screen().update_enabled(data.get('id'), data.get('enabled')) self._model_store.studio().update_enabled(data.get('id'), data.get('enabled'))
return jsonify({'status': 'ok'}) return jsonify({'status': 'ok'})
def fleet_screen_delete(self): def fleet_studio_delete(self):
data = request.get_json() data = request.get_json()
self._model_store.screen().delete(data.get('id')) self._model_store.studio().delete(data.get('id'))
return jsonify({'status': 'ok'}) return jsonify({'status': 'ok'})
def fleet_screen_position(self): def fleet_studio_position(self):
data = request.get_json() data = request.get_json()
self._model_store.screen().update_positions(data) self._model_store.studio().update_positions(data)
return jsonify({'status': 'ok'}) return jsonify({'status': 'ok'})

View File

@ -33,7 +33,7 @@ class SettingsController(ObController):
if variable.name == 'slide_upload_limit': if variable.name == 'slide_upload_limit':
self.reload_web_server() self.reload_web_server()
if variable.name == 'fleet_composer_enabled': if variable.name == 'fleet_studio_enabled':
self.reload_web_server() self.reload_web_server()
if variable.name == 'auth_enabled': if variable.name == 'auth_enabled':

View File

@ -63,7 +63,7 @@ class SysinfoController(ObController):
os.execl(python, python, *sys.argv) os.execl(python, python, *sys.argv)
else: else:
try: try:
subprocess.run(["sudo", "systemctl", "restart", 'obscreen-composer'], check=True, timeout=10, stdout=subprocess.PIPE, stderr=subprocess.PIPE) subprocess.run(["sudo", "systemctl", "restart", 'obscreen-studio'], check=True, timeout=10, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
pass pass
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
pass pass

View File

@ -1,15 +1,15 @@
from typing import Dict, Optional, List, Tuple, Union from typing import Dict, Optional, List, Tuple, Union
from src.model.entity.Screen import Screen from src.model.entity.Studio import Studio
from src.manager.DatabaseManager import DatabaseManager from src.manager.DatabaseManager import DatabaseManager
from src.manager.LangManager import LangManager from src.manager.LangManager import LangManager
from src.manager.UserManager import UserManager from src.manager.UserManager import UserManager
from src.service.ModelManager import ModelManager from src.service.ModelManager import ModelManager
class ScreenManager(ModelManager): class StudioManager(ModelManager):
TABLE_NAME = "fleet" TABLE_NAME = "fleet_studio"
TABLE_MODEL = [ TABLE_MODEL = [
"name CHAR(255)", "name CHAR(255)",
"enabled INTEGER DEFAULT 0", "enabled INTEGER DEFAULT 0",
@ -22,23 +22,23 @@ class ScreenManager(ModelManager):
super().__init__(lang_manager, database_manager, user_manager) super().__init__(lang_manager, database_manager, user_manager)
self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL) self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL)
def hydrate_object(self, raw_screen: dict, id: Optional[int] = None) -> Screen: def hydrate_object(self, raw_studio: dict, id: Optional[int] = None) -> Studio:
if id: if id:
raw_screen['id'] = id raw_studio['id'] = id
return Screen(**raw_screen) return Studio(**raw_studio)
def hydrate_list(self, raw_screens: list) -> List[Screen]: def hydrate_list(self, raw_studios: list) -> List[Studio]:
return [self.hydrate_object(raw_screen) for raw_screen in raw_screens] return [self.hydrate_object(raw_studio) for raw_studio in raw_studios]
def get(self, id: int) -> Optional[Screen]: def get(self, id: int) -> Optional[Studio]:
object = self._db.get_by_id(self.TABLE_NAME, id) object = self._db.get_by_id(self.TABLE_NAME, id)
return self.hydrate_object(object, id) if object else None return self.hydrate_object(object, id) if object else None
def get_by(self, query, sort: Optional[str] = None) -> List[Screen]: def get_by(self, query, sort: Optional[str] = None) -> List[Studio]:
return self.hydrate_list(self._db.get_by_query(self.TABLE_NAME, query=query, sort=sort)) return self.hydrate_list(self._db.get_by_query(self.TABLE_NAME, query=query, sort=sort))
def get_one_by(self, query) -> Optional[Screen]: def get_one_by(self, query) -> Optional[Studio]:
object = self._db.get_one_by_query(self.TABLE_NAME, query=query) object = self._db.get_one_by_query(self.TABLE_NAME, query=query)
if not object: if not object:
@ -46,30 +46,30 @@ class ScreenManager(ModelManager):
return self.hydrate_object(object) return self.hydrate_object(object)
def get_all(self, sort: bool = False) -> List[Screen]: def get_all(self, sort: bool = False) -> List[Studio]:
return self.hydrate_list(self._db.get_all(self.TABLE_NAME, "position" if sort else None)) return self.hydrate_list(self._db.get_all(self.TABLE_NAME, "position" if sort else None))
def get_enabled_screens(self) -> List[Screen]: def get_enabled_studios(self) -> List[Studio]:
return self.get_by(query="enabled = 1", sort="position") return self.get_by(query="enabled = 1", sort="position")
def get_disabled_screens(self) -> List[Screen]: def get_disabled_studios(self) -> List[Studio]:
return self.get_by(query="enabled = 0", sort="position") return self.get_by(query="enabled = 0", sort="position")
def update_enabled(self, id: int, enabled: bool) -> None: def update_enabled(self, id: int, enabled: bool) -> None:
self._db.update_by_id(self.TABLE_NAME, id, {"enabled": enabled, "position": 999}) self._db.update_by_id(self.TABLE_NAME, id, {"enabled": enabled, "position": 999})
def update_positions(self, positions: list) -> None: def update_positions(self, positions: list) -> None:
for screen_id, screen_position in positions.items(): for studio_id, studio_position in positions.items():
self._db.update_by_id(self.TABLE_NAME, screen_id, {"position": screen_position}) self._db.update_by_id(self.TABLE_NAME, studio_id, {"position": studio_position})
def update_form(self, id: int, name: str, host: str, port: int) -> None: def update_form(self, id: int, name: str, host: str, port: int) -> None:
self._db.update_by_id(self.TABLE_NAME, id, {"name": name, "host": host, "port": port}) self._db.update_by_id(self.TABLE_NAME, id, {"name": name, "host": host, "port": port})
def add_form(self, screen: Union[Screen, Dict]) -> None: def add_form(self, studio: Union[Studio, Dict]) -> None:
form = screen form = studio
if not isinstance(screen, dict): if not isinstance(studio, dict):
form = screen.to_dict() form = studio.to_dict()
del form['id'] del form['id']
self._db.add(self.TABLE_NAME, form) self._db.add(self.TABLE_NAME, form)
@ -77,5 +77,5 @@ class ScreenManager(ModelManager):
def delete(self, id: int) -> None: def delete(self, id: int) -> None:
self._db.delete_by_id(self.TABLE_NAME, id) self._db.delete_by_id(self.TABLE_NAME, id)
def to_dict(self, screens: List[Screen]) -> List[Dict]: def to_dict(self, studios: List[Studio]) -> List[Dict]:
return [screen.to_dict() for screen in screens] return [studio.to_dict() for studio in studios]

View File

@ -104,7 +104,7 @@ class VariableManager(ModelManager):
### General ### General
{"name": "lang", "section": self.t(VariableSection.GENERAL), "value": "en", "type": VariableType.SELECT_SINGLE, "editable": True, "description": self.t('settings_variable_desc_lang'), "selectables": self.t(ApplicationLanguage), "refresh_player": False}, {"name": "lang", "section": self.t(VariableSection.GENERAL), "value": "en", "type": VariableType.SELECT_SINGLE, "editable": True, "description": self.t('settings_variable_desc_lang'), "selectables": self.t(ApplicationLanguage), "refresh_player": False},
{"name": "auth_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_auth_enabled'), "description_edition": self.t('settings_variable_desc_edition_auth_enabled'), "refresh_player": False}, {"name": "auth_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_auth_enabled'), "description_edition": self.t('settings_variable_desc_edition_auth_enabled'), "refresh_player": False},
{"name": "fleet_composer_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_fleet_composer_enabled'), "refresh_player": False}, {"name": "fleet_studio_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_fleet_studio_enabled'), "refresh_player": False},
{"name": "playlist_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_playlist_enabled'), "refresh_player": False}, {"name": "playlist_enabled", "section": self.t(VariableSection.GENERAL), "value": False, "type": VariableType.BOOL, "editable": True, "description": self.t('settings_variable_desc_playlist_enabled'), "refresh_player": False},
{"name": "external_url", "section": self.t(VariableSection.GENERAL), "value": "", "type": VariableType.STRING, "editable": True, "description": self.t('settings_variable_desc_external_url'), "refresh_player": False}, {"name": "external_url", "section": self.t(VariableSection.GENERAL), "value": "", "type": VariableType.STRING, "editable": True, "description": self.t('settings_variable_desc_external_url'), "refresh_player": False},
{"name": "slide_upload_limit", "section": self.t(VariableSection.GENERAL), "value": 32, "unit": VariableUnit.MEGABYTE, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_slide_upload_limit'), "refresh_player": False}, {"name": "slide_upload_limit", "section": self.t(VariableSection.GENERAL), "value": 32, "unit": VariableUnit.MEGABYTE, "type": VariableType.INT, "editable": True, "description": self.t('settings_variable_desc_slide_upload_limit'), "refresh_player": False},

View File

@ -3,7 +3,7 @@ import json
from typing import Optional, Union from typing import Optional, Union
class Screen: class Studio:
def __init__(self, host: str = '', port: int = 5000, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[int] = None): def __init__(self, host: str = '', port: int = 5000, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[int] = None):
self._id = id if id else None self._id = id if id else None
@ -58,7 +58,7 @@ class Screen:
self._position = value self._position = value
def __str__(self) -> str: def __str__(self) -> str:
return f"Screen(" \ return f"Studio(" \
f"id='{self.id}',\n" \ f"id='{self.id}',\n" \
f"name='{self.name}',\n" \ f"name='{self.name}',\n" \
f"enabled='{self.enabled}',\n" \ f"enabled='{self.enabled}',\n" \

View File

@ -1,6 +1,6 @@
from src.manager.PlaylistManager import PlaylistManager from src.manager.PlaylistManager import PlaylistManager
from src.manager.SlideManager import SlideManager from src.manager.SlideManager import SlideManager
from src.manager.ScreenManager import ScreenManager from src.manager.StudioManager import StudioManager
from src.manager.UserManager import UserManager from src.manager.UserManager import UserManager
from src.manager.VariableManager import VariableManager from src.manager.VariableManager import VariableManager
from src.manager.LangManager import LangManager from src.manager.LangManager import LangManager
@ -26,7 +26,7 @@ class ModelStore:
self._logging_manager = LoggingManager(config_manager=self._config_manager) self._logging_manager = LoggingManager(config_manager=self._config_manager)
# Model # Model
self._screen_manager = ScreenManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager) self._studio_manager = StudioManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager)
self._playlist_manager = PlaylistManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager) self._playlist_manager = PlaylistManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager)
self._slide_manager = SlideManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager) self._slide_manager = SlideManager(lang_manager=self._lang_manager, database_manager=self._database_manager, user_manager=self._user_manager)
self._variable_manager.reload() self._variable_manager.reload()
@ -49,8 +49,8 @@ class ModelStore:
def playlist(self) -> PlaylistManager: def playlist(self) -> PlaylistManager:
return self._playlist_manager return self._playlist_manager
def screen(self) -> ScreenManager: def studio(self) -> StudioManager:
return self._screen_manager return self._studio_manager
def lang(self) -> LangManager: def lang(self) -> LangManager:
return self._lang_manager return self._lang_manager

View File

@ -26,7 +26,7 @@ class TemplateRenderer:
globals = dict( globals = dict(
STATIC_PREFIX="/{}/{}/".format(WebDirConstant.FOLDER_STATIC, WebDirConstant.FOLDER_STATIC_WEB_ASSETS), STATIC_PREFIX="/{}/{}/".format(WebDirConstant.FOLDER_STATIC, WebDirConstant.FOLDER_STATIC_WEB_ASSETS),
SECRET_KEY=self._model_store.config().map().get('secret_key'), SECRET_KEY=self._model_store.config().map().get('secret_key'),
FLEET_COMPOSER_ENABLED=self._model_store.variable().map().get('fleet_composer_enabled').as_bool(), FLEET_STUDIO_ENABLED=self._model_store.variable().map().get('fleet_studio_enabled').as_bool(),
AUTH_ENABLED=self._model_store.variable().map().get('auth_enabled').as_bool(), AUTH_ENABLED=self._model_store.variable().map().get('auth_enabled').as_bool(),
PLAYLIST_ENABLED=self._model_store.variable().map().get('playlist_enabled').as_bool(), PLAYLIST_ENABLED=self._model_store.variable().map().get('playlist_enabled').as_bool(),
track_created=self._model_store.user().track_user_created, track_created=self._model_store.user().track_user_created,

View File

@ -1,5 +1,5 @@
[Unit] [Unit]
Description=Obscreen Composer Description=Obscreen Studio
After=network.target After=network.target
[Service] [Service]

View File

@ -63,10 +63,10 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% if FLEET_COMPOSER_ENABLED %} {% if FLEET_STUDIO_ENABLED %}
<li class="{{ 'active' if request.url_rule.endpoint == 'fleet_screen_list' }}"> <li class="{{ 'active' if request.url_rule.endpoint == 'fleet_studio_list' }}">
<a href="{{ url_for('fleet_screen_list') }}"> <a href="{{ url_for('fleet_studio_list') }}">
<i class="fa fa-tv"></i> {{ l.fleet_page_title }} <i class="fa fa-server"></i> {{ l.fleet_page_title }}
</a> </a>
</li> </li>
{% endif %} {% endif %}
@ -124,7 +124,7 @@
var l = { var l = {
'js_playlist_delete_confirmation': '{{ l.js_playlist_delete_confirmation }}', 'js_playlist_delete_confirmation': '{{ l.js_playlist_delete_confirmation }}',
'js_slideshow_slide_delete_confirmation': '{{ l.js_slideshow_slide_delete_confirmation }}', 'js_slideshow_slide_delete_confirmation': '{{ l.js_slideshow_slide_delete_confirmation }}',
'js_fleet_screen_delete_confirmation': '{{ l.js_fleet_screen_delete_confirmation }}', 'js_fleet_studio_delete_confirmation': '{{ l.js_fleet_studio_delete_confirmation }}',
'js_auth_user_delete_confirmation': '{{ l.js_auth_user_delete_confirmation }}', 'js_auth_user_delete_confirmation': '{{ l.js_auth_user_delete_confirmation }}',
'js_sysinfo_restart_confirmation': '{{ l.js_sysinfo_restart_confirmation }}', 'js_sysinfo_restart_confirmation': '{{ l.js_sysinfo_restart_confirmation }}',
'js_sysinfo_restart_loading': '{{ l.js_sysinfo_restart_loading }}' 'js_sysinfo_restart_loading': '{{ l.js_sysinfo_restart_loading }}'

View File

@ -1,55 +1,55 @@
<table class="{{ tclass }}-screens"> <table class="{{ tclass }}-studios">
<thead> <thead>
<tr> <tr>
<th>{{ l.fleet_screen_panel_th_name }}</th> <th>{{ l.fleet_studio_panel_th_name }}</th>
<th class="tac">{{ l.fleet_screen_panel_th_host }}</th> <th class="tac">{{ l.fleet_studio_panel_th_host }}</th>
<th class="tac">{{ l.fleet_screen_panel_th_port }}</th> <th class="tac">{{ l.fleet_studio_panel_th_port }}</th>
<th class="tac">{{ l.fleet_screen_panel_th_enabled }}</th> <th class="tac">{{ l.fleet_studio_panel_th_enabled }}</th>
<th class="tac">{{ l.fleet_screen_panel_th_activity }}</th> <th class="tac">{{ l.fleet_studio_panel_th_activity }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="empty-tr {% if screens|length != 0 %}hidden{% endif %}"> <tr class="empty-tr {% if studios|length != 0 %}hidden{% endif %}">
<td colspan="4"> <td colspan="4">
{{ l.fleet_screen_panel_empty|replace( {{ l.fleet_studio_panel_empty|replace(
'%link%', '%link%',
('<a href="javascript:void(0);" class="item-add screen-add">'~l.fleet_screen_button_add~'</a>')|safe ('<a href="javascript:void(0);" class="item-add studio-add">'~l.fleet_studio_button_add~'</a>')|safe
) }} ) }}
</td> </td>
</tr> </tr>
{% for screen in screens %} {% for studio in studios %}
<tr class="screen-item" data-level="{{ screen.id }}" data-entity="{{ screen.to_json() }}"> <tr class="studio-item" data-level="{{ studio.id }}" data-entity="{{ studio.to_json() }}">
<td class="infos"> <td class="infos">
<div class="inner"> <div class="inner">
<a href="javascript:void(0);" class="item-sort screen-sort"> <a href="javascript:void(0);" class="item-sort studio-sort">
<i class="fa fa-sort icon-left"></i> <i class="fa fa-sort icon-left"></i>
</a> </a>
<div class="badge"><i class="fa fa-key icon-left"></i> {{ screen.id }}</div> <div class="badge"><i class="fa fa-key icon-left"></i> {{ studio.id }}</div>
<i class="fa fa-tv icon-left"></i> <i class="fa fa-server icon-left"></i>
{{ screen.name }} {{ studio.name }}
</div> </div>
</td> </td>
<td class="tac"> <td class="tac">
{{ screen.host }} {{ studio.host }}
</td> </td>
<td class="tac"> <td class="tac">
{{ screen.port }} {{ studio.port }}
</td> </td>
<td class="tac"> <td class="tac">
<label class="pure-material-switch"> <label class="pure-material-switch">
<input type="checkbox" {% if screen.enabled %}checked="checked"{% endif %}><span></span> <input type="checkbox" {% if studio.enabled %}checked="checked"{% endif %}><span></span>
</label> </label>
</td> </td>
<td class="actions tac"> <td class="actions tac">
<a href="javascript:void(0);" class="item-edit screen-edit"> <a href="javascript:void(0);" class="item-edit studio-edit">
<i class="fa fa-pencil"></i> <i class="fa fa-pencil"></i>
</a> </a>
<a href="http://{{ screen.host }}:{{ screen.port }}" class="item-download screen-download" target="_blank"> <a href="http://{{ studio.host }}:{{ studio.port }}" class="item-download studio-download" target="_blank">
<i class="fa fa-eye"></i> <i class="fa fa-eye"></i>
</a> </a>
<a href="javascript:void(0);" class="item-delete screen-delete"> <a href="javascript:void(0);" class="item-delete studio-delete">
<i class="fa fa-trash"></i> <i class="fa fa-trash"></i>
</a> </a>
</td> </td>

View File

@ -9,39 +9,39 @@
ul li a {flex:1;display: flex;flex-direction: row;justify-content: center;align-items: center;padding: 20px 5px;color:#0eef5f;font-weight: bold;text-decoration: none;} ul li a {flex:1;display: flex;flex-direction: row;justify-content: center;align-items: center;padding: 20px 5px;color:#0eef5f;font-weight: bold;text-decoration: none;}
ul li.active a { background: #0eef5f;color:white; } ul li.active a { background: #0eef5f;color:white; }
main {display: flex;flex:1;} main {display: flex;flex:1;}
main .screen-frame {display: flex; flex:1;} main .studio-frame {display: flex; flex:1;}
main .screen-frame iframe {display: flex; flex: 1;} main .studio-frame iframe {display: flex; flex: 1;}
.hidden {display: none !important;} .hidden {display: none !important;}
</style> </style>
</head> </head>
<body> <body>
<ul> <ul>
{% for screen in screens %} {% for studio in studios %}
<li class="{% if loop.first %}active{% endif %}"> <li class="{% if loop.first %}active{% endif %}">
<a href="javascript:void(0);" class="screen-switch" data-id="{{ screen.id }}" onclick="tab('{{ screen.id }}')"> <a href="javascript:void(0);" class="studio-switch" data-id="{{ studio.id }}" onclick="tab('{{ studio.id }}')">
{{ screen.name }} {{ studio.name }}
</a> </a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
<main> <main>
{% for screen in screens %} {% for studio in studios %}
<div class="screen-frame {% if not loop.first %}hidden{% endif %}" data-id="{{ screen.id }}"> <div class="studio-frame {% if not loop.first %}hidden{% endif %}" data-id="{{ studio.id }}">
<iframe src="http://{{ screen.host }}:{{ screen.port }}/slideshow?fleet_mode=1" frameborder="0" allowtransparency=""></iframe> <iframe src="http://{{ studio.host }}:{{ studio.port }}/slideshow?fleet_mode=1" frameborder="0" allowtransparency=""></iframe>
</div> </div>
{% endfor %} {% endfor %}
</main> </main>
<script type="text/javascript"> <script type="text/javascript">
const tab = function(id) { const tab = function(id) {
const $switches = document.getElementsByClassName('screen-switch'); const $switches = document.getElementsByClassName('studio-switch');
const $frames = document.getElementsByClassName('screen-frame'); const $frames = document.getElementsByClassName('studio-frame');
for (let i = 0; i < $switches.length; i++) { for (let i = 0; i < $switches.length; i++) {
const $switch = $switches[i]; const $switch = $switches[i];
$switch.parentElement.className = $switch.dataset.id === id ? 'active' : ''; $switch.parentElement.className = $switch.dataset.id === id ? 'active' : '';
} }
for (let j = 0; j < $frames.length; j++) { for (let j = 0; j < $frames.length; j++) {
const $frame = $frames[j]; const $frame = $frames[j];
$frame.className = $frame.dataset.id === id ? 'screen-frame' : 'screen-frame hidden'; $frame.className = $frame.dataset.id === id ? 'studio-frame' : 'studio-frame hidden';
} }
document.location.hash = id; document.location.hash = id;
}; };

View File

@ -10,7 +10,7 @@
{% block add_js %} {% block add_js %}
<script src="{{ STATIC_PREFIX }}js/lib/tablednd-fixed.js"></script> <script src="{{ STATIC_PREFIX }}js/lib/tablednd-fixed.js"></script>
<script src="{{ STATIC_PREFIX }}js/fleet/screens.js"></script> <script src="{{ STATIC_PREFIX }}js/fleet/studios.js"></script>
{{ HOOK(H_FLEET_JAVASCRIPT) }} {{ HOOK(H_FLEET_JAVASCRIPT) }}
{% endblock %} {% endblock %}
@ -20,25 +20,25 @@
<div class="toolbar-actions"> <div class="toolbar-actions">
{{ HOOK(H_FLEET_TOOLBAR_ACTIONS_START) }} {{ HOOK(H_FLEET_TOOLBAR_ACTIONS_START) }}
<a class="btn normal" href="{{ url_for('fleet') }}" target="_blank"><i class="fa fa-table icon-left"></i>{{ l.fleet_screen_button_fleetview }}</a> <a class="btn normal" href="{{ url_for('fleet') }}" target="_blank"><i class="fa fa-table icon-left"></i>{{ l.fleet_studio_button_fleetview }}</a>
<button class="purple screen-add item-add"><i class="fa fa-plus icon-left"></i>{{ l.fleet_screen_button_add }}</button> <button class="purple studio-add item-add"><i class="fa fa-plus icon-left"></i>{{ l.fleet_studio_button_add }}</button>
{{ HOOK(H_FLEET_TOOLBAR_ACTIONS_END) }} {{ HOOK(H_FLEET_TOOLBAR_ACTIONS_END) }}
</div> </div>
</div> </div>
<div class="panel"> <div class="panel">
<div class="panel-body"> <div class="panel-body">
<h3>{{ l.fleet_screen_panel_active }}</h3> <h3>{{ l.fleet_studio_panel_active }}</h3>
{% with tclass='active', screens=enabled_screens %} {% with tclass='active', studios=enabled_studios %}
{% include 'fleet/component/table.jinja.html' %} {% include 'fleet/component/table.jinja.html' %}
{% endwith %} {% endwith %}
</div> </div>
</div> </div>
<div class="panel panel-inactive"> <div class="panel panel-inactive">
<div class="panel-body"> <div class="panel-body">
<h3>{{ l.fleet_screen_panel_inactive }}</h3> <h3>{{ l.fleet_studio_panel_inactive }}</h3>
{% with tclass='inactive', screens=disabled_screens %} {% with tclass='inactive', studios=disabled_studios %}
{% include 'fleet/component/table.jinja.html' %} {% include 'fleet/component/table.jinja.html' %}
{% endwith %} {% endwith %}
</div> </div>

View File

@ -1,36 +1,36 @@
<div class="modal modal-screen-add"> <div class="modal modal-studio-add">
<h2> <h2>
{{ l.fleet_screen_form_add_title }} {{ l.fleet_studio_form_add_title }}
</h2> </h2>
<form action="/fleet/screen/add" method="POST" enctype="multipart/form-data"> <form action="/fleet/studio/add" method="POST" enctype="multipart/form-data">
<div class="form-group"> <div class="form-group">
<label for="screen-add-name">{{ l.fleet_screen_form_label_name }}</label> <label for="studio-add-name">{{ l.fleet_studio_form_label_name }}</label>
<div class="widget"> <div class="widget">
<input name="name" type="text" id="screen-add-name" required="required" /> <input name="name" type="text" id="studio-add-name" required="required" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="screen-add-host">{{ l.fleet_screen_form_label_host }}</label> <label for="studio-add-host">{{ l.fleet_studio_form_label_host }}</label>
<div class="widget"> <div class="widget">
<input type="text" name="host" id="screen-add-host" required="required" /> <input type="text" name="host" id="studio-add-host" required="required" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="screen-add-port">{{ l.fleet_screen_form_label_port }}</label> <label for="studio-add-port">{{ l.fleet_studio_form_label_port }}</label>
<div class="widget"> <div class="widget">
<input type="number" name="port" id="screen-add-port" required="required" /> <input type="number" name="port" id="studio-add-port" required="required" />
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">
<button type="button" class="btn-normal modal-close"> <button type="button" class="btn-normal modal-close">
{{ l.fleet_screen_form_button_cancel }} {{ l.fleet_studio_form_button_cancel }}
</button> </button>
<button type="submit" class="green"> <button type="submit" class="green">
<i class="fa fa-plus icon-left"></i> {{ l.fleet_screen_form_add_submit }} <i class="fa fa-plus icon-left"></i> {{ l.fleet_studio_form_add_submit }}
</button> </button>
</div> </div>
</form> </form>

View File

@ -1,38 +1,38 @@
<div class="modal modal-screen-edit hidden"> <div class="modal modal-studio-edit hidden">
<h2> <h2>
{{ l.fleet_screen_form_edit_title }} {{ l.fleet_studio_form_edit_title }}
</h2> </h2>
<form action="/fleet/screen/edit" method="POST"> <form action="/fleet/studio/edit" method="POST">
<input type="hidden" name="id" id="screen-edit-id" /> <input type="hidden" name="id" id="studio-edit-id" />
<div class="form-group"> <div class="form-group">
<label for="screen-edit-name">{{ l.fleet_screen_form_label_name }}</label> <label for="studio-edit-name">{{ l.fleet_studio_form_label_name }}</label>
<div class="widget"> <div class="widget">
<input type="text" name="name" id="screen-edit-name" required="required" /> <input type="text" name="name" id="studio-edit-name" required="required" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="screen-edit-host">{{ l.fleet_screen_form_label_host }}</label> <label for="studio-edit-host">{{ l.fleet_studio_form_label_host }}</label>
<div class="widget"> <div class="widget">
<input type="text" name="host" id="screen-edit-host" required="required" /> <input type="text" name="host" id="studio-edit-host" required="required" />
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="screen-edit-port">{{ l.fleet_screen_form_label_port }}</label> <label for="studio-edit-port">{{ l.fleet_studio_form_label_port }}</label>
<div class="widget"> <div class="widget">
<input type="number" name="port" id="screen-edit-port" required="required" /> <input type="number" name="port" id="studio-edit-port" required="required" />
</div> </div>
</div> </div>
<div class="actions"> <div class="actions">
<button type="button" class="btn-normal modal-close"> <button type="button" class="btn-normal modal-close">
{{ l.fleet_screen_form_button_cancel }} {{ l.fleet_studio_form_button_cancel }}
</button> </button>
<button type="submit" class="green"> <button type="submit" class="green">
<i class="fa fa-save icon-left"></i>{{ l.fleet_screen_form_edit_submit }} <i class="fa fa-save icon-left"></i>{{ l.fleet_studio_form_edit_submit }}
</button> </button>
</div> </div>
</form> </form>