From ed21ddf65324afb6cdce3aec0b97449e6c5c2829 Mon Sep 17 00:00:00 2001 From: Christian Heller <c.heller@plomlompom.de> Date: Tue, 17 Oct 2023 00:51:07 +0200 Subject: [PATCH] Improve ledger.py code. --- ledger.py | 103 +++++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 47 deletions(-) diff --git a/ledger.py b/ledger.py index 412c27d..640c63a 100755 --- a/ledger.py +++ b/ledger.py @@ -223,6 +223,9 @@ class Database: self.bookings += ret[0] self.comments += ret[1] + def get_lines(self, start, end): + return db.real_lines[start:end] + def replace(self, start, end, lines): import shutil if os.path.exists(self.lock_file): @@ -250,14 +253,21 @@ class Database: class MyServer(BaseHTTPRequestHandler): - header = '<html><meta charset="UTF-8"><body><a href="/ledger">ledger</a> <a href="/balance">balance</a> <a href="/add_free">add free</a> <a href="/add_structured">add structured</a><hr />' - footer = '</body><html>' + header = """<html> +<meta charset="UTF-8"> +<body> +<a href="/ledger">ledger</a> +<a href="/balance">balance</a> +<a href="/add_free">add free</a> +<a href="/add_structured">add structured</a> +<hr /> +""" + footer = "</body>\n<html>" def do_POST(self): length = int(self.headers['content-length']) postvars = parse_qs(self.rfile.read(length).decode(), keep_blank_values=1) parsed_url = urlparse(self.path) - if '/add_structured' == parsed_url.path: n_lines = int(len(postvars) / 4) date = postvars['date'][0] @@ -270,7 +280,7 @@ class MyServer(BaseHTTPRequestHandler): currency = postvars[f'line_{i}_currency'][0] comment = postvars[f'line_{i}_comment'][0] new_main = f'{account} {amount} {currency}' - if '' == new_main.rstrip() == comment.rstrip(): + if '' == new_main.rstrip() == comment.rstrip(): # don't write empty lines continue lines += [f'{new_main} ; {comment}'] elif '/add_free' == parsed_url.path: @@ -283,14 +293,13 @@ class MyServer(BaseHTTPRequestHandler): db.append(lines) else: db.replace(start, end, lines) - self.send_response(200) + self.send_response(301) + self.send_header('Location', '/') self.end_headers() - page = f'{self.header}Success!{self.footer}' - self.wfile.write(bytes(page, "utf-8")) except HandledException as e: self.send_response(400) self.end_headers() - page = f'{self.header}{e}{self.footer}' + page = f'{self.header}ERROR: {e}{self.footer}' self.wfile.write(bytes(page, "utf-8")) def do_GET(self): @@ -300,17 +309,14 @@ class MyServer(BaseHTTPRequestHandler): db = Database() parsed_url = urlparse(self.path) page = self.header + '' + params = parse_qs(parsed_url.query) + start = int(params.get('start', ['0'])[0]) + end = int(params.get('end', ['0'])[0]) if parsed_url.path == '/balance': page += self.balance_as_html(db) elif parsed_url.path == '/add_free': - params = parse_qs(parsed_url.query) - start = int(params.get('start', ['0'])[0]) - end = int(params.get('end', ['0'])[0]) page += self.add_free(db, start, end) elif parsed_url.path == '/add_structured': - params = parse_qs(parsed_url.query) - start = int(params.get('start', ['0'])[0]) - end = int(params.get('end', ['0'])[0]) bonus_lines = int(params.get('bonus_lines', ['0'])[0]) page += self.add_structured(db, start, end) else: @@ -398,52 +404,55 @@ class MyServer(BaseHTTPRequestHandler): suffix = f' {lines[i]}' if len(lines[i]) > 0 else '' value = f' {booking_line[1]} {booking_line[2]}' if booking_line[1] else '' lines[i] = f'{booking_line[0]}{value}{suffix}' - lines[i] = lines[i][:-len(line_sep)] + f'</p>edit: <a href="/add_structured?start={booking.start_line}&end={i+1}">structured</a> / <a href="/add_free?start={booking.start_line}&end={i+1}">free</a><br />' + lines[i] = lines[i][:-len(line_sep)] + f"""</p> +edit: +<a href="/add_structured?start={booking.start_line}&end={i+1}">structured</a> +/ <a href="/add_free?start={booking.start_line}&end={i+1}">free</a> +<br />""" return '\n'.join(lines) + def header_add_form(self, action): + return f"<form method=\"POST\" action=\"/{action}\">\n" + + def footer_add_form(self, start, end): + return f""" +<input type="hidden" name="start" value={start} /> +<input type="hidden" name="end" value={end} /> +<input type="submit"> +</form>""" + def add_free(self, db, start=0, end=0): - if start == end == 0: - content = '' - else: - content = html.escape(''.join(db.real_lines[start:end])) - return f'<form method="POST" action="/add_free"><textarea name="booking" rows="8" cols="80">{content}</textarea><input type="hidden" name="start" value={start} /><input type="hidden" name="end" value={end} /><input type="submit"></form>' + content = html.escape(''.join(db.get_lines(start, end))) + return f'{self.header_add_form("add_free")}<textarea name="booking" rows="8" cols="80">{content}</textarea>{self.footer_add_form(start, end)}' def add_structured(self, db, start=0, end=0, bonus_lines=10): - if start == end == 0: - lines = [] - else: - lines= db.real_lines[start:end] + lines = db.get_lines(start, end) bookings, comments = parse_lines(lines) if len(bookings) > 1: raise HandledException('can only edit single Booking') input_lines = '' + last_line = 0 + def inpu(name, val=""): + safe_val = html.escape(str(val)) + return f'<input name="{name}" value="{safe_val}" />' if len(bookings) == 0: - input_lines += f'<input name="date" /> <input name="description" /> ; <input name="line_0_comment" /><br />' - comments = [''] + input_lines += f'{inpu("date")} {inpu("description")} ; {inpu("comment")}<br />' + last_line = 1 else: booking = bookings[0] - if booking.start_line != 0: - raise HandledException('need to start on first Booking line') - for i, comment in enumerate(comments): - if i == 0: - safe_date_string = html.escape(booking.date_string) - safe_description = html.escape(booking.description) - safe_comment = html.escape(comment) - input_lines += f'<input name="date" value="{safe_date_string}" /> <input name="description" value="{safe_description}" /> ; <input name="line_{i}_comment" value="{safe_comment}" /><br />' - continue - safe_account = safe_amount = safe_currency = '' - safe_comment = html.escape(comment) - if i < len(booking.lines): - main = booking.lines[i] - if main != '': - safe_account = html.escape(main[0]) - safe_amount = '' if main[1] is None else html.escape(str(main[1])) - safe_currency = '' if main[2] is None else html.escape(main[2]) - input_lines += f'<input name="line_{i}_account" value="{safe_account}" /> <input name="line_{i}_amount" value="{safe_amount}" /> <input name="line_{i}_currency" value="{safe_currency}" /> ; <input name="line_{i}_comment" value="{safe_comment}" /><br />' + last_line = len(comments) + input_lines += f'{inpu("date", booking.date_string)} {inpu("description", booking.description)} ; {inpu("comment", comments[0])}<br />' + for i in range(1, len(comments)): + account = amount = currency = '' + if i < len(booking.lines) and booking.lines[i] != '': + account = booking.lines[i][0] + amount = booking.lines[i][1] + currency = booking.lines[i][2] + input_lines += f'{inpu("line_{i}_account", account)} {inpu("line_{i}_amount", amount)} {inpu("line_{i}_currency", currency)} ; {inpu("line_{i}_comment", comments[i])}<br />' for j in range(bonus_lines): - i = j + len(comments) - input_lines += f'<input name="line_{i}_account"/> <input name="line_{i}_amount"/> <input name="line_{i}_currency"/> ; <input name="line_{i}_comment" /><br />' - return f'<form method="POST" action="/add_structured">{input_lines}<input type="hidden" name="start" value={start} /><input type="hidden" name="end" value={end} /><input type="submit"></form>' + i = j + last_line + input_lines += f'{inpu("line_{i}_account")} {inpu("line_{i}_amount")} {inpu("line_{i}_currency")} ; {inpu("line_{i}_comment")}<br />' + return f'{self.header_add_form("add_structured")}{input_lines}{self.footer_add_form(start, end)}' db = Database() -- 2.30.2