tabletop-frog/ttfrog/webserver/controllers/base.py

130 lines
3.7 KiB
Python
Raw Normal View History

2024-02-01 00:28:17 -08:00
import logging
2024-02-02 15:40:45 -08:00
import re
2024-01-28 22:14:50 -08:00
2024-02-04 11:40:30 -08:00
from collections import defaultdict
2024-01-28 22:14:50 -08:00
2024-02-02 15:40:45 -08:00
from pyramid.httpexceptions import HTTPFound
from pyramid.interfaces import IRoutesMapper
2024-02-04 11:40:30 -08:00
from ttfrog.attribute_map import AttributeMap
2024-01-31 22:39:54 -08:00
from ttfrog.db.manager import db
2024-02-08 01:14:35 -08:00
from ttfrog.db import transaction_log
2024-01-28 22:14:50 -08:00
2024-02-02 15:40:45 -08:00
def get_all_routes(request):
2024-02-04 11:40:30 -08:00
routes = {
'static': '/static',
}
2024-02-02 15:40:45 -08:00
uri_pattern = re.compile(r"^([^\{\*]+)")
mapper = request.registry.queryUtility(IRoutesMapper)
for route in mapper.get_routes():
if route.name.startswith('__'):
continue
m = uri_pattern.search(route.pattern)
if m:
routes[route.name] = m .group(0)
return routes
2024-01-31 22:39:54 -08:00
class BaseController:
model = None
2024-02-04 11:40:30 -08:00
model_form = None
2024-01-31 22:39:54 -08:00
def __init__(self, request):
self.request = request
self.attrs = defaultdict(str)
2024-02-04 11:40:30 -08:00
self._slug = None
self._record = None
self._form = None
2024-01-31 22:39:54 -08:00
self.config = {
'static_url': '/static',
'project_name': 'TTFROG'
}
2024-02-01 00:28:17 -08:00
self.configure_for_model()
2024-02-04 11:40:30 -08:00
@property
def slug(self):
if not self._slug:
parts = self.request.matchdict.get('uri', '').split('-')
self._slug = parts[0].replace('/', '')
return self._slug
@property
def record(self):
if not self._record and self.model:
try:
self._record = db.query(self.model).filter(self.model.slug == self.slug)[0]
except IndexError:
logging.warning(f"Could not load record with slug {self.slug}")
self._record = self.model()
return self._record
@property
def form(self):
2024-02-01 00:28:17 -08:00
if not self.model:
return
2024-02-04 11:40:30 -08:00
if not self._form:
if self.request.POST:
self._form = self.model_form(self.request.POST, obj=self.record)
else:
self._form = self.model_form(obj=self.record)
return self._form
2024-02-01 00:28:17 -08:00
2024-02-08 01:14:35 -08:00
@property
def resources(self):
return [
{'type': 'style', 'uri': 'css/styles.css'},
]
2024-02-04 11:40:30 -08:00
def configure_for_model(self):
2024-02-01 00:28:17 -08:00
if 'all_records' not in self.attrs:
self.attrs['all_records'] = db.query(self.model).all()
2024-02-04 11:40:30 -08:00
def template_context(self, **kwargs) -> dict:
return AttributeMap.from_dict({
'c': dict(
config=self.config,
request=self.request,
form=self.form,
record=self.record,
routes=get_all_routes(self.request),
2024-02-08 01:14:35 -08:00
resources=self.resources,
2024-02-04 11:40:30 -08:00
**self.attrs,
**kwargs,
)
})
2024-01-31 22:39:54 -08:00
2024-02-04 15:22:54 -08:00
def save(self):
if not self.form.save.data:
return
if not self.form.validate():
return
2024-02-08 01:14:35 -08:00
previous = dict(self.record)
2024-02-04 15:22:54 -08:00
self.form.populate_obj(self.record)
2024-02-08 01:14:35 -08:00
transaction_log.record(previous, self.record)
2024-02-04 15:22:54 -08:00
if self.record.id:
return
with db.transaction():
db.add(self.record)
logging.debug(f"Added {self.record = }")
location = f"{self.request.current_route_path()}/{self.record.uri}"
return HTTPFound(location=location)
def delete(self):
if not self.record.id:
return
with db.transaction():
db.query(self.model).filter_by(id=self.record.id).delete()
logging.debug(f"Deleted {self.record = }")
location = self.request.current_route_path()
return HTTPFound(location=location)
2024-01-31 22:39:54 -08:00
def response(self):
2024-02-04 15:22:54 -08:00
if not self.form:
2024-02-04 11:40:30 -08:00
return
2024-02-04 15:22:54 -08:00
elif self.form.save.data:
return self.save()
elif self.form.delete.data:
return self.delete()