from flask import url_for, redirect, render_template, request, jsonify from flask_security import login_required from flask_security.core import current_user from sqlalchemy.exc import IntegrityError import json from ..entities import Vehicle, Consumable from ..forms import EditVehicleForm, DeleteVehicleForm, DeleteAccountForm from ..tools import db_log_update, db_log_delete, db_log_add from .. import app, db, user_datastore @app.route("/account", methods=["GET"]) @login_required def get_account_page(): stations = [x.as_dict() for x in current_user.favourite_filling_stations] for station in stations: station["state"] = "favourite" return render_template( "account.html", map_pos=(current_user.home_lat, current_user.home_long, current_user.home_zoom), fs=json.dumps(stations), ) @app.route("/account/vehicle/edit/", methods=["GET", "POST"]) @login_required def edit_vehicle(vid): vehicle = Vehicle.query.filter(Vehicle.id == vid).first() # prevent edit of foreign vehicles if vehicle not in current_user.vehicles: return redirect(url_for("get_account_page")) form = EditVehicleForm() form.consumables.choices = [(g.id, g.name) for g in Consumable.query.all()] if not form.consumables.data: form.consumables.default = [g.id for g in vehicle.consumables] if form.name.data is not None: form.name.default = form.name.data if form.is_active.data is not None: form.is_active.default = form.is_active.data if form.validate_on_submit(): vehicle.name = form.name.data vehicle.is_active = form.is_active.data # we cannot delete consumables where there are pitstops for => report error vehicle.consumables = [] for consumable_id in form.consumables.data: consumable = Consumable.query.get(consumable_id) if consumable is not None: vehicle.consumables.append(consumable) try: db.session.commit() db_log_update(vehicle) except IntegrityError: db.session.rollback() form.name.errors.append('"%s" is not unique.' % (form.name.data)) return render_template("editVehicleForm.html", form=form) return redirect(url_for("get_account_page")) form.name.default = vehicle.name form.is_active.default = vehicle.is_active form.process() return render_template("editVehicleForm.html", form=form, vehicle=vehicle) @app.route("/account/vehicle/delete/", methods=["GET", "POST"]) @login_required def delete_vehicle(vid): vehicle = Vehicle.query.filter(Vehicle.id == vid).first() # prevent deletion of foreign vehicles if vehicle not in current_user.vehicles: return redirect(url_for("get_account_page")) if len(current_user.vehicles) == 1: return redirect(url_for("get_account_page")) form = DeleteVehicleForm() if form.validate_on_submit(): db.session.delete(vehicle) db.session.commit() db_log_delete(vehicle) return redirect(url_for("get_account_page")) return render_template("deleteVehicleForm.html", form=form, vehicle=vehicle) @app.route("/account/vehicle/create", methods=["GET", "POST"]) @login_required def create_vehicle(): form = EditVehicleForm() form.consumables.choices = [(g.id, g.name) for g in Consumable.query.all()] if form.name.data is not None: form.name.default = form.name.data if form.consumables.data: form.consumables.default = form.consumables.data else: form.consumables.default = [] if form.validate_on_submit(): if len(form.consumables.data) == 0: form.consumables.errors.append("At least one consumable must be selected.") return render_template("createVehicleForm.html", form=form) vehicle_name = form.name.data new_vehicle = Vehicle(vehicle_name) for consumable_id in form.consumables.data: consumable = Consumable.query.get(consumable_id) if consumable is not None: new_vehicle.consumables.append(consumable) db.session.add(new_vehicle) current_user.vehicles.append(new_vehicle) try: db.session.commit() db_log_add(new_vehicle) except IntegrityError: db.session.rollback() form.name.errors.append('"%s" is not unique.' % (form.name.data)) return render_template("createVehicleForm.html", form=form) return redirect(url_for("get_account_page")) return render_template("createVehicleForm.html", form=form) @app.route("/account/delete", methods=["GET", "POST"]) @login_required def delete_account(): form = DeleteAccountForm() if form.validate_on_submit(): user_datastore.delete_user(current_user) db.session.commit() return redirect(url_for("index")) return render_template("deleteAccountForm.html", form=form) @app.route("/account/home", methods=["GET"]) @login_required def get_users_home(): return jsonify( { "lat": float(current_user.home_lat), "long": float(current_user.home_long), "zoom": current_user.home_zoom, } ) @app.route("/account/home", methods=["POST"]) @login_required def set_users_home(): current_user.home_lat = request.json["lat"] current_user.home_long = request.json["long"] current_user.home_zoom = request.json["zoom"] db.session.commit() return jsonify({})