Files
natureinpots_community/plugins/plant/growlog/routes.py

177 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# plugins/plant/growlog/routes.py
from uuid import UUID as _UUID
from flask import (
Blueprint, render_template, abort, redirect,
url_for, request, flash
)
from flask_login import login_required, current_user
from app import db
from .models import GrowLog
from .forms import GrowLogForm
from plugins.plant.models import Plant, PlantCommonName
bp = Blueprint(
'growlog',
__name__,
url_prefix='/growlogs',
template_folder='templates',
)
def _get_plant_by_uuid(uuid_val):
"""
Normalize & validate a UUID (may be a uuid.UUID or a string),
then return the Plant owned by current_user or 404.
"""
# 1) If Flask gave us a real UUID, stringify it
if isinstance(uuid_val, _UUID):
val = str(uuid_val)
else:
# 2) Otherwise try to parse it
try:
val = str(_UUID(uuid_val))
except (ValueError, TypeError):
abort(404)
# 3) Only return plants owned by this user
return (
Plant.query
.filter_by(uuid=val, owner_id=current_user.id)
.first_or_404()
)
def _user_plant_choices():
"""
Return [(uuid, "Common Name uuid"), ...] for all plants
owned by current_user, sorted by common name.
"""
plants = (
Plant.query
.filter_by(owner_id=current_user.id)
.join(PlantCommonName, Plant.common_id == PlantCommonName.id)
.order_by(PlantCommonName.name)
.all()
)
return [
(p.uuid, f"{p.common_name.name} {p.uuid}")
for p in plants
]
@bp.route('/add', methods=['GET','POST'])
@bp.route('/<uuid:plant_uuid>/add', methods=['GET','POST'])
@login_required
def add_log(plant_uuid=None):
form = GrowLogForm()
# always populate the select behind the scenes
form.plant_uuid.choices = _user_plant_choices()
plant = None
hide_select = False
# if URL gave us a plant_uuid, lock to that one
if plant_uuid:
plant = _get_plant_by_uuid(plant_uuid)
form.plant_uuid.data = str(plant_uuid)
hide_select = True
if form.validate_on_submit():
plant = _get_plant_by_uuid(form.plant_uuid.data)
log = GrowLog(
plant_id = plant.id,
event_type = form.event_type.data,
title = form.title.data,
notes = form.notes.data,
is_public = form.is_public.data,
)
db.session.add(log)
db.session.commit()
flash('Grow log added.', 'success')
return redirect(
url_for('growlog.list_logs', plant_uuid=plant.uuid)
)
return render_template(
'growlog/log_form.html',
form = form,
plant = plant,
hide_plant_select = hide_select,
)
@bp.route('/', defaults={'plant_uuid': None})
@bp.route('/<uuid:plant_uuid>')
@login_required
def list_logs(plant_uuid):
from plugins.utility.celery import celery_app
celery_app.send_task('plugins.utility.tasks.ping')
limit = request.args.get('limit', default=10, type=int)
if plant_uuid:
# logs for one plant
plant = _get_plant_by_uuid(plant_uuid)
query = GrowLog.query.filter_by(plant_id=plant.id)
else:
# logs across all of this users plants
plant = None
query = (
GrowLog.query
.join(Plant, GrowLog.plant_id == Plant.id)
.filter(Plant.owner_id == current_user.id)
)
logs = (
query
.order_by(GrowLog.created_at.desc())
.limit(limit)
.all()
)
return render_template(
'growlog/log_list.html',
plant = plant,
logs = logs,
limit = limit,
)
@bp.route('/<uuid:plant_uuid>/edit/<int:log_id>', methods=['GET','POST'])
@login_required
def edit_log(plant_uuid, log_id):
plant = _get_plant_by_uuid(plant_uuid)
log = GrowLog.query.filter_by(id=log_id, plant_id=plant.id).first_or_404()
form = GrowLogForm(obj=log)
# lock the dropdown to this plant
form.plant_uuid.choices = [(plant.uuid, plant.common_name.name)]
form.plant_uuid.data = plant.uuid
if form.validate_on_submit():
log.event_type = form.event_type.data
log.title = form.title.data
log.notes = form.notes.data
log.is_public = form.is_public.data
db.session.commit()
flash('Grow log updated.', 'success')
return redirect(url_for('growlog.list_logs', plant_uuid=plant_uuid))
return render_template(
'growlog/log_form.html',
form = form,
plant_uuid = plant_uuid,
plant = plant,
log = log,
)
@bp.route('/<uuid:plant_uuid>/delete/<int:log_id>', methods=['POST'])
@login_required
def delete_log(plant_uuid, log_id):
plant = _get_plant_by_uuid(plant_uuid)
log = GrowLog.query.filter_by(id=log_id, plant_id=plant.id).first_or_404()
db.session.delete(log)
db.session.commit()
flash('Grow log deleted.', 'warning')
return redirect(url_for('growlog.list_logs', plant_uuid=plant_uuid))