bump project
This commit is contained in:
84
app/people/routes.py
Normal file
84
app/people/routes.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from flask import Blueprint, abort, flash, redirect, render_template, request, url_for
|
||||
|
||||
from app.extensions import db
|
||||
from app.models import FaceEncoding, Person, Role
|
||||
from app.people.forms import PersonForm
|
||||
from app.services.attendance import last_presence_summary
|
||||
from app.services.recognition import RecognitionUnavailable, encode_uploaded_image
|
||||
from app.services.security import roles_required
|
||||
|
||||
bp = Blueprint("people", __name__, url_prefix="/people")
|
||||
|
||||
|
||||
@bp.get("/")
|
||||
@roles_required(Role.ADMIN, Role.OPERATOR, Role.VIEWER)
|
||||
def index():
|
||||
people = Person.query.order_by(Person.full_name.asc()).all()
|
||||
return render_template("people/index.html", people=people)
|
||||
|
||||
|
||||
@bp.route("/new", methods=["GET", "POST"])
|
||||
@roles_required(Role.ADMIN, Role.OPERATOR)
|
||||
def new_person():
|
||||
form = PersonForm()
|
||||
if form.validate_on_submit():
|
||||
files = [field.data for field in (form.photo_1, form.photo_2, form.photo_3, form.photo_4) if field.data]
|
||||
files = [file for file in files if file.filename]
|
||||
if not files:
|
||||
flash("Upload at least one reference photo.", "danger")
|
||||
return render_template("people/form.html", form=form)
|
||||
|
||||
try:
|
||||
vectors = [encode_uploaded_image(file) for file in files]
|
||||
except RecognitionUnavailable as exc:
|
||||
flash(str(exc), "danger")
|
||||
return render_template("people/form.html", form=form), 503
|
||||
except ValueError as exc:
|
||||
flash(str(exc), "danger")
|
||||
return render_template("people/form.html", form=form)
|
||||
|
||||
person = Person(
|
||||
full_name=form.full_name.data.strip(),
|
||||
employee_id=form.employee_id.data.strip(),
|
||||
notes=form.notes.data.strip() or None,
|
||||
)
|
||||
for slot, vector in enumerate(vectors, start=1):
|
||||
encoding = FaceEncoding(image_slot=slot)
|
||||
encoding.vector = vector
|
||||
person.face_encodings.append(encoding)
|
||||
|
||||
db.session.add(person)
|
||||
db.session.commit()
|
||||
flash(f"{person.full_name} has been enrolled.", "success")
|
||||
return redirect(url_for("people.detail", person_id=person.id))
|
||||
return render_template("people/form.html", form=form)
|
||||
|
||||
|
||||
@bp.get("/<int:person_id>")
|
||||
@roles_required(Role.ADMIN, Role.OPERATOR, Role.VIEWER)
|
||||
def detail(person_id: int):
|
||||
person = db.session.get(Person, person_id)
|
||||
if not person:
|
||||
abort(404)
|
||||
events = person.attendance_events[:]
|
||||
events.sort(key=lambda event: event.occurred_at, reverse=True)
|
||||
return render_template(
|
||||
"people/detail.html",
|
||||
person=person,
|
||||
events=events[:20],
|
||||
presence_summary=last_presence_summary(person),
|
||||
)
|
||||
|
||||
|
||||
@bp.post("/<int:person_id>/toggle")
|
||||
@roles_required(Role.ADMIN, Role.OPERATOR)
|
||||
def toggle_person(person_id: int):
|
||||
person = db.session.get(Person, person_id)
|
||||
if not person:
|
||||
abort(404)
|
||||
person.active = not person.active
|
||||
db.session.commit()
|
||||
flash(f"{person.full_name} is now {'active' if person.active else 'inactive'}.", "success")
|
||||
return redirect(request.referrer or url_for("people.index"))
|
||||
Reference in New Issue
Block a user