platypush/platypush/backend/http/utils.py

135 lines
3.9 KiB
Python
Raw Normal View History

2023-07-24 00:33:39 +02:00
import collections.abc
import datetime
import json
import logging
import os
import re
from platypush.config import Config
2019-05-26 03:53:48 +02:00
from platypush.backend.http.app import template_folder
2023-07-24 00:33:39 +02:00
class HttpUtils:
"""
Common utilities used by the HTTP backend and jinja templates.
"""
2020-09-27 01:33:38 +02:00
log = logging.getLogger('platypush:web')
@staticmethod
def widget_columns_to_html_class(columns):
if not isinstance(columns, int):
2019-07-07 20:11:32 +02:00
try:
columns = int(columns)
2023-07-24 00:33:39 +02:00
except ValueError as e:
raise RuntimeError(
f'columns should be a number, got {type(columns)} ({columns})'
) from e
2019-07-07 20:11:32 +02:00
if 1 <= columns <= 12:
2023-07-24 00:33:39 +02:00
return f'col-{columns}'
2019-07-07 20:11:32 +02:00
2023-07-24 00:33:39 +02:00
raise RuntimeError(
'Constraint violation: should be 1 <= columns <= 12, '
f'got columns={columns}'
)
@staticmethod
def search_directory(directory, *extensions, recursive=False):
files = []
if recursive:
2023-07-24 00:33:39 +02:00
for root, _, files in os.walk(directory):
for file in files:
2023-07-24 00:33:39 +02:00
if (
not extensions
or os.path.splitext(file)[1].lower() in extensions
):
files.append(os.path.join(root, file))
else:
for file in os.listdir(directory):
if not extensions or os.path.splitext(file)[1].lower() in extensions:
files.append(os.path.join(directory, file))
return files
@classmethod
def search_web_directory(cls, directory, *extensions):
directory = os.path.abspath(os.path.expanduser(directory))
resource_dirs = (Config.get('backend.http') or {}).get('resource_dirs', {})
resource_path = None
uri = ''
for name, resource_path in resource_dirs.items():
resource_path = os.path.abspath(os.path.expanduser(resource_path))
if directory.startswith(resource_path):
uri = '/resources/' + name
break
if not uri:
2023-07-24 00:33:39 +02:00
raise RuntimeError(
(
'Directory {} not found among the available '
+ 'static resources on the webserver'
).format(directory)
)
results = [
2023-07-24 00:33:39 +02:00
re.sub(fr'^{resource_path}(.*)$', uri + '\\1', path)
for path in cls.search_directory(directory, *extensions)
]
return results
@classmethod
def to_json(cls, data):
def json_parse(x):
2023-07-24 00:33:39 +02:00
if isinstance(x, datetime.timedelta):
return x.days * 24 * 60 * 60 + x.seconds + x.microseconds / 1e6
# Ignore non-serializable attributes
2023-07-24 00:33:39 +02:00
cls.log.warning('Non-serializable attribute type "%s": %s', type(x), x)
return None
2023-07-24 00:33:39 +02:00
if isinstance(data, collections.abc.KeysView):
2019-05-15 09:31:04 +02:00
# Convert dict_keys to list before serializing
data = list(data)
return json.dumps(data, default=json_parse)
@classmethod
def from_json(cls, data):
return json.loads(data)
@classmethod
def get_config(cls, attr):
return Config.get(attr)
@classmethod
def plugin_name_to_tag(cls, module_name):
2021-04-05 00:58:44 +02:00
return module_name.replace('.', '-')
2019-05-26 03:53:48 +02:00
@classmethod
def find_templates_in_dir(cls, directory):
2021-04-05 00:58:44 +02:00
# noinspection PyTypeChecker
2019-05-26 03:53:48 +02:00
return [
os.path.join(directory, file)
2023-07-24 00:33:39 +02:00
for _, __, files in os.walk(
os.path.abspath(os.path.join(template_folder, directory))
)
2019-05-26 03:53:48 +02:00
for file in files
if file.endswith('.html') or file.endswith('.htm')
]
@classmethod
def readfile(cls, file):
with open(file) as f:
return f.read()
2019-07-07 20:11:32 +02:00
@classmethod
def isfile(cls, *path):
path = path[0] if len(path) == 1 else os.path.join(*path)
return os.path.isfile(path)
2023-07-24 00:33:39 +02:00
# vim:sw=4:ts=4:et: