forked from s3lph/matemat
Reworked and cleaned up config file integration.
This commit is contained in:
parent
a52f09fc58
commit
2dd57dcfd6
9 changed files with 63 additions and 48 deletions
|
@ -1,4 +1,2 @@
|
|||
|
||||
__version__ = '2.0'
|
||||
|
||||
from .config import parse_config_file
|
||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Dict
|
|||
|
||||
import sys
|
||||
|
||||
from matemat import parse_config_file
|
||||
from matemat.webserver import parse_config_file
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Those imports are actually needed, as they implicitly register pagelets.
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
from typing import Any, Dict
|
||||
|
||||
from configparser import ConfigParser, NoSectionError
|
||||
|
||||
|
||||
def parse_config_file(path: str) -> Dict[str, Any]:
|
||||
config: Dict[str, Any] = dict()
|
||||
|
||||
parser: ConfigParser = ConfigParser()
|
||||
parser.read(path, 'utf-8')
|
||||
if 'Matemat' not in parser.sections():
|
||||
raise NoSectionError(f'Section "matemat" missing in file {path}')
|
||||
config['listen'] = parser['Matemat'].get('Address', '::')
|
||||
config['port'] = int(parser['Matemat'].get('Port', '8080'))
|
||||
config['dbpath'] = parser['Matemat'].get('DatabaseFile', '/var/matemat/db/matemat.sqlite3')
|
||||
config['staticroot'] = parser['Matemat'].get('StaticPath', '/var/matemat/static/')
|
||||
config['templateroot'] = parser['Matemat'].get('TemplatePath', '/var/matemat/templates/')
|
||||
|
||||
config['pagelet_arguments']: Dict[str, str] = dict()
|
||||
config['pagelet_arguments']['DatabaseFile'] = config['dbpath']
|
||||
config['pagelet_arguments']['StaticPath'] = config['staticroot']
|
||||
config['pagelet_arguments']['TemplatePath'] = config['templateroot']
|
||||
|
||||
if 'Pagelets' in parser.sections():
|
||||
for k, v in parser['Pagelets'].items():
|
||||
config['pagelet_arguments'][k] = v
|
||||
|
||||
return config
|
|
@ -9,3 +9,4 @@ server will attempt to serve the request with a static resource in a previously
|
|||
from .requestargs import RequestArgument, RequestArguments
|
||||
from .responses import PageletResponse, RedirectResponse, TemplateResponse
|
||||
from .httpd import MatematWebserver, HttpHandler, pagelet
|
||||
from .config import parse_config_file
|
||||
|
|
47
matemat/webserver/config.py
Normal file
47
matemat/webserver/config.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
|
||||
from typing import Any, Dict
|
||||
|
||||
from configparser import ConfigParser
|
||||
|
||||
|
||||
def parse_config_file(path: str) -> Dict[str, Any]:
|
||||
"""
|
||||
Parse the configuration file at the given path.
|
||||
|
||||
:param path: The config file to parse.
|
||||
:return: A dictionary containing the parsed configuration.
|
||||
"""
|
||||
# Set up default values
|
||||
config: Dict[str, Any] = {
|
||||
# Address to listen on
|
||||
'listen': '::',
|
||||
# TCP port to listen on
|
||||
'port': 80,
|
||||
# Root directory of statically served content
|
||||
'staticroot': '/var/matemat/static',
|
||||
# Root directory of Jinja2 templates
|
||||
'templateroot': '/var/matemat/templates',
|
||||
# Variables passed to pagelets
|
||||
'pagelet_variables': dict()
|
||||
}
|
||||
|
||||
# Initialize the config parser
|
||||
parser: ConfigParser = ConfigParser()
|
||||
# Replace the original option transformation by a string constructor to preserve the case of config keys
|
||||
parser.optionxform = str
|
||||
# Read the configuration file
|
||||
parser.read(path, 'utf-8')
|
||||
|
||||
# Read values from the [Matemat] section, if present, falling back to default values
|
||||
if 'Matemat' in parser.sections():
|
||||
config['listen'] = parser['Matemat'].get('Address', config['listen'])
|
||||
config['port'] = int(parser['Matemat'].get('Port', config['port']))
|
||||
config['staticroot'] = parser['Matemat'].get('StaticPath', config['staticroot'])
|
||||
config['templateroot'] = parser['Matemat'].get('TemplatePath', config['templateroot'])
|
||||
|
||||
# Read all values from the [Pagelets] section, if present. These values are passed to pagelet functions
|
||||
if 'Pagelets' in parser.sections():
|
||||
for k, v in parser['Pagelets'].items():
|
||||
config['pagelet_variables'][k] = v
|
||||
|
||||
return config
|
|
@ -57,7 +57,8 @@ def pagelet(path: str):
|
|||
path: str,
|
||||
args: RequestArguments,
|
||||
session_vars: Dict[str, Any],
|
||||
headers: Dict[str, str])
|
||||
headers: Dict[str, str],
|
||||
config: Dict[str, str])
|
||||
-> Union[bytes, str, Tuple[int, str]]
|
||||
|
||||
method: The HTTP method (GET, POST) that was used.
|
||||
|
@ -65,6 +66,7 @@ def pagelet(path: str):
|
|||
args: The arguments that were passed with the request (as GET or POST arguments).
|
||||
session_vars: The session storage. May be read from and written to.
|
||||
headers: The dictionary of HTTP response headers. Add headers you wish to send with the response.
|
||||
config: The dictionary of variables read from the [Pagelets] section of the configuration file.
|
||||
returns: One of the following:
|
||||
- A HTTP Response body as str or bytes
|
||||
- A PageletResponse class instance: An instance of (a subclass of)
|
||||
|
@ -104,17 +106,15 @@ class MatematHTTPServer(HTTPServer):
|
|||
handler: Type[BaseHTTPRequestHandler],
|
||||
staticroot: str,
|
||||
templateroot: str,
|
||||
dbpath: str,
|
||||
pagelet_arguments: Dict[str, str],
|
||||
pagelet_variables: Dict[str, str],
|
||||
bind_and_activate: bool = True) -> None:
|
||||
super().__init__(server_address, handler, bind_and_activate)
|
||||
# Resolve webroot directory and database file
|
||||
# Resolve webroot directory
|
||||
self.webroot = os.path.abspath(staticroot)
|
||||
self.database_file = os.path.abspath(dbpath)
|
||||
# Set up session vars dict
|
||||
self.session_vars: Dict[str, Tuple[datetime, Dict[str, Any]]] = dict()
|
||||
# Set up pagelet arguments dict
|
||||
self.pagelet_arguments = pagelet_arguments
|
||||
self.pagelet_variables = pagelet_variables
|
||||
# Set up the Jinja2 environment
|
||||
self.jinja_env: jinja2.Environment = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(os.path.abspath(templateroot))
|
||||
|
@ -141,8 +141,7 @@ class MatematWebserver(object):
|
|||
port: int,
|
||||
staticroot: str,
|
||||
templateroot: str,
|
||||
dbpath: str,
|
||||
pagelet_arguments: Dict[str, str]) -> None:
|
||||
pagelet_variables: Dict[str, str]) -> None:
|
||||
"""
|
||||
Instantiate a MatematWebserver.
|
||||
|
||||
|
@ -150,14 +149,14 @@ class MatematWebserver(object):
|
|||
:param port: The TCP port to listen on.
|
||||
:param staticroot: Path to the static webroot directory.
|
||||
:param templateroot: Path to the Jinja2 templates root directory.
|
||||
:param dbpath: Path to the database file.
|
||||
:param pagelet_variables: Dictionary of variables to pass to pagelet functions.
|
||||
"""
|
||||
# IPv4 address detection heuristic
|
||||
if ':' not in listen and '.' in listen:
|
||||
# Rewrite IPv4 address to IPv6-mapped form
|
||||
listen = f'::ffff:{listen}'
|
||||
# Create the http server
|
||||
self._httpd = MatematHTTPServer((listen, port), HttpHandler, staticroot, templateroot, dbpath, pagelet_arguments)
|
||||
self._httpd = MatematHTTPServer((listen, port), HttpHandler, staticroot, templateroot, pagelet_variables)
|
||||
|
||||
def start(self) -> None:
|
||||
"""
|
||||
|
@ -296,14 +295,13 @@ class HttpHandler(BaseHTTPRequestHandler):
|
|||
'Content-Type': 'text/html',
|
||||
'Cache-Control': 'no-cache'
|
||||
}
|
||||
print(self.server.pagelet_arguments)
|
||||
# Call the pagelet function
|
||||
pagelet_res = _PAGELET_PATHS[path](method,
|
||||
path,
|
||||
args,
|
||||
self.session_vars,
|
||||
headers,
|
||||
self.server.pagelet_arguments)
|
||||
self.server.pagelet_variables)
|
||||
# Parse the pagelet's return value, vielding a HTTP status code and a response body
|
||||
hsc, data = self._parse_pagelet_result(pagelet_res, headers)
|
||||
# Send the HTTP status code
|
||||
|
|
|
@ -18,7 +18,7 @@ def login_page(method: str,
|
|||
if 'user' in session_vars:
|
||||
return RedirectResponse('/')
|
||||
if method == 'GET':
|
||||
return TemplateResponse('login.html', setupname=config['name'])
|
||||
return TemplateResponse('login.html', setupname=config['InstanceName'])
|
||||
elif method == 'POST':
|
||||
with MatematDatabase(config['DatabaseFile']) as db:
|
||||
try:
|
||||
|
|
|
@ -18,7 +18,7 @@ def main_page(method: str,
|
|||
if 'user' in session_vars:
|
||||
user: User = session_vars['user']
|
||||
products = db.list_products()
|
||||
return TemplateResponse('main.html', user=user, list=products, setupname=config['name'])
|
||||
return TemplateResponse('main.html', user=user, list=products, setupname=config['InstanceName'])
|
||||
else:
|
||||
users = db.list_users()
|
||||
return TemplateResponse('main.html', list=users, setupname=config['name'])
|
||||
return TemplateResponse('main.html', list=users, setupname=config['InstanceName'])
|
||||
|
|
|
@ -22,7 +22,7 @@ def touchkey_page(method: str,
|
|||
if method == 'GET':
|
||||
return TemplateResponse('touchkey.html',
|
||||
username=str(args.username) if 'username' in args else None,
|
||||
setupname=config['name'])
|
||||
setupname=config['InstanceName'])
|
||||
elif method == 'POST':
|
||||
with MatematDatabase(config['DatabaseFile']) as db:
|
||||
try:
|
||||
|
|
Loading…
Reference in a new issue