commit - 7fac138e7c03ad906cb8cf863af760311239236f
commit + c093e3cd0479fc88566628fac9e9daf815ee2a4d
blob - 77995b9386d798e6a40beaa9d6506da82c5d68af
blob + 9a11ad497b966156c047c0fad2ef81f79b3ae680
--- lonk.py
+++ lonk.py
self.content = []
self.footer = []
return "\n".join([result] + footer) + "\n" if result else ""
+
-
class LinkTag(_BaseTag):
def __init__(self, href, paragraph, tag, attrs):
super().__init__(tag, attrs)
)
def get(self, action, answer_is_json=True, **kwargs):
- query = {**{"action": action, "token": self._token}, **kwargs}
- with urlopen(self.build(path="api", query=urlencode(query)), timeout=45) as response:
- answer = response.read().decode("utf8")
- return json_loads(answer) if answer_is_json else answer
+ start_time = clock_gettime(CLOCK_MONOTONIC)
+ try:
+ query = {**{"action": action, "token": self._token}, **kwargs}
+ with urlopen(self.build(path="api", query=urlencode(query)), timeout=45) as response:
+ answer = response.read().decode("utf8")
+ return json_loads(answer) if answer_is_json else answer
+ finally:
+ stderr.write(f"GET {action} {kwargs}|{clock_gettime(CLOCK_MONOTONIC) - start_time:.3f}sec.\n")
def db_create_schema(db_con):
"""
CREATE TABLE
client (
- client_id INTEGER PRIMARY KEY,
- cert_hash TEXT UNIQUE,
+ cert_hash TEXT PRIMARY KEY,
honk_url TEXT NOT NULL,
token TEXT NOT NULL
- )
- """
- )
- db_con.execute(
- """
- CREATE TABLE
- convoy (
- convoy_id INTEGER PRIMARY KEY,
- convoy TEXT,
- client_id INTEGER,
- honk_id INTEGER,
- handle TEXT,
- oondle TEXT,
- url TEXT,
- html TEXT,
- date TEXT,
- public INTEGER,
- handles TEXT,
- honker_url TEXT,
- oonker_url TEXT,
- FOREIGN KEY (client_id) REFERENCES client (client_id),
- UNIQUE (convoy, client_id)
- )
- """
- )
- db_con.execute(
- """
- CREATE TABLE
- donk (
- donk_id INTEGER PRIMARY KEY,
- client_id INTEGER,
- convoy_id INTEGER,
- url TEXT NOT NULL,
- mime TEXT,
- alt_text TEXT,
- FOREIGN KEY (client_id) REFERENCES client (client_id),
- FOREIGN KEY (convoy_id) REFERENCES convoy (convoy_id)
)
"""
)
class _LonkTreeItem:
- def __init__(self, convoy_id, convoy, honk_id, handle, oondle, url, html, date, public, handles, honker, oonker):
- self.convoy_id = convoy_id
- self.convoy = convoy
- self.honk_id = honk_id
- self.handle = handle
- self.oondle = oondle
- self.url = url
- self.html = html
- self.date = date
- self.public = bool(public)
- self.handles = handles
- self.honker = honker
- self.oonker = oonker
- self.donks = []
+ def __init__(self, honk=None):
+ self.honk = honk
self.thread = []
def iterate_honks(self):
- if self.html is not None:
- yield {
- "Convoy": self.convoy,
- "Handle": self.handle,
- "Oondle": self.oondle,
- "ID": self.honk_id,
- "XID": self.url,
- "HTML": self.html,
- "Date": self.date,
- "Public": self.public,
- "Handles": self.handles,
- "Honker": self.honker,
- "Oonker": self.oonker,
- "Donks": [
- {"URL": donk[0], "Media": donk[1], "Desc": donk[2]}
- for donk in self.donks
- ]
- }
- child_honks = self.thread[:]
- child_honks.reverse()
- yield from reversed(child_honks)
+ if self.honk is not None:
+ yield self.honk
+ yield from self.thread
-def page_lonk(db_con, client_id, lonk_url, honk_url):
+def page_lonk(lonk_url, honk_url):
gethonks_answer = honk_url.get("gethonks", page="home")
lonk_page = {}
convoy_map = {}
for honk in reversed(gethonks_answer.pop("honks", None) or []):
convoy = convoy_map.get(honk["Convoy"], honk["Convoy"])
-
- def _select_convoy_from_db(convoy):
- row = db_con.execute(
- """
- SELECT
- convoy_id, convoy, honk_id, handle, oondle, url, html, date, public, handles, honker_url, oonker_url
- FROM
- convoy
- WHERE
- client_id=? AND convoy=?
- """,
- (client_id, convoy)
- ).fetchone()
- if row:
- lonk_page[convoy] = _LonkTreeItem(*row)
- res_donks = db_con.execute(
- "SELECT url, mime, alt_text FROM donk WHERE client_id=? AND convoy_id=?",
- (client_id, lonk_page[convoy].convoy_id, )
- )
- while True:
- donks = res_donks.fetchmany()
- if not donks:
- break
-
- for donk in donks:
- donk_url, donk_mime, donk_text = donk
- lonk_page[convoy].donks.append((donk_url, donk_mime, donk_text))
-
if convoy not in lonk_page:
- _select_convoy_from_db(convoy)
-
- if convoy not in lonk_page:
- def _save_convoy(convoy, honk):
- is_public = 1 if honk.get("Public") else 0
- row = db_con.execute(
- """
- INSERT INTO
- convoy(convoy, client_id, honk_id, handle, oondle, url, html, date, public, handles, honker_url, oonker_url)
- VALUES
- (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- RETURNING
- convoy_id, convoy, honk_id, handle, oondle, url, html, date, public, handles, honker_url, oonker_url
- """,
- (convoy, client_id, honk["ID"], honk["Handle"], honk.get("Oondle"), honk["XID"], honk["HTML"], honk["Date"], is_public, honk["Handles"], honk.get("Honker"), honk.get("Oonker"))
- ).fetchone()
- lonk_page[convoy] = _LonkTreeItem(*row)
-
- for donk in (honk.get("Donks") or []):
- donk_url = honk_url.build(path=f'/d/{donk["XID"]}') if donk.get("XID") else donk["URL"]
- donk_mime, donk_text = donk["Media"], donk.get("Desc") or donk.get("Name") or None
- db_con.execute(
- "INSERT INTO donk (client_id, convoy_id, url, mime, alt_text) VALUES (?, ?, ?, ?, ?)",
- (client_id, lonk_page[convoy].convoy_id, donk_url, donk_mime, donk_text, )
- )
- lonk_page[convoy].donks.append((donk_url, donk_mime, donk_text))
-
if honk.get("RID"):
for honk_in_convoy in honk_url.get("gethonks", page="convoy", c=convoy)["honks"]:
if honk_in_convoy["What"] == "honked":
if convoy != honk_in_convoy["Convoy"]:
convoy_map[convoy] = honk_in_convoy["Convoy"]
convoy = honk_in_convoy["Convoy"]
- if convoy not in lonk_page:
- _select_convoy_from_db(convoy)
if convoy not in lonk_page:
- _save_convoy(convoy, honk_in_convoy)
+ lonk_page[convoy] = _LonkTreeItem(honk_in_convoy)
break
else:
- _save_convoy(convoy, {"ID": None, "Handle": None, "XID": None, "HTML": None, "Date": None, "Handles": None})
+ lonk_page[convoy] = _LonkTreeItem(None)
else:
- _save_convoy(convoy, honk)
+ lonk_page[convoy] = _LonkTreeItem(honk)
if honk.get("RID"):
lonk_page[convoy].thread.append(honk)
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_convoy(db_con, client_id, lonk_url, honk_url):
+def page_convoy(lonk_url, honk_url):
query = {pair[0]: pair[1] for pair in parse_qsl(lonk_url.query)}
if "c" not in query:
print("51 Not found\r")
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_search(db_con, client_id, lonk_url, honk_url):
+def page_search(lonk_url, honk_url):
if not lonk_url.query:
print("10 What are we looking for?\r")
return
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_atme(db_con, client_id, lonk_url, honk_url):
+def page_atme(lonk_url, honk_url):
gethonks_answer = honk_url.get("gethonks", page="atme")
print_header("@me")
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_longago(db_con, client_id, lonk_url, honk_url):
+def page_longago(lonk_url, honk_url):
gethonks_answer = honk_url.get("gethonks", page="longago")
print_header("long ago")
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_myhonks(db_con, client_id, lonk_url, honk_url):
+def page_myhonks(lonk_url, honk_url):
gethonks_answer = honk_url.get("gethonks", page="myhonks")
print_header("my honks")
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def page_honker(db_con, client_id, lonk_url, honk_url):
+def page_honker(lonk_url, honk_url):
xid = {pair[0]: pair[1] for pair in parse_qsl(lonk_url.query)}.get("xid")
if not xid:
print("51 Not found\r")
print_gethonks(gethonks_answer, lonk_url, honk_url)
-def bonk(db_con, client_id, lonk_url, honk_url):
+def bonk(lonk_url, honk_url):
what = {pair[0]: pair[1] for pair in parse_qsl(lonk_url.query)}.get("w")
if not what:
print("51 Not found\r")
print(f'30 {lonk_url.build("myhonks")}\r')
-def gethonkers(db_con, client_id, lonk_url, honk_url):
+def gethonkers(lonk_url, honk_url):
print_header("honkers")
print_menu(lonk_url, honk_url)
print_menu(lonk_url, honk_url)
-def addhonker(db_con, client_id, lonk_url, honk_url):
+def addhonker(lonk_url, honk_url):
if not lonk_url.query:
print("10 honker url: \r")
return
print(f'> {error.fp.read().decode("utf8")}\r')
-def unsubscribe(db_con, client_id, lonk_url, honk_url):
+def unsubscribe(lonk_url, honk_url):
honkerid = {pair[0]: pair[1] for pair in parse_qsl(lonk_url.query)}.get("honkerid")
if not honkerid:
print("51 Not found\r")
print(f'30 {lonk_url.build("gethonkers")}\r')
-def subscribe(db_con, client_id, lonk_url, honk_url):
+def subscribe(lonk_url, honk_url):
honkerid = {pair[0]: pair[1] for pair in parse_qsl(lonk_url.query)}.get("honkerid")
if not honkerid:
print("51 Not found\r")
print(f'30 {lonk_url.build("gethonkers")}\r')
-def newhonk(db_con, client_id, lonk_url, honk_url):
+def newhonk(lonk_url, honk_url):
if not lonk_url.query:
print("10 let's make some noise: \r")
return
print(f'30 {lonk_url.build("myhonks")}\r')
-def honkback(db_con, client_id, lonk_url, honk_url):
+def honkback(lonk_url, honk_url):
if not lonk_url.query:
handles = unquote(lonk_url.splitted_path[-3]).strip()
rid = unquote(lonk_url.splitted_path[-2])
def authenticated(cert_hash, lonk_url, fn_impl):
db_con = db_connect()
- row = db_con.execute("SELECT client_id, honk_url, token FROM client WHERE cert_hash=?", (cert_hash, )).fetchone()
+ row = db_con.execute("SELECT honk_url, token FROM client WHERE cert_hash=?", (cert_hash, )).fetchone()
if not row:
print(f'30 {lonk_url.build("ask_server")}\r')
return
- client_id, honk_url, token = row
+ honk_url, token = row
with db_con:
- fn_impl(db_con, client_id, lonk_url, HonkUrl(honk_url, token))
+ fn_impl(lonk_url, HonkUrl(honk_url, token))
def new_client_stage_1_ask_server(lonk_url):