forked from iarv/meshing-around
Compare commits
9 Commits
v1.9.8.9.1
...
v1.9.9.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b92cf48fd0 | ||
|
|
227ffc94e6 | ||
|
|
b9f5a0c7f9 | ||
|
|
d56c1380c3 | ||
|
|
e8a8eefcc2 | ||
|
|
5738e8d306 | ||
|
|
11359e4016 | ||
|
|
7bb31af1d2 | ||
|
|
fd115916f5 |
@@ -401,9 +401,9 @@ enable_runShellCmd = False
|
||||
# direct shell command handler the x: command in DMs
|
||||
allowXcmd = False
|
||||
# Enable 2 factor authentication for x: commands
|
||||
2factor_enabled = True
|
||||
twoFactor_enabled = True
|
||||
# time in seconds to wait for the correct 2FA answer
|
||||
2factor_timeout = 100
|
||||
twoFactor_timeout = 100
|
||||
|
||||
[smtp]
|
||||
# enable or disable the SMTP module
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# # Simulate meshing-around de K7MHI 2024
|
||||
from modules.log import logger, getPrettyTime # Import the logger; ### --> If you are reading this put the script in the project root <-- ###
|
||||
import time
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
import random
|
||||
|
||||
# Initialize the tool
|
||||
@@ -51,8 +51,8 @@ def example_handler(message, nodeID, deviceID):
|
||||
msg = f"Hello {get_name_from_number(nodeID)}, simulator ready for testing {projectName} project! on device {deviceID}"
|
||||
msg += f" Your location is {location}"
|
||||
msg += f" you said: {message}"
|
||||
|
||||
|
||||
# Add timestamp
|
||||
msg += f" [Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}]"
|
||||
return msg
|
||||
|
||||
|
||||
|
||||
@@ -1996,12 +1996,12 @@ def onReceive(packet, interface):
|
||||
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} found the Word of the Day🎊:\n {wordWas}, {metaWas}"
|
||||
send_message(msg, channel_number, 0, rxNode)
|
||||
if bingo_win:
|
||||
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} scored BINGO!🥳 {bingo_message}"
|
||||
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} scored word-search-BINGO!🥳 {bingo_message}"
|
||||
send_message(msg, channel_number, 0, rxNode)
|
||||
|
||||
slotMachine = theWordOfTheDay.emojiMiniGame(message_string, emojiSeen=emojiSeen, nodeID=message_from_id, nodeInt=rxNode)
|
||||
if slotMachine:
|
||||
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} played the Slot Machine and got: {slotMachine} 🥳"
|
||||
msg = f"🎉 {get_name_from_number(message_from_id, 'long', rxNode)} played the emote-Fruit-Machine and got: {slotMachine} 🥳"
|
||||
send_message(msg, channel_number, 0, rxNode)
|
||||
|
||||
# add message to tts queue
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Fetches DX spots from Spothole API based on user commands
|
||||
# 2025 K7MHI Kelly Keeton
|
||||
import requests
|
||||
import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from modules.log import logger
|
||||
from modules.settings import latitudeValue, longitudeValue
|
||||
|
||||
@@ -69,7 +69,6 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
|
||||
url = "https://spothole.app/api/v1/spots"
|
||||
params = {}
|
||||
fetched_count = 0
|
||||
|
||||
|
||||
# Add administrative filters if provided
|
||||
qrt = False # Always fetch active spots
|
||||
@@ -83,7 +82,7 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
|
||||
params["needs_sig"] = str(needs_sig).lower()
|
||||
params["needs_sig_ref"] = 'true'
|
||||
# Only get spots from last 9 hours
|
||||
received_since_dt = datetime.datetime.utcnow() - datetime.timedelta(hours=9)
|
||||
received_since_dt = datetime.utcnow() - timedelta(hours=9)
|
||||
received_since = int(received_since_dt.timestamp())
|
||||
params["received_since"] = received_since
|
||||
|
||||
@@ -170,7 +169,7 @@ def get_spothole_spots(source=None, band=None, mode=None, date=None, dx_call=Non
|
||||
return spots
|
||||
|
||||
def handle_post_dxspot():
|
||||
time = int(datetime.datetime.utcnow().timestamp())
|
||||
time = int(datetime.utcnow().timestamp())
|
||||
freq = 14200000 # 14 MHz
|
||||
comment = "Test spot please ignore"
|
||||
de_spot = "N0CALL"
|
||||
|
||||
@@ -462,7 +462,6 @@ def alertBrodcastNOAA():
|
||||
# broadcast the alerts send to wxBrodcastCh
|
||||
elif currentAlert[0] not in wxAlertCacheNOAA:
|
||||
# Check if the current alert is not in the weather alert cache
|
||||
logger.debug("Location:Broadcasting weather alerts")
|
||||
wxAlertCacheNOAA = currentAlert[0]
|
||||
return currentAlert
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import html
|
||||
from html.parser import HTMLParser
|
||||
import bs4 as bs
|
||||
import requests
|
||||
import datetime
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Common User-Agent for all RSS requests
|
||||
COMMON_USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
|
||||
@@ -146,7 +146,7 @@ def get_newsAPI(user_search="meshtastic"):
|
||||
if not user_search:
|
||||
user_search = "meshtastic"
|
||||
try:
|
||||
last_week = datetime.datetime.now() - datetime.timedelta(days=7)
|
||||
last_week = datetime.now() - timedelta(days=7)
|
||||
newsAPIurl = (
|
||||
f"https://newsapi.org/v2/everything?"
|
||||
f"q={user_search}&language=en&from={last_week.strftime('%Y-%m-%d')}&sortBy={newsAPIsort}shedAt&pageSize=5&apiKey={newsAPI_KEY}"
|
||||
|
||||
@@ -344,7 +344,7 @@ try:
|
||||
myStateFIPSList = config['location'].get('myFIPSList', '').split(',') # default empty
|
||||
mySAMEList = config['location'].get('mySAMEList', '').split(',') # default empty
|
||||
myRegionalKeysDE = config['location'].get('myRegionalKeysDE', '110000000000').split(',') # default city Berlin
|
||||
eAlertBroadcastChannel = config['location'].getint('eAlertBroadcastChannel', '') # default empty
|
||||
eAlertBroadcastChannel = config['location'].get('eAlertBroadcastCh', '').split(',') # default empty
|
||||
|
||||
# any US alerts enabled
|
||||
usAlerts = (
|
||||
@@ -459,8 +459,8 @@ try:
|
||||
news_random_line_only = config['fileMon'].getboolean('news_random_line', False) # default False
|
||||
enable_runShellCmd = config['fileMon'].getboolean('enable_runShellCmd', False) # default False
|
||||
allowXcmd = config['fileMon'].getboolean('allowXcmd', False) # default False
|
||||
xCmd2factorEnabled = config['fileMon'].getboolean('2factor_enabled', True) # default True
|
||||
xCmd2factor_timeout = config['fileMon'].getint('2factor_timeout', 100) # default 100 seconds
|
||||
xCmd2factorEnabled = config['fileMon'].getboolean('twoFactor_enabled', True) # default True
|
||||
xCmd2factor_timeout = config['fileMon'].getint('twoFactor_timeout', 100) # default 100 seconds
|
||||
|
||||
# games
|
||||
game_hop_limit = config['games'].getint('game_hop_limit', 5) # default 5 hops
|
||||
|
||||
@@ -376,6 +376,9 @@ for i in range(1, 10):
|
||||
logger.critical(f"System: abort. Initializing Interface{i} {e}")
|
||||
exit()
|
||||
|
||||
# Get my node numbers for global use
|
||||
my_node_ids = [globals().get(f'myNodeNum{i}') for i in range(1, 10)]
|
||||
|
||||
# Get the node number of the devices, check if the devices are connected meshtastic devices
|
||||
for i in range(1, 10):
|
||||
if globals().get(f'interface{i}') and globals().get(f'interface{i}_enabled'):
|
||||
@@ -659,7 +662,7 @@ async def get_closest_nodes(nodeInt=1,returnCount=3, channel=publicChannel):
|
||||
distance = round(geopy.distance.geodesic((latitudeValue, longitudeValue), (latitude, longitude)).m, 2)
|
||||
|
||||
if (distance < sentry_radius):
|
||||
if (nodeID not in [globals().get(f'myNodeNum{i}') for i in range(1, 10)]) and str(nodeID) not in sentryIgnoreList:
|
||||
if (nodeID not in my_node_ids) and str(nodeID) not in sentryIgnoreList:
|
||||
node_list.append({'id': nodeID, 'latitude': latitude, 'longitude': longitude, 'distance': distance})
|
||||
|
||||
except Exception as e:
|
||||
@@ -671,7 +674,7 @@ async def get_closest_nodes(nodeInt=1,returnCount=3, channel=publicChannel):
|
||||
try:
|
||||
logger.debug(f"System: Requesting location data for {node['id']}, lastHeard: {node.get('lastHeard', 'N/A')}")
|
||||
# if not a interface node
|
||||
if node['num'] in [globals().get(f'myNodeNum{i}') for i in range(1, 10)]:
|
||||
if node['num'] in my_node_ids:
|
||||
ignore = True
|
||||
else:
|
||||
# one idea is to send a ping to the node to request location data for if or when, ask again later
|
||||
@@ -1169,9 +1172,15 @@ def handleAlertBroadcast(deviceID=1):
|
||||
for alert_type, alert_msg, enabled in alert_types:
|
||||
if enabled and alert_msg and NO_ALERTS not in alert_msg and ERROR_FETCHING_DATA not in alert_msg:
|
||||
if should_send_alert(alert_type, alert_msg):
|
||||
logger.debug(f"System: Sending {alert_type} alert to emergency responder channel {emergency_responder_alert_channel}")
|
||||
send_message(alert_msg, emergency_responder_alert_channel, 0, emergency_responder_alert_interface)
|
||||
if eAlertBroadcastChannel != '':
|
||||
send_message(alert_msg, eAlertBroadcastChannel, 0, emergency_responder_alert_interface)
|
||||
if eAlertBroadcastChannel:
|
||||
for ch in eAlertBroadcastChannel:
|
||||
ch = ch.strip()
|
||||
if ch:
|
||||
logger.debug(f"System: Sending {alert_type} alert to aux channel {ch}")
|
||||
time.sleep(splitDelay)
|
||||
send_message(alert_msg, int(ch), 0, emergency_responder_alert_interface)
|
||||
except Exception as e:
|
||||
logger.error(f"System: Error in handleAlertBroadcast: {e}")
|
||||
return False
|
||||
@@ -1371,11 +1380,13 @@ def consumeMetadata(packet, rxNode=0, channel=-1):
|
||||
|
||||
# Meta for most Messages leaderboard
|
||||
if packet_type == 'TEXT_MESSAGE':
|
||||
message_count = meshLeaderboard.get('nodeMessageCounts', {})
|
||||
message_count[nodeID] = message_count.get(nodeID, 0) + 1
|
||||
meshLeaderboard['nodeMessageCounts'] = message_count
|
||||
if message_count[nodeID] > meshLeaderboard['mostMessages']['value']:
|
||||
meshLeaderboard['mostMessages'] = {'nodeID': nodeID, 'value': message_count[nodeID], 'timestamp': time.time()}
|
||||
# if packet isnt TO a my_node_id count it
|
||||
if packet.get('to') not in my_node_ids:
|
||||
message_count = meshLeaderboard.get('nodeMessageCounts', {})
|
||||
message_count[nodeID] = message_count.get(nodeID, 0) + 1
|
||||
meshLeaderboard['nodeMessageCounts'] = message_count
|
||||
if message_count[nodeID] > meshLeaderboard['mostMessages']['value']:
|
||||
meshLeaderboard['mostMessages'] = {'nodeID': nodeID, 'value': message_count[nodeID], 'timestamp': time.time()}
|
||||
else:
|
||||
tmessage_count = meshLeaderboard.get('nodeTMessageCounts', {})
|
||||
tmessage_count[nodeID] = tmessage_count.get(nodeID, 0) + 1
|
||||
|
||||
27
update.sh
27
update.sh
@@ -28,10 +28,18 @@ fi
|
||||
# Fetch latest changes from GitHub
|
||||
echo "Fetching latest changes from GitHub..."
|
||||
if ! git fetch origin; then
|
||||
echo "Error: Failed to fetch from GitHub, check your network connection."
|
||||
echo "Error: Failed to fetch from GitHub, check your network connection. script expects to be run inside a git repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for detached HEAD state
|
||||
if [[ $(git symbolic-ref --short -q HEAD) == "" ]]; then
|
||||
echo "WARNING: You are in a detached HEAD state."
|
||||
echo "You may not be on a branch. To return to the main branch, run:"
|
||||
echo " git checkout main"
|
||||
echo "Proceed with caution; changes may not be saved to a branch."
|
||||
fi
|
||||
|
||||
# git pull with rebase to avoid unnecessary merge commits
|
||||
echo "Pulling latest changes from GitHub..."
|
||||
if ! git pull origin main --rebase; then
|
||||
@@ -63,24 +71,7 @@ if [[ -f "modules/custom_scheduler.py" ]]; then
|
||||
echo "Including custom_scheduler.py in backup..."
|
||||
cp modules/custom_scheduler.py data/
|
||||
fi
|
||||
# Check config.ini ownership and permissions
|
||||
if [[ -f "config.ini" ]]; then
|
||||
owner=$(stat -f "%Su" config.ini)
|
||||
perms=$(stat -f "%A" config.ini)
|
||||
|
||||
if [[ "$owner" == "root" ]]; then
|
||||
echo "config.ini is owned by: $owner"
|
||||
echo "Warning: config.ini is owned by root check out the etc/set-permissions.sh script"
|
||||
fi
|
||||
if [[ $(stat -f "%Lp" config.ini) =~ .*[7,6,2]$ ]]; then
|
||||
cho "config.ini permissions: $perms"
|
||||
echo "Warning: config.ini is world-writable or world-readable! check out the etc/set-permissions.sh script"
|
||||
fi
|
||||
|
||||
echo "Including config.ini in backup..."
|
||||
|
||||
cp config.ini data/config.backup
|
||||
fi
|
||||
#create the tar.gz backup
|
||||
tar -czf "$backup_file" "$path2backup"
|
||||
if [ $? -ne 0 ]; then
|
||||
|
||||
Reference in New Issue
Block a user