summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Powers <mark@marks.kitchen>2023-01-31 22:11:34 -0600
committerMark Powers <mark@marks.kitchen>2023-01-31 22:11:34 -0600
commitf74a597c0931122dff6f76452270633419472354 (patch)
tree82ed3de8c0e76e4c55f3797db0c39f16e69065df
parentad11ec7f93dca356748cb6c8bc49313a7ee7c3d7 (diff)
Add task timer
-rw-r--r--server.py23
-rw-r--r--static/index.html4
-rw-r--r--static/timer.html141
3 files changed, 168 insertions, 0 deletions
diff --git a/server.py b/server.py
index b678cf0..5a46c17 100644
--- a/server.py
+++ b/server.py
@@ -39,10 +39,13 @@ class TrackerHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
u = urlparse(self.path)
print("GET", u.path)
+ print("/timer", u.path)
if u.path == "/":
self.send_static_file("index.html")
elif u.path == "/new_form":
self.send_static_file("new_form.html")
+ elif u.path == "/timer":
+ self.send_static_file("timer.html")
elif date_pattern.match(u.path[1:]):
with conn.cursor() as cur:
cur.execute("SELECT datatype, key, value FROM datapoint where date(created) = %s", (u.path[1:],))
@@ -65,6 +68,15 @@ class TrackerHTTPRequestHandler(BaseHTTPRequestHandler):
self.send_response(200)
self.end_headers()
self.wfile.write(json.dumps(items).encode("utf-8"))
+ elif u.path == "/tasks":
+ with conn.cursor() as cur:
+ cur.execute("SELECT type FROM task")
+ items = []
+ for row in cur:
+ items.append(row[0])
+ self.send_response(200)
+ self.end_headers()
+ self.wfile.write(json.dumps(items).encode("utf-8"))
elif u.path == "/forms":
with conn.cursor() as cur:
cur.execute("SELECT type, prompt, prompt_id, extra FROM form ORDER BY id")
@@ -122,6 +134,15 @@ class TrackerHTTPRequestHandler(BaseHTTPRequestHandler):
self.send_response(204)
self.end_headers()
self.wfile.write(b"")
+ elif u.path == "/submit_task_time":
+ task_type = post_data.pop("type")
+ seconds = post_data.pop("seconds")
+ with conn.cursor() as cur:
+ cur.execute("INSERT INTO task_datapoint (type, seconds) VALUES (%s, %s)", (task_type, seconds))
+ conn.commit()
+ self.send_response(204)
+ self.end_headers()
+ self.wfile.write(b"")
else:
self.send_response(404)
self.end_headers()
@@ -133,6 +154,8 @@ def setup_db():
cur.execute("CREATE TABLE IF NOT EXISTS datapoint (id SERIAL PRIMARY KEY, created TIMESTAMP, datatype TEXT, key TEXT, value TEXT);")
cur.execute("CREATE TABLE IF NOT EXISTS outside_weather (id SERIAL PRIMARY KEY, created TIMESTAMP, temp FLOAT8, humidity FLOAT8, pressure FLOAT8, uvi FLOAT8, dew_point FLOAT8, wind_speed FLOAT8, wind_guest FLOAT8, wind_deg FLOAT8);")
cur.execute("CREATE TABLE IF NOT EXISTS book (id SERIAL PRIMARY KEY, title TEXT, completed BOOLEAN);")
+ cur.execute("CREATE TABLE IF NOT EXISTS task (id SERIAL PRIMARY KEY, type TEXT);")
+ cur.execute("CREATE TABLE IF NOT EXISTS task_datapoint (id SERIAL PRIMARY KEY, type TEXT, seconds TEXT);")
cur.execute("CREATE TABLE IF NOT EXISTS book_datapoint (id SERIAL PRIMARY KEY, created TIMESTAMP, book_id SERIAL, pages TEXT, CONSTRAINT fk_book FOREIGN KEY(book_id) REFERENCES book(id));")
cur.execute("CREATE TABLE IF NOT EXISTS email (id SERIAL PRIMARY KEY, created TIMESTAMP, username TEXT, domain TEXT);")
cur.execute("CREATE TABLE IF NOT EXISTS form (id SERIAL PRIMARY KEY, type TEXT, prompt TEXT, prompt_id TEXT, extra JSON);")
diff --git a/static/index.html b/static/index.html
index 83136dc..fd37550 100644
--- a/static/index.html
+++ b/static/index.html
@@ -51,6 +51,10 @@
<div id="books"></div>
<div id="prompts"></div>
<div><button onclick="on_submit()">Submit</button></div>
+ <div style="margin-top: 2rem;">
+ <a href="/timer"><button>Timer</button></a>
+ <a href="/new_form"><button>New Form</button></a>
+ </div>
<script>
function insert_multiple_select(prompt, prompt_id, items){
let root_el = document.getElementById("prompts")
diff --git a/static/timer.html b/static/timer.html
new file mode 100644
index 0000000..ecaf966
--- /dev/null
+++ b/static/timer.html
@@ -0,0 +1,141 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <style>
+ p {
+ #margin-top: 0;
+ #margin-bottom: 0;
+ }
+ label.number, label.text {
+ margin-right: 1rem;
+ }
+ label.multi-label {
+ padding: 1rem;
+ border: 1px solid #3366ff;
+ }
+ input[type="checkbox"].multi-checkbox {
+ display: none;
+ }
+ input[type="checkbox"] {
+ height: 2rem;
+ width: 2rem;
+ }
+ input:checked + label{
+ background-color: #99ccff;
+ }
+ input[type="number"] {
+ height: 3rem;
+ }
+ input[type="range"] {
+ width: 60%;
+ }
+ input[type="text"] {
+ height: 3rem;
+ }
+ .prompt {
+ margin-bottom: 2rem;
+ }
+ textarea {
+ width: 80ch;
+ height: 5rem;
+ }
+ button, select {
+ padding: 1rem;
+ border: 1px solid #3366ff;
+ }
+ .main>div {
+ margin: 1rem;
+ }
+ </style>
+ </head>
+ <body>
+ <nav></nav>
+ <div class="main">
+
+ <div id="stopwatch">0 minutes 0 seconds</div>
+ <div>
+ <button onclick="start()" id="start">Start</button>
+ </div>
+ <div>
+ <button onclick="pause()" id="pause">Pause</button>
+ </div>
+ <div>
+ <button onclick="reset()" id="reset">Reset</button>
+ </div>
+
+ <div>
+ <select id="select_el" name="type">
+ </select>
+ </div>
+
+ <div>
+ <button onclick="on_submit()">Submit</button>
+ </div>
+
+
+ <script>
+ var seconds = 0;
+ var timeoutId;
+ let stopwatch = document.getElementById("stopwatch")
+ let start_button = document.getElementById("start")
+ let pause_button = document.getElementById("pause")
+ let reset_button = document.getElementById("reset")
+ function start(){
+ start_button.disabled = true
+ pause_button.disabled = false
+ reset_button.disabled = false
+ timeoutId = setTimeout(function() {
+ seconds++
+ let disp_seconds = seconds % 60
+ let minutes = Math.trunc(seconds/60)
+ stopwatch.innerHTML = minutes + ' minutes ' + disp_seconds + " seconds"
+ start();
+ }, 1000); // setTimeout delay time 10 milliseconds
+ }
+ function pause(){
+ clearTimeout(timeoutId)
+ start_button.disabled = false
+ pause_button.disabled = true
+ reset_button.disabled = false
+ }
+ function reset(){
+ start_button.disabled = false
+ pause_button.disabled = true
+ reset_button.disabled = true
+ seconds = 0
+ stopwatch.innerHTML = '0 minutes 0 seconds'
+ }
+ async function enqueue_data(path, payload, do_alert=false){
+ payload["timestamp"] = Date.now()
+ await fetch(path, {method: "POST", body: JSON.stringify(payload)})
+ if(do_alert){
+ alert("saved!")
+ }
+ }
+ function on_submit(){
+ let payload = {
+ "type": document.getElementById("select_el").value,
+ "seconds": seconds,
+ }
+ console.log(payload)
+ enqueue_data("/submit_task_time", payload, do_alert=true)
+ }
+ window.onload = function(){
+ start_button.disabled = false
+ pause_button.disabled = true
+ reset_button.disabled = true
+ fetch("/tasks").then(res => res.json()).then(data => {
+ let el = document.getElementById("select_el")
+ data.forEach(i => {
+ let option = document.createElement("option")
+ option.setAttribute("value", i)
+ option.innerHTML = i
+
+ el.appendChild(option)
+ })
+ })
+ }
+ </script>
+ </div>
+ </body>
+</html>