mirror of
https://github.com/TheCommsChannel/TC2-BBS-mesh.git
synced 2024-10-01 01:15:36 -04:00
Add JS8Call capability
This commit is contained in:
parent
048772af0f
commit
6363c8dd91
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
bulletins.db
|
bulletins.db
|
||||||
|
js8call.db
|
||||||
venv/
|
venv/
|
||||||
.venv
|
.venv
|
||||||
.idea
|
.idea
|
||||||
|
@ -21,7 +21,7 @@ def handle_help_command(sender_id, interface, menu_name=None):
|
|||||||
if menu_name:
|
if menu_name:
|
||||||
update_user_state(sender_id, {'command': 'MENU', 'menu': menu_name, 'step': 1})
|
update_user_state(sender_id, {'command': 'MENU', 'menu': menu_name, 'step': 1})
|
||||||
if menu_name == 'bbs':
|
if menu_name == 'bbs':
|
||||||
response = "📰BBS Menu📰\n[M]ail\n[B]ulletins\n[C]hannel Dir\nE[X]IT"
|
response = "📰BBS Menu📰\n[M]ail\n[B]ulletins\n[C]hannel Dir\n[J]S8CALL\nE[X]IT"
|
||||||
elif menu_name == 'utilities':
|
elif menu_name == 'utilities':
|
||||||
response = "🛠️Utilities Menu🛠️\n[S]tats\n[F]ortune\n[W]all of Shame\nE[X]IT"
|
response = "🛠️Utilities Menu🛠️\n[S]tats\n[F]ortune\n[W]all of Shame\nE[X]IT"
|
||||||
else:
|
else:
|
||||||
@ -30,8 +30,6 @@ def handle_help_command(sender_id, interface, menu_name=None):
|
|||||||
send_message(response, sender_id, interface)
|
send_message(response, sender_id, interface)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_node_name(node_id, interface):
|
def get_node_name(node_id, interface):
|
||||||
node_info = interface.nodes.get(node_id)
|
node_info = interface.nodes.get(node_id)
|
||||||
if node_info:
|
if node_info:
|
||||||
@ -605,29 +603,8 @@ def handle_list_channels_command(sender_id, interface):
|
|||||||
logging.error(f"Error processing list channels command: {e}")
|
logging.error(f"Error processing list channels command: {e}")
|
||||||
send_message("Error processing list channels command.", sender_id, interface)
|
send_message("Error processing list channels command.", sender_id, interface)
|
||||||
|
|
||||||
def handle_read_channel_command(sender_id, message, state, interface):
|
|
||||||
try:
|
|
||||||
channels = state.get('channels', [])
|
|
||||||
message_number = int(message) - 1
|
|
||||||
|
|
||||||
if message_number < 0 or message_number >= len(channels):
|
|
||||||
send_message("Invalid channel number. Please try again.", sender_id, interface)
|
|
||||||
return
|
|
||||||
|
|
||||||
channel_name, channel_url = channels[message_number]
|
|
||||||
response = f"Channel Name: {channel_name}\nChannel URL: {channel_url}"
|
|
||||||
send_message(response, sender_id, interface)
|
|
||||||
|
|
||||||
update_user_state(sender_id, None)
|
|
||||||
|
|
||||||
except ValueError:
|
|
||||||
send_message("Invalid input. Please enter a valid channel number.", sender_id, interface)
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Error processing read channel command: {e}")
|
|
||||||
send_message("Error processing read channel command.", sender_id, interface)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_quick_help_command(sender_id, interface):
|
def handle_quick_help_command(sender_id, interface):
|
||||||
response = ("✈️QUICK COMMANDS✈️\nSend command below for usage info:\nSM,, - Send "
|
response = ("✈️QUICK COMMANDS✈️\nSend command below for usage info:\nSM,, - Send "
|
||||||
"Mail\nCM - Check Mail\nPB,, - Post Bulletin\nCB,, - Check Bulletins\n")
|
"Mail\nCM - Check Mail\nPB,, - Post Bulletin\nCB,, - Check Bulletins\n")
|
||||||
send_message(response, sender_id, interface)
|
send_message(response, sender_id, interface)
|
||||||
|
296
js8call_integration.py
Normal file
296
js8call_integration.py
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
from socket import socket, AF_INET, SOCK_STREAM
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import sqlite3
|
||||||
|
import configparser
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from meshtastic import BROADCAST_NUM
|
||||||
|
|
||||||
|
from command_handlers import handle_help_command
|
||||||
|
from utils import send_message, update_user_state
|
||||||
|
|
||||||
|
config_file = 'config.ini'
|
||||||
|
|
||||||
|
def from_message(content):
|
||||||
|
try:
|
||||||
|
return json.loads(content)
|
||||||
|
except ValueError:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
def to_message(typ, value='', params=None):
|
||||||
|
if params is None:
|
||||||
|
params = {}
|
||||||
|
return json.dumps({'type': typ, 'value': value, 'params': params})
|
||||||
|
|
||||||
|
|
||||||
|
class JS8CallClient:
|
||||||
|
def __init__(self, interface, logger=None):
|
||||||
|
self.logger = logger or logging.getLogger('js8call')
|
||||||
|
self.logger.setLevel(logging.INFO)
|
||||||
|
self.config = configparser.ConfigParser()
|
||||||
|
self.config.read(config_file)
|
||||||
|
|
||||||
|
self.server = (
|
||||||
|
self.config.get('js8call', 'host', fallback=None),
|
||||||
|
self.config.getint('js8call', 'port', fallback=None)
|
||||||
|
)
|
||||||
|
self.db_file = self.config.get('js8call', 'db_file', fallback=None)
|
||||||
|
self.js8groups = self.config.get('js8call', 'js8groups', fallback='').split(',')
|
||||||
|
self.store_messages = self.config.getboolean('js8call', 'store_messages', fallback=True)
|
||||||
|
self.js8urgent = self.config.get('js8call', 'js8urgent', fallback='').split(',')
|
||||||
|
self.js8groups = [group.strip() for group in self.js8groups]
|
||||||
|
self.js8urgent = [group.strip() for group in self.js8urgent]
|
||||||
|
|
||||||
|
self.connected = False
|
||||||
|
self.sock = None
|
||||||
|
self.db_conn = None
|
||||||
|
self.interface = interface
|
||||||
|
|
||||||
|
if self.db_file:
|
||||||
|
self.db_conn = sqlite3.connect(self.db_file)
|
||||||
|
self.create_tables()
|
||||||
|
else:
|
||||||
|
self.logger.info("JS8Call configuration not found. Skipping JS8Call integration.")
|
||||||
|
|
||||||
|
def create_tables(self):
|
||||||
|
if not self.db_conn:
|
||||||
|
return
|
||||||
|
|
||||||
|
with self.db_conn:
|
||||||
|
self.db_conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
sender TEXT,
|
||||||
|
receiver TEXT,
|
||||||
|
message TEXT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
self.db_conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS groups (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
sender TEXT,
|
||||||
|
groupname TEXT,
|
||||||
|
message TEXT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
self.db_conn.execute('''
|
||||||
|
CREATE TABLE IF NOT EXISTS urgent (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
sender TEXT,
|
||||||
|
groupname TEXT,
|
||||||
|
message TEXT,
|
||||||
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
''')
|
||||||
|
self.logger.info("Database tables created or verified.")
|
||||||
|
|
||||||
|
def insert_message(self, sender, receiver, message):
|
||||||
|
if not self.db_conn:
|
||||||
|
self.logger.error("Database connection is not available.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with self.db_conn:
|
||||||
|
self.db_conn.execute('''
|
||||||
|
INSERT INTO messages (sender, receiver, message)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
''', (sender, receiver, message))
|
||||||
|
self.logger.info(f"Message inserted: {sender} to {receiver} - {message}")
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
self.logger.error(f"Failed to insert message into database: {e}")
|
||||||
|
|
||||||
|
def insert_group(self, sender, groupname, message):
|
||||||
|
if not self.db_conn:
|
||||||
|
self.logger.error("Database connection is not available.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with self.db_conn:
|
||||||
|
self.db_conn.execute('''
|
||||||
|
INSERT INTO groups (sender, groupname, message)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
''', (sender, groupname, message))
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
self.logger.error(f"Failed to insert group message into database: {e}")
|
||||||
|
|
||||||
|
def insert_urgent(self, sender, groupname, message):
|
||||||
|
if not self.db_conn:
|
||||||
|
self.logger.error("Database connection is not available.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with self.db_conn:
|
||||||
|
self.db_conn.execute('''
|
||||||
|
INSERT INTO urgent (sender, groupname, message)
|
||||||
|
VALUES (?, ?, ?)
|
||||||
|
''', (sender, groupname, message))
|
||||||
|
self.logger.info(f"Urgent message inserted: {sender} to {groupname} - {message}")
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
self.logger.error(f"Failed to insert urgent message into database: {e}")
|
||||||
|
|
||||||
|
def process(self, message):
|
||||||
|
typ = message.get('type', '')
|
||||||
|
value = message.get('value', '')
|
||||||
|
params = message.get('params', {})
|
||||||
|
|
||||||
|
if not typ:
|
||||||
|
return
|
||||||
|
|
||||||
|
rx_types = [
|
||||||
|
'RX.ACTIVITY', 'RX.DIRECTED', 'RX.SPOT', 'RX.CALL_ACTIVITY',
|
||||||
|
'RX.CALL_SELECTED', 'RX.DIRECTED_ME', 'RX.ECHO', 'RX.DIRECTED_GROUP',
|
||||||
|
'RX.META', 'RX.MSG', 'RX.PING', 'RX.PONG', 'RX.STREAM'
|
||||||
|
]
|
||||||
|
|
||||||
|
if typ not in rx_types:
|
||||||
|
return
|
||||||
|
|
||||||
|
if typ == 'RX.DIRECTED' and value:
|
||||||
|
parts = value.split(' ')
|
||||||
|
if len(parts) < 3:
|
||||||
|
self.logger.warning(f"Unexpected message format: {value}")
|
||||||
|
return
|
||||||
|
|
||||||
|
sender = parts[0]
|
||||||
|
receiver = parts[1]
|
||||||
|
msg = ' '.join(parts[2:]).strip()
|
||||||
|
|
||||||
|
self.logger.info(f"Received JS8Call message: {sender} to {receiver} - {msg}")
|
||||||
|
|
||||||
|
if receiver in self.js8urgent:
|
||||||
|
self.insert_urgent(sender, receiver, msg)
|
||||||
|
notification_message = f"💥 URGENT JS8Call Message Received 💥\nFrom: {sender}\nCheck BBS for message"
|
||||||
|
send_message(notification_message, BROADCAST_NUM, self.interface)
|
||||||
|
elif receiver in self.js8groups:
|
||||||
|
self.insert_group(sender, receiver, msg)
|
||||||
|
elif self.store_messages:
|
||||||
|
self.insert_message(sender, receiver, msg)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def send(self, *args, **kwargs):
|
||||||
|
params = kwargs.get('params', {})
|
||||||
|
if '_ID' not in params:
|
||||||
|
params['_ID'] = '{}'.format(int(time.time() * 1000))
|
||||||
|
kwargs['params'] = params
|
||||||
|
message = to_message(*args, **kwargs)
|
||||||
|
self.sock.send((message + '\n').encode('utf-8')) # Convert to bytes
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
if not self.server[0] or not self.server[1]:
|
||||||
|
self.logger.info("JS8Call server configuration not found. Skipping JS8Call connection.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.logger.info(f"Connecting to {self.server}")
|
||||||
|
self.sock = socket(AF_INET, SOCK_STREAM)
|
||||||
|
try:
|
||||||
|
self.sock.connect(self.server)
|
||||||
|
self.connected = True
|
||||||
|
self.send("STATION.GET_STATUS")
|
||||||
|
|
||||||
|
while self.connected:
|
||||||
|
content = self.sock.recv(65500).decode('utf-8') # Decode received bytes to string
|
||||||
|
if not content:
|
||||||
|
continue # Skip empty content
|
||||||
|
|
||||||
|
try:
|
||||||
|
message = json.loads(content)
|
||||||
|
except ValueError:
|
||||||
|
continue # Skip invalid JSON content
|
||||||
|
|
||||||
|
if not message:
|
||||||
|
continue # Skip empty message
|
||||||
|
|
||||||
|
self.process(message)
|
||||||
|
except ConnectionRefusedError:
|
||||||
|
self.logger.error(f"Connection to JS8Call server {self.server} refused.")
|
||||||
|
finally:
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.connected = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def handle_js8call_command(sender_id, interface):
|
||||||
|
response = "JS8Call Menu:\n[G]roup Messages\n[S]tation Messages\n[U]rgent Messages\nE[X]IT"
|
||||||
|
send_message(response, sender_id, interface)
|
||||||
|
update_user_state(sender_id, {'command': 'JS8CALL_MENU', 'step': 1})
|
||||||
|
|
||||||
|
def handle_js8call_steps(sender_id, message, step, interface, state):
|
||||||
|
if step == 1:
|
||||||
|
choice = message.lower()
|
||||||
|
if choice == 'x':
|
||||||
|
handle_help_command(sender_id, interface, 'bbs')
|
||||||
|
return
|
||||||
|
elif choice == 'g':
|
||||||
|
handle_group_messages_command(sender_id, interface)
|
||||||
|
elif choice == 's':
|
||||||
|
handle_station_messages_command(sender_id, interface)
|
||||||
|
elif choice == 'u':
|
||||||
|
handle_urgent_messages_command(sender_id, interface)
|
||||||
|
else:
|
||||||
|
send_message("Invalid option. Please choose again.", sender_id, interface)
|
||||||
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
|
def handle_group_messages_command(sender_id, interface):
|
||||||
|
conn = sqlite3.connect('js8call.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT DISTINCT groupname FROM groups")
|
||||||
|
groups = c.fetchall()
|
||||||
|
if groups:
|
||||||
|
response = "Group Messages Menu:\n" + "\n".join([f"[{i}] {group[0]}" for i, group in enumerate(groups)])
|
||||||
|
send_message(response, sender_id, interface)
|
||||||
|
update_user_state(sender_id, {'command': 'GROUP_MESSAGES', 'step': 1, 'groups': groups})
|
||||||
|
else:
|
||||||
|
send_message("No group messages available.", sender_id, interface)
|
||||||
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
|
def handle_station_messages_command(sender_id, interface):
|
||||||
|
conn = sqlite3.connect('js8call.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT sender, receiver, message, timestamp FROM messages")
|
||||||
|
messages = c.fetchall()
|
||||||
|
if messages:
|
||||||
|
response = "Station Messages:\n" + "\n".join([f"[{i+1}] {msg[0]} -> {msg[1]}: {msg[2]} ({msg[3]})" for i, msg in enumerate(messages)])
|
||||||
|
send_message(response, sender_id, interface)
|
||||||
|
else:
|
||||||
|
send_message("No station messages available.", sender_id, interface)
|
||||||
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
|
def handle_urgent_messages_command(sender_id, interface):
|
||||||
|
conn = sqlite3.connect('js8call.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT sender, groupname, message, timestamp FROM urgent")
|
||||||
|
messages = c.fetchall()
|
||||||
|
if messages:
|
||||||
|
response = "Urgent Messages:\n" + "\n".join([f"[{i+1}] {msg[0]} -> {msg[1]}: {msg[2]} ({msg[3]})" for i, msg in enumerate(messages)])
|
||||||
|
send_message(response, sender_id, interface)
|
||||||
|
else:
|
||||||
|
send_message("No urgent messages available.", sender_id, interface)
|
||||||
|
handle_js8call_command(sender_id, interface)
|
||||||
|
|
||||||
|
def handle_group_message_selection(sender_id, message, step, state, interface):
|
||||||
|
groups = state['groups']
|
||||||
|
try:
|
||||||
|
group_index = int(message)
|
||||||
|
groupname = groups[group_index][0]
|
||||||
|
|
||||||
|
conn = sqlite3.connect('js8call.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute("SELECT sender, message, timestamp FROM groups WHERE groupname=?", (groupname,))
|
||||||
|
messages = c.fetchall()
|
||||||
|
|
||||||
|
if messages:
|
||||||
|
response = f"Messages for group {groupname}:\n" + "\n".join([f"[{i+1}] {msg[0]}: {msg[1]} ({msg[2]})" for i, msg in enumerate(messages)])
|
||||||
|
send_message(response, sender_id, interface)
|
||||||
|
else:
|
||||||
|
send_message(f"No messages for group {groupname}.", sender_id, interface)
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
send_message("Invalid group selection. Please choose again.", sender_id, interface)
|
||||||
|
handle_group_messages_command(sender_id, interface)
|
||||||
|
|
||||||
|
handle_js8call_command(sender_id, interface)
|
@ -11,6 +11,7 @@ from command_handlers import (
|
|||||||
handle_post_channel_command, handle_list_channels_command, handle_quick_help_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 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
|
from utils import get_user_state, get_node_short_name, get_node_id_from_num, send_message
|
||||||
|
|
||||||
main_menu_handlers = {
|
main_menu_handlers = {
|
||||||
@ -24,6 +25,7 @@ bbs_menu_handlers = {
|
|||||||
"m": handle_mail_command,
|
"m": handle_mail_command,
|
||||||
"b": handle_bulletin_command,
|
"b": handle_bulletin_command,
|
||||||
"c": handle_channel_directory_command,
|
"c": handle_channel_directory_command,
|
||||||
|
"j": handle_js8call_command,
|
||||||
"x": handle_help_command
|
"x": handle_help_command
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,6 +109,12 @@ def process_message(sender_id, message, interface, is_sync_message=False):
|
|||||||
handlers = bulletin_menu_handlers
|
handlers = bulletin_menu_handlers
|
||||||
elif state and state['command'] == 'BULLETIN_ACTION':
|
elif state and state['command'] == 'BULLETIN_ACTION':
|
||||||
handlers = board_action_handlers
|
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:
|
else:
|
||||||
handlers = main_menu_handlers
|
handlers = main_menu_handlers
|
||||||
|
|
||||||
@ -152,10 +160,13 @@ def process_message(sender_id, message, interface, is_sync_message=False):
|
|||||||
handle_bb_steps(sender_id, message, 5, state, interface, bbs_nodes)
|
handle_bb_steps(sender_id, message, 5, state, interface, bbs_nodes)
|
||||||
elif command == 'BULLETIN_READ':
|
elif command == 'BULLETIN_READ':
|
||||||
handle_bb_steps(sender_id, message, 3, state, interface, bbs_nodes)
|
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:
|
else:
|
||||||
handle_help_command(sender_id, interface)
|
handle_help_command(sender_id, interface)
|
||||||
|
|
||||||
|
|
||||||
def on_receive(packet, interface):
|
def on_receive(packet, interface):
|
||||||
try:
|
try:
|
||||||
if 'decoded' in packet and packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP':
|
if 'decoded' in packet and packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP':
|
||||||
|
33
server.py
33
server.py
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
TC²-BBS Server for Meshtastic by TheCommsChannel (TC²)
|
TC²-BBS Server for Meshtastic by TheCommsChannel (TC²)
|
||||||
Date: 07/09/2024
|
Date: 07/14/2024
|
||||||
Version: 0.1.4
|
Version: 0.1.6
|
||||||
|
|
||||||
Description:
|
Description:
|
||||||
The system allows for mail message handling, bulletin boards, and a channel
|
The system allows for mail message handling, bulletin boards, and a channel
|
||||||
@ -13,15 +13,29 @@ other BBS servers listed in the config.ini file.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
from config_init import initialize_config, get_interface, init_cli_parser, merge_config
|
from config_init import initialize_config, get_interface, init_cli_parser, merge_config
|
||||||
from db_operations import initialize_database
|
from db_operations import initialize_database
|
||||||
|
from js8call_integration import JS8CallClient
|
||||||
from message_processing import on_receive
|
from message_processing import on_receive
|
||||||
from pubsub import pub
|
from pubsub import pub
|
||||||
import time
|
|
||||||
|
|
||||||
# Configure logging
|
# General logging
|
||||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||||
|
datefmt='%Y-%m-%d %H:%M:%S'
|
||||||
|
)
|
||||||
|
|
||||||
|
# JS8Call logging
|
||||||
|
js8call_logger = logging.getLogger('js8call')
|
||||||
|
js8call_logger.setLevel(logging.DEBUG)
|
||||||
|
js8call_handler = logging.StreamHandler()
|
||||||
|
js8call_handler.setLevel(logging.DEBUG)
|
||||||
|
js8call_formatter = logging.Formatter('%(asctime)s - JS8Call - %(levelname)s - %(message)s', '%Y-%m-%d %H:%M:%S')
|
||||||
|
js8call_handler.setFormatter(js8call_formatter)
|
||||||
|
js8call_logger.addHandler(js8call_handler)
|
||||||
|
|
||||||
def display_banner():
|
def display_banner():
|
||||||
banner = """
|
banner = """
|
||||||
@ -58,6 +72,13 @@ def main():
|
|||||||
|
|
||||||
pub.subscribe(receive_packet, system_config['mqtt_topic'])
|
pub.subscribe(receive_packet, system_config['mqtt_topic'])
|
||||||
|
|
||||||
|
# Initialize and start JS8Call Client if configured
|
||||||
|
js8call_client = JS8CallClient(interface)
|
||||||
|
js8call_client.logger = js8call_logger
|
||||||
|
|
||||||
|
if js8call_client.db_conn:
|
||||||
|
js8call_client.connect()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
@ -65,6 +86,8 @@ def main():
|
|||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logging.info("Shutting down the server...")
|
logging.info("Shutting down the server...")
|
||||||
interface.close()
|
interface.close()
|
||||||
|
if js8call_client.connected:
|
||||||
|
js8call_client.close()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
Loading…
Reference in New Issue
Block a user