mirror of
https://github.com/TheCommsChannel/TC2-BBS-mesh.git
synced 2025-03-05 20:51:53 -08:00
comments for js8call
This commit is contained in:
parent
87add16151
commit
571df87c69
|
@ -13,18 +13,131 @@ from utils import send_message, update_user_state
|
||||||
config_file = 'config.ini'
|
config_file = 'config.ini'
|
||||||
|
|
||||||
def from_message(content):
|
def from_message(content):
|
||||||
|
"""
|
||||||
|
Converts a JSON-formatted string into a dictionary.
|
||||||
|
|
||||||
|
This method attempts to parse a JSON-formatted string and convert it into a Python dictionary.
|
||||||
|
If the content is not valid JSON, it returns an empty dictionary.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
content : str
|
||||||
|
The JSON-formatted string to be converted into a dictionary.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
dict
|
||||||
|
A dictionary representation of the JSON content. If the content is not valid JSON, an empty
|
||||||
|
dictionary is returned.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
return json.loads(content)
|
return json.loads(content)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def to_message(typ, value='', params=None):
|
def to_message(typ, value='', params=None):
|
||||||
|
"""
|
||||||
|
Converts data into a JSON-formatted string for messaging.
|
||||||
|
|
||||||
|
This method creates a dictionary with the provided type, value, and parameters, and then converts it
|
||||||
|
into a JSON-formatted string. The resulting string is suitable for sending as a message to the JS8Call server.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
type : str
|
||||||
|
The type of the message. This is a required field.
|
||||||
|
|
||||||
|
value : str, optional
|
||||||
|
The value or content of the message. Default is an empty string.
|
||||||
|
|
||||||
|
params : dict, optional
|
||||||
|
Additional parameters for the message. Default is an empty dictionary if not provided.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
--------
|
||||||
|
str
|
||||||
|
A JSON-formatted string representing the message.
|
||||||
|
"""
|
||||||
if params is None:
|
if params is None:
|
||||||
params = {}
|
params = {}
|
||||||
return json.dumps({'type': typ, 'value': value, 'params': params})
|
return json.dumps({'type': typ, 'value': value, 'params': params})
|
||||||
|
|
||||||
|
|
||||||
class JS8CallClient:
|
class JS8CallClient:
|
||||||
|
"""
|
||||||
|
JS8CallClient integrates with the JS8Call server to handle messaging.
|
||||||
|
|
||||||
|
This class establishes a connection with the JS8Call server, processes incoming messages,
|
||||||
|
and provides methods to send messages and store them in a SQLite database. It handles different
|
||||||
|
types of messages, such as individual, group, and urgent messages.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
-----------
|
||||||
|
interface : object
|
||||||
|
The communication interface used to interact with the user.
|
||||||
|
|
||||||
|
logger : logging.Logger
|
||||||
|
The logger for the client, used to log information, warnings, and errors.
|
||||||
|
|
||||||
|
config : configparser.ConfigParser
|
||||||
|
The configuration parser to read settings from the config file.
|
||||||
|
|
||||||
|
server : tuple
|
||||||
|
The server address and port for the JS8Call server.
|
||||||
|
|
||||||
|
db_file : str
|
||||||
|
The file path for the SQLite database.
|
||||||
|
|
||||||
|
js8groups : list
|
||||||
|
The list of group names for JS8Call group messages.
|
||||||
|
|
||||||
|
store_messages : bool
|
||||||
|
Flag indicating whether to store regular messages in the database.
|
||||||
|
|
||||||
|
js8urgent : list
|
||||||
|
The list of group names for JS8Call urgent messages.
|
||||||
|
|
||||||
|
connected : bool
|
||||||
|
Flag indicating whether the client is connected to the JS8Call server.
|
||||||
|
|
||||||
|
sock : socket.socket
|
||||||
|
The socket used for the connection to the JS8Call server.
|
||||||
|
|
||||||
|
db_conn : sqlite3.Connection
|
||||||
|
The SQLite database connection.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
--------
|
||||||
|
from_message(content):
|
||||||
|
Converts message content from JSON format.
|
||||||
|
|
||||||
|
to_message(type, value='', params=None):
|
||||||
|
Converts data to JSON message format.
|
||||||
|
|
||||||
|
create_tables():
|
||||||
|
Creates necessary tables in the database if they do not already exist.
|
||||||
|
|
||||||
|
insert_message(sender, receiver, message):
|
||||||
|
Inserts a message into the 'messages' table in the database.
|
||||||
|
|
||||||
|
insert_group(sender, groupname, message):
|
||||||
|
Inserts a group message into the 'groups' table in the database.
|
||||||
|
|
||||||
|
insert_urgent(sender, groupname, message):
|
||||||
|
Inserts an urgent message into the 'urgent' table in the database.
|
||||||
|
|
||||||
|
process(message):
|
||||||
|
Processes a received message from the JS8Call server.
|
||||||
|
|
||||||
|
send(*args, **kwargs):
|
||||||
|
Sends a message to the JS8Call server.
|
||||||
|
|
||||||
|
connect():
|
||||||
|
Establishes a connection to the JS8Call server.
|
||||||
|
|
||||||
|
close():
|
||||||
|
Closes the connection to the JS8Call server.
|
||||||
|
"""
|
||||||
def __init__(self, interface, logger=None):
|
def __init__(self, interface, logger=None):
|
||||||
self.logger = logger or logging.getLogger('js8call')
|
self.logger = logger or logging.getLogger('js8call')
|
||||||
self.logger.setLevel(logging.INFO)
|
self.logger.setLevel(logging.INFO)
|
||||||
|
@ -56,6 +169,19 @@ class JS8CallClient:
|
||||||
self.logger.info("JS8Call configuration not found. Skipping JS8Call integration.")
|
self.logger.info("JS8Call configuration not found. Skipping JS8Call integration.")
|
||||||
|
|
||||||
def create_tables(self):
|
def create_tables(self):
|
||||||
|
"""
|
||||||
|
Creates necessary tables in the database if they do not already exist.
|
||||||
|
|
||||||
|
This method sets up the 'messages', 'groups', and 'urgent' tables in the database.
|
||||||
|
Each table is created with columns for storing relevant information about messages.
|
||||||
|
If the database connection is not available, it logs an error message.
|
||||||
|
|
||||||
|
Tables:
|
||||||
|
-------
|
||||||
|
- messages: Stores individual messages with sender, receiver, and message content.
|
||||||
|
- groups: Stores group messages with sender, group name, and message content.
|
||||||
|
- urgent: Stores urgent messages with sender, group name, and message content.
|
||||||
|
"""
|
||||||
if not self.db_conn:
|
if not self.db_conn:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -90,6 +216,23 @@ class JS8CallClient:
|
||||||
self.logger.info("Database tables created or verified.")
|
self.logger.info("Database tables created or verified.")
|
||||||
|
|
||||||
def insert_message(self, sender, receiver, message):
|
def insert_message(self, sender, receiver, message):
|
||||||
|
"""
|
||||||
|
Inserts a message into the 'messages' table in the database.
|
||||||
|
|
||||||
|
This method saves a message along with its sender and receiver into the 'messages'
|
||||||
|
table. If the database connection is not available, it logs an error message.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender : str
|
||||||
|
The meshtastic node identifier of the sender who issued the command
|
||||||
|
|
||||||
|
receiver : str
|
||||||
|
The identifier of the receiver of the message. This is typically the user's node id
|
||||||
|
|
||||||
|
message : str
|
||||||
|
The content of the urgent message.
|
||||||
|
"""
|
||||||
if not self.db_conn:
|
if not self.db_conn:
|
||||||
self.logger.error("Database connection is not available.")
|
self.logger.error("Database connection is not available.")
|
||||||
return
|
return
|
||||||
|
@ -104,6 +247,20 @@ class JS8CallClient:
|
||||||
self.logger.error(f"Failed to insert message into database: {e}")
|
self.logger.error(f"Failed to insert message into database: {e}")
|
||||||
|
|
||||||
def insert_group(self, sender, groupname, message):
|
def insert_group(self, sender, groupname, message):
|
||||||
|
"""
|
||||||
|
Inserts a group message into the 'groups' table in the database.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender : str
|
||||||
|
The meshtastic node identifier of the sender who issued the command
|
||||||
|
|
||||||
|
groupname : str
|
||||||
|
The name of the group to which the urgent message belongs.
|
||||||
|
|
||||||
|
message : str
|
||||||
|
The content of the urgent message.
|
||||||
|
"""
|
||||||
if not self.db_conn:
|
if not self.db_conn:
|
||||||
self.logger.error("Database connection is not available.")
|
self.logger.error("Database connection is not available.")
|
||||||
return
|
return
|
||||||
|
@ -118,6 +275,20 @@ class JS8CallClient:
|
||||||
self.logger.error(f"Failed to insert group message into database: {e}")
|
self.logger.error(f"Failed to insert group message into database: {e}")
|
||||||
|
|
||||||
def insert_urgent(self, sender, groupname, message):
|
def insert_urgent(self, sender, groupname, message):
|
||||||
|
"""
|
||||||
|
Inserts an urgent message into the 'urgent' table in the database.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender : str
|
||||||
|
The meshtastic node identifier of the sender who issued the command
|
||||||
|
|
||||||
|
groupname : str
|
||||||
|
The name of the group to which the urgent message belongs.
|
||||||
|
|
||||||
|
message : str
|
||||||
|
The content of the urgent message.
|
||||||
|
"""
|
||||||
if not self.db_conn:
|
if not self.db_conn:
|
||||||
self.logger.error("Database connection is not available.")
|
self.logger.error("Database connection is not available.")
|
||||||
return
|
return
|
||||||
|
@ -131,7 +302,34 @@ class JS8CallClient:
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
self.logger.error(f"Failed to insert urgent message into database: {e}")
|
self.logger.error(f"Failed to insert urgent message into database: {e}")
|
||||||
|
|
||||||
|
|
||||||
def process(self, message):
|
def process(self, message):
|
||||||
|
"""
|
||||||
|
Processes a received message from the JS8Call server.
|
||||||
|
|
||||||
|
This method handles various types of messages received from the JS8Call server.
|
||||||
|
It categorizes messages based on their type and performs the necessary actions
|
||||||
|
such as logging, storing in the database, or sending notifications.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
message : dict
|
||||||
|
The message dictionary received from the JS8Call server. It should contain
|
||||||
|
the following message portions:
|
||||||
|
- 'type' (str): The type of the message (e.g., 'RX.DIRECTED').
|
||||||
|
- 'value' (str): The content of the message, which may include the sender,
|
||||||
|
receiver, and the message body.
|
||||||
|
- 'params' (dict): Additional parameters associated with the message (optional).
|
||||||
|
|
||||||
|
For 'RX.DIRECTED' messages, the method extracts the sender, receiver, and message
|
||||||
|
content, and performs specific actions based on the receiver's role:
|
||||||
|
- If the receiver is in the urgent list, the message is stored in the urgent messages
|
||||||
|
table and a notification is sent.
|
||||||
|
- If the receiver is in the group list, the message is stored in the group messages table.
|
||||||
|
- If message storage is enabled, the message is stored in the regular messages table.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Extract 'type', 'value', and 'params' from the message
|
||||||
typ = message.get('type', '')
|
typ = message.get('type', '')
|
||||||
value = message.get('value', '')
|
value = message.get('value', '')
|
||||||
params = message.get('params', {})
|
params = message.get('params', {})
|
||||||
|
@ -139,17 +337,19 @@ class JS8CallClient:
|
||||||
if not typ:
|
if not typ:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Only handle these message types
|
||||||
rx_types = [
|
rx_types = [
|
||||||
'RX.ACTIVITY', 'RX.DIRECTED', 'RX.SPOT', 'RX.CALL_ACTIVITY',
|
'RX.ACTIVITY', 'RX.DIRECTED', 'RX.SPOT', 'RX.CALL_ACTIVITY',
|
||||||
'RX.CALL_SELECTED', 'RX.DIRECTED_ME', 'RX.ECHO', 'RX.DIRECTED_GROUP',
|
'RX.CALL_SELECTED', 'RX.DIRECTED_ME', 'RX.ECHO', 'RX.DIRECTED_GROUP',
|
||||||
'RX.META', 'RX.MSG', 'RX.PING', 'RX.PONG', 'RX.STREAM'
|
'RX.META', 'RX.MSG', 'RX.PING', 'RX.PONG', 'RX.STREAM'
|
||||||
]
|
]
|
||||||
|
|
||||||
if typ not in rx_types:
|
if typ not in rx_types:
|
||||||
return
|
return
|
||||||
|
|
||||||
if typ == 'RX.DIRECTED' and value:
|
if typ == 'RX.DIRECTED' and value:
|
||||||
|
# Split the message string into an array
|
||||||
parts = value.split(' ')
|
parts = value.split(' ')
|
||||||
|
# Make sure we have at least 3 elements in the array
|
||||||
if len(parts) < 3:
|
if len(parts) < 3:
|
||||||
self.logger.warning(f"Unexpected message format: {value}")
|
self.logger.warning(f"Unexpected message format: {value}")
|
||||||
return
|
return
|
||||||
|
@ -160,26 +360,70 @@ class JS8CallClient:
|
||||||
|
|
||||||
self.logger.info(f"Received JS8Call message: {sender} to {receiver} - {msg}")
|
self.logger.info(f"Received JS8Call message: {sender} to {receiver} - {msg}")
|
||||||
|
|
||||||
|
# Receiver is in the urgent list, insert the message into the urgent table and notify
|
||||||
if receiver in self.js8urgent:
|
if receiver in self.js8urgent:
|
||||||
self.insert_urgent(sender, receiver, msg)
|
self.insert_urgent(sender, receiver, msg)
|
||||||
notification_message = f"💥 URGENT JS8Call Message Received 💥\nFrom: {sender}\nCheck BBS for message"
|
notification_message = f"💥 URGENT JS8Call Message Received 💥\nFrom: {sender}\nCheck BBS for message"
|
||||||
send_message(notification_message, BROADCAST_NUM, self.interface)
|
send_message(notification_message, BROADCAST_NUM, self.interface)
|
||||||
|
# Receiver is in the groups list, insert the message into the groups table
|
||||||
elif receiver in self.js8groups:
|
elif receiver in self.js8groups:
|
||||||
self.insert_group(sender, receiver, msg)
|
self.insert_group(sender, receiver, msg)
|
||||||
|
# If storing messages is enabled, insert the message into the messages table
|
||||||
elif self.store_messages:
|
elif self.store_messages:
|
||||||
self.insert_message(sender, receiver, msg)
|
self.insert_message(sender, receiver, msg)
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def send(self, *args, **kwargs):
|
def send(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Sends a message to the JS8Call server.
|
||||||
|
|
||||||
|
This method formats the given arguments into a JSON message and sends it to the JS8Call server
|
||||||
|
over a socket connection. Each message is assigned a unique ID if not provided.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
*args : tuple
|
||||||
|
Positional arguments that represent the components of the message to be sent.
|
||||||
|
These typically include the message type and value.
|
||||||
|
|
||||||
|
**kwargs : dict
|
||||||
|
Keyword arguments that provide additional parameters for the message. The 'params' key
|
||||||
|
is expected to be a dictionary of parameters to include in the message. If the '_ID' key
|
||||||
|
is not present in 'params', it is generated automatically.
|
||||||
|
|
||||||
|
- 'params' (dict): Optional dictionary of additional parameters to include in the message.
|
||||||
|
If not provided, an empty dictionary is used.
|
||||||
|
Example: {'TO': 'CALLSIGN'}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Retrieve the 'params' dictionary from the keyword arguments, or initialize it as an empty dictionary if not provided
|
||||||
params = kwargs.get('params', {})
|
params = kwargs.get('params', {})
|
||||||
|
|
||||||
|
# If '_ID' is not in the params dictionary, generate a unique ID based on the current time in milliseconds
|
||||||
if '_ID' not in params:
|
if '_ID' not in params:
|
||||||
params['_ID'] = '{}'.format(int(time.time() * 1000))
|
params['_ID'] = '{}'.format(int(time.time() * 1000))
|
||||||
kwargs['params'] = params
|
kwargs['params'] = params
|
||||||
|
|
||||||
|
# Convert the provided arguments and keyword arguments to a JSON message
|
||||||
message = to_message(*args, **kwargs)
|
message = to_message(*args, **kwargs)
|
||||||
self.sock.send((message + '\n').encode('utf-8')) # Convert to bytes
|
|
||||||
|
# Send the JSON message to the JS8Call server by adding a newline character and encoding it to UTF-8
|
||||||
|
self.sock.send((message + '\n').encode('utf-8'))
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
|
"""
|
||||||
|
Establishes a connection to the JS8Call server.
|
||||||
|
|
||||||
|
This method attempts to connect to the JS8Call server using the host and port
|
||||||
|
specified in the configuration file. Once connected, it sends a status request
|
||||||
|
to the server and continuously listens for incoming messages. If the connection
|
||||||
|
is refused or an error occurs, it logs the appropriate message.
|
||||||
|
|
||||||
|
The method will keep the connection open and process any received messages until
|
||||||
|
the connection is closed or an error occurs.
|
||||||
|
"""
|
||||||
|
|
||||||
if not self.server[0] or not self.server[1]:
|
if not self.server[0] or not self.server[1]:
|
||||||
self.logger.info("JS8Call server configuration not found. Skipping JS8Call connection.")
|
self.logger.info("JS8Call server configuration not found. Skipping JS8Call connection.")
|
||||||
return
|
return
|
||||||
|
@ -191,6 +435,7 @@ class JS8CallClient:
|
||||||
self.connected = True
|
self.connected = True
|
||||||
self.send("STATION.GET_STATUS")
|
self.send("STATION.GET_STATUS")
|
||||||
|
|
||||||
|
# Continuously listen for incoming messages while connected
|
||||||
while self.connected:
|
while self.connected:
|
||||||
content = self.sock.recv(65500).decode('utf-8') # Decode received bytes to string
|
content = self.sock.recv(65500).decode('utf-8') # Decode received bytes to string
|
||||||
if not content:
|
if not content:
|
||||||
|
@ -216,11 +461,51 @@ class JS8CallClient:
|
||||||
|
|
||||||
|
|
||||||
def handle_js8call_command(sender_id, interface):
|
def handle_js8call_command(sender_id, interface):
|
||||||
|
"""
|
||||||
|
Handles the initial JS8Call command.
|
||||||
|
|
||||||
|
This method sends a JS8Call menu to the specified sender, providing options for
|
||||||
|
group messages, station messages, urgent messages, and all messages. It also updates
|
||||||
|
the user state to indicate that the JS8Call menu has been presented.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
The meshtastic node identifier of the sender who issued the command
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
The interface through which messages are sent. This is typically an instance
|
||||||
|
of the communication interface used to interact with the user.
|
||||||
|
"""
|
||||||
response = "JS8Call Menu:\n[G]roup Messages\n[S]tation Messages\n[U]rgent Messages\nE[X]IT"
|
response = "JS8Call Menu:\n[G]roup Messages\n[S]tation Messages\n[U]rgent Messages\nE[X]IT"
|
||||||
send_message(response, sender_id, interface)
|
send_message(response, sender_id, interface)
|
||||||
update_user_state(sender_id, {'command': 'JS8CALL_MENU', 'step': 1})
|
update_user_state(sender_id, {'command': 'JS8CALL_MENU', 'step': 1})
|
||||||
|
|
||||||
def handle_js8call_steps(sender_id, message, step, interface, state):
|
def handle_js8call_steps(sender_id, message, step, interface, state):
|
||||||
|
"""
|
||||||
|
Handles the steps for the JS8Call command.
|
||||||
|
|
||||||
|
Processes the user's input at each step of the JS8Call menu. Based on the user's choice,
|
||||||
|
it directs them to the appropriate sub-menu or handles invalid options
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
Meshtastic node id
|
||||||
|
|
||||||
|
message : str
|
||||||
|
The message or input received from the user, representing their choice in the JS8Call menu.
|
||||||
|
|
||||||
|
step : int
|
||||||
|
The current step in the JS8Call menu navigation process.
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
Instance of meshtastic interface of type specified by the configuration
|
||||||
|
see get_interface for more details
|
||||||
|
|
||||||
|
state : dict
|
||||||
|
The current state of the user's interaction
|
||||||
|
"""
|
||||||
if step == 1:
|
if step == 1:
|
||||||
choice = message.lower()
|
choice = message.lower()
|
||||||
if choice == 'x':
|
if choice == 'x':
|
||||||
|
@ -237,6 +522,22 @@ def handle_js8call_steps(sender_id, message, step, interface, state):
|
||||||
handle_js8call_command(sender_id, interface)
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
def handle_group_messages_command(sender_id, interface):
|
def handle_group_messages_command(sender_id, interface):
|
||||||
|
"""
|
||||||
|
Handles the command to display group messages.
|
||||||
|
|
||||||
|
This method retrieves distinct group names from the group messages database and presents
|
||||||
|
a menu to the user with the available groups. If no group messages are available, it notifies
|
||||||
|
the user and returns to the main JS8Call menu.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
Meshtastic node id
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
Instance of meshtastic interface of type specified by the configuration
|
||||||
|
see get_interface for more details
|
||||||
|
"""
|
||||||
conn = sqlite3.connect('js8call.db')
|
conn = sqlite3.connect('js8call.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute("SELECT DISTINCT groupname FROM groups")
|
c.execute("SELECT DISTINCT groupname FROM groups")
|
||||||
|
@ -250,6 +551,22 @@ def handle_group_messages_command(sender_id, interface):
|
||||||
handle_js8call_command(sender_id, interface)
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
def handle_station_messages_command(sender_id, interface):
|
def handle_station_messages_command(sender_id, interface):
|
||||||
|
"""
|
||||||
|
Handles the command to display station messages.
|
||||||
|
|
||||||
|
This method retrieves all messages from the 'messages' table in the database and presents
|
||||||
|
them to the user. Each message includes the sender, receiver, and the message content.
|
||||||
|
If no station messages are available, it notifies the user and returns to the main JS8Call menu.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
Meshtastic node id
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
Instance of meshtastic interface of type specified by the configuration
|
||||||
|
see get_interface for more details
|
||||||
|
"""
|
||||||
conn = sqlite3.connect('js8call.db')
|
conn = sqlite3.connect('js8call.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute("SELECT sender, receiver, message, timestamp FROM messages")
|
c.execute("SELECT sender, receiver, message, timestamp FROM messages")
|
||||||
|
@ -262,6 +579,22 @@ def handle_station_messages_command(sender_id, interface):
|
||||||
handle_js8call_command(sender_id, interface)
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
def handle_urgent_messages_command(sender_id, interface):
|
def handle_urgent_messages_command(sender_id, interface):
|
||||||
|
"""
|
||||||
|
Handles the command to display urgent messages.
|
||||||
|
|
||||||
|
This method retrieves all urgent messages from the 'urgent' table in the database and presents
|
||||||
|
them to the user. Each message includes the sender, group name, and the message content.
|
||||||
|
If no urgent messages are available, it notifies the user and returns to the main JS8Call menu.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
Meshtastic node id
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
Instance of meshtastic interface of type specified by the configuration
|
||||||
|
see get_interface for more details
|
||||||
|
"""
|
||||||
conn = sqlite3.connect('js8call.db')
|
conn = sqlite3.connect('js8call.db')
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
c.execute("SELECT sender, groupname, message, timestamp FROM urgent")
|
c.execute("SELECT sender, groupname, message, timestamp FROM urgent")
|
||||||
|
@ -274,6 +607,31 @@ def handle_urgent_messages_command(sender_id, interface):
|
||||||
handle_js8call_command(sender_id, interface)
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
def handle_group_message_selection(sender_id, message, step, state, interface):
|
def handle_group_message_selection(sender_id, message, step, state, interface):
|
||||||
|
"""
|
||||||
|
Handles the selection of a group from the group messages menu.
|
||||||
|
|
||||||
|
This method processes the user's selection of a group and retrieves the messages
|
||||||
|
for the selected group from the database. It then presents the messages to the user.
|
||||||
|
If the selection is invalid, it prompts the user to choose again.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
-----------
|
||||||
|
sender_id : str
|
||||||
|
Meshtastic node id
|
||||||
|
|
||||||
|
message : str
|
||||||
|
The message or input received from the user, representing their choice in the JS8Call menu.
|
||||||
|
|
||||||
|
step : int
|
||||||
|
The current step in the JS8Call menu navigation process.
|
||||||
|
|
||||||
|
interface : object
|
||||||
|
Instance of meshtastic interface of type specified by the configuration
|
||||||
|
see get_interface for more details
|
||||||
|
|
||||||
|
state : dict
|
||||||
|
The current state of the user's interaction
|
||||||
|
"""
|
||||||
groups = state['groups']
|
groups = state['groups']
|
||||||
try:
|
try:
|
||||||
group_index = int(message)
|
group_index = int(message)
|
||||||
|
|
Loading…
Reference in a new issue