Merge pull request #20 from jr-k/core/custom-max-upload-size
Allow custom max upload size
This commit is contained in:
commit
4674e43bb1
@ -65,6 +65,7 @@
|
||||
"settings_variable_desc_lang": "Server language",
|
||||
"settings_variable_desc_fleet_enabled": "Enable fleet screen management view",
|
||||
"settings_variable_desc_external_url": "External url (i.e: https://screen-01.company.com or http://10.10.3.100)",
|
||||
"settings_variable_desc_slide_upload_limit": "Slide upload limit (in bytes, 32*1024*1024 for 32MB)",
|
||||
|
||||
"settings_variable_desc_slide_animation_enabled": "Enable animation effect between slides",
|
||||
"settings_variable_desc_slide_animation_entrance_effect": "Slide animation entrance effect",
|
||||
|
||||
@ -65,6 +65,7 @@
|
||||
"settings_variable_desc_lang": "Langage de l'application",
|
||||
"settings_variable_desc_fleet_enabled": "Activer la gestion de flotte des écrans",
|
||||
"settings_variable_desc_external_url": "URL externe (i.e: https://screen-01.company.com or http://10.10.3.100)",
|
||||
"settings_variable_desc_slide_upload_limit": "Limite d'upload du fichier d'une slide (en octets, 32*1024*1024 pour 32Mo)",
|
||||
|
||||
"settings_variable_desc_slide_animation_enabled": "Activer les effets d'animation entre les slides",
|
||||
"settings_variable_desc_slide_animation_entrance_effect": "Effet d'animation d'arrivée de la slide",
|
||||
|
||||
@ -5,6 +5,7 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
from typing import Optional, List, Dict, Union
|
||||
from src.model.entity.Variable import Variable
|
||||
from src.model.enum.VariableType import VariableType
|
||||
from src.model.enum.VariableUnit import VariableUnit
|
||||
from src.model.enum.HookType import HookType
|
||||
from src.model.hook.HookRegistration import HookRegistration
|
||||
from src.model.hook.StaticHookRegistration import StaticHookRegistration
|
||||
@ -55,13 +56,14 @@ class ObPlugin(abc.ABC):
|
||||
def get_plugin_variable_name(self, name: str) -> str:
|
||||
return "{}_{}".format(self.get_plugin_variable_prefix(), name)
|
||||
|
||||
def add_variable(self, name: str, value='', type: VariableType = VariableType.STRING, editable: bool = True, description: str = '', selectables: Optional[Dict[str, str]] = None) -> Variable:
|
||||
def add_variable(self, name: str, value='', type: VariableType = VariableType.STRING, editable: bool = True, description: str = '', selectables: Optional[Dict[str, str]] = None, unit: Optional[VariableUnit] = None) -> Variable:
|
||||
return self._model_store.variable().set_variable(
|
||||
name=self.get_plugin_variable_name(name),
|
||||
value=value,
|
||||
type=type,
|
||||
editable=editable,
|
||||
description=description,
|
||||
unit=unit,
|
||||
selectables=selectables if isinstance(selectables, dict) else None,
|
||||
plugin=self.use_id(),
|
||||
)
|
||||
|
||||
33
src/manager/DatabaseManager.py
Normal file
33
src/manager/DatabaseManager.py
Normal file
@ -0,0 +1,33 @@
|
||||
import json
|
||||
import sys
|
||||
|
||||
from pysondb import PysonDB
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class DatabaseManager:
|
||||
|
||||
DB_DIR = 'data/db'
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def open(self, table_name: str, table_model: list) -> PysonDB:
|
||||
db_file = "{}/{}.json".format(self.DB_DIR, table_name)
|
||||
db = PysonDB(db_file)
|
||||
db = self._update_model(db_file, table_model)
|
||||
return db
|
||||
|
||||
@staticmethod
|
||||
def _update_model(db_file: str, table_model: list) -> Optional[PysonDB]:
|
||||
try:
|
||||
with open(db_file, 'r') as file:
|
||||
db_model = file.read()
|
||||
db_model = json.loads(db_model)
|
||||
db_model['keys'] = table_model
|
||||
with open(db_file, 'w') as file:
|
||||
file.write(json.dumps(db_model, indent=4))
|
||||
return PysonDB(db_file)
|
||||
except FileNotFoundError:
|
||||
logging.error("Database file {} not found".format(db_file))
|
||||
return None
|
||||
@ -1,15 +1,24 @@
|
||||
from typing import Dict, Optional, List, Tuple, Union
|
||||
from src.model.entity.Screen import Screen
|
||||
from pysondb import PysonDB
|
||||
from pysondb.errors import IdDoesNotExistError
|
||||
from typing import Dict, Optional, List, Tuple, Union
|
||||
|
||||
from src.model.entity.Screen import Screen
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
|
||||
|
||||
class ScreenManager:
|
||||
|
||||
DB_FILE = "data/db/fleet.json"
|
||||
TABLE_NAME = "fleet"
|
||||
TABLE_MODEL = [
|
||||
"name",
|
||||
"enabled",
|
||||
"position",
|
||||
"host",
|
||||
"port"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self._db = PysonDB(self.DB_FILE)
|
||||
def __init__(self, database_manager: DatabaseManager):
|
||||
self._database_manager = database_manager
|
||||
self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL)
|
||||
|
||||
@staticmethod
|
||||
def hydrate_object(raw_screen: dict, id: Optional[str] = None) -> Screen:
|
||||
|
||||
@ -1,18 +1,29 @@
|
||||
import os
|
||||
|
||||
from typing import Dict, Optional, List, Tuple, Union
|
||||
from pysondb.errors import IdDoesNotExistError
|
||||
|
||||
from src.model.entity.Slide import Slide
|
||||
from src.utils import str_to_enum, get_optional_string
|
||||
from pysondb import PysonDB
|
||||
from pysondb.errors import IdDoesNotExistError
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
|
||||
|
||||
class SlideManager:
|
||||
|
||||
DB_FILE = "data/db/slideshow.json"
|
||||
TABLE_NAME = "slideshow"
|
||||
TABLE_MODEL = [
|
||||
"name",
|
||||
"type",
|
||||
"enabled",
|
||||
"duration",
|
||||
"position",
|
||||
"location",
|
||||
"cron_schedule"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self._db = PysonDB(self.DB_FILE)
|
||||
def __init__(self, database_manager: DatabaseManager):
|
||||
self._database_manager = database_manager
|
||||
self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL)
|
||||
|
||||
@staticmethod
|
||||
def hydrate_object(raw_slide: dict, id: str = None) -> Slide:
|
||||
|
||||
@ -1,27 +1,41 @@
|
||||
import time
|
||||
from typing import Dict, Optional, List, Tuple, Union
|
||||
from pysondb.errors import IdDoesNotExistError
|
||||
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
from src.model.entity.Variable import Variable
|
||||
from src.model.entity.Selectable import Selectable
|
||||
from src.model.enum.VariableType import VariableType
|
||||
from src.model.enum.VariableUnit import VariableUnit
|
||||
from src.model.enum.AnimationEntranceEffect import AnimationEntranceEffect
|
||||
from src.model.enum.AnimationExitEffect import AnimationExitEffect
|
||||
from src.model.enum.AnimationSpeed import AnimationSpeed
|
||||
from pysondb import PysonDB
|
||||
from pysondb.errors import IdDoesNotExistError
|
||||
from src.utils import get_keys
|
||||
import time
|
||||
from src.utils import get_keys, enum_to_str
|
||||
|
||||
SELECTABLE_BOOLEAN = {"1": "✅", "0": "❌"}
|
||||
|
||||
|
||||
class VariableManager:
|
||||
|
||||
DB_FILE = "data/db/settings.json"
|
||||
TABLE_NAME = "settings"
|
||||
TABLE_MODEL = [
|
||||
"description",
|
||||
"editable",
|
||||
"name",
|
||||
"plugin",
|
||||
"selectables",
|
||||
"type",
|
||||
"unit",
|
||||
"value"
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
self._db = PysonDB(self.DB_FILE)
|
||||
def __init__(self, database_manager: DatabaseManager):
|
||||
self._database_manager = database_manager
|
||||
self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL)
|
||||
self._var_map = {}
|
||||
self.reload()
|
||||
|
||||
def set_variable(self, name: str, value, type: VariableType, editable: bool, description: str, plugin: Optional[None] = None, selectables: Optional[Dict[str, str]] = None) -> Variable:
|
||||
def set_variable(self, name: str, value, type: VariableType, editable: bool, description: str, plugin: Optional[None] = None, selectables: Optional[Dict[str, str]] = None, unit: Optional[VariableUnit] = None) -> Variable:
|
||||
if isinstance(value, bool) and value:
|
||||
value = '1'
|
||||
elif isinstance(value, bool) and not value:
|
||||
@ -37,6 +51,7 @@ class VariableManager:
|
||||
"editable": editable,
|
||||
"description": description,
|
||||
"plugin": plugin,
|
||||
"unit": unit.value if unit else None,
|
||||
"selectables": ([{"key": key, "label": label} for key, label in selectables.items()]) if isinstance(selectables, dict) else None
|
||||
}
|
||||
variable = self.get_one_by_name(default_var['name'])
|
||||
@ -50,6 +65,9 @@ class VariableManager:
|
||||
if variable.description != default_var['description']:
|
||||
self._db.update_by_id(variable.id, {"description": default_var['description']})
|
||||
|
||||
if variable.unit != default_var['unit']:
|
||||
self._db.update_by_id(variable.id, {"unit": default_var['unit']})
|
||||
|
||||
if not same_selectables:
|
||||
self._db.update_by_id(variable.id, {"selectables": default_var['selectables']})
|
||||
|
||||
@ -63,6 +81,7 @@ class VariableManager:
|
||||
{"name": "lang", "value": "en", "type": VariableType.SELECT_SINGLE, "editable": True, "description": lang_map['settings_variable_desc_lang'] if lang_map else "", "selectables": {"en": "English", "fr": "French"}},
|
||||
{"name": "fleet_enabled", "value": False, "type": VariableType.BOOL, "editable": True, "description": lang_map['settings_variable_desc_fleet_enabled'] if lang_map else ""},
|
||||
{"name": "external_url", "value": "", "type": VariableType.STRING, "editable": True, "description": lang_map['settings_variable_desc_external_url'] if lang_map else ""},
|
||||
{"name": "slide_upload_limit", "value": 32 * 1024 * 1024, "unit": VariableUnit.BYTE, "type": VariableType.INT, "editable": True, "description": lang_map['settings_variable_desc_slide_upload_limit'] if lang_map else ""},
|
||||
{"name": "slide_animation_enabled", "value": False, "type": VariableType.BOOL, "editable": True, "description": lang_map['settings_variable_desc_slide_animation_enabled'] if lang_map else ""},
|
||||
{"name": "slide_animation_entrance_effect", "value": AnimationEntranceEffect.FADE_IN.value, "type": VariableType.SELECT_SINGLE, "editable": True, "description": lang_map['settings_variable_desc_slide_animation_entrance_effect'] if lang_map else "", "selectables": AnimationEntranceEffect.get_values()},
|
||||
{"name": "slide_animation_exit_effect", "value": AnimationExitEffect.NONE.value, "type": VariableType.SELECT_SINGLE, "editable": True, "description": lang_map['settings_variable_desc_slide_animation_exit_effect'] if lang_map else "", "selectables": AnimationExitEffect.get_values()},
|
||||
|
||||
@ -3,6 +3,7 @@ import time
|
||||
|
||||
from typing import Optional, Union, Dict, List
|
||||
from src.model.enum.VariableType import VariableType
|
||||
from src.model.enum.VariableUnit import VariableUnit
|
||||
from src.model.entity.Selectable import Selectable
|
||||
from src.utils import str_to_enum
|
||||
|
||||
@ -11,10 +12,11 @@ class Variable:
|
||||
|
||||
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,
|
||||
plugin: Optional[str] = None, selectables: Optional[List[Selectable]] = None):
|
||||
plugin: Optional[str] = None, selectables: Optional[List[Selectable]] = None, unit: Optional[VariableUnit] = 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._unit = str_to_enum(unit, VariableUnit) if isinstance(unit, str) else unit
|
||||
self._description = description
|
||||
self._value = value
|
||||
self._editable = editable
|
||||
@ -52,6 +54,14 @@ class Variable:
|
||||
def type(self, value: VariableType):
|
||||
self._type = value
|
||||
|
||||
@property
|
||||
def unit(self) -> VariableUnit:
|
||||
return self._unit
|
||||
|
||||
@unit.setter
|
||||
def unit(self, value: VariableUnit):
|
||||
self._unit = value
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return self._description
|
||||
@ -90,6 +100,7 @@ class Variable:
|
||||
f"name='{self.name}',\n" \
|
||||
f"value='{self.value}',\n" \
|
||||
f"type='{self.type}',\n" \
|
||||
f"unit='{self.unit}',\n" \
|
||||
f"description='{self.description}',\n" \
|
||||
f"editable='{self.editable}',\n" \
|
||||
f"plugin='{self.plugin}',\n" \
|
||||
@ -105,6 +116,7 @@ class Variable:
|
||||
"name": self.name,
|
||||
"value": self.value,
|
||||
"type": self.type.value,
|
||||
"unit": self.unit.value if self.unit else None,
|
||||
"description": self.description,
|
||||
"editable": self.editable,
|
||||
"plugin": self.plugin,
|
||||
@ -130,7 +142,14 @@ class Variable:
|
||||
if isinstance(self._selectables, list):
|
||||
for selectable in self.selectables:
|
||||
if selectable.key == value:
|
||||
return str(selectable.label)
|
||||
value = str(selectable.label)
|
||||
break
|
||||
|
||||
if self.unit == VariableUnit.BYTE:
|
||||
value = "{} {}".format(
|
||||
value / 1024 / 1024,
|
||||
"MB"
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
6
src/model/enum/VariableUnit.py
Normal file
6
src/model/enum/VariableUnit.py
Normal file
@ -0,0 +1,6 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class VariableUnit(Enum):
|
||||
|
||||
BYTE = 'byte'
|
||||
@ -2,6 +2,7 @@ from src.manager.SlideManager import SlideManager
|
||||
from src.manager.ScreenManager import ScreenManager
|
||||
from src.manager.VariableManager import VariableManager
|
||||
from src.manager.LangManager import LangManager
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
from src.manager.ConfigManager import ConfigManager
|
||||
from src.manager.LoggingManager import LoggingManager
|
||||
|
||||
@ -9,11 +10,12 @@ from src.manager.LoggingManager import LoggingManager
|
||||
class ModelStore:
|
||||
|
||||
def __init__(self):
|
||||
self._variable_manager = VariableManager()
|
||||
self._database_manager = DatabaseManager()
|
||||
self._variable_manager = VariableManager(database_manager=self._database_manager)
|
||||
self._config_manager = ConfigManager(variable_manager=self._variable_manager)
|
||||
self._logging_manager = LoggingManager(config_manager=self._config_manager)
|
||||
self._screen_manager = ScreenManager()
|
||||
self._slide_manager = SlideManager()
|
||||
self._screen_manager = ScreenManager(database_manager=self._database_manager)
|
||||
self._slide_manager = SlideManager(database_manager=self._database_manager)
|
||||
self._lang_manager = LangManager(lang=self.variable().map().get('lang').as_string())
|
||||
self._variable_manager.reload(lang_map=self._lang_manager.map())
|
||||
|
||||
@ -26,6 +28,9 @@ class ModelStore:
|
||||
def variable(self) -> VariableManager:
|
||||
return self._variable_manager
|
||||
|
||||
def database(self) -> DatabaseManager:
|
||||
return self._database_manager
|
||||
|
||||
def slide(self) -> SlideManager:
|
||||
return self._slide_manager
|
||||
|
||||
|
||||
@ -15,8 +15,6 @@ from src.constant.WebDirConstant import WebDirConstant
|
||||
|
||||
class WebServer:
|
||||
|
||||
MAX_UPLOADS = 16 * 1024 * 1024
|
||||
|
||||
def __init__(self, project_dir: str, model_store: ModelStore, template_renderer: TemplateRenderer):
|
||||
self._project_dir = project_dir
|
||||
self._model_store = model_store
|
||||
@ -54,7 +52,7 @@ class WebServer:
|
||||
)
|
||||
|
||||
self._app.config['UPLOAD_FOLDER'] = "{}/{}".format(WebDirConstant.FOLDER_STATIC, WebDirConstant.FOLDER_STATIC_WEB_UPLOADS)
|
||||
self._app.config['MAX_CONTENT_LENGTH'] = self.MAX_UPLOADS
|
||||
self._app.config['MAX_CONTENT_LENGTH'] = self._model_store.variable().map().get('slide_upload_limit').as_int()
|
||||
|
||||
if self._debug:
|
||||
self._app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||
|
||||
@ -60,6 +60,14 @@ def get_keys(dict_or_object, key_list_name: str, key_attr_name: str = 'key') ->
|
||||
return None
|
||||
|
||||
|
||||
def enum_to_str(enum: Optional[Enum]) -> Optional[str]:
|
||||
if enum:
|
||||
print(enum)
|
||||
return str(enum.value)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def str_to_enum(str_val: str, enum_class) -> Enum:
|
||||
for enum_item in enum_class:
|
||||
if enum_item.value == str_val:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user