Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.git
.git
.venv
14 changes: 7 additions & 7 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"configurations": [
{
"name": "Debug Server",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -25,7 +25,7 @@
},
{
"name": "Production",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -41,7 +41,7 @@
},
{
"name": "Init DB",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -55,7 +55,7 @@
},
{
"name": "Generate Codes",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -69,7 +69,7 @@
},
{
"name": "Generate Secret",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -83,7 +83,7 @@
},
{
"name": "Generate Migration Revision",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand All @@ -98,7 +98,7 @@
},
{
"name": "Migrate DB",
"type": "python",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
Expand Down
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# syntax=docker/dockerfile:1

FROM python:3.10-slim
FROM python:3.14-slim

LABEL maintainer="Matt Soucy <first@msoucy.me>"

ENV MODULE_NAME signinapp.webapp
ENV CS_SIGNIN_DB /appdata/signin.db
ENV STATIC_PATH /app/signinapp/static

WORKDIR /app

COPY --from=ghcr.io/astral-sh/uv:0.9.17 /uv /uvx /bin/

COPY . /app

RUN apt update && apt install -y --no-install-recommends locales; rm -rf /var/lib/apt/lists/*; sed -i '/^#.* en_US.UTF-8 /s/^#//' /etc/locale.gen; locale-gen

RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt

WORKDIR /app
RUN uv sync

CMD ["gunicorn", "--bind", "0.0.0.0:8100", "--workers", "2", "signinapp:app"]
CMD ["uv", "run", "gunicorn", "--bind", "0.0.0.0:8100", "--workers", "2", "signinapp:app"]
1,509 changes: 0 additions & 1,509 deletions poetry.lock

This file was deleted.

105 changes: 57 additions & 48 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,56 +1,65 @@
[tool.poetry]
authors = ["Matt Soucy <first@msoucy.me>", "Ben Beauregard <bot190@gmail.com>"]
description = "A tool to track your team's hours during the season, using QR codes that can be quickly scanned as team members come and go."
license = "MIT"
[project]
name = "signinapp"
packages = [
{ include = "signinapp" }
version = "1.5.5"
description = "A tool to track your team's hours during the season, using QR codes that can be quickly scanned as team members come and go."
authors = [
{ name = "Matt Soucy", email = "first@msoucy.me" },
{ name = "Ben Beauregard", email = "bot190@gmail.com" },
]
requires-python = ">=3.11, <4"
readme = "README.md"
repository = "https://github.com/chopshop-166/SignInWebApp"
version = "1.5.5"
license = "MIT"
dependencies = [
"bootstrap-flask>=2.5.0,<2.6.0",
"cssmin>=0.2.0,<0.3.0",
"email-validator>=2.3.0,<2.4.0",
"flask>=3.1.0,<3.2.0",
"flask-admin>=2.0.0,<2.1.0",
"flask-apscheduler>=1.13.0,<1.14.0",
"flask-assets>=2.0,<3.0",
"flask-excel>=0.0.7,<0.1.0",
"flask-login>=0.6.2,<0.7.0",
"flask-migrate>=4.1.0,<4.2.0",
"flask-wtf>=1.2.0,<1.3.0",
"get-docker-secret>=2.0.0,<2.1.0",
"gunicorn>=23.0.0,<23.1.0",
"libsass>=0.21,<1.0",
"markupsafe>=3.0.0,<3.1.0",
"pysass>=0.1.0,<0.2.0",
"python-dateutil>=2.9.0,<2.10.0",
"pytz>=2025.2,<2026.0",
"pyyaml>=6.0,<7.0",
"regex>=2025.11.3,<2025.12.0",
"psycopg2-binary>=2.9.7,<2.10.0",
"requests>=2.32.3,<2.33.0",
"six>=1.17.0,<1.18.0",
"sqlalchemy>=2.0.0,<2.1.0",
"toml>=0.10.2,<0.11.0",
"tomli>=2.3.0,<2.4.0",
"tzdata>=2025.2,<2026.0",
"tzlocal>=5.3.0,<5.4.0",
"webassets>=3.0,<3.1",
"wtforms>=3.2.1,<3.3.0",
"flask-sqlalchemy-lite>=0.2.1",
"types-wtforms>=3.2.1.20250809",
"types-requests>=2.32.4.20260107",
]

[tool.poetry.dependencies]
python = "^3.11"
bootstrap-flask = ">=2.4.0,<2.5.0"
cssmin = ">=0.2.0,<0.3.0"
email-validator = ">=2.1.0,<2.2.0"
flask = ">=3.0.0,<3.1.0"
flask-admin = ">=1.6.1,<1.7.0"
flask-apscheduler = ">=1.13.0,<1.14.0"
flask-assets = ">=2.0,<3.0"
flask-excel = ">=0.0.7,<0.1.0"
flask-login = ">=0.6.2,<0.7.0"
flask-migrate = ">=4.0.0,<4.1.0"
flask-sqlalchemy = ">=3.1.1,<3.2.0"
flask-wtf = ">=1.2.0,<1.3.0"
get-docker-secret = ">=2.0.0,<2.1.0"
gunicorn = ">=22.0.0,<22.1.0"
libsass = ">=0.21,<1.0"
markupsafe = ">=2.1.1,<2.2.0"
pysass = ">=0.1.0,<0.2.0"
python-dateutil = ">=2.9.0,<2.10.0"
pytz = ">=2024.1,<2025.0"
pyyaml = ">=6.0,<7.0"
regex = ">=2024.5.15,<2024.6.0"
psycopg2-binary = ">=2.9.7,<2.10.0"
requests = ">=2.32.3,<2.33.0"
six = ">=1.16.0,<1.17.0"
sqlalchemy = ">=2.0.0,<2.1.0"
toml = ">=0.10.2,<0.11.0"
tomli = ">=2.0.1,<2.1.0"
tzdata = ">=2024.1,<2025.0"
tzlocal = ">=5.2.0,<5.3.0"
webassets = ">=2.0,<3.0"
wtforms = ">=3.1.1,<3.2.0"

[tool.poetry.group.dev.dependencies]
ruff = "^0.8.3"
[project.urls]
Repository = "https://github.com/chopshop-166/SignInWebApp"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[dependency-groups]
dev = ["ruff>=0.14.3,<0.15"]

[tool.hatch.build.targets.sdist]
include = ["signinapp"]

[tool.hatch.build.targets.wheel]
include = ["signinapp"]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
# Exclude a variety of commonly ignored directories.
Expand Down Expand Up @@ -123,4 +132,4 @@ docstring-code-format = true
# Set the line length limit used when formatting code snippets in
# docstrings.
# enabled.
docstring-code-line-length = "dynamic"
docstring-code-line-length = "dynamic"
2 changes: 1 addition & 1 deletion signin-cli
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/bash

env FLASK_APP=signinapp.webapp python -m flask "$@"
env FLASK_APP=signinapp.webapp uv run python -m flask "$@"
45 changes: 30 additions & 15 deletions signinapp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .model import (
Active,
Badge,
Base,
Event,
EventType,
Guardian,
Expand Down Expand Up @@ -86,8 +87,12 @@ class DebugConfig(Config):
assert (
app.config["TIME_ZONE"] in zoneinfo.available_timezones()
), "Invalid time zone given in config"
assert app.config["PRE_EVENT_ACTIVE_TIME"] >= 0, "Invalid pre active time given in config"
assert app.config["POST_EVENT_ACTIVE_TIME"] >= 0, "Invalid post active time given in config"
assert (
app.config["PRE_EVENT_ACTIVE_TIME"] >= 0
), "Invalid pre active time given in config"
assert (
app.config["POST_EVENT_ACTIVE_TIME"] >= 0
), "Invalid post active time given in config"
assert app.config["AUTO_SIGNOUT_BEHAVIOR"] in (
"Credit",
"Discard",
Expand Down Expand Up @@ -115,7 +120,7 @@ class DebugConfig(Config):

db.init_app(app)
with app.app_context():
db.create_all()
Base.metadata.create_all(db.get_engine())

migrate = Migrate(app, db)

Expand Down Expand Up @@ -147,15 +152,19 @@ def index():
@app.errorhandler(404)
def page_not_found(e):
return (
render_template("error.html.jinja2", error_headline="Page Not Found", error_msg=e),
render_template(
"error.html.jinja2", error_headline="Page Not Found", error_msg=e
),
404,
)


@app.errorhandler(500)
def internal_server_error(e: int):
return (
render_template("error.html.jinja2", error_headline="Internal Error", error_msg=e),
render_template(
"error.html.jinja2", error_headline="Internal Error", error_msg=e
),
500,
)

Expand Down Expand Up @@ -193,8 +202,12 @@ def init_default_db():
create_if_not_exists(Role, name="guardian_limited", guardian=True, visible=False)
create_if_not_exists(Role, name="guardian", guardian=True)

create_if_not_exists(EventType, name="Training", description="Training Session", autoload=True)
create_if_not_exists(EventType, name="Build", description="Build Season", autoload=True)
create_if_not_exists(
EventType, name="Training", description="Training Session", autoload=True
)
create_if_not_exists(
EventType, name="Build", description="Build Season", autoload=True
)
create_if_not_exists(EventType, name="Fundraiser", description="Fundraiser")
create_if_not_exists(EventType, name="Competition", description="Competition")

Expand Down Expand Up @@ -256,7 +269,8 @@ def init_default_db():
location="D124",
code="8765",
start=now - offset,
end=now - datetime.timedelta(minutes=app.config["POST_EVENT_ACTIVE_TIME"] - 5),
end=now
- datetime.timedelta(minutes=app.config["POST_EVENT_ACTIVE_TIME"] - 5),
event_type="Build",
)
db.session.commit()
Expand Down Expand Up @@ -284,14 +298,15 @@ def init_default_db():
approved=True,
tshirt_size="Large",
)
student_user.student_user_data.add_guardian(
guardian=Guardian.get_from(
name="Parent Burke",
phone_number="(603)555-5555",
email="pburke@signin.chopshoplib.info",
contact_order=1,
if sud := student_user.student_user_data:
sud.add_guardian(
Guardian.get_from(
name="Parent Burke",
phone_number="(603)555-5555",
email="pburke@signin.chopshoplib.info",
contact_order=1,
)
)
)

student_training_event = Active(
user_id=student_user.id, event_id=expired_event.id, start=now - offset
Expand Down
11 changes: 7 additions & 4 deletions signinapp/active.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ def view():
@mentor_required
def post():
active_event = db.session.get(Active, request.form["active_id"])
stamp = Stamps(user=active_event.user, event=active_event.event, start=active_event.start)
db.session.delete(active_event)
db.session.add(stamp)
db.session.commit()
if active_event:
stamp = Stamps(
user=active_event.user, event=active_event.event, start=active_event.start
)
db.session.delete(active_event)
db.session.add(stamp)
db.session.commit()
return redirect(url_for("active.view"))


Expand Down
Loading