From 8cb642bcb85f9933be9a045b771ed27b96d4ca0d Mon Sep 17 00:00:00 2001
From: Mason10198 <31994327+Mason10198@users.noreply.github.com>
Date: Sat, 27 Jul 2024 16:07:38 -0500
Subject: [PATCH] v0.8.1
---
ASL3_Supermon_Workaround.py | 97 +++++++++++++++++++++++++++++++++++++
swp-install | 67 ++++++++++++++++++-------
2 files changed, 147 insertions(+), 17 deletions(-)
create mode 100644 ASL3_Supermon_Workaround.py
diff --git a/ASL3_Supermon_Workaround.py b/ASL3_Supermon_Workaround.py
new file mode 100644
index 0000000..48c825e
--- /dev/null
+++ b/ASL3_Supermon_Workaround.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python3
+
+"""
+ASL3_Supermon_Workaround.py by Mason Nelson
+===============================================================================
+This script is a workaround for the Supermon compatibility issue with ASL 3.
+With Asterisk 20 no longer running as the root user, SkywarnPlus is unable to
+write to the old AUTOSKY directories. This script can be added to the crontab
+with root privileges as a workaround to write the alerts to the old AUTOSKY
+directories for Supermon compatibility.
+
+This file is part of SkywarnPlus.
+SkywarnPlus is free software: you can redistribute it and/or modify it under the terms of
+the GNU General Public License as published by the Free Software Foundation, either version 3
+of the License, or (at your option) any later version. SkywarnPlus is distributed in the hope
+that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with SkywarnPlus. If not, see .
+"""
+
+import os
+import json
+import logging
+from collections import OrderedDict
+
+# Paths
+BASE_DIR = os.path.dirname(os.path.realpath(__file__))
+COUNTY_CODES_PATH = os.path.join(BASE_DIR, "CountyCodes.md")
+DATA_FILE = "/tmp/SkywarnPlus/data.json"
+
+# Logging setup
+logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s")
+
+def load_state():
+ if os.path.exists(DATA_FILE):
+ with open(DATA_FILE, "r") as file:
+ state = json.load(file)
+ state["last_alerts"] = OrderedDict((x[0], x[1]) for x in state.get("last_alerts", []))
+ return state
+ logging.error("Data file not found, returning initial state")
+ return {"last_alerts": OrderedDict()}
+
+def generate_title_string(alerts, county_data):
+ alert_titles_with_counties = []
+ for alert in alerts:
+ counties = sorted(set(replace_with_county_name(x["county_code"], county_data) for x in alerts[alert]))
+ alert_titles_with_counties.append("{} [{}]".format(alert, ", ".join(counties)))
+ logging.info("String generated: %s", alert_titles_with_counties)
+ return alert_titles_with_counties
+
+def supermon_back_compat(alerts, county_data):
+ if os.getuid() != 0:
+ logging.error("Not running as root, exiting function")
+ return
+ alert_titles_with_counties = generate_title_string(alerts, county_data)
+ for path in ["/tmp/AUTOSKY", "/var/www/html/AUTOSKY"]:
+ try:
+ os.makedirs(path, exist_ok=True)
+ if os.access(path, os.W_OK):
+ file_path = os.path.join(path, "warnings.txt")
+ with open(file_path, "w") as file:
+ file.write("
".join(alert_titles_with_counties))
+ else:
+ logging.error("No write permission for %s", path)
+ except Exception as e:
+ logging.error("An error occurred while writing to %s: %s", path, e)
+
+def load_county_names(md_file):
+ with open(md_file, "r") as f:
+ lines = f.readlines()
+ county_data = {}
+ in_table = False
+ for line in lines:
+ if line.startswith("| County |"):
+ in_table = True
+ continue
+ elif not in_table or line.strip() == "" or line.startswith("##"):
+ continue
+ else:
+ name, code = [s.strip() for s in line.split("|")[1:-1]]
+ county_data[code] = name
+ return county_data
+
+def replace_with_county_name(county_code, county_data):
+ county_name = county_data.get(county_code, county_code)
+ return county_name
+
+def main():
+ if not os.path.isfile(DATA_FILE):
+ logging.warning("Data file does not exist, exiting.")
+ exit()
+ state = load_state()
+ last_alerts = state["last_alerts"]
+ county_data = load_county_names(COUNTY_CODES_PATH)
+ supermon_back_compat(last_alerts, county_data)
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/swp-install b/swp-install
index 7eb7faf..087fa6e 100644
--- a/swp-install
+++ b/swp-install
@@ -31,7 +31,7 @@ print_notice() {
echo "NOTE: This script is an installer only and will NOT automate configuration."
echo "Please edit the config.yaml file manually after installation."
print_divider
- read -r -p "Would you like to continue? (y/n) [y]: " CONTINUE
+ read -r -p "Would you like to continue? (Y/n): " CONTINUE
CONTINUE=${CONTINUE:-y}
if [[ "$CONTINUE" != [Yy] ]]; then
print_divider
@@ -62,7 +62,7 @@ determine_system_type() {
else
SYSTEM_TYPE="ASL1/2"
fi
- elif [ -f /etc/arch-release ]; then
+ elif [ -f /etc/arch-release ]; then
OS=arch
VER=$(uname -r)
SYSTEM_TYPE="HamVoIP"
@@ -78,7 +78,7 @@ confirm_system_type() {
print_divider
echo "Detected system type: $SYSTEM_TYPE."
print_divider
- read -r -p "Is this correct? Enter 'y' for yes or 'n' for no to override. [y]: " CONFIRMATION
+ read -r -p "Is this correct? (Y/n): " CONFIRMATION
CONFIRMATION=${CONFIRMATION:-y}
if [[ "$CONFIRMATION" != [Yy] ]]; then
print_divider
@@ -92,19 +92,19 @@ confirm_system_type() {
case $SYSTEM_TYPE_INPUT in
1)
SYSTEM_TYPE="ASL1/2"
- ;;
+ ;;
3)
SYSTEM_TYPE="ASL3"
- ;;
+ ;;
5)
SYSTEM_TYPE="HamVoIP"
- ;;
+ ;;
*)
print_divider
echo "Invalid input. Exiting."
print_divider
exit 1
- ;;
+ ;;
esac
fi
}
@@ -120,7 +120,7 @@ install_dependencies() {
else
apt install -y unzip python3 python3-pip ffmpeg python3-ruamel.yaml python3-requests python3-dateutil python3-pydub
fi
- elif [ "$OS" = "arch" ]; then
+ elif [ "$OS" = "arch" ]; then
pacman -Syu --noconfirm
pacman -S --noconfirm --needed ffmpeg
if ! command -v pip &> /dev/null; then
@@ -146,7 +146,7 @@ check_existing() {
[N] Continue with a fresh install after making a backup to SkywarnPlus_$(date +'%m-%d-%Y')/
(you can grab your old config.yaml file from the backup)
-Please choose an option (y/n) [y]: " INSTALL_OPTION
+ Please choose an option (Y/n): " INSTALL_OPTION
INSTALL_OPTION=${INSTALL_OPTION:-y}
if [[ "$INSTALL_OPTION" =~ ^[Yy]$ ]]; then
@@ -180,12 +180,12 @@ download_swp() {
configure_perms() {
print_divider
echo "Configuring permissions..."
-
+
if [ "$SYSTEM_TYPE" = "ASL3" ]; then
chown -R asterisk:asterisk /usr/local/bin/SkywarnPlus/
chmod -R u+rw /usr/local/bin/SkywarnPlus/
fi
-
+
chmod +x /usr/local/bin/SkywarnPlus/*.py
}
@@ -203,13 +203,13 @@ remove_old_cron() {
else
echo "No "old style" crontab entry found for SkywarnPlus.py."
fi
-
+
print_divider
echo "Checking for existing crontab entry for ast_var_update.sh..."
CRONTAB_AST=$(crontab -l | grep 'ast_var_update.sh')
if [ -n "$CRONTAB_AST" ]; then
echo "It looks like you have added a crontab entry for ast_var_update.sh - this functionality will now be handled by SkywarnPlus, and this crontab entry should be removed to avoid conflicts."
- read -r -p "Would you like to remove the crontab entry now? (y/n) [y]: " choice
+ read -r -p "Would you like to remove the crontab entry now? (Y/n): " choice
choice=${choice:-y}
if [[ "$choice" =~ ^[Yy]$ ]]; then
echo "Removing old crontab entry for ast_var_update.sh..."
@@ -234,19 +234,20 @@ setup_crontab() {
echo
echo "By default, the existing crontab entry will be kept."
echo
- echo "To keep the existing interval, press enter."
+ echo "To keep the existing $EXISTING_INTERVAL minute interval, press enter."
echo "To change the interval, enter a different number of minutes."
echo "To disable the crontab entry and require manual execution, enter '0'."
- read -r -p "Keep existing interval [$EXISTING_INTERVAL]: " CRONTAB_INTERVAL
+ read -r -p "Crontab interval ($EXISTING_INTERVAL): " CRONTAB_INTERVAL
print_divider
CRONTAB_INTERVAL=${CRONTAB_INTERVAL:-$EXISTING_INTERVAL}
fi
else
echo "By default, a new crontab entry will be added to trigger SkywarnPlus (check for alerts) every 1 minute."
echo
+ echo "To keep the default 1 minute interval, press enter."
echo "If you would like to increase this interval, enter a different number of minutes."
echo "To disable the crontab entry and require manual execution, enter '0'."
- read -r -p "To keep the default 1 minute interval, press enter. [1]: " CRONTAB_INTERVAL
+ read -r -p "Crontab interval: (1): " CRONTAB_INTERVAL
print_divider
CRONTAB_INTERVAL=${CRONTAB_INTERVAL:-1}
fi
@@ -276,13 +277,45 @@ setup_crontab() {
}
fi
fi
+
+ if [ "$SYSTEM_TYPE" = "ASL3" ]; then
+ echo "This is an ASL3 system. In order for Supermon to display SkywarnPlus alerts on ASL3, a second crontab entry needs to be created to run ASL3_Supermon_Workaround.py as the root user."
+
+ if [ -d "/var/www/html/supermon/" ]; then
+ echo "It looks like you have Supermon installed, so it is recommended to create this crontab entry."
+ else
+ echo "It looks like you do not have Supermon installed, but you can still safely create this crontab entry in case you decide to use Supermon later."
+ fi
+
+ read -r -p "Would you like to create the crontab entry for ASL3_Supermon_Workaround.py now? (Y/n): " CREATE_SUPERMON_CRON
+ CREATE_SUPERMON_CRON=${CREATE_SUPERMON_CRON:-y}
+
+ if [ "$CREATE_SUPERMON_CRON" = "y" ] || [ "$CREATE_SUPERMON_CRON" = "Y" ]; then
+ SUPERMON_CRON_FILE="/etc/cron.d/ASL3_Supermon_Workaround"
+ SUPERMON_CRONTAB_ENTRY="*/$CRONTAB_INTERVAL * * * * root /usr/local/bin/SkywarnPlus/ASL3_Supermon_Workaround.py"
+
+ if grep -Fxq "$SUPERMON_CRONTAB_ENTRY" "$SUPERMON_CRON_FILE" 2>/dev/null; then
+ echo "Supermon crontab entry already exists. Skipping."
+ else
+ echo "$SUPERMON_CRONTAB_ENTRY" > "$SUPERMON_CRON_FILE" || {
+ print_divider
+ echo "Failed to create Supermon crontab entry. Exiting."
+ print_divider
+ exit 1
+ }
+ echo "Supermon crontab entry created successfully."
+ fi
+ else
+ echo "Supermon crontab entry not created."
+ fi
+ fi
}
edit_config() {
print_divider
echo "Installation and configuration complete. Please edit the config.yaml file as per your needs."
print_divider
- read -r -p "Would you like to edit the config.yaml file now? (y/n) [y]: " EDIT_CONFIG
+ read -r -p "Would you like to edit the config.yaml file now? (Y/n): " EDIT_CONFIG
EDIT_CONFIG=${EDIT_CONFIG:-y}
if [[ "$EDIT_CONFIG" =~ ^[Yy]$ ]]; then
nano /usr/local/bin/SkywarnPlus/config.yaml