X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=plomlib.py;h=2d92977a4b967b891c7052e7250b75a5f42f5de9;hb=HEAD;hp=9dac71284a5c990514c0e2c89bbd6f8a16e8a55d;hpb=5f3b9e7eb997cacea086decc3dcd04d6619b9121;p=misc diff --git a/plomlib.py b/plomlib.py index 9dac712..2d92977 100644 --- a/plomlib.py +++ b/plomlib.py @@ -1,5 +1,7 @@ import os -from http.server import BaseHTTPRequestHandler +from http.server import BaseHTTPRequestHandler +from http.cookies import SimpleCookie +import json class PlomException(Exception): @@ -9,10 +11,10 @@ class PlomException(Exception): class PlomDB: def __init__(self, db_name): - self.db_file = db_name + ".json" - self.lock_file = db_name+ ".lock" + self.db_file = db_name + self.lock_file = db_name+ '.lock' if os.path.exists(self.db_file): - with open(self.db_file, "r") as f: + with open(self.db_file, 'r') as f: self.read_db_file(f) def lock(self): @@ -27,47 +29,60 @@ class PlomDB: def backup(self): import shutil from datetime import datetime, timedelta + if not os.path.exists(self.db_file): + return + # collect modification times of numbered .bak files + # print('DEBUG BACKUP') 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.fromtimestamp(mod_time))] - i += 1 - bak_as = f'{bak_prefix}{i}' + # backup_dates = [] + mtimes_to_paths = {} + for path in [path for path in os.listdir(os.path.dirname(bak_prefix)) + if path.startswith(os.path.basename(bak_prefix))]: + path = os.path.dirname(bak_prefix) + f'/{path}' + mod_time = os.path.getmtime(path) + # print(f'DEBUG pre-exists: {path} {mod_time}') + mtimes_to_paths[str(datetime.fromtimestamp(mod_time))] = path + + # for mtime in sorted(mtimes_to_paths.keys()): + # print(f'DEBUG mtimes_to_paths: {mtime}:{mtimes_to_paths[mtime]}') # 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 = [] + # print(f'DEBUG ages_to_keep: {ages_to_keep}') + now = datetime.now() + to_save = {} 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] + limit = now - age + for mtime in reversed(sorted(mtimes_to_paths.keys())): + # print(f'DEBUG checking if {mtime} < {limit} ({now} - {age})') + if len(mtime) < 20: + mtime_test = mtime + '.000000' + else: + mtime_test = mtime + if datetime.strptime(mtime_test, '%Y-%m-%d %H:%M:%S.%f') < limit: + # print('DEBUG it is, adding!') + to_save[mtime] = mtimes_to_paths[mtime] break - # remove redundant backup files - j = 0 - for i in to_save: - if i != j: - source = f'{bak_prefix}{i}' - target = f'{bak_prefix}{j}' + for path in [path for path in mtimes_to_paths.values() + if path not in to_save.values()]: + # print(f'DEBUG removing {path} cause not in to_save') + os.remove(path) + + i = 0 + for mtime in sorted(to_save.keys()): + source = to_save[mtime] + target = f'{bak_prefix}{i}' + # print(f'DEBUG to_save {source} -> {target}') + if source != target: shutil.move(source, target) - j += 1 - for i in range(j, len(backup_dates)): - try: - os.remove(f'{bak_prefix}{i}') - except FileNotFoundError: - pass + i += 1 - # put copy of current state at end of bak list - shutil.copy(self.db_file, f'{bak_prefix}{j}') + # put copy of current state at end of bak list + # print(f'DEBUG saving current state to {bak_prefix}{i}') + shutil.copy(self.db_file, f'{bak_prefix}{i}') def write_text_to_db(self, text, mode='w'): self.lock() @@ -77,39 +92,69 @@ class PlomDB: self.unlock() -class PlomServer(BaseHTTPRequestHandler): - header = '' - footer = '' - - def run(self, port): - from http.server import HTTPServer - webServer = HTTPServer(('localhost', port), type(self)) - print(f"Server started http://localhost:{port}") - try: - webServer.serve_forever() - except KeyboardInterrupt: - pass - webServer.server_close() - print("Server stopped.") +class PlomHandler(BaseHTTPRequestHandler): + homepage = '/' + html_head = '\n\n' + html_foot = '\n' def fail_400(self, e): - page = f'{self.header}ERROR: {e}{self.footer}' - self.send_HTML(page, 400) + self.send_HTML(f'ERROR BAR: {e}', 400) def send_HTML(self, html, code=200): self.send_code_and_headers(code, [('Content-type', 'text/html')]) - self.wfile.write(bytes(html, "utf-8")) + self.wfile.write(bytes(f'{self.html_head}\n{html}\n{self.html_foot}', 'utf-8')) + + def ensure_cookies_to_set(self): + if not hasattr(self, 'cookies_to_set'): + self.cookies_to_set = [] + + def set_cookie(self, cookie_name, cookie_path, cookie_db): + self.ensure_cookies_to_set() + cookie = SimpleCookie() + cookie[cookie_name] = json.dumps(cookie_db) + cookie[cookie_name]['path'] = cookie_path + self.cookies_to_set += [cookie] + + def unset_cookie(self, cookie_name, cookie_path): + self.ensure_cookies_to_set() + cookie = SimpleCookie() + cookie[cookie_name] = '' + cookie[cookie_name]['path'] = cookie_path + cookie[cookie_name]['expires'] = 'Thu, 01 Jan 1970 00:00:00 GMT' + self.cookies_to_set += [cookie] + + def get_cookie_db(self, cookie_name): + cookie_db = {} + if 'Cookie' in self.headers: + cookie = SimpleCookie(self.headers['Cookie']) + if cookie_name in cookie: + cookie_db = json.loads(cookie[cookie_name].value) + return cookie_db def send_code_and_headers(self, code, headers=[]): + self.ensure_cookies_to_set() self.send_response(code) + for cookie in self.cookies_to_set: + for morsel in cookie.values(): + self.send_header('Set-Cookie', morsel.OutputString()) for fieldname, content in headers: self.send_header(fieldname, content) self.end_headers() + def redirect(self, url='/'): + self.send_code_and_headers(302, [('Location', url)]) + + def try_do(self, do_method): + try: + do_method() + except PlomException as e: + self.fail_400(e) + + -def run_server(port, server_class): +def run_server(port, handler_class): from http.server import HTTPServer - webServer = HTTPServer(('localhost', port), server_class) + webServer = HTTPServer(('localhost', port), handler_class) print(f"Server started http://localhost:{port}") try: webServer.serve_forever()