add plugin description + use functional hook for button update plugin + add plugin store for controllers)

This commit is contained in:
jr-k 2024-05-27 16:11:25 +02:00
parent 5a2cf1c60c
commit 34e58cad37
12 changed files with 63 additions and 22 deletions

View File

@ -750,4 +750,11 @@ a.badge:hover {
min-height: 200px;
max-height: 500px;
overflow: auto;
}
.plugin-description {
font-size: 14px;
margin-left: 34px;
color: #999;
}

View File

@ -15,6 +15,9 @@ class FleetmodeStudioRestart(ObPlugin):
def use_title(self):
return 'Fleetmode Studio Restart'
def use_description(self):
return 'Adds a restart button to fleet studio management view'
def use_variables(self) -> List[Variable]:
return [
# self.add_variable(

View File

@ -5,6 +5,7 @@ from src.model.entity.Variable import Variable
from src.model.enum.VariableType import VariableType
from src.model.enum.HookType import HookType
from src.model.hook.HookRegistration import HookRegistration
from src.utils import am_i_in_docker
class GitUpdater(ObPlugin):
@ -13,12 +14,18 @@ class GitUpdater(ObPlugin):
return 'git_updater'
def use_title(self):
return 'Git Updater (for system wide installations)'
return 'Git Updater'
def use_description(self):
return 'Adds a update button (only for system wide installations)'
def use_variables(self) -> List[Variable]:
return []
def use_hooks_registrations(self) -> List[HookRegistration]:
return [
super().add_static_hook_registration(hook=HookType.H_SYSINFO_TOOLBAR_ACTIONS_START, priority=10),
super().add_functional_hook_registration(hook=HookType.H_SYSINFO_TOOLBAR_ACTIONS_START, priority=10, function=self.hook_update_button),
]
def hook_update_button(self) -> str:
return self.render_view('@update_button.jinja.html', am_i_in_docker=am_i_in_docker)

View File

@ -1,2 +0,0 @@
<a href="{{ url_for('git_updater_update_now') }}" class="btn sysinfo-update protected"><i class="fa fa-cloud-arrow-down icon-left"></i>{{ l.git_updater_button_update }}</a>

View File

@ -0,0 +1,4 @@
{% if not am_i_in_docker() %}
<a href="{{ url_for('git_updater_update_now') }}" class="btn sysinfo-update protected"><i class="fa fa-cloud-arrow-down icon-left"></i>{{ l.git_updater_button_update }}</a>
{% endif %}

View File

@ -15,11 +15,11 @@ class Application:
def __init__(self, project_dir: str):
self._project_dir = project_dir
self._stop_event = threading.Event()
self._model_store = ModelStore()
self._model_store = ModelStore(self.get_plugins)
self._template_renderer = TemplateRenderer(project_dir=project_dir, model_store=self._model_store, render_hook=self.render_hook)
self._web_server = WebServer(project_dir=project_dir, model_store=self._model_store, template_renderer=self._template_renderer)
logging.info("[obscreen] Starting...")
logging.info("[obscreen] Starting application v{}...".format(self.get_version()))
self._plugin_store = PluginStore(project_dir=project_dir, model_store=self._model_store, template_renderer=self._template_renderer, web_server=self._web_server)
signal.signal(signal.SIGINT, self.signal_handler)
@ -35,6 +35,9 @@ class Application:
def render_hook(self, hook: HookType) -> str:
return self._template_renderer.render_hooks(self._plugin_store.map_hooks()[hook])
def get_plugins(self):
return self._plugin_store.map_plugins()
@staticmethod
def get_name() -> str:
return 'obscreen-studio'

View File

@ -15,16 +15,17 @@ class SettingsController(ObController):
def settings_variable_list(self):
return render_template(
'settings/list.jinja.html',
plugins=self._model_store.plugins(),
system_variables=self._model_store.variable().get_editable_variables(plugin=False, sort='section'),
plugin_variables=self._model_store.variable().get_editable_variables(plugin=True, sort='plugin'),
)
def settings_variable_edit(self):
self._model_store.variable().update_form(request.form['id'], request.form['value'])
forward = self._post_update(request.form['id'])
return forward if forward is not None else redirect(url_for('settings_variable_list'))
self._post_update(request.form['id'])
return redirect(url_for('settings_variable_list'))
def _post_update(self, id: int):
def _post_update(self, id: int) -> None:
variable = self._model_store.variable().get(id)
if variable.refresh_player:
@ -42,4 +43,3 @@ class SettingsController(ObController):
if variable.name == 'lang':
self._model_store.lang().set_lang(variable.value)
self._model_store.variable().reload()

View File

@ -36,6 +36,10 @@ class ObPlugin(abc.ABC):
def use_title(self) -> str:
pass
@abc.abstractmethod
def use_description(self) -> str:
pass
@abc.abstractmethod
def use_variables(self) -> List[Variable]:
pass

View File

@ -1,3 +1,5 @@
from typing import Dict
from src.manager.PlaylistManager import PlaylistManager
from src.manager.SlideManager import SlideManager
from src.manager.StudioManager import StudioManager
@ -11,7 +13,9 @@ from src.manager.LoggingManager import LoggingManager
class ModelStore:
def __init__(self):
def __init__(self, get_plugins: Dict):
self._get_plugins = get_plugins
# Pure
self._lang_manager = LangManager()
self._database_manager = DatabaseManager()
@ -58,5 +62,8 @@ class ModelStore:
def user(self) -> UserManager:
return self._user_manager
def plugins(self) -> Dict:
return self._get_plugins()
def on_user_delete(self, user_id: int) -> None:
self._slide_manager.forget_user(user_id)

View File

@ -31,10 +31,17 @@ class PluginStore:
self._hooks = self.pre_load_hooks()
self._dead_variables_candidates = VariableManager.list_to_map(self._model_store.variable().get_by_prefix(ObPlugin.PLUGIN_PREFIX))
self._system_plugins = self.find_plugins_in_directory(self.FOLDER_PLUGINS_SYSTEM)
self._system_plugins = self.find_plugins_in_directory(self.FOLDER_PLUGINS_USER)
self._user_plugins = self.find_plugins_in_directory(self.FOLDER_PLUGINS_USER)
self.post_load_hooks()
self.clean_dead_variables()
def map_plugins(self) -> Dict[str, ObPlugin]:
plugins = {}
for plugin in self._system_plugins:
plugins[plugin.use_id()] = plugin
return plugins
def map_hooks(self) -> Dict[HookType, List[HookRegistration]]:
return self._hooks
@ -150,7 +157,6 @@ class PluginStore:
# WEB CONTROLLERS
self.load_controllers(plugin)
def clean_dead_variables(self) -> None:
for variable_name, variable in self._dead_variables_candidates.items():
logging.info("Removing dead plugin variable {}".format(variable_name))
@ -161,5 +167,3 @@ class PluginStore:
logging.info("[plugin] {} {}".format("🟢" if var.as_bool() else "⚫️", plugin.use_title()))
return var.as_bool() if var else False

View File

@ -9,7 +9,7 @@ from src.model.hook.HookRegistration import HookRegistration
from src.model.hook.StaticHookRegistration import StaticHookRegistration
from src.model.hook.FunctionalHookRegistration import FunctionalHookRegistration
from src.constant.WebDirConstant import WebDirConstant
from src.utils import get_safe_cron_descriptor, is_validate_cron_date_time, seconds_to_hhmmss
from src.utils import get_safe_cron_descriptor, is_validate_cron_date_time, seconds_to_hhmmss, am_i_in_docker
class TemplateRenderer:

View File

@ -9,15 +9,18 @@
<tbody>
{% set ns = namespace(last_section='') %}
{% for variable in variables %}
{% if
variable.plugin and ns.last_section != variable.plugin
or variable.section and ns.last_section != variable.section
%}
{% set section_change = variable.plugin and ns.last_section != variable.plugin or variable.section and ns.last_section != variable.section %}
{% if section_change %}
<tr>
<td colspan="2">
<td colspan="3">
<h3>
{% if variable.is_from_plugin() %}
<i class="fa fa-puzzle-piece icon-left"></i> {{ variable.plugin.replace('_',' ')|capitalize }}
{% set plugin = plugins[variable.plugin] %}
<i class="fa fa-puzzle-piece icon-left"></i> {{ plugin.use_title() }}
{% if plugin.use_description() %}
<div class="plugin-description">{{ plugin.use_description() }}</div>
{% endif %}
{% else %}
<i class="fa fa-cog icon-left"></i> {{ variable.section }}
{% endif %}
@ -52,6 +55,7 @@
</a>
</td>
</tr>
{% if variable.is_from_plugin() %}
{% set ns.last_section = variable.plugin %}
{% else %}