X-Git-Url: https://plomlompom.com/repos/process?a=blobdiff_plain;ds=inline;f=ledger.py;h=7771f7f7e458ec4848cf0c19535034c18cda7556;hb=88432b5868d90a30de13a6745f68817d54d40092;hp=412c27d44b373e5aa9beeac82ec7e90b0d7b4a24;hpb=c018936a82d6caa32affe9c01af8f1d68e568a70;p=misc
diff --git a/ledger.py b/ledger.py
index 412c27d..7771f7f 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 = '
ledger balance add free add structured
'
- footer = ''
+ header = """
+
+
+ledger
+balance
+add free
+add structured
+
+"""
+ footer = "\n"
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,9 +280,12 @@ 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}']
+ new_line = new_main
+ if comment.rstrip() != '':
+ new_line += f' ; {comment}'
+ lines += [new_line]
elif '/add_free' == parsed_url.path:
lines = postvars['booking'][0].splitlines()
start = int(postvars['start'][0])
@@ -283,14 +296,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 +312,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:
@@ -385,7 +394,7 @@ class MyServer(BaseHTTPRequestHandler):
lines = []
line_sep = '
'
for comment in db.comments:
- line = f'; {comment}' if comment != '' else ''
+ line = f' ; {comment}' if comment != '' else ''
lines += [line + line_sep]
for booking in db.bookings:
i = booking.start_line
@@ -398,52 +407,75 @@ 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'edit: structured / free
'
+ lines[i] = lines[i][:-len(line_sep)] + f"""
+edit:
+structured
+/ free
+
"""
return '\n'.join(lines)
+ def header_add_form(self, action):
+ return f""""
+
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''
+ content = html.escape(''.join(db.get_lines(start, end)))
+ return f'{self.header_add_form("add_free")}{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]
+ import datetime
+ 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="", datalist=""):
+ val = val if val is not None else ""
+ safe_val = html.escape(str(val))
+ datalist_string = '' if datalist == '' else f'list="{datalist}"'
+ return f''
if len(bookings) == 0:
- input_lines += f' ;
'
- comments = ['']
+ today = str(datetime.datetime.now())[:10]
+ input_lines += f'{inpu("date", today)} {inpu("description", "", "descriptions")} ; {inpu("line_0_comment")}
'
+ 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' ;
'
- 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' ;
'
+ last_line = len(comments)
+ input_lines += f'{inpu("date", booking.date_string)} {inpu("description", booking.description, "descriptions")} ; {inpu("line_0_comment", comments[0])}
'
+ 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(f"line_{i}_account", account, "accounts")} {inpu(f"line_{i}_amount", amount)} {inpu(f"line_{i}_currency", currency, "currencies")} ; {inpu(f"line_{i}_comment", comments[i])}
'
for j in range(bonus_lines):
- i = j + len(comments)
- input_lines += f' ;
'
- return f''
+ i = j + last_line
+ input_lines += f'{inpu(f"line_{i}_account", "", "accounts")} {inpu(f"line_{i}_amount", "", "amounts")} {inpu(f"line_{i}_currency", "â¬", "currencies")} ; {inpu(f"line_{i}_comment")}
'
+ datalist_sets = {'descriptions': set(), 'accounts': set(), 'currencies': set()}
+ for b in db.bookings:
+ datalist_sets['descriptions'].add(b.description)
+ for account, moneys in b.account_changes.items():
+ datalist_sets['accounts'].add(account)
+ for currency in moneys.keys():
+ datalist_sets['currencies'].add(currency)
+ def build_datalist(name):
+ datalist = f'\n"
+ datalists = build_datalist('descriptions')
+ datalists += build_datalist('accounts')
+ datalists += build_datalist('currencies')
+ return f'{self.header_add_form("add_structured")}{input_lines}{datalists}{self.footer_add_form(start, end)}'
db = Database()