mirror of
https://github.com/TheCommsChannel/TC2-BBS-mesh.git
synced 2024-11-09 22:24:06 -08:00
e9709fd781
This is to allow web client users to use the BBS since the web client doesn't allow you to send single characters
214 lines
10 KiB
Python
214 lines
10 KiB
Python
import logging
|
|
|
|
from meshtastic import BROADCAST_NUM
|
|
|
|
from command_handlers import (
|
|
handle_mail_command, handle_bulletin_command, handle_help_command, handle_stats_command, handle_fortune_command,
|
|
handle_bb_steps, handle_mail_steps, handle_stats_steps, handle_wall_of_shame_command,
|
|
handle_channel_directory_command, handle_channel_directory_steps, handle_send_mail_command,
|
|
handle_read_mail_command, handle_check_mail_command, handle_delete_mail_confirmation, handle_post_bulletin_command,
|
|
handle_check_bulletin_command, handle_read_bulletin_command, handle_read_channel_command,
|
|
handle_post_channel_command, handle_list_channels_command, handle_quick_help_command
|
|
)
|
|
from db_operations import add_bulletin, add_mail, delete_bulletin, delete_mail, get_db_connection, add_channel
|
|
from js8call_integration import handle_js8call_command, handle_js8call_steps, handle_group_message_selection
|
|
from utils import get_user_state, get_node_short_name, get_node_id_from_num, send_message
|
|
|
|
main_menu_handlers = {
|
|
"q": handle_quick_help_command,
|
|
"b": lambda sender_id, interface: handle_help_command(sender_id, interface, 'bbs'),
|
|
"u": lambda sender_id, interface: handle_help_command(sender_id, interface, 'utilities'),
|
|
"x": handle_help_command
|
|
}
|
|
|
|
bbs_menu_handlers = {
|
|
"m": handle_mail_command,
|
|
"b": handle_bulletin_command,
|
|
"c": handle_channel_directory_command,
|
|
"j": handle_js8call_command,
|
|
"x": handle_help_command
|
|
}
|
|
|
|
|
|
utilities_menu_handlers = {
|
|
"s": handle_stats_command,
|
|
"f": handle_fortune_command,
|
|
"w": handle_wall_of_shame_command,
|
|
"x": handle_help_command
|
|
}
|
|
|
|
|
|
bulletin_menu_handlers = {
|
|
"g": lambda sender_id, interface: handle_bb_steps(sender_id, '0', 1, {'board': 'General'}, interface, None),
|
|
"i": lambda sender_id, interface: handle_bb_steps(sender_id, '1', 1, {'board': 'Info'}, interface, None),
|
|
"n": lambda sender_id, interface: handle_bb_steps(sender_id, '2', 1, {'board': 'News'}, interface, None),
|
|
"u": lambda sender_id, interface: handle_bb_steps(sender_id, '3', 1, {'board': 'Urgent'}, interface, None),
|
|
"x": handle_help_command
|
|
}
|
|
|
|
|
|
board_action_handlers = {
|
|
"r": lambda sender_id, interface, state: handle_bb_steps(sender_id, 'r', 2, state, interface, None),
|
|
"p": lambda sender_id, interface, state: handle_bb_steps(sender_id, 'p', 2, state, interface, None),
|
|
"x": handle_help_command
|
|
}
|
|
|
|
def process_message(sender_id, message, interface, is_sync_message=False):
|
|
state = get_user_state(sender_id)
|
|
message_lower = message.lower().strip()
|
|
bbs_nodes = interface.bbs_nodes
|
|
|
|
# Handle repeated characters for single character commands using a prefix
|
|
if len(message_lower) == 2 and message_lower[1] == 'x':
|
|
message_lower = message_lower[0]
|
|
|
|
if is_sync_message:
|
|
if message.startswith("BULLETIN|"):
|
|
parts = message.split("|")
|
|
board, sender_short_name, subject, content, unique_id = parts[1], parts[2], parts[3], parts[4], parts[5]
|
|
add_bulletin(board, sender_short_name, subject, content, [], interface, unique_id=unique_id)
|
|
|
|
if board.lower() == "urgent":
|
|
notification_message = f"💥NEW URGENT BULLETIN💥\nFrom: {sender_short_name}\nTitle: {subject}"
|
|
send_message(notification_message, BROADCAST_NUM, interface)
|
|
elif message.startswith("MAIL|"):
|
|
parts = message.split("|")
|
|
sender_id, sender_short_name, recipient_id, subject, content, unique_id = parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]
|
|
add_mail(sender_id, sender_short_name, recipient_id, subject, content, [], interface, unique_id=unique_id)
|
|
elif message.startswith("DELETE_BULLETIN|"):
|
|
unique_id = message.split("|")[1]
|
|
delete_bulletin(unique_id, [], interface)
|
|
elif message.startswith("DELETE_MAIL|"):
|
|
unique_id = message.split("|")[1]
|
|
logging.info(f"Processing delete mail with unique_id: {unique_id}")
|
|
recipient_id = get_recipient_id_by_mail(unique_id)
|
|
delete_mail(unique_id, recipient_id, [], interface)
|
|
elif message.startswith("CHANNEL|"):
|
|
parts = message.split("|")
|
|
channel_name, channel_url = parts[1], parts[2]
|
|
add_channel(channel_name, channel_url)
|
|
else:
|
|
if message_lower.startswith("sm,,"):
|
|
handle_send_mail_command(sender_id, message_lower, interface, bbs_nodes)
|
|
elif message_lower.startswith("cm"):
|
|
handle_check_mail_command(sender_id, interface)
|
|
elif message_lower.startswith("pb,,"):
|
|
handle_post_bulletin_command(sender_id, message_lower, interface, bbs_nodes)
|
|
elif message_lower.startswith("cb,,"):
|
|
handle_check_bulletin_command(sender_id, message_lower, interface)
|
|
elif message_lower.startswith("chp,,"):
|
|
handle_post_channel_command(sender_id, message_lower, interface)
|
|
elif message_lower.startswith("chl"):
|
|
handle_list_channels_command(sender_id, interface)
|
|
else:
|
|
if state and state['command'] == 'MENU':
|
|
menu_name = state['menu']
|
|
if menu_name == 'bbs':
|
|
handlers = bbs_menu_handlers
|
|
elif menu_name == 'utilities':
|
|
handlers = utilities_menu_handlers
|
|
else:
|
|
handlers = main_menu_handlers
|
|
elif state and state['command'] == 'BULLETIN_MENU':
|
|
handlers = bulletin_menu_handlers
|
|
elif state and state['command'] == 'BULLETIN_ACTION':
|
|
handlers = board_action_handlers
|
|
elif state and state['command'] == 'JS8CALL_MENU':
|
|
handle_js8call_steps(sender_id, message, state['step'], interface, state)
|
|
return
|
|
elif state and state['command'] == 'GROUP_MESSAGES':
|
|
handle_group_message_selection(sender_id, message, state['step'], state, interface)
|
|
return
|
|
else:
|
|
handlers = main_menu_handlers
|
|
|
|
if message_lower == 'x':
|
|
# Reset to main menu state
|
|
handle_help_command(sender_id, interface)
|
|
return
|
|
|
|
if message_lower in handlers:
|
|
if state and state['command'] in ['BULLETIN_ACTION', 'BULLETIN_READ', 'BULLETIN_POST', 'BULLETIN_POST_CONTENT']:
|
|
handlers[message_lower](sender_id, interface, state)
|
|
else:
|
|
handlers[message_lower](sender_id, interface)
|
|
elif state:
|
|
command = state['command']
|
|
step = state['step']
|
|
|
|
if command == 'MAIL':
|
|
handle_mail_steps(sender_id, message, step, state, interface, bbs_nodes)
|
|
elif command == 'BULLETIN':
|
|
handle_bb_steps(sender_id, message, step, state, interface, bbs_nodes)
|
|
elif command == 'STATS':
|
|
handle_stats_steps(sender_id, message, step, interface)
|
|
elif command == 'CHANNEL_DIRECTORY':
|
|
handle_channel_directory_steps(sender_id, message, step, state, interface)
|
|
elif command == 'CHECK_MAIL':
|
|
if step == 1:
|
|
handle_read_mail_command(sender_id, message, state, interface)
|
|
elif step == 2:
|
|
handle_delete_mail_confirmation(sender_id, message, state, interface, bbs_nodes)
|
|
elif command == 'CHECK_BULLETIN':
|
|
if step == 1:
|
|
handle_read_bulletin_command(sender_id, message, state, interface)
|
|
elif command == 'CHECK_CHANNEL':
|
|
if step == 1:
|
|
handle_read_channel_command(sender_id, message, state, interface)
|
|
elif command == 'LIST_CHANNELS':
|
|
if step == 1:
|
|
handle_read_channel_command(sender_id, message, state, interface)
|
|
elif command == 'BULLETIN_POST':
|
|
handle_bb_steps(sender_id, message, 4, state, interface, bbs_nodes)
|
|
elif command == 'BULLETIN_POST_CONTENT':
|
|
handle_bb_steps(sender_id, message, 5, state, interface, bbs_nodes)
|
|
elif command == 'BULLETIN_READ':
|
|
handle_bb_steps(sender_id, message, 3, state, interface, bbs_nodes)
|
|
elif command == 'JS8CALL_MENU':
|
|
handle_js8call_steps(sender_id, message, step, interface, state)
|
|
elif command == 'GROUP_MESSAGES':
|
|
handle_group_message_selection(sender_id, message, step, state, interface)
|
|
else:
|
|
handle_help_command(sender_id, interface)
|
|
|
|
|
|
def on_receive(packet, interface):
|
|
try:
|
|
if 'decoded' in packet and packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP':
|
|
message_bytes = packet['decoded']['payload']
|
|
message_string = message_bytes.decode('utf-8')
|
|
sender_id = packet['from']
|
|
to_id = packet.get('to')
|
|
sender_node_id = packet['fromId']
|
|
|
|
sender_short_name = get_node_short_name(sender_node_id, interface)
|
|
receiver_short_name = get_node_short_name(get_node_id_from_num(to_id, interface),
|
|
interface) if to_id else "Group Chat"
|
|
logging.info(f"Received message from user '{sender_short_name}' to {receiver_short_name}: {message_string}")
|
|
|
|
bbs_nodes = interface.bbs_nodes
|
|
is_sync_message = any(message_string.startswith(prefix) for prefix in
|
|
["BULLETIN|", "MAIL|", "DELETE_BULLETIN|", "DELETE_MAIL|"])
|
|
|
|
if sender_node_id in bbs_nodes:
|
|
if is_sync_message:
|
|
process_message(sender_id, message_string, interface, is_sync_message=True)
|
|
else:
|
|
logging.info("Ignoring non-sync message from known BBS node")
|
|
elif to_id is not None and to_id != 0 and to_id != 255 and to_id == interface.myInfo.my_node_num:
|
|
process_message(sender_id, message_string, interface, is_sync_message=False)
|
|
else:
|
|
logging.info("Ignoring message sent to group chat or from unknown node")
|
|
except KeyError as e:
|
|
logging.error(f"Error processing packet: {e}")
|
|
|
|
def get_recipient_id_by_mail(unique_id):
|
|
# Fix for Mail Delete sync issue
|
|
conn = get_db_connection()
|
|
c = conn.cursor()
|
|
c.execute("SELECT recipient FROM mail WHERE unique_id = ?", (unique_id,))
|
|
result = c.fetchone()
|
|
if result:
|
|
return result[0]
|
|
return None
|