import time from flask import Blueprint, abort, redirect, render_template, request, url_for from flask_login import current_user, login_required from flask_wtf import FlaskForm from wtforms import IntegerField, StringField, SubmitField from wtforms.validators import DataRequired, Length, NumberRange from wtforms.widgets import NumberInput from .days import Day from .db import Accomplishment, db main = Blueprint('main', __name__) class NewAccomplishementForm(FlaskForm): text = StringField( 'Accomplishment', validators=[ DataRequired(), Length(max=256)]) submit_5 = SubmitField('5 XP') submit_10 = SubmitField('10 XP') submit_15 = SubmitField('15 XP') def handle_accomplishment_submission(form): accomplishment = Accomplishment() accomplishment.user_id = current_user.id accomplishment.text = form.text.data accomplishment.difficulty = 5 if form.submit_10.data: accomplishment.difficulty = 10 elif form.submit_15.data: accomplishment.difficulty = 15 accomplishment.time = Day.today(current_user).timestamp db.session.add(accomplishment) db.session.commit() return redirect(url_for('main.index')) def parse_day(day_string, user): day = None if day_string == "today": day = Day.today(user) else: day = Day.from_str(day_string, user) return day def get_day_template_data(day_string, user): day = parse_day(day_string, user) accomplishments = list(reversed( Accomplishment.get_day(current_user, day))) total = sum(a.difficulty for a in accomplishments) yesterday = day - 1 tomorrow = day + 1 if tomorrow.is_future: tomorrow = None return { "day": day, "links": { "yesterday": url_for('main.index', day=yesterday.url), "tomorrow": url_for('main.index', day=tomorrow.url) if tomorrow is not None else None }, "accomplishments": accomplishments, "total_xp": sum(a.difficulty for a in accomplishments), "ts": int(time.time()), # timestamp for cachebusting } @main.route('/', defaults={'day': 'today'}, methods=['GET', 'POST']) @main.route('/day/') def index(day): if not current_user.is_authenticated: # TODO: handle the case when the user is on /day/ and is not logged in return render_template('index.html') form = NewAccomplishementForm() if form.validate_on_submit(): return handle_accomplishment_submission(form) return render_template( 'main/app.html', form=form, **get_day_template_data(day, current_user) ) @main.route('/day//edit') @login_required def edit_day(day): form = NewAccomplishementForm() if form.validate_on_submit(): return handle_accomplishment_submission(form) return render_template( 'main/app.html', form=form, edit=True, **get_day_template_data(day, current_user) ) class DeleteForm(FlaskForm): submit = SubmitField('Delete') @main.route('/accomplishment//delete', methods=['GET', 'POST']) @login_required def delete_accomplishment(accomplishment_id): a = Accomplishment.query.get_or_404(accomplishment_id) if a.user_id != current_user.id: abort(403) back_url = url_for('main.edit_day', day=Day.from_timestamp( a.time, current_user).url) form = DeleteForm() if form.validate_on_submit(): db.session.delete(a) db.session.commit() return redirect(back_url) return render_template( 'main/delete.html', form=form, accomplishment=a, cancel=back_url) class EditForm(FlaskForm): text = StringField( 'Accomplishment', validators=[DataRequired(), Length(max=256)] ) difficulty = IntegerField( 'Difficulty (XP)', widget=NumberInput(min=-100, max=100), validators=[DataRequired(), NumberRange(max=100, min=-100)] ) submit = SubmitField('Save') @main.route('/accomplishment//edit', methods=['GET', 'POST']) @login_required def edit_accomplishment(accomplishment_id): a = Accomplishment.query.get_or_404(accomplishment_id) if a.user_id != current_user.id: abort(403) back_url = url_for('main.edit_day', day=Day.from_timestamp( a.time, current_user).url) form = EditForm(obj=a) if form.validate_on_submit(): a.text = form.text.data a.difficulty = form.difficulty.data db.session.commit() return redirect(back_url) return render_template('main/edit.html', form=form, cancel=back_url) @main.route('/day//add', methods=['GET', 'POST']) @login_required def add_day(day): day = parse_day(day, current_user) form = EditForm() back_url = "" from_top = ("from" in request.args) and ("top" in request.args["from"]) # to the bottom # bottom to top I stop # at the core I've forgotten # in the middle of my thoughts # taken far from my safety # the picture is there back_to_day = url_for('main.index', day=day.url) back_to_edit = url_for('main.edit_day', day=day.url) if form.validate_on_submit(): accomplishment = Accomplishment() accomplishment.user_id = current_user.id accomplishment.text = form.text.data accomplishment.difficulty = form.difficulty.data accomplishment.time = day.timestamp db.session.add(accomplishment) db.session.commit() return redirect(back_to_day) return render_template( 'main/edit.html', day=day, form=form, edit=True, cancel=back_to_day if from_top else back_to_edit )