mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-07-21 03:50:59 +00:00
155 lines
6.7 KiB
Python
155 lines
6.7 KiB
Python
from datetime import UTC, datetime
|
|
|
|
from .provider import DatabaseProvider
|
|
|
|
|
|
class MiscDAO:
|
|
def __init__(self, provider: DatabaseProvider):
|
|
self.provider = provider
|
|
|
|
# Blocked Destinations
|
|
def add_blocked_destination(self, destination_hash):
|
|
self.provider.execute(
|
|
"INSERT OR IGNORE INTO blocked_destinations (destination_hash, updated_at) VALUES (?, ?)",
|
|
(destination_hash, datetime.now(UTC)),
|
|
)
|
|
|
|
def is_destination_blocked(self, destination_hash):
|
|
return self.provider.fetchone("SELECT 1 FROM blocked_destinations WHERE destination_hash = ?", (destination_hash,)) is not None
|
|
|
|
def get_blocked_destinations(self):
|
|
return self.provider.fetchall("SELECT * FROM blocked_destinations")
|
|
|
|
def delete_blocked_destination(self, destination_hash):
|
|
self.provider.execute("DELETE FROM blocked_destinations WHERE destination_hash = ?", (destination_hash,))
|
|
|
|
# Spam Keywords
|
|
def add_spam_keyword(self, keyword):
|
|
self.provider.execute(
|
|
"INSERT OR IGNORE INTO spam_keywords (keyword, updated_at) VALUES (?, ?)",
|
|
(keyword, datetime.now(UTC)),
|
|
)
|
|
|
|
def get_spam_keywords(self):
|
|
return self.provider.fetchall("SELECT * FROM spam_keywords")
|
|
|
|
def delete_spam_keyword(self, keyword_id):
|
|
self.provider.execute("DELETE FROM spam_keywords WHERE id = ?", (keyword_id,))
|
|
|
|
def check_spam_keywords(self, title, content):
|
|
keywords = self.get_spam_keywords()
|
|
search_text = (title + " " + content).lower()
|
|
for kw in keywords:
|
|
if kw["keyword"].lower() in search_text:
|
|
return True
|
|
return False
|
|
|
|
# User Icons
|
|
def update_lxmf_user_icon(self, destination_hash, icon_name, foreground_colour, background_colour):
|
|
now = datetime.now(UTC)
|
|
self.provider.execute("""
|
|
INSERT INTO lxmf_user_icons (destination_hash, icon_name, foreground_colour, background_colour, updated_at)
|
|
VALUES (?, ?, ?, ?, ?)
|
|
ON CONFLICT(destination_hash) DO UPDATE SET
|
|
icon_name = EXCLUDED.icon_name,
|
|
foreground_colour = EXCLUDED.foreground_colour,
|
|
background_colour = EXCLUDED.background_colour,
|
|
updated_at = EXCLUDED.updated_at
|
|
""", (destination_hash, icon_name, foreground_colour, background_colour, now))
|
|
|
|
def get_user_icon(self, destination_hash):
|
|
return self.provider.fetchone("SELECT * FROM lxmf_user_icons WHERE destination_hash = ?", (destination_hash,))
|
|
|
|
# Forwarding Rules
|
|
def get_forwarding_rules(self, identity_hash=None, active_only=False):
|
|
query = "SELECT * FROM lxmf_forwarding_rules WHERE 1=1"
|
|
params = []
|
|
if identity_hash:
|
|
query += " AND (identity_hash = ? OR identity_hash IS NULL)"
|
|
params.append(identity_hash)
|
|
if active_only:
|
|
query += " AND is_active = 1"
|
|
return self.provider.fetchall(query, params)
|
|
|
|
def create_forwarding_rule(self, identity_hash, forward_to_hash, source_filter_hash, is_active=True):
|
|
now = datetime.now(UTC)
|
|
self.provider.execute(
|
|
"INSERT INTO lxmf_forwarding_rules (identity_hash, forward_to_hash, source_filter_hash, is_active, updated_at) VALUES (?, ?, ?, ?, ?)",
|
|
(identity_hash, forward_to_hash, source_filter_hash, 1 if is_active else 0, now),
|
|
)
|
|
|
|
def delete_forwarding_rule(self, rule_id):
|
|
self.provider.execute("DELETE FROM lxmf_forwarding_rules WHERE id = ?", (rule_id,))
|
|
|
|
def toggle_forwarding_rule(self, rule_id):
|
|
self.provider.execute("UPDATE lxmf_forwarding_rules SET is_active = NOT is_active WHERE id = ?", (rule_id,))
|
|
|
|
# Archived Pages
|
|
def archive_page(self, destination_hash, page_path, content, page_hash):
|
|
self.provider.execute(
|
|
"INSERT INTO archived_pages (destination_hash, page_path, content, hash) VALUES (?, ?, ?, ?)",
|
|
(destination_hash, page_path, content, page_hash),
|
|
)
|
|
|
|
def get_archived_page_versions(self, destination_hash, page_path):
|
|
return self.provider.fetchall(
|
|
"SELECT * FROM archived_pages WHERE destination_hash = ? AND page_path = ? ORDER BY created_at DESC",
|
|
(destination_hash, page_path),
|
|
)
|
|
|
|
def get_archived_pages_paginated(self, destination_hash=None, query=None):
|
|
sql = "SELECT * FROM archived_pages WHERE 1=1"
|
|
params = []
|
|
if destination_hash:
|
|
sql += " AND destination_hash = ?"
|
|
params.append(destination_hash)
|
|
if query:
|
|
like_term = f"%{query}%"
|
|
sql += " AND (destination_hash LIKE ? OR page_path LIKE ? OR content LIKE ?)"
|
|
params.extend([like_term, like_term, like_term])
|
|
|
|
sql += " ORDER BY created_at DESC"
|
|
return self.provider.fetchall(sql, params)
|
|
|
|
def delete_archived_pages(self, destination_hash=None, page_path=None):
|
|
if destination_hash and page_path:
|
|
self.provider.execute("DELETE FROM archived_pages WHERE destination_hash = ? AND page_path = ?", (destination_hash, page_path))
|
|
else:
|
|
self.provider.execute("DELETE FROM archived_pages")
|
|
|
|
# Crawl Tasks
|
|
def upsert_crawl_task(self, destination_hash, page_path, status="pending", retry_count=0):
|
|
self.provider.execute("""
|
|
INSERT INTO crawl_tasks (destination_hash, page_path, status, retry_count)
|
|
VALUES (?, ?, ?, ?)
|
|
ON CONFLICT(destination_hash, page_path) DO UPDATE SET
|
|
status = EXCLUDED.status,
|
|
retry_count = EXCLUDED.retry_count
|
|
""", (destination_hash, page_path, status, retry_count))
|
|
|
|
def get_pending_crawl_tasks(self):
|
|
return self.provider.fetchall("SELECT * FROM crawl_tasks WHERE status = 'pending'")
|
|
|
|
def update_crawl_task(self, task_id, **kwargs):
|
|
allowed_keys = {"destination_hash", "page_path", "status", "retry_count", "updated_at"}
|
|
filtered_kwargs = {k: v for k, v in kwargs.items() if k in allowed_keys}
|
|
|
|
if not filtered_kwargs:
|
|
return
|
|
|
|
set_clause = ", ".join([f"{k} = ?" for k in filtered_kwargs])
|
|
params = list(filtered_kwargs.values())
|
|
params.append(task_id)
|
|
query = f"UPDATE crawl_tasks SET {set_clause} WHERE id = ?" # noqa: S608
|
|
self.provider.execute(query, params)
|
|
|
|
def get_pending_or_failed_crawl_tasks(self, max_retries, max_concurrent):
|
|
return self.provider.fetchall(
|
|
"SELECT * FROM crawl_tasks WHERE status IN ('pending', 'failed') AND retry_count < ? LIMIT ?",
|
|
(max_retries, max_concurrent),
|
|
)
|
|
|
|
def get_archived_page_by_id(self, archive_id):
|
|
return self.provider.fetchone("SELECT * FROM archived_pages WHERE id = ?", (archive_id,))
|
|
|