home · contact · privacy
Add energy tracker script.
[misc] / energy_tracker.py
1 from http.server import BaseHTTPRequestHandler, HTTPServer
2 import os
3 import json
4
5
6
7 def build_page(entries):
8     return """<html>
9 <meta charset="UTF-8">
10 <style>
11 .energy_cell {
12   text-align: center;
13 }
14 </style>
15 <body>
16 <form action="/" method="POST">
17 energy level:
18 <input name="energy" type="number" step="1" min="-2" max="2" value="0" />
19 comment:
20 <input name="comment" type="text" />
21 <input type="submit" value="submit!" />
22 </form>""" + f"""
23 <details>
24 <summary>
25 [tracking]
26 </summary>
27 <table>
28 <tr><th>datetime</th><th>energy level</th><th>comment</th></tr>
29 {entries}
30 </table>""" + """
31 </details>
32 </body>
33 </html>"""
34
35
36
37 class Database: 
38
39     def __init__(self):
40         db_name = "energy_tracker"
41         self.db_file = db_name + ".json"
42         self.lock_file = db_name+ ".lock"
43         self.entries = {}
44         if os.path.exists(self.db_file):
45             with open(self.db_file, "r") as f:
46                 self.from_dict(json.load(f))
47
48     def from_dict(self, d):
49         self.entries = d
50
51     def to_dict(self):
52         return self.entries 
53
54     def write(self):
55         import shutil
56         if os.path.exists(self.lock_file):
57             raise LockFileDetected
58         if os.path.exists(self.db_file):
59             shutil.copy(self.db_file, self.db_file + ".bak")
60         f = open(self.lock_file, "w+")
61         f.close()
62         with open(self.db_file, "w") as f:
63             json.dump(self.to_dict(), f)
64         os.remove(self.lock_file)
65
66
67
68 class MyServer(BaseHTTPRequestHandler):
69
70     def do_POST(self):
71         import datetime
72         from urllib.parse import parse_qs
73         length = int(self.headers['content-length'])
74         postvars = parse_qs(self.rfile.read(length), keep_blank_values=1)
75         db = Database()
76         db.entries[str(datetime.datetime.now())[:19]] = [int(postvars[b'energy'][0].decode()), postvars[b'comment'][0].decode()] 
77         try:
78             db.write()
79             self.send_response(302)
80             self.send_header('Location', '/')
81             self.end_headers()
82         except LockFileDetected:
83             self.send_response(400)
84             self.end_headers()
85             self.wfile.write(bytes("Sorry, lock file!", "utf-8"))
86
87     def do_GET(self):
88         self.send_response(200)
89         self.send_header("Content-type", "text/html")
90         self.end_headers()
91         db = Database()
92         entries = ""
93         for datetime, data in db.entries.items():
94             entries = "<tr><td>%s</td><td class=\"energy_cell\">%s</td><td>%s</td></tr>\n" % (datetime, data[0], data[1]) + entries
95         page = build_page(entries)
96         self.wfile.write(bytes(page, "utf-8"))
97
98
99
100 hostName = "localhost"
101 serverPort = 8080
102 if __name__ == "__main__":        
103     webServer = HTTPServer((hostName, serverPort), MyServer)
104     print("Server started http://%s:%s" % (hostName, serverPort))
105     try:
106         webServer.serve_forever()
107     except KeyboardInterrupt:
108         pass
109     webServer.server_close()
110     print("Server stopped.")