From: Christian Heller Date: Sat, 18 Nov 2023 23:08:56 +0000 (+0100) Subject: Improve ledger.py. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/%7B%7Bdb.prefix%7D%7D/day?a=commitdiff_plain;h=75169bb51854ec32d147976ac4381c6011c5320d;p=misc Improve ledger.py. --- diff --git a/ledger.py b/ledger.py index 4a6a071..c004d22 100755 --- a/ledger.py +++ b/ledger.py @@ -3,7 +3,7 @@ import os import html import jinja2 import decimal -import datetime +from datetime import datetime, timedelta from urllib.parse import parse_qs, urlparse hostName = "localhost" serverPort = 8082 @@ -108,7 +108,7 @@ def parse_lines(lines, validate_bookings=True): toks = non_comment.split(maxsplit=1) date_string = toks[0] try: - datetime.datetime.strptime(date_string, '%Y-%m-%d') + datetime.strptime(date_string, '%Y-%m-%d') except ValueError: raise HandledException(f"{prefix} bad date string: {date_string}") if last_date > date_string: @@ -279,37 +279,30 @@ class Database: f = open(self.lock_file, 'w+') f.close() - # always back up most recent to .bak - bakpath = f'{self.db_file}.bak' - shutil.copy(self.db_file, bakpath) - # collect modification times of numbered .bak files - bak_prefix = f'{bakpath}.' + bak_prefix = f'{self.db_file}.bak.' backup_dates = [] i = 0 bak_as = f'{bak_prefix}{i}' while os.path.exists(bak_as): mod_time = os.path.getmtime(bak_as) - backup_dates += [str(datetime.datetime.fromtimestamp(mod_time))] + backup_dates += [str(datetime.fromtimestamp(mod_time))] i += 1 bak_as = f'{bak_prefix}{i}' - # collect what numbered .bak files to save: - # shrink datetime string right to left character by character, - # on each step add the oldest file whose mtime still fits the pattern - # (privilege older files to keep existing longer) + # collect what numbered .bak files to save: the older, the fewer; for each + # timedelta, keep the newest file that's older + ages_to_keep = [timedelta(minutes=4**i) for i in range(0, 8)] + now = datetime.now() to_save = [] - datetime_len = 19 - now = str(datetime.datetime.now())[:datetime_len] - while datetime_len > 2: - # assume backup_dates starts with oldest dates - for i, date in enumerate(backup_dates): - if date[:datetime_len] == now: - if i not in to_save: - to_save += [i] - break - datetime_len -= 1 - now = now[:datetime_len] + for age in ages_to_keep: + limit = now - age + for i, date in enumerate(reversed(backup_dates)): + if datetime.strptime(date, '%Y-%m-%d %H:%M:%S.%f') < limit: + unreversed_i = len(backup_dates) - i - 1 + if unreversed_i not in to_save: + to_save += [unreversed_i] + break # remove redundant backup files j = 0 @@ -325,7 +318,7 @@ class Database: except FileNotFoundError: pass - # put second backup copy of current state at end of bak list + # put copy of current state at end of bak list shutil.copy(self.db_file, f'{bak_prefix}{j}') with open(self.db_file, mode) as f: f.write(text); @@ -564,20 +557,20 @@ input[type=number] { text-align: right; font-family: monospace; } _, _ = parse_lines(lines) # if saving, process where to and where to redirect after if 'save' in postvars.keys(): - last_date = str(datetime.datetime.now())[:10] + last_date = str(datetime.now())[:10] if len(db.bookings) > 0: last_date = db.bookings[-1].date_string target_date = last_date[:] first_line_tokens = lines[0].split() if len(lines) > 0 else '' first_token = first_line_tokens[0] if len(first_line_tokens) > 0 else '' try: - datetime.datetime.strptime(first_token, '%Y-%m-%d') + datetime.strptime(first_token, '%Y-%m-%d') target_date = first_token except ValueError: pass if start == end == 0: - start = db.insert_at_date(lines, target_date) - nth = db.get_nth_for_booking_of_start_line(start) + start = db.insert_at_date(lines, target_date) + nth = db.get_nth_for_booking_of_start_line(start) else: new_start = db.update(start, end, lines, target_date) nth = db.get_nth_for_booking_of_start_line(new_start) @@ -811,7 +804,7 @@ input[type=number] { text-align: right; font-family: monospace; } for currency in moneys.keys(): datalist_sets['currencies'].add(currency) content = '' - today = str(datetime.datetime.now())[:10] + today = str(datetime.now())[:10] booking_lines = [] if copy: start = end = 0