commit - 4acbf994ae02d25a0bf1246afa8a910382a03bff
commit + 9f761a0c0a4789c52a4e767bcc5f9f3699de5a53
blob - 61b7bd6bc9df99a108fca291d18a79aeacf0bfb4
blob + f08611d87263eb82aa444c73f7bcf8f283755ad2
--- lonk.py
+++ lonk.py
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
"""
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(
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()
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):
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: