include time restriction
All checks were successful
release-tag / release-image (push) Successful in 42s

This commit is contained in:
2025-05-26 10:48:10 +02:00
parent 4170eb14fb
commit df2d8f33a5
10 changed files with 90 additions and 105 deletions

View File

@@ -6,8 +6,10 @@ from sqlmodel import Session
from app.core.db import engine
def get_db() -> Generator[Session, None, None]:
with Session(engine) as session:
yield session
SessionDep = Annotated[Session, Depends(get_db)]

View File

@@ -5,27 +5,28 @@ from app.models import RegistrationCreate
from app import crud
from app.api.deps import SessionDep
from app.core.utils import is_registration_open
from fastapi.responses import RedirectResponse
router = APIRouter(prefix="/registration")
@router.post(
"/register",
"/register_form",
)
def register(*, session: SessionDep, registration_create: Annotated[RegistrationCreate, Form()]):
print(registration_create)
def register(
*, session: SessionDep, registration_create: Annotated[RegistrationCreate, Form()]
):
"""
Register
"""
registration = crud.create_registration(session=session, registration_create=registration_create)
#if settings.emails_enabled and user_in.email:
# email_data = generate_new_account_email(
# email_to=user_in.email, username=user_in.email, password=user_in.password
# )
# send_email(
# email_to=user_in.email,
# subject=email_data.subject,
# html_content=email_data.html_content,
# )
return registration
if is_registration_open():
crud.create_registration(
session=session, registration_create=registration_create
)
return RedirectResponse("/success.html", status_code=303)
else:
return RedirectResponse("/", status_code=303)

View File

@@ -1,10 +1,24 @@
from pydantic_settings import BaseSettings
import os
from datetime import datetime
from zoneinfo import ZoneInfo
date_format = "%Y-%m-%dT%H:%M:%S%z"
class Settings(BaseSettings):
API_V1_STR: str = ""
PROJECT_NAME: str = "Choriosity Anmeldung"
SQLALCHEMY_DATABASE_URI: str = "sqlite:///" + os.environ.get("DATABASE_URL", "/data/db.sqlite")
SQLALCHEMY_DATABASE_URI: str = "sqlite:///" + os.environ.get(
"DATABASE_URL", "/data/db.sqlite"
)
NOT_BEFORE: datetime = datetime.strptime(
os.environ.get("NOT_BEFORE", "2000-01-01T00:00:01+02:00"), date_format
)
NOT_AFTER: datetime = datetime.strptime(
os.environ.get("NOT_AFTER", "2100-01-01T00:00:01+02:00"), date_format
)
TZ: ZoneInfo = ZoneInfo(os.environ.get("TZ", "Europe/Berlin"))
settings = Settings()

View File

@@ -9,6 +9,7 @@ engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI))
# otherwise, SQLModel might fail to initialize relationships properly
# for more details: https://github.com/fastapi/full-stack-fastapi-template/issues/28
def init_db(session: Session) -> None:
# Tables should be created with Alembic migrations
# But if you don't want to use migrations, create
@@ -16,4 +17,4 @@ def init_db(session: Session) -> None:
from sqlmodel import SQLModel
# This works because the models are already imported and registered from app.models
SQLModel.metadata.create_all(engine)
SQLModel.metadata.create_all(engine)

View File

@@ -3,9 +3,11 @@ from sqlmodel import Session
from app.models import Registration, RegistrationCreate
def create_registration(*, session: Session, registration_create: RegistrationCreate) -> Registration:
def create_registration(
*, session: Session, registration_create: RegistrationCreate
) -> Registration:
db_obj = Registration.model_validate(registration_create)
session.add(db_obj)
session.commit()
session.refresh(db_obj)
return db_obj
return db_obj

View File

@@ -1,79 +0,0 @@
<html>
<head>
<title>Choriosity Anmeldung</title>
</head>
<body>
<form method="POST" action="/registration/register">
<label for="email">E-Mail-Adresse:</label> <input type="email" id="email" name="email" />
<label for="first_name">Dein Vorname:</label> <input type="text" id="first_name" name="first_name" />
<label for="last_name">Dein Nachname:</label> <input type="text" id="last_name" name="last_name" />
<label for="birthday">Dein Geburtstag:</label> <input type="date" id="birthday" name="birthday" />
<fieldset>
<legend>Welche Stimme singst du?</legend>
<div>
<input type="radio" id="base" name="voice" value="Bass" checked />
<label for="base">Bass</label>
</div>
<div>
<input type="radio" id="tenor" name="voice" value="Tenor" checked />
<label for="tenor">Tenor</label>
</div>
<div>
<input type="radio" id="alto" name="voice" value="Alt" checked />
<label for="alto">Alt</label>
</div>
<div>
<input type="radio" id="soprano" name="voice" value="Sopran" checked />
<label for="soprano">Sopran</label>
</div>
<div>
<input type="radio" id="women" name="voice" value="Alt oder Sopran" checked />
<label for="women">Sopran oder Alt</label>
</div>
<div>
<input type="radio" id="men" name="voice" value="Bass oder Tenor" checked />
<label for="men">Bass oder Tenor</label>
</div>
</fieldset>
<fieldset>
<legend>Wie lange bleibst du in Ulm?</legend>
<div>
<input type="radio" id="halfyear" name="duration" value="1/2 Jahr" checked />
<label for="halfyear">1/2 Jahr</label>
</div>
<div>
<input type="radio" id="halfyear" name="duration" value="1/2 - 1 Jahr" checked />
<label for="halfyear">1/2 - 1 Jahr</label>
</div>
<div>
<input type="radio" id="twoyears" name="duration" value="1 - 2 Jahre" checked />
<label for="twoyears">1 - 2 jahre</label>
</div>
<div>
<input type="radio" id="longterm" name="duration" value="mehr als zwei Jahre" checked />
<label for="longterm">länger als 2 Jahre</label>
</div>
</fieldset>
<input type="submit" value="Anmelden" />
</form>
</body>
</html>

View File

@@ -1,7 +1,10 @@
from fastapi import FastAPI
from fastapi import FastAPI, Request
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from fastapi.templating import Jinja2Templates
from app.api.main import api_router
from app.core.config import settings
@@ -9,6 +12,8 @@ from app.core.db import init_db, engine
from sqlmodel import Session
from app.core.utils import is_registration_open
with Session(engine) as session:
init_db(session)
@@ -16,10 +21,34 @@ app = FastAPI(
title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json"
)
@api_router.get("/")
def index():
return FileResponse("app/index.html")
templates = Jinja2Templates(directory="app/templates")
@api_router.get("/")
def index(request: Request):
reg_open, not_before, not_after = is_registration_open()
if reg_open:
return templates.TemplateResponse(
request=request, name="registration-open.html", context={}
)
else:
return templates.TemplateResponse(
request=request, name="registration-closed.html", context={
"not_before": settings.NOT_BEFORE,
"not_after": settings.NOT_AFTER,
}
)
@api_router.get("/success.html")
def success(request: Request):
return templates.TemplateResponse(
request=request, name="registration-success.html", context={
"not_before": settings.NOT_BEFORE,
"not_after": settings.NOT_AFTER,
}
)
app.include_router(api_router, prefix=settings.API_V1_STR)
app.mount("/static", StaticFiles(directory="app/static"), name="static")

View File

@@ -25,18 +25,21 @@ class PeriodEnum(str, Enum):
twoyears = "1 - 2 Jahre"
longterm = "mehr als zwei Jahre"
class RegistrationBase(SQLModel):
email: EmailStr = Field(unique=True, index=True, max_length=255)
email: EmailStr = Field(max_length=255)
first_name: str
last_name: str
birthday: date
voice: VoiceEnum
duration: PeriodEnum
number_of_attempts: int
class RegistrationCreate(RegistrationBase):
pass
class Registration(RegistrationBase, table=True):
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
timestamp: datetime = Field(default_factory=func.now)