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

112 lines
3.3 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-31 22:39:54 -08:00
from collections import defaultdict
2024-01-28 22:14:50 -08:00
2024-01-31 22:39:54 -08:00
from wtforms_sqlalchemy.orm import model_form
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-01-31 22:39:54 -08:00
from ttfrog.db.manager import db
2024-01-28 22:14:50 -08:00
2024-02-02 15:40:45 -08:00
def get_all_routes(request):
uri_pattern = re.compile(r"^([^\{\*]+)")
mapper = request.registry.queryUtility(IRoutesMapper)
routes = {}
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
def __init__(self, request):
self.request = request
self.attrs = defaultdict(str)
2024-02-01 00:28:17 -08:00
self.record = None
2024-02-02 15:40:45 -08:00
self.form = None
2024-02-01 00:28:17 -08:00
self.model_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-02 15:40:45 -08:00
self.configure()
2024-02-01 00:28:17 -08:00
def configure_for_model(self):
if not self.model:
return
if not self.model_form:
self.model_form = model_form(self.model, db_session=db.session)
if not self.record:
2024-02-02 15:40:45 -08:00
self.record = self.get_record_from_slug()
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-01-31 22:39:54 -08:00
def configure(self):
2024-02-01 00:28:17 -08:00
pass
2024-02-02 15:40:45 -08:00
def get_record_from_slug(self):
2024-02-01 00:28:17 -08:00
if not self.model:
return
2024-02-02 15:40:45 -08:00
parts = self.request.matchdict.get('uri', '').split('-')
2024-02-01 00:28:17 -08:00
if not parts:
return
2024-02-02 15:40:45 -08:00
slug = parts[0].replace('/', '')
if not slug:
return
2024-02-01 00:28:17 -08:00
try:
2024-02-02 15:40:45 -08:00
return db.query(self.model).filter(self.model.slug == slug)[0]
2024-02-01 00:28:17 -08:00
except IndexError:
2024-02-02 15:40:45 -08:00
logging.warning(f"Could not load record with slug {slug}")
2024-01-31 22:39:54 -08:00
2024-02-02 15:40:45 -08:00
def process_form(self):
2024-01-31 22:39:54 -08:00
if not self.model:
2024-02-02 15:40:45 -08:00
return False
2024-01-31 22:39:54 -08:00
2024-01-31 23:05:46 -08:00
if self.request.method == 'POST':
2024-02-02 15:40:45 -08:00
# if we haven't loaded a record, we're creating a new one
2024-02-01 00:28:17 -08:00
if not self.record:
self.record = self.model()
2024-02-02 15:40:45 -08:00
# generate a form object using the POST form data and the db record
self.form = self.model_form(self.request.POST, obj=self.record)
if self.model.validate(self.form):
# update the record. If it's a record bound to the session
# updates will be commited automatically. Otherwise we must
# add and commit the record.
self.form.populate_obj(self.record)
2024-02-01 00:28:17 -08:00
if not self.record.id:
with db.transaction():
db.session.add(self.record)
logging.debug(f"Added {self.record = }")
2024-02-02 15:40:45 -08:00
return True
return False
self.form = self.model_form(obj=self.record)
return False
2024-01-28 22:14:50 -08:00
def output(self, **kwargs) -> dict:
2024-02-02 15:40:45 -08:00
return dict(c=dict(
2024-01-31 22:39:54 -08:00
config=self.config,
request=self.request,
2024-02-02 15:40:45 -08:00
form=self.form,
record=self.record,
routes=get_all_routes(self.request),
2024-01-31 22:39:54 -08:00
**self.attrs,
2024-01-28 22:14:50 -08:00
**kwargs,
2024-02-02 15:40:45 -08:00
))
2024-01-31 22:39:54 -08:00
def response(self):
2024-02-02 15:40:45 -08:00
if self.process_form():
return HTTPFound(location=f"{self.request.current_route_path}/{self.record.uri}")
2024-01-31 22:39:54 -08:00
return self.output()