commit 9f761a0c0a4789c52a4e767bcc5f9f3699de5a53 from: Aleksey Ryndin date: Wed Sep 25 19:46:12 2024 UTC Fix: move demo to sqlite3 commit - 4acbf994ae02d25a0bf1246afa8a910382a03bff commit + 9f761a0c0a4789c52a4e767bcc5f9f3699de5a53 blob - 61b7bd6bc9df99a108fca291d18a79aeacf0bfb4 blob + f08611d87263eb82aa444c73f7bcf8f283755ad2 --- lonk.py +++ lonk.py @@ -236,59 +236,14 @@ def _proxy_url_factory(proxy_media_enabled, lonk_url): url ) return _get_proxy_url - - -def demo(lonk_url, honk_url): - collected = {} - banned = set() - - home = honk_url.do_get(action="gethonks", page="home") - for honk in reversed(home["honks"]): - convoy = honk["Convoy"] - if convoy in collected or convoy in banned: - continue - if honk.get("RID"): - for honk_in_convoy in honk_url.do_get(action="gethonks", page="convoy", c=convoy)["honks"]: - if not honk_in_convoy.get("RID"): - from_ = honk_in_convoy.get("Oondle") or honk_in_convoy["Handle"] - header = f'## From: {from_}, {honk_in_convoy["Date"]} (๐Ÿงต {honk["Handle"]})' - collected[convoy] = (honk_in_convoy, header) - break - else: - banned.add(convoy) - else: - oondle = honk.get("Oondle") - if oondle: - header = f'## From: {oondle}, {honk["Date"]} (๐Ÿ” {honk["Handle"]})' - else: - header = f'## From: {honk["Handle"]}, {honk["Date"]}' - collected[convoy] = (honk, header) - - print("20 text/gemini\r") - print("# ๐“— onk\n") - - line = f"=> {honk_url.build_url(path='atme')} @me" - if home["mecount"]: - line += f' ({home["mecount"]})' - print(line) - line = f"=> {honk_url.build_url(path='chatter')} chatter" - if home["chatcount"]: - line += f' ({home["chatcount"]})' - print(line) - fn_media_url = _proxy_url_factory(environ.get("LONK_PROXY_MEDIA"), lonk_url) - for honk, header in reversed(collected.values()): - print() - print(_format_honk(honk, header, honk_url, fn_media_url)) - - def _create_schema(db_con, cert_hash): db_con.execute( """ CREATE TABLE client ( - client_id INTEGER PRIMARY KEY AUTOINCREMENT, + client_id INTEGER PRIMARY KEY, cert_hash TEXT UNIQUE, honk_url TEXT NOT NULL, token TEXT NOT NULL @@ -299,32 +254,36 @@ def _create_schema(db_con, cert_hash): """ CREATE TABLE convoy ( - convoy_id TEXT, + convoy_id INTEGER PRIMARY KEY, + convoy TEXT, client_id INTEGER, - header TEXT, - FOREIGN KEY (client_id) REFERENCES client(client_id), - PRIMARY KEY (convoy_id, client_id) + honk_id INTEGER, + honker TEXT, + url TEXT, + html TEXT, + date TEXT, + FOREIGN KEY (client_id) REFERENCES client (client_id), + UNIQUE (convoy, client_id), + UNIQUE (honk_id, client_id) ) """ ) db_con.execute( """ CREATE TABLE - honk ( - honk_id INTEGER, - client_id INTEGER, - convoy_id TEXT, + donk ( + donk_id INTEGER PRIMARY KEY, + convoy_id INTEGER, url TEXT NOT NULL, - html TEXT NOT NULL, - FOREIGN KEY (client_id) REFERENCES client(client_id), - FOREIGN KEY (convoy_id) REFERENCES convoy(convoy_id), - PRIMARY KEY (honk_id, client_id) + mime TEXT, + alt_text TEXT, + FOREIGN KEY (convoy_id) REFERENCES convoy (convoy_id) ) """ ) # ========================================================================== - # TODO: test code + # TODO: test code (cert_hash must be removed, cascade) with open(".local/settings.json") as f: settings = json_loads(f.read()) db_con.execute( @@ -347,70 +306,124 @@ def db_connect(cert_hash): def _lonk_impl(db_con, client_id, lonk_url, honk_url): row = db_con.execute( - "SELECT MAX(honk_id) FROM honk WHERE client_id=?", + "SELECT MAX(honk_id) FROM convoy WHERE client_id=?", (client_id, ) - ) + ).fetchone() after, = row + fn_media_url = _proxy_url_factory(environ.get("LONK_PROXY_MEDIA"), lonk_url) + home = honk_url.do_get(action="gethonks", page="home", after=after) - for honk in reversed(home["honks"]): - convoy_id = honk["Convoy"] - raise RuntimeError(convoy_id) + for honk in reversed(home.get("honks") or []): + convoy = honk["Convoy"] row = db_con.execute( - "SELECT convoy.header, honk.url, honk.html FROM convoy JOIN honk USING (convoy_id) WHERE convoy.client_id=? AND convoy_id=?", - (client_id, convoy_id) + "SELECT convoy_id FROM convoy WHERE client_id=? AND convoy=?", + (client_id, convoy) ).fetchone() if row: continue - def _save_convoy_and_honk(header, honk): - db_con.execute( + def _save_convoy(honker, honk): + row = db_con.execute( """ INSERT INTO - convoy(convoy_id, client_id, header) + convoy(convoy, client_id, honk_id, honker, url, html, date) VALUES - (?, ?, ?) + (?, ?, ?, ?, ?, ?, ?) + RETURNING convoy_id """, - (convoy_id, client_id, header) - ) - db_con.execute( - """ - INSERT INTO - honk (honk_id, client_id, convoy_id, url, html) - VALUES - (?, ?, ?, ?, ?) - """, - (honk["ID"], client_id, convoy_id, honk["XID"], honk["HTML"]) - ) - + (convoy, client_id, honk["ID"], honker, honk["XID"], honk["HTML"], honk["Date"]) + ).fetchone() + convoy_id, = row + for donk in (honk.get("Donks") or []): + donk_url = honk_url.build_url(path=f'/d/{donk["XID"]}') if donk.get("XID") else donk["URL"] + db_con.execute( + "INSERT INTO donk (convoy_id, url, mime, alt_text) VALUES (?, ?, ?, ?)", + (convoy_id, donk_url, donk["Media"], donk.get("Desc") or donk.get("Name") or None) + ) + if honk.get("RID"): - for honk_in_convoy in honk_url.do_get(action="gethonks", page="convoy", c=convoy_id)["honks"]: + for honk_in_convoy in honk_url.do_get(action="gethonks", page="convoy", c=convoy)["honks"]: if not honk_in_convoy.get("RID"): - from_ = honk_in_convoy.get("Oondle") or honk_in_convoy["Handle"] - header = f'## From: {from_}, {honk_in_convoy["Date"]} (๐Ÿงต {honk["Handle"]})' - _save_convoy_and_honk(header, honk_in_convoy) + author = honk_in_convoy.get("Oondle") or honk_in_convoy["Handle"] + honker = f'{author} (๐Ÿงต {honk["Handle"]})' + _save_convoy(honker, honk_in_convoy) break else: db_con.execute( """ INSERT INTO - convoy(convoy_id, client_id) + convoy(convoy, client_id, honk_id) VALUES - (?, ?) + (?, ?, ?) """, - (convoy_id, client_id) + (convoy, client_id, honk["ID"]) ) else: - honk_from = honk.get("Oondle") or honk["Handle"] oondle = honk.get("Oondle") - if oondle: - header = f'From: {oondle}, {honk["Date"]} (๐Ÿ” {honk["Handle"]})' - else: - header = f'From: {honk["Handle"]}, {honk["Date"]}' - _save_convoy_and_honk(header, honk) + honker = f'{oondle} (๐Ÿ” {honk["Handle"]})' if oondle else f'{honk["Handle"]}' + _save_convoy(honker, honk) + res = db_con.execute( + """ + SELECT + convoy_id, honker, url, html, date + FROM + convoy + WHERE + client_id=? AND honker IS NOT NULL + ORDER BY + convoy_id DESC + LIMIT 256 + """, + (client_id, ) + ) + print("20 text/gemini\r") + print("# ๐“— onk\r") + print("\r") + + line = f"=> {honk_url.build_url(path='atme')} @me" + if home["mecount"]: + line += f' ({home["mecount"]})' + print(line + "\r") + + line = f"=> {honk_url.build_url(path='chatter')} chatter" + if home["chatcount"]: + line += f' ({home["chatcount"]})' + print(line + "\r") + print("\r") + + while True: + rows = res.fetchmany() + if not rows: + break + + for row in rows: + convoy_id, honker, url, html, date, = row + lines = [ + f"## From {honker} {date}", + f"=> {url}", + HtmlToGmi(honk_url.build_url(), fn_media_url).feed(html) + ] + res_donks = db_con.execute( + "SELECT url, mime, alt_text FROM donk WHERE convoy_id=?", + (convoy_id, ) + ) + while True: + donks = res_donks.fetchmany() + if not donks: + break + for donk in donks: + donk_url, donk_mime, donk_text, = donk + lines.append(f'=> {fn_media_url(donk_mime, donk_url)}') + if donk_text: + lines.append(donk_text) + print("\r\n".join(lines)) + print("\r") + + def lonk(cert_hash, lonk_url): db_con = db_connect(cert_hash) row = db_con.execute("SELECT client_id, honk_url, token FROM client WHERE cert_hash=?", (cert_hash, )).fetchone() @@ -420,7 +433,6 @@ def lonk(cert_hash, lonk_url): client_id, honk_url, token = row with db_con: _lonk_impl(db_con, client_id, lonk_url, HonkUrl(honk_url, token)) - # demo(lonk_url, HonkUrl(honk_url, token)) def new_client_stage_1_ask_server(lonk_url): @@ -510,7 +522,7 @@ if __name__ == '__main__': raw_url = input().strip() vgi(cert_hash, raw_url) finally: - stderr.write(f"{raw_url}|{clock_gettime(CLOCK_MONOTONIC) - start_time:.3f}sec.\n") + stderr.write(f"{cert_hash}|{raw_url}|{clock_gettime(CLOCK_MONOTONIC) - start_time:.3f}sec.\n") except HTTPError as error: print(f"43 Remote server return {error.code}: {error.reason}\r") except URLError as error: