forked from mudhorn/TC2-BBS-mesh
15d836db27
Added reply option and some fixes for the Urgent board permissions
167 lines
6.1 KiB
Python
167 lines
6.1 KiB
Python
import logging
|
|
import sqlite3
|
|
import threading
|
|
import uuid
|
|
from datetime import datetime
|
|
|
|
from meshtastic import BROADCAST_NUM
|
|
|
|
from utils import (
|
|
send_bulletin_to_bbs_nodes,
|
|
send_delete_bulletin_to_bbs_nodes,
|
|
send_delete_mail_to_bbs_nodes,
|
|
send_mail_to_bbs_nodes, send_message, send_channel_to_bbs_nodes
|
|
)
|
|
|
|
|
|
thread_local = threading.local()
|
|
|
|
def get_db_connection():
|
|
if not hasattr(thread_local, 'connection'):
|
|
thread_local.connection = sqlite3.connect('bulletins.db')
|
|
return thread_local.connection
|
|
|
|
def initialize_database():
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute('''CREATE TABLE IF NOT EXISTS bulletins (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
board TEXT NOT NULL,
|
|
sender_short_name TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
subject TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
unique_id TEXT NOT NULL
|
|
)''')
|
|
c.execute('''CREATE TABLE IF NOT EXISTS mail (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
sender TEXT NOT NULL,
|
|
sender_short_name TEXT NOT NULL,
|
|
recipient TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
subject TEXT NOT NULL,
|
|
content TEXT NOT NULL,
|
|
unique_id TEXT NOT NULL
|
|
);''')
|
|
c.execute('''CREATE TABLE IF NOT EXISTS channels (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
url TEXT NOT NULL
|
|
);''')
|
|
conn.commit()
|
|
print("Database schema initialized.")
|
|
|
|
def add_channel(name, url, bbs_nodes=None, interface=None):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("INSERT INTO channels (name, url) VALUES (?, ?)", (name, url))
|
|
conn.commit()
|
|
|
|
if bbs_nodes and interface:
|
|
send_channel_to_bbs_nodes(name, url, bbs_nodes, interface)
|
|
|
|
|
|
def get_channels():
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT name, url FROM channels")
|
|
return c.fetchall()
|
|
|
|
|
|
|
|
def add_bulletin(board, sender_short_name, subject, content, bbs_nodes, interface, unique_id=None):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
date = datetime.now().strftime('%Y-%m-%d %H:%M')
|
|
if not unique_id:
|
|
unique_id = str(uuid.uuid4())
|
|
c.execute(
|
|
"INSERT INTO bulletins (board, sender_short_name, date, subject, content, unique_id) VALUES (?, ?, ?, ?, ?, ?)",
|
|
(board, sender_short_name, date, subject, content, unique_id))
|
|
conn.commit()
|
|
if bbs_nodes and interface:
|
|
send_bulletin_to_bbs_nodes(board, sender_short_name, subject, content, unique_id, bbs_nodes, interface)
|
|
|
|
# New logic to send group chat notification for urgent bulletins
|
|
if board.lower() == "urgent":
|
|
notification_message = f"💥NEW URGENT BULLETIN💥\nFrom: {sender_short_name}\nTitle: {subject}"
|
|
send_message(notification_message, BROADCAST_NUM, interface)
|
|
|
|
return unique_id
|
|
|
|
|
|
def get_bulletins(board):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT id, subject, sender_short_name, date, unique_id FROM bulletins WHERE board = ?", (board,))
|
|
return c.fetchall()
|
|
|
|
def get_bulletin_content(bulletin_id):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT sender_short_name, date, subject, content, unique_id FROM bulletins WHERE id = ?", (bulletin_id,))
|
|
return c.fetchone()
|
|
|
|
|
|
def delete_bulletin(bulletin_id, bbs_nodes, interface):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("DELETE FROM bulletins WHERE id = ?", (bulletin_id,))
|
|
conn.commit()
|
|
send_delete_bulletin_to_bbs_nodes(bulletin_id, bbs_nodes, interface)
|
|
|
|
def add_mail(sender_id, sender_short_name, recipient_id, subject, content, bbs_nodes, interface, unique_id=None):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
date = datetime.now().strftime('%Y-%m-%d %H:%M')
|
|
if not unique_id:
|
|
unique_id = str(uuid.uuid4())
|
|
c.execute("INSERT INTO mail (sender, sender_short_name, recipient, date, subject, content, unique_id) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
(sender_id, sender_short_name, recipient_id, date, subject, content, unique_id))
|
|
conn.commit()
|
|
if bbs_nodes and interface:
|
|
send_mail_to_bbs_nodes(sender_id, sender_short_name, recipient_id, subject, content, unique_id, bbs_nodes, interface)
|
|
return unique_id
|
|
|
|
def get_mail(recipient_id):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT id, sender_short_name, subject, date, unique_id FROM mail WHERE recipient = ?", (recipient_id,))
|
|
return c.fetchall()
|
|
|
|
def get_mail_content(mail_id, recipient_id):
|
|
# TODO: ensure only recipient can read mail
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT sender_short_name, date, subject, content, unique_id FROM mail WHERE id = ? and recipient = ?", (mail_id, recipient_id,))
|
|
return c.fetchone()
|
|
|
|
def delete_mail(unique_id, recipient_id, bbs_nodes, interface):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
try:
|
|
c.execute("SELECT recipient FROM mail WHERE unique_id = ?", (unique_id,))
|
|
result = c.fetchone()
|
|
if result is None:
|
|
logging.error(f"No mail found with unique_id: {unique_id}")
|
|
return # Early exit if no matching mail found
|
|
recipient_id = result[0]
|
|
logging.info(f"Attempting to delete mail with unique_id: {unique_id} by {recipient_id}")
|
|
c.execute("DELETE FROM mail WHERE unique_id = ? and recipient = ?", (unique_id, recipient_id,))
|
|
conn.commit()
|
|
send_delete_mail_to_bbs_nodes(unique_id, bbs_nodes, interface)
|
|
logging.info(f"Mail with unique_id: {unique_id} deleted and sync message sent.")
|
|
except Exception as e:
|
|
logging.error(f"Error deleting mail with unique_id {unique_id}: {e}")
|
|
raise
|
|
|
|
|
|
def get_sender_id_by_mail_id(mail_id):
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT sender FROM mail WHERE id = ?", (mail_id,))
|
|
result = c.fetchone()
|
|
if result:
|
|
return result[0]
|
|
return None
|