Commit ccd30bff authored by Martin Matějek's avatar Martin Matějek

Refactor jinja env creation and usage in module

Use one jinja env per plugin for all notifications that belongs to it
parent 067b72c7
......@@ -44,7 +44,7 @@ class Api:
raise NotADirectoryError("Missing persistent messages directory {}".format(persistent_dir))
self.plugins = PluginStorage(plugin_dir, templates_dir)
self.notifications = NotificationStorage(volatile_dir, persistent_dir)
self.notifications = NotificationStorage(volatile_dir, persistent_dir, self.plugins)
def get_notifications(self, media_type='simple', lang='en'):
"""Return all notifications"""
......
......@@ -56,7 +56,7 @@ class Notification:
return n
@classmethod
def from_file(cls, path):
def from_file(cls, path, plugin_storage):
"""Load notification from it's file and return new instance"""
try:
with open(path, 'r') as f:
......@@ -68,7 +68,12 @@ class Notification:
logger.warning("Failed to deserialize json file: %s", e)
return None
skel_obj = NotificationSkeleton(**json_data['skeleton'])
skel_args = json_data['skeleton']
plug = plugin_storage.get_plugin(skel_args['plugin_name'])
skel_args['jinja_env'] = plug.get_jinja_env()
skel_obj = NotificationSkeleton(**skel_args)
json_data['skeleton'] = skel_obj # replace json data with skeleton instance
return cls(**json_data)
......
import gettext
import jinja2
import yaml
class NotificationSkeleton:
ATTRS = ['name', 'plugin_name', 'version', 'template', 'actions', 'template_dirs', 'timeout', 'severity', 'persistent', 'explicit_dismiss']
ATTRS = ['name', 'plugin_name', 'version', 'template', 'actions', 'timeout', 'severity', 'persistent', 'explicit_dismiss']
DEFAULT_ATTRS = ['timeout', 'severity', 'persistent', 'explicit_dismiss']
def __init__(self, name, plugin_name, version, template, actions, template_dirs, timeout=None, severity='info', persistent=False, explicit_dismiss=True):
def __init__(self, name, plugin_name, version, template, actions, jinja_env, timeout=None, severity='info', persistent=False, explicit_dismiss=True):
self.name = name
self.plugin_name = plugin_name
self.version = version
self.template = template
self.actions = actions
self.template_dirs = template_dirs
self.jinja_env = jinja_env
self.timeout = timeout
self.severity = severity
self.persistent = persistent
self.explicit_dismiss = explicit_dismiss
self.init_jinja_env()
self.setup_jinja_env()
self.translations = {}
def get_media_types(self):
......@@ -57,20 +56,8 @@ class NotificationSkeleton:
pa['name']: pa['title'] for pa in parsed['actions'] if pa['name'] in self.actions
}
def init_jinja_env(self):
"""
Init jinja environment
Prepare template for later use
For now it will be initiated when creating new skeleton instance
"""
template_loader = jinja2.FileSystemLoader(self.template_dirs)
self.jinja_env = jinja2.Environment(
loader=template_loader,
autoescape=True,
extensions=['jinja2.ext.i18n']
)
def setup_jinja_env(self):
"""Prepare templates for later use"""
self.jinja_message_template = self.jinja_env.get_template(self.template['src'])
plugin_template = '{}.yml'.format(self.plugin_name)
......
......@@ -14,11 +14,12 @@ class NotificationStorage:
"""In-memory notification storage that serialize and deserialize them"""
SHORTID_LENGTH = 8
def __init__(self, volatile_dir, persistent_dir):
def __init__(self, volatile_dir, persistent_dir, plugin_storage):
self.storage_dirs = {
'persistent': persistent_dir,
'volatile': volatile_dir,
}
self.plugin_storage = plugin_storage
self.notifications = {}
self.shortid_map = {}
......@@ -54,7 +55,7 @@ class NotificationStorage:
"""Deserialize all notifications from FS"""
logger.debug("Deserializing notifications from '%s'", storage_dir)
for filepath in glob.glob(os.path.join(storage_dir, '*.json')):
n = Notification.from_file(filepath)
n = Notification.from_file(filepath, self.plugin_storage)
if n:
self.notifications[n.notif_id] = n
......
import logging
import os
import pathlib
import jinja2
import yaml
logger = logging.getLogger(__name__)
......@@ -13,8 +16,9 @@ class Plugin:
# 'notifications' section is intentionally omitted for now
# until mandatory and optional attributes check for 'notifications' is implemented
def __init__(self, name, actions, templates, notifications):
def __init__(self, name, template_dirs, actions, templates, notifications):
self.name = name
self.template_dirs = template_dirs
self.actions = {}
self.templates = {}
self.notification_types = {}
......@@ -30,8 +34,10 @@ class Plugin:
logger.debug("concrete notif: %s", n)
self.notification_types[n['name']] = n
self.init_jinja_env()
@classmethod
def from_file(cls, filepath):
def from_file(cls, filepath, plugin_dir, templates_dir):
try:
with open(filepath, 'r') as f:
data = yaml.safe_load(f)
......@@ -52,7 +58,12 @@ class Plugin:
# Get only file name without suffix
filename = pathlib.Path(filepath).stem
return cls(filename, **data)
# TODO: fix absolute plugin_dir path
jinja_template_dirs = [
os.path.join(templates_dir, filename),
os.path.join(os.getcwd(), plugin_dir),
]
return cls(filename, jinja_template_dirs, **data)
@classmethod
def valid_schema(cls, data):
......@@ -75,6 +86,14 @@ class Plugin:
return True
def init_jinja_env(self):
template_loader = jinja2.FileSystemLoader(self.template_dirs)
self.jinja_env = jinja2.Environment(
loader=template_loader,
autoescape=True,
extensions=['jinja2.ext.i18n']
)
def get_actions(self):
return self.actions
......@@ -84,6 +103,9 @@ class Plugin:
def get_notification_types(self):
return self.notification_types
def get_jinja_env(self):
return self.jinja_env
def __str__(self):
"""For debug purposes"""
out = "{\n"
......
......@@ -26,7 +26,7 @@ class PluginStorage:
def load(self):
"""Load plugins from FS"""
for filepath in glob.glob(os.path.join(self.plugin_dir, '*.yml')):
p = Plugin.from_file(filepath)
p = Plugin.from_file(filepath, self.plugin_dir, self.templates_dir)
if p:
self.plugins[p.name] = p
......@@ -99,10 +99,7 @@ class PluginStorage:
if attr in skeleton:
notification_args[attr] = skeleton[attr]
notification_args['template_dirs'] = [
os.path.join(self.templates_dir, plugin_name),
os.path.join(os.getcwd(), self.plugin_dir),
]
notification_args['jinja_env'] = plugin.get_jinja_env()
return NotificationSkeleton(**notification_args)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment