fix README URLs, handler tests, sync improvements, block/retract gossip

This commit is contained in:
lichenblankie 2026-06-05 00:32:30 +00:00
parent a8aabb3427
commit a2d029097d
4 changed files with 440 additions and 36 deletions

View file

@ -66,6 +66,22 @@ class ForumDB:
db.execute("CREATE INDEX IF NOT EXISTS idx_posts_created ON posts(created_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_threads_updated ON threads(updated_at)")
db.execute("CREATE INDEX IF NOT EXISTS idx_threads_created ON threads(created_at)")
db.execute(
"CREATE TABLE IF NOT EXISTS peer_blocks ("
" peer_hash TEXT NOT NULL,"
" blocked_hash TEXT NOT NULL,"
" PRIMARY KEY (peer_hash, blocked_hash)"
")"
)
db.execute(
"CREATE TABLE IF NOT EXISTS retracted_content ("
" content_id TEXT NOT NULL,"
" content_type TEXT NOT NULL,"
" author_instance TEXT NOT NULL,"
" retracted_at TEXT NOT NULL,"
" PRIMARY KEY (content_id, content_type)"
")"
)
db.commit()
db.close()
@ -213,6 +229,16 @@ class ForumDB:
finally:
self.return_db(db)
def has_upvoted(self, thread_id, instance_hash):
db = self.get_db()
try:
return db.execute(
"SELECT 1 FROM upvotes WHERE thread_id = ? AND instance_hash = ?",
(thread_id, instance_hash),
).fetchone() is not None
finally:
self.return_db(db)
def get_synced_instances(self):
db = self.get_db()
try:
@ -274,6 +300,17 @@ class ForumDB:
finally:
self.return_db(db)
def update_thread(self, thread_id, title, url, body, tags, now):
db = self.get_db()
try:
db.execute(
"UPDATE threads SET title=?, url=?, body=?, tags=?, updated_at=? WHERE id=?",
(title, url, body, tags, now, thread_id),
)
db.commit()
finally:
self.return_db(db)
def merge_thread(self, thread):
db = self.get_db()
try:
@ -319,3 +356,122 @@ class ForumDB:
db.commit()
finally:
self.return_db(db)
def record_peer_block(self, peer_hash, blocked_hash):
db = self.get_db()
try:
db.execute(
"INSERT OR IGNORE INTO peer_blocks (peer_hash, blocked_hash) VALUES (?, ?)",
(peer_hash, blocked_hash),
)
db.commit()
finally:
self.return_db(db)
def get_peer_block_counts(self):
db = self.get_db()
try:
return {
r["blocked_hash"]: r["count"]
for r in db.execute(
"SELECT blocked_hash, count(*) as count FROM peer_blocks GROUP BY blocked_hash"
).fetchall()
}
finally:
self.return_db(db)
def get_peer_block_list(self):
db = self.get_db()
try:
return [r["blocked_hash"] for r in db.execute(
"SELECT DISTINCT blocked_hash FROM peer_blocks"
).fetchall()]
finally:
self.return_db(db)
def clear_peer_block(self, blocked_hash):
db = self.get_db()
try:
db.execute("DELETE FROM peer_blocks WHERE blocked_hash = ?", (blocked_hash,))
db.commit()
finally:
self.return_db(db)
def retract_thread(self, thread_id, author_instance, now):
db = self.get_db()
try:
db.execute(
"INSERT OR REPLACE INTO retracted_content (content_id, content_type, author_instance, retracted_at) "
"VALUES (?, 'thread', ?, ?)",
(thread_id, author_instance, now),
)
db.execute("UPDATE threads SET title='[retracted]', url='', body='', tags='', score=0 WHERE id=?",
(thread_id,))
db.commit()
finally:
self.return_db(db)
def retract_post(self, post_id, author_instance, now):
db = self.get_db()
try:
db.execute(
"INSERT OR REPLACE INTO retracted_content (content_id, content_type, author_instance, retracted_at) "
"VALUES (?, 'post', ?, ?)",
(post_id, author_instance, now),
)
db.execute("UPDATE posts SET body='[retracted]' WHERE id=?", (post_id,))
db.commit()
finally:
self.return_db(db)
def merge_retraction(self, content_id, content_type, author_instance, now):
db = self.get_db()
try:
existing = db.execute(
"SELECT retracted_at FROM retracted_content WHERE content_id=? AND content_type=?",
(content_id, content_type),
).fetchone()
if existing and existing["retracted_at"] >= now:
return
if content_type == "thread":
t = db.execute("SELECT author_instance FROM threads WHERE id=?", (content_id,)).fetchone()
if t and t["author_instance"] == author_instance:
db.execute(
"INSERT OR REPLACE INTO retracted_content VALUES (?, ?, ?, ?)",
(content_id, content_type, author_instance, now),
)
db.execute("UPDATE threads SET title='[retracted]', url='', body='', tags='', score=0 WHERE id=?",
(content_id,))
elif content_type == "post":
p = db.execute("SELECT author_instance FROM posts WHERE id=?", (content_id,)).fetchone()
if p and p["author_instance"] == author_instance:
db.execute(
"INSERT OR REPLACE INTO retracted_content VALUES (?, ?, ?, ?)",
(content_id, content_type, author_instance, now),
)
db.execute("UPDATE posts SET body='[retracted]' WHERE id=?", (content_id,))
db.commit()
finally:
self.return_db(db)
def get_retracted_ids(self):
db = self.get_db()
try:
threads = set(r["content_id"] for r in db.execute(
"SELECT content_id FROM retracted_content WHERE content_type='thread'"
).fetchall())
posts = set(r["content_id"] for r in db.execute(
"SELECT content_id FROM retracted_content WHERE content_type='post'"
).fetchall())
return threads, posts
finally:
self.return_db(db)
def get_raw_retractions(self):
db = self.get_db()
try:
return db.execute(
"SELECT content_id, content_type, author_instance, retracted_at FROM retracted_content"
).fetchall()
finally:
self.return_db(db)