???
This commit is contained in:
@@ -10,7 +10,7 @@ import yaml
|
||||
import sqlite3
|
||||
import re
|
||||
import asyncio
|
||||
from nio import AsyncClient, LoginResponse, RoomMessageText, SyncResponse, RoomSendResponse
|
||||
from nio import AsyncClient, LoginResponse, MessageDirection, ProfileGetDisplayNameResponse, RoomMessageText, RoomMessagesResponse, RoomSendResponse, SyncResponse
|
||||
from post import Post
|
||||
import requests
|
||||
import dbutil
|
||||
@@ -64,7 +64,7 @@ class Room:
|
||||
def init_db(self):
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS suggestions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user TEXT,
|
||||
@@ -78,17 +78,17 @@ class Room:
|
||||
)
|
||||
''')
|
||||
# Add is_posted column if it doesn't exist
|
||||
c.execute("PRAGMA table_info(suggestions)")
|
||||
_ = c.execute("PRAGMA table_info(suggestions)")
|
||||
cols = [row[1] for row in c.fetchall()]
|
||||
if 'is_posted' not in cols:
|
||||
c.execute('ALTER TABLE suggestions ADD COLUMN is_posted INTEGER DEFAULT 0')
|
||||
_ = c.execute('ALTER TABLE suggestions ADD COLUMN is_posted INTEGER DEFAULT 0')
|
||||
if 'event_id' not in cols:
|
||||
c.execute('ALTER TABLE suggestions ADD COLUMN event_id TEXT')
|
||||
_ = c.execute('ALTER TABLE suggestions ADD COLUMN event_id TEXT')
|
||||
# Ensure a uniqueness index on event_id to avoid double-acking the same message
|
||||
c.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_suggestions_event_id ON suggestions(event_id)')
|
||||
_ = c.execute('CREATE UNIQUE INDEX IF NOT EXISTS idx_suggestions_event_id ON suggestions(event_id)')
|
||||
|
||||
# New: table to log all !gettitles detections (prevents duplicates)
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS gettitles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
event_id TEXT,
|
||||
@@ -101,7 +101,7 @@ class Room:
|
||||
''')
|
||||
|
||||
# New: table to log all !mayhem detections (prevents duplicates)
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS mayhem (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
event_id TEXT,
|
||||
@@ -114,7 +114,7 @@ class Room:
|
||||
''')
|
||||
|
||||
# New: table to log all !countvotes detections (prevents duplicates)
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS countvotes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
event_id TEXT,
|
||||
@@ -127,7 +127,7 @@ class Room:
|
||||
''')
|
||||
|
||||
# New: table to log all !voteurl detections (prevents duplicates)
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS voteurl (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
event_id TEXT,
|
||||
@@ -161,13 +161,14 @@ class Room:
|
||||
return False
|
||||
|
||||
async def get_display_name(self, user_id):
|
||||
assert self.client is not None
|
||||
room = self.client.rooms.get(self.config.room_id)
|
||||
if room and user_id in room.users:
|
||||
member = room.users[user_id]
|
||||
if hasattr(member, "display_name") and member.display_name:
|
||||
return member.display_name
|
||||
resp = await self.client.get_displayname(user_id)
|
||||
if hasattr(resp, "displayname") and resp.displayname:
|
||||
if isinstance(resp, ProfileGetDisplayNameResponse) and resp.displayname:
|
||||
return resp.displayname
|
||||
return user_id
|
||||
|
||||
@@ -219,6 +220,7 @@ class Room:
|
||||
batch_size = self.config.batch_size
|
||||
next_batch = None
|
||||
fetched = 0
|
||||
assert self.client is not None
|
||||
|
||||
while fetched < limit:
|
||||
fetch_amount = min(batch_size, limit - fetched)
|
||||
@@ -226,10 +228,10 @@ class Room:
|
||||
self.config.room_id,
|
||||
start=next_batch,
|
||||
limit=fetch_amount,
|
||||
direction="b"
|
||||
direction=MessageDirection.back
|
||||
)
|
||||
|
||||
if not hasattr(response, "chunk") or not response.chunk:
|
||||
if not isinstance(response, RoomMessagesResponse) or not response.chunk:
|
||||
break
|
||||
|
||||
for event in response.chunk:
|
||||
@@ -304,7 +306,7 @@ class Room:
|
||||
self.newly_inserted_posts = []
|
||||
for post in self.posts:
|
||||
try:
|
||||
c.execute(
|
||||
_ = c.execute(
|
||||
"INSERT INTO suggestions (user, display_name, message, timestamp, age, is_posted, event_id) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
||||
post.as_tuple()
|
||||
)
|
||||
@@ -319,21 +321,21 @@ class Room:
|
||||
room_id = self.config.room_id
|
||||
conn = dbutil.connect("last_run.db")
|
||||
c = conn.cursor()
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS last_run (
|
||||
room_id TEXT PRIMARY KEY,
|
||||
timestamp INTEGER,
|
||||
datetime TEXT
|
||||
)
|
||||
''')
|
||||
c.execute("PRAGMA table_info(last_run)")
|
||||
_ = c.execute("PRAGMA table_info(last_run)")
|
||||
cols = [row[1] for row in c.fetchall()]
|
||||
if 'datetime' not in cols:
|
||||
c.execute('ALTER TABLE last_run ADD COLUMN datetime TEXT')
|
||||
_ = c.execute('ALTER TABLE last_run ADD COLUMN datetime TEXT')
|
||||
|
||||
now = int(_time.time())
|
||||
now_str = datetime.datetime.now().isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('INSERT OR REPLACE INTO last_run (room_id, timestamp, datetime) VALUES (?, ?, ?)', (room_id, now, now_str))
|
||||
_ = c.execute('INSERT OR REPLACE INTO last_run (room_id, timestamp, datetime) VALUES (?, ?, ?)', (room_id, now, now_str))
|
||||
dbutil.commit(conn)
|
||||
conn.close()
|
||||
|
||||
@@ -341,7 +343,7 @@ class Room:
|
||||
room_id = self.config.room_id
|
||||
conn = dbutil.connect("last_run.db")
|
||||
c = conn.cursor()
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS last_run (
|
||||
room_id TEXT PRIMARY KEY,
|
||||
timestamp INTEGER,
|
||||
@@ -349,11 +351,11 @@ class Room:
|
||||
)
|
||||
''')
|
||||
|
||||
c.execute("PRAGMA table_info(last_run)")
|
||||
_ = c.execute("PRAGMA table_info(last_run)")
|
||||
cols = [row[1] for row in c.fetchall()]
|
||||
if 'datetime' not in cols:
|
||||
c.execute('ALTER TABLE last_run ADD COLUMN datetime TEXT')
|
||||
c.execute('SELECT timestamp FROM last_run WHERE room_id = ?', (room_id,))
|
||||
_ = c.execute('ALTER TABLE last_run ADD COLUMN datetime TEXT')
|
||||
_ = c.execute('SELECT timestamp FROM last_run WHERE room_id = ?', (room_id,))
|
||||
row = c.fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
@@ -366,7 +368,7 @@ class Room:
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
dt_str = datetime.datetime.fromtimestamp(int(timestamp)).isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
INSERT OR IGNORE INTO gettitles (event_id, sender, timestamp, datetime)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (event_id, sender, int(timestamp), dt_str))
|
||||
@@ -381,7 +383,7 @@ class Room:
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
dt_str = datetime.datetime.fromtimestamp(int(timestamp)).isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
INSERT OR IGNORE INTO mayhem (event_id, sender, timestamp, datetime)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (event_id, sender, int(timestamp), dt_str))
|
||||
@@ -396,7 +398,7 @@ class Room:
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
dt_str = datetime.datetime.fromtimestamp(int(timestamp)).isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
INSERT OR IGNORE INTO countvotes (event_id, sender, timestamp, datetime)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (event_id, sender, int(timestamp), dt_str))
|
||||
@@ -411,7 +413,7 @@ class Room:
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
dt_str = datetime.datetime.fromtimestamp(int(timestamp)).isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
INSERT OR IGNORE INTO voteurl (event_id, sender, timestamp, datetime)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (event_id, sender, int(timestamp), dt_str))
|
||||
@@ -427,6 +429,7 @@ class Room:
|
||||
next_batch = None
|
||||
suggestion_votes = {}
|
||||
all_events = []
|
||||
assert self.client is not None
|
||||
|
||||
# First pass: collect all recent events (both messages and reactions)
|
||||
for _ in range(15): # Look back further to catch more events
|
||||
@@ -434,10 +437,10 @@ class Room:
|
||||
self.config.room_id,
|
||||
start=next_batch,
|
||||
limit=batch_size,
|
||||
direction="b"
|
||||
direction=MessageDirection.back
|
||||
)
|
||||
|
||||
if not hasattr(response, "chunk") or not response.chunk:
|
||||
if not isinstance(response, RoomMessagesResponse) or not response.chunk:
|
||||
break
|
||||
|
||||
all_events.extend(response.chunk)
|
||||
@@ -522,6 +525,7 @@ class Room:
|
||||
if since_ms is None:
|
||||
since_ms = int(_time.time() * 1000)
|
||||
|
||||
assert self.client is not None
|
||||
while True:
|
||||
sync_response = await self.client.sync(timeout=30000)
|
||||
if not isinstance(sync_response, SyncResponse):
|
||||
@@ -585,6 +589,7 @@ class Room:
|
||||
return result == "gettitles"
|
||||
|
||||
async def alert_post(self, post):
|
||||
assert self.client is not None
|
||||
content = {
|
||||
"msgtype": "m.text",
|
||||
"body": post
|
||||
@@ -628,7 +633,7 @@ class Room:
|
||||
if conditions:
|
||||
query += " WHERE " + " AND ".join(conditions)
|
||||
query += " ORDER BY timestamp ASC"
|
||||
c.execute(query, tuple(params))
|
||||
_ = c.execute(query, tuple(params))
|
||||
rows = c.fetchall()
|
||||
conn.close()
|
||||
self.posts = [Post(poster=row[0], display_name=row[1], content=row[2], time=row[3], age=row[4], is_posted=bool(row[5])) for row in rows]
|
||||
@@ -636,18 +641,18 @@ class Room:
|
||||
def get_last_post(self):
|
||||
conn = dbutil.connect("last_post.db")
|
||||
c = conn.cursor()
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS last_post (
|
||||
room_id TEXT PRIMARY KEY,
|
||||
timestamp INTEGER,
|
||||
datetime TEXT
|
||||
)
|
||||
''')
|
||||
c.execute("PRAGMA table_info(last_post)")
|
||||
_ = c.execute("PRAGMA table_info(last_post)")
|
||||
cols = [row[1] for row in c.fetchall()]
|
||||
if 'datetime' not in cols:
|
||||
c.execute('ALTER TABLE last_post ADD COLUMN datetime TEXT')
|
||||
c.execute('SELECT timestamp FROM last_post WHERE room_id = ?', (self.config.room_id,))
|
||||
_ = c.execute('ALTER TABLE last_post ADD COLUMN datetime TEXT')
|
||||
_ = c.execute('SELECT timestamp FROM last_post WHERE room_id = ?', (self.config.room_id,))
|
||||
row = c.fetchone()
|
||||
conn.close()
|
||||
if row:
|
||||
@@ -657,29 +662,29 @@ class Room:
|
||||
def update_last_post(self):
|
||||
conn = dbutil.connect("last_post.db")
|
||||
c = conn.cursor()
|
||||
c.execute('''
|
||||
_ = c.execute('''
|
||||
CREATE TABLE IF NOT EXISTS last_post (
|
||||
room_id TEXT PRIMARY KEY,
|
||||
timestamp INTEGER,
|
||||
datetime TEXT
|
||||
)
|
||||
''')
|
||||
c.execute("PRAGMA table_info(last_post)")
|
||||
_ = c.execute("PRAGMA table_info(last_post)")
|
||||
cols = [row[1] for row in c.fetchall()]
|
||||
if 'datetime' not in cols:
|
||||
c.execute('ALTER TABLE last_post ADD COLUMN datetime TEXT')
|
||||
_ = c.execute('ALTER TABLE last_post ADD COLUMN datetime TEXT')
|
||||
|
||||
now = int(_time.time())
|
||||
now_str = datetime.datetime.now().isoformat(sep=' ', timespec='seconds')
|
||||
c.execute('INSERT OR REPLACE INTO last_post (room_id, timestamp, datetime) VALUES (?, ?, ?)',
|
||||
_ = c.execute('INSERT OR REPLACE INTO last_post (room_id, timestamp, datetime) VALUES (?, ?, ?)',
|
||||
(self.config.room_id, now, now_str))
|
||||
dbutil.commit(conn)
|
||||
conn.close()
|
||||
|
||||
async def post_suggestions(self):
|
||||
assert self.client is not None
|
||||
# Filter out already posted suggestions
|
||||
unposted_posts = [post for post in self.posts if not post.is_posted]
|
||||
|
||||
if not unposted_posts:
|
||||
await self.alert_post("No new unposted suggestions found.")
|
||||
return
|
||||
@@ -714,6 +719,7 @@ class Room:
|
||||
|
||||
async def post_suggestions_individually(self):
|
||||
"""Post each unposted suggestion as its own message with a 👍 reaction for voting."""
|
||||
assert self.client is not None
|
||||
unposted_posts = [post for post in self.posts if not post.is_posted]
|
||||
if not unposted_posts:
|
||||
await self.alert_post("No new unposted suggestions found.")
|
||||
@@ -791,7 +797,7 @@ class Room:
|
||||
conn = dbutil.connect(self.db_path)
|
||||
c = conn.cursor()
|
||||
for post in posts:
|
||||
c.execute(
|
||||
_ = c.execute(
|
||||
"UPDATE suggestions SET is_posted = 1 WHERE user = ? AND message = ? AND timestamp = ?",
|
||||
(post.poster, post.content, post.time)
|
||||
)
|
||||
@@ -804,6 +810,7 @@ class Room:
|
||||
|
||||
async def acknowledge_new_suggestions(self):
|
||||
"""React ✅ to newly recorded suggestions to confirm they were saved."""
|
||||
assert self.client is not None
|
||||
if not self.newly_inserted_posts:
|
||||
return
|
||||
for post in self.newly_inserted_posts:
|
||||
|
||||
Reference in New Issue
Block a user