X-Git-Url: https://plomlompom.com/repos/pick_tasks?a=blobdiff_plain;f=income_progress_bars.py;h=5d9a887323feb2cc7da85f1e81dae7bc696d83f2;hb=4cfc09fc8f1a60aa266c16eb7d67b13c5e576042;hp=1ecd8b9a14452b0bc352084ef98ca7f4a8955140;hpb=a546cea97f153d5f6def4e46309dcb76038d7891;p=misc
diff --git a/income_progress_bars.py b/income_progress_bars.py
index 1ecd8b9..5d9a887 100644
--- a/income_progress_bars.py
+++ b/income_progress_bars.py
@@ -1,12 +1,12 @@
-from http.server import BaseHTTPRequestHandler, HTTPServer
import os
import json
+import jinja2
+from plomlib import PlomDB, PlomException, run_server, PlomHandler
-hostName = "localhost"
-serverPort = 8081
+server_port = 8083
+db_path = '/home/plom/org/income.json'
-header = """
-
+tmpl = """
- | earned | progress | surplus |
-"""
-footer = """
-
-"""
+"""
-db_default = {
- "timestamp_year": 0,
- "timestamp_month": 0,
- "timestamp_week": 0,
- "year_income": 0,
- "month_income": 0,
- "week_income": 0,
- "workday_hourly_rate_1": 10,
- "workday_minutes_worked_1": 0,
- "workday_hourly_rate_2": 25,
- "workday_minutes_worked_2": 0,
- "workday_hourly_rate_3": 50,
- "workday_minutes_worked_3": 0,
- "year_goal": 20000,
- "workdays_per_month": 16
-}
-db_file = "db.json"
-lock_file = "db.lock"
-def load_db():
- if os.path.exists(db_file):
- with open(db_file, "r") as f:
- return json.load(f)
- else:
- return db_default
-class MyServer(BaseHTTPRequestHandler):
+class IncomeDB(PlomDB):
+
+ def __init__(self):
+ # defaults
+ self.timestamp_year = 0,
+ self.timestamp_month = 0,
+ self.timestamp_week = 0,
+ self.year_income = 0,
+ self.month_income = 0,
+ self.week_income = 0,
+ self.workday_hourly_rate_1 = 10,
+ self.workday_hourly_rate_2 = 25,
+ self.workday_hourly_rate_3 = 50,
+ self.workday_minutes_worked_1 = 0,
+ self.workday_minutes_worked_2 = 0,
+ self.workday_minutes_worked_3 = 0,
+ self.year_goal = 20000,
+ self.workdays_per_month = 16
+ super().__init__(db_path)
+
+ def read_db_file(self, f):
+ d = json.load(f)
+ for k, v in d.items():
+ if not hasattr(self, k):
+ raise PlomException("bad key in db: " + k)
+ setattr(self, k, v)
+
+ def to_dict(self):
+ keys = [k for k in dir(self) if (not k.startswith('_')) and (not callable(getattr(self, k)))]
+ d = {}
+ for k in keys:
+ d[k] = getattr(self, k)
+ return d
+
+ def write_db(self):
+ self.write_text_to_db(json.dumps(self.to_dict()))
+
+
+class ProgressBar:
+ def __init__(self, title, earned, goal, time_progress=-1):
+ self.title = title
+ self.earned = earned
+ self.time_progress = int(time_progress * 100)
+ success_income = self.earned / goal
+ self.success_income_cut = int(min(success_income, 1.0) * 100)
+ self.success_income_bonus = int(max(success_income - 1.0, 0) * 100)
+ self.success = success_income + 0
+ self.diff_goal = "%.2fâ¬" % (self.earned - goal)
+ if title != "workday":
+ self.diff_goal += "(%.2fâ¬)" % (self.earned - (goal * time_progress))
+ if time_progress >= 0:
+ self.success = 1
+ if time_progress > 0:
+ self.success = success_income / time_progress
+
+
+class IncomeProgressHandler(PlomHandler):
+
+ def app_init(self, handler):
+ default_path = '/income_progress'
+ handler.add_route('GET', default_path, self.display_income_progress)
+ handler.add_route('POST', default_path, self.post_income_update)
+ return 'income_progress', default_path
def do_POST(self):
+ self.try_do(self.post_income_update)
+
+ def post_income_update(self):
from urllib.parse import parse_qs
length = int(self.headers['content-length'])
- postvars = parse_qs(self.rfile.read(length), keep_blank_values=1)
- db = load_db()
- db["workday_minutes_worked_1"] = int(postvars[b'workday_minutes_worked_1'][0].decode())
- db["workday_minutes_worked_2"] = int(postvars[b'workday_minutes_worked_2'][0].decode())
- db["workday_minutes_worked_3"] = int(postvars[b'workday_minutes_worked_3'][0].decode())
- db["workday_hourly_rate_1"] = int(postvars[b'workday_hourly_rate_1'][0].decode())
- db["workday_hourly_rate_2"] = int(postvars[b'workday_hourly_rate_2'][0].decode())
- db["workday_hourly_rate_3"] = int(postvars[b'workday_hourly_rate_3'][0].decode())
- db["year_goal"] = int(postvars[b'year_goal'][0].decode())
- db["workdays_per_month"] = int(postvars[b'workdays_per_month'][0].decode())
- if b'finish' in postvars.keys():
- day_income = (db["workday_minutes_worked_1"] / 60.0) * db["workday_hourly_rate_1"]
- day_income += (db["workday_minutes_worked_2"] / 60.0) * db["workday_hourly_rate_2"]
- day_income += (db["workday_minutes_worked_3"] / 60.0) * db["workday_hourly_rate_3"]
- db["year_income"] += day_income
- db["month_income"] += day_income
- db["week_income"] += day_income
- db["workday_minutes_worked_1"] = 0
- db["workday_minutes_worked_2"] = 0
- db["workday_minutes_worked_3"] = 0
- if not os.path.exists(lock_file):
- with open(lock_file, "w+"): pass
- with open(db_file, "w") as f:
- json.dump(db, f)
- os.remove(lock_file)
- self.send_response(302)
- self.send_header('Location', '/')
- self.end_headers()
- else:
- self.send_response(400)
- self.end_headers()
- self.wfile.write(bytes("Sorry, lock file!", "utf-8"))
+ postvars = parse_qs(self.rfile.read(length).decode(), keep_blank_values=1)
+ db = IncomeDB()
+ db.workday_minutes_worked_1 = int(postvars['workday_minutes_worked_1'][0])
+ db.workday_minutes_worked_2 = int(postvars['workday_minutes_worked_2'][0])
+ db.workday_minutes_worked_3 = int(postvars['workday_minutes_worked_3'][0])
+ db.workday_hourly_rate_1 = int(postvars['workday_hourly_rate_1'][0])
+ db.workday_hourly_rate_2 = int(postvars['workday_hourly_rate_2'][0])
+ db.workday_hourly_rate_3 = int(postvars['workday_hourly_rate_3'][0])
+ db.year_goal = int(postvars['year_goal'][0])
+ db.workdays_per_month = int(postvars['workdays_per_month'][0])
+ if 'finish' in postvars.keys():
+ day_income = (db.workday_minutes_worked_1 / 60.0) * db.workday_hourly_rate_1
+ day_income += (db.workday_minutes_worked_2 / 60.0) * db.workday_hourly_rate_2
+ day_income += (db.workday_minutes_worked_3 / 60.0) * db.workday_hourly_rate_3
+ db.year_income += day_income
+ db.month_income += day_income
+ db.week_income += day_income
+ db.workday_minutes_worked_1 = 0
+ db.workday_minutes_worked_2 = 0
+ db.workday_minutes_worked_3 = 0
+ db.write_db()
+ homepage = self.apps['income_progress'] if hasattr(self, 'apps') else self.homepage
+ self.redirect(homepage)
def do_GET(self):
+ self.try_do(self.display_income_progress)
+
+ def display_income_progress(self):
import datetime
- import calendar
- self.send_response(200)
- self.send_header("Content-type", "text/html")
- self.end_headers()
- db = load_db()
+ import calendar
+ db = IncomeDB()
today = datetime.datetime.now()
- if not os.path.exists(lock_file):
- update_db = False
- if today.year != db["timestamp_year"]:
- db["timestamp_year"] = today.year
- db["year_income"] = 0
- update_db = True
- if today.month != db["timestamp_month"]:
- db["timestamp_month"] = today.month
- db["month_income"] = 0
- update_db = True
- if today.isocalendar()[1] != db["timestamp_week"]:
- db["timestamp_week"] = today.isocalendar()[1]
- db["week_income"] = 0
- update_db = True
- if update_db:
- print("Resetting timestamp")
- with open(lock_file, "w+"): pass
- with open(db_file, "w") as f:
- json.dump(db, f)
- os.remove(lock_file)
- else:
- self.send_response(400)
- self.end_headers()
- self.wfile.write(bytes("Sorry, lock file!", "utf-8"))
- return
+ update_db = False
+ if today.year != db.timestamp_year:
+ db.timestamp_year = today.year
+ db.timestamp_month = today.month
+ db.year_income = 0
+ db.month_income = 0
+ update_db = True
+ if today.month != db.timestamp_month:
+ db.timestamp_month = today.month
+ db.month_income = 0
+ update_db = True
+ if today.isocalendar()[1] != db.timestamp_week:
+ db.timestamp_week = today.isocalendar()[1]
+ db.week_income = 0
+ update_db = True
+ if update_db:
+ print("Resetting timestamp")
+ db.write_db()
day_of_year = today.toordinal() - datetime.date(today.year, 1, 1).toordinal() + 1
year_length = 365 + calendar.isleap(today.year)
- workday_goal = db["year_goal"] / 12 / db["workdays_per_month"]
- workdays_per_week = (db["workdays_per_month"] * 12) / (year_length / 7)
- month_goal = db["year_goal"] / 12
- week_goal = db["year_goal"] / (year_length / 7)
- def success_color(success):
- if success < 0.5:
- return "red";
- elif success < 1:
- return "yellow";
- else:
- return "green"
- def progressbar(title, earned, goal, time_progress=-1):
- time_progress_indicator = ""
- success_income = earned / goal
- success_income_cut = min(success_income, 1.0)
- success_income_bonus = max(success_income - 1.0, 0)
- success = success_income + 0
- diff_goal = "%.2fâ¬" % (earned - goal)
- if title != "workday":
- diff_goal += "(%.2fâ¬)" % (earned - (goal * time_progress))
- if time_progress >= 0:
- success = 1
- if time_progress > 0:
- success = success_income / time_progress
- time_progress_indicator = "" % int(time_progress * 100)
- return "%s | " \
- "%.2f⬠| " \
- "%s | " \
- "%s |
" % (
- title, earned, time_progress_indicator, success_color(success), int(success_income_cut * 100), diff_goal, int(success_income_bonus * 100))
- day_income = (db["workday_minutes_worked_1"] / 60.0) * db["workday_hourly_rate_1"]
- day_income += (db["workday_minutes_worked_2"] / 60.0) * db["workday_hourly_rate_2"]
- day_income += (db["workday_minutes_worked_3"] / 60.0) * db["workday_hourly_rate_3"]
- year_plus = db["year_income"] + day_income
- month_plus = db["month_income"] + day_income
- week_plus = db["week_income"] + day_income
- progress_time_year = day_of_year / year_length
- progress_time_month = today.day / calendar.monthrange(today.year, today.month)[1]
- progress_time_week = today.weekday() / 7
- year_line = progressbar("year", year_plus, db["year_goal"], progress_time_year)
- month_line = progressbar("month", month_plus, month_goal, progress_time_month)
- week_line = progressbar("week", week_plus, week_goal, progress_time_week)
- day_line = progressbar("workday", day_income, workday_goal)
- body = year_line + "\n" + month_line + "\n" + week_line + "\n" + day_line
- page = header + body + footer % (
- db["workday_hourly_rate_1"], db["workday_minutes_worked_1"],
- db["workday_hourly_rate_2"], db["workday_minutes_worked_2"],
- db["workday_hourly_rate_3"], db["workday_minutes_worked_3"],
- db["year_goal"],
- month_goal,
- week_goal,
- db["workdays_per_month"],
- workday_goal,
- workdays_per_week,
+ workday_goal = db.year_goal / 12 / db.workdays_per_month
+ workdays_per_week = (db.workdays_per_month * 12) / (year_length / 7)
+ month_goal = db.year_goal / 12
+ week_goal = db.year_goal / (year_length / 7)
+ day_income = (db.workday_minutes_worked_1 / 60.0) * db.workday_hourly_rate_1
+ day_income += (db.workday_minutes_worked_2 / 60.0) * db.workday_hourly_rate_2
+ day_income += (db.workday_minutes_worked_3 / 60.0) * db.workday_hourly_rate_3
+ year_plus = db.year_income + day_income
+ month_plus = db.month_income + day_income
+ week_plus = db.week_income + day_income
+ progress_time_year = day_of_year / year_length
+ progress_time_month = today.day / calendar.monthrange(today.year, today.month)[1]
+ progress_time_week = today.weekday() / 7
+ progress_bars = [ProgressBar("year", year_plus, db.year_goal, progress_time_year),
+ ProgressBar("month", month_plus, month_goal, progress_time_month),
+ ProgressBar("week", week_plus, week_goal, progress_time_week),
+ ProgressBar("workday", day_income, workday_goal)]
+ homepage = self.apps['income_progress'] if hasattr(self, 'apps') else self.homepage
+ page = jinja2.Template(tmpl).render(
+ homepage = homepage,
+ progress_bars = progress_bars,
+ workday_hourly_rate_1 = db.workday_hourly_rate_1,
+ workday_minutes_worked_1 = db.workday_minutes_worked_1,
+ workday_hourly_rate_2 = db.workday_hourly_rate_2,
+ workday_minutes_worked_2 = db.workday_minutes_worked_2,
+ workday_hourly_rate_3 = db.workday_hourly_rate_3,
+ workday_minutes_worked_3 = db.workday_minutes_worked_3,
+ year_goal = db.year_goal,
+ month_goal = month_goal,
+ week_goal = week_goal,
+ workdays_per_month = db.workdays_per_month,
+ workday_goal = workday_goal,
+ workdays_per_week = workdays_per_week,
)
- self.wfile.write(bytes(page, "utf-8"))
+ self.send_HTML(page)
+
-if __name__ == "__main__":
- webServer = HTTPServer((hostName, serverPort), MyServer)
- print(f"Server started http://{hostName}:{serverPort}")
- try:
- webServer.serve_forever()
- except KeyboardInterrupt:
- pass
- webServer.server_close()
- print("Server stopped.")
+if __name__ == "__main__":
+ run_server(server_port, IncomeProgressHandler)