An ADHD-friendly regular task tracker
Revision | 2d918ccd5331987ddf3127194c07f0e7484249c9 (tree) |
---|---|
Time | 2024-03-10 10:53:39 |
Author | Corbin <cds@corb...> |
Commiter | Corbin |
Wire up basic buttons for doing tasks.
@@ -1,18 +1,20 @@ | ||
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | |
3 | 3 | from datetime import datetime, timedelta |
4 | -import html | |
4 | +import os | |
5 | 5 | import sqlite3 |
6 | +import time | |
6 | 7 | |
7 | -from flask import Flask, render_template | |
8 | +from flask import Flask, flash, redirect, render_template, url_for | |
8 | 9 | |
9 | 10 | # XXX Flask multithreading -> need to reconnect per-thread |
10 | 11 | # XXX I think there's an extension that solves this? |
11 | -def cursor(): return sqlite3.connect("every.db").cursor() | |
12 | +def connect(): return sqlite3.connect("every.db") | |
12 | 13 | |
13 | 14 | TEMPLATE_PATH = "@template_path@" |
14 | 15 | |
15 | 16 | app = Flask("every-card", template_folder=TEMPLATE_PATH) |
17 | +app.secret_key = os.urandom(16) | |
16 | 18 | |
17 | 19 | @app.route("/") |
18 | 20 | def root(): return "Working on it..." |
@@ -42,7 +44,8 @@ def deltaDays(s): return timedelta(seconds=s).days | ||
42 | 44 | |
43 | 45 | @app.route("/show/<wheel>") |
44 | 46 | def show(wheel): |
45 | - c = cursor() | |
47 | + conn = connect() | |
48 | + c = conn.cursor() | |
46 | 49 | l = [(row[0], row[1]) + prepDates(row[2], row[3]) |
47 | 50 | for row in c.execute(SHOW_QUERY, (wheel,))] |
48 | 51 | dets = c.execute(SHOW_ALL_QUERY, (wheel,)) |
@@ -56,13 +59,16 @@ where wheel=? and label=? | ||
56 | 59 | |
57 | 60 | @app.route("/do/<wheel>/<label>", methods=("POST",)) |
58 | 61 | def do(wheel, label): |
59 | - c = cursor() | |
62 | + conn = connect() | |
63 | + c = conn.cursor() | |
60 | 64 | t = c.execute(UPDATED_AT_QUERY, (wheel, label)).fetchone() |
61 | - if not t: return "No such task!" | |
62 | - | |
63 | - c.execute("update tasks set updated_at=? where wheel=? and label=?", | |
64 | - (time.time(), wheel, label)) | |
65 | - c.commit() | |
66 | - return "Task done! Nice!" | |
65 | + if t: | |
66 | + c.execute("update tasks set updated_at=? where wheel=? and label=?", | |
67 | + (time.time(), wheel, label)) | |
68 | + conn.commit() | |
69 | + flash("Task done! Nice!") | |
70 | + else: | |
71 | + flash("No such task!") | |
72 | + return redirect(url_for("show", wheel=wheel)) | |
67 | 73 | |
68 | 74 | app.run(debug=True, host="0.0.0.0", port=1312) |
@@ -10,6 +10,7 @@ | ||
10 | 10 | flake-utils.lib.eachDefaultSystem (system: |
11 | 11 | let |
12 | 12 | pkgs = import nixpkgs { inherit system; }; |
13 | + pyflakes = pkgs.python311Packages.pyflakes; | |
13 | 14 | py = pkgs.python311.withPackages (ps: [ |
14 | 15 | ps.click ps.flask |
15 | 16 | ]); |
@@ -34,14 +35,14 @@ | ||
34 | 35 | ''; |
35 | 36 | doCheck = true; |
36 | 37 | checkPhase = '' |
37 | - ${pkgs.python311Packages.pyflakes}/bin/pyflakes $out/bin/* | |
38 | + ${pyflakes}/bin/pyflakes $out/bin/* | |
38 | 39 | ''; |
39 | 40 | }; |
40 | 41 | in { |
41 | 42 | packages.default = every; |
42 | 43 | devShells.default = pkgs.mkShell { |
43 | 44 | packages = [ |
44 | - py | |
45 | + py pyflakes | |
45 | 46 | pkgs.sqlite pkgs.rlwrap |
46 | 47 | ]; |
47 | 48 | }; |
@@ -1,25 +1,42 @@ | ||
1 | -<!DOCTYPE html> | |
1 | +<!doctype html> | |
2 | 2 | |
3 | -<h1>Tasks for {{ wheel }}</h1> | |
4 | - | |
5 | -<ol> | |
6 | - {% for label, description, updated_delta, consequences_delta in availableTasks %} | |
7 | - <li>{{ description }} ({{ label }}): Last done {{ updated_delta.days + 1 | |
8 | - }} days ago, | |
9 | - {% if consequences_delta.total_seconds() is lt(0) %} | |
10 | - needs to be done immediately or there will be consequences | |
11 | - {% else %} | |
12 | - needs to be done within {{ consequences_delta.days }} days | |
13 | - {% endif %} | |
14 | - </li> | |
15 | - {% endfor %} | |
16 | -</ol> | |
17 | - | |
18 | -<details> | |
19 | - <ul> | |
20 | - {% for description, available_every, consequences_after in allTasks %} | |
21 | - <li>{{ description }}: every {{ available_every | deltadays }}–{{ | |
22 | - consequences_after | deltadays }} days</li> | |
3 | +<head> | |
4 | + <title>Tasks for {{ wheel }}</title> | |
5 | + <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
6 | +</head> | |
7 | +<body> | |
8 | + <div class="flashes"> | |
9 | + {% for message in get_flashed_messages() %} | |
10 | + <div class="flash"> | |
11 | + {{ message }} | |
12 | + </div> | |
13 | + {% endfor %} | |
14 | + </div> | |
15 | + <h1>Tasks for {{ wheel }}</h1> | |
16 | + <ol> | |
17 | + {% for label, description, updated_delta, consequences_delta in availableTasks %} | |
18 | + <li> | |
19 | + <div class="button"> | |
20 | + <form action="{{ url_for("do", wheel=wheel, label=label) }}" method="POST"> | |
21 | + <input type="submit" value="Done!" /> | |
22 | + </form> | |
23 | + </div> | |
24 | + {{ description }} ({{ label }}): Last done {{ updated_delta.days + 1 | |
25 | + }} days ago, | |
26 | + {% if consequences_delta.total_seconds() is lt(0) %} | |
27 | + needs to be done immediately or there will be consequences | |
28 | + {% else %} | |
29 | + needs to be done within {{ consequences_delta.days }} days | |
30 | + {% endif %} | |
31 | + </li> | |
23 | 32 | {% endfor %} |
24 | - </ul> | |
25 | -</details> | |
33 | + </ol> | |
34 | + <details> | |
35 | + <ul> | |
36 | + {% for description, available_every, consequences_after in allTasks %} | |
37 | + <li>{{ description }}: every {{ available_every | deltadays }}–{{ | |
38 | + consequences_after | deltadays }} days</li> | |
39 | + {% endfor %} | |
40 | + </ul> | |
41 | + </details> | |
42 | +</body> |