|
|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
#!/usr/bin/python3
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
SkywarnPlus Updater v0.3.2 by Mason Nelson
|
|
|
|
|
SkywarnPlus Updater v0.3.3 by Mason Nelson
|
|
|
|
|
===============================================================================
|
|
|
|
|
Script to update SkywarnPlus to the latest version. This script will download
|
|
|
|
|
the latest version of SkywarnPlus from GitHub, and then merge the existing
|
|
|
|
|
@ -31,20 +31,28 @@ from ruamel.yaml import YAML
|
|
|
|
|
import argparse
|
|
|
|
|
|
|
|
|
|
# Set up command line arguments
|
|
|
|
|
parser = argparse.ArgumentParser(description="Update SkywarnPlus script.")
|
|
|
|
|
parser.add_argument("-f", "--force", help="Force update without confirmation prompt", action="store_true")
|
|
|
|
|
parser = argparse.ArgumentParser(description="Update SkywarnPlus")
|
|
|
|
|
parser.add_argument(
|
|
|
|
|
"-f",
|
|
|
|
|
"--force",
|
|
|
|
|
help="Force update without confirmation prompt",
|
|
|
|
|
action="store_true",
|
|
|
|
|
)
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Logging function
|
|
|
|
|
def log(message):
|
|
|
|
|
print("[UPDATE]:", message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Function to load a yaml file
|
|
|
|
|
def load_yaml_file(filename):
|
|
|
|
|
yaml = YAML()
|
|
|
|
|
with open(filename, "r") as f:
|
|
|
|
|
return yaml.load(f)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Function to save a yaml file
|
|
|
|
|
def save_yaml_file(filename, data):
|
|
|
|
|
yaml = YAML()
|
|
|
|
|
@ -52,6 +60,7 @@ def save_yaml_file(filename, data):
|
|
|
|
|
with open(filename, "w") as f:
|
|
|
|
|
yaml.dump(data, f)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Function to merge two yaml files
|
|
|
|
|
def merge_yaml_files(old_file, new_file):
|
|
|
|
|
# Load the old and new yaml files
|
|
|
|
|
@ -61,7 +70,9 @@ def merge_yaml_files(old_file, new_file):
|
|
|
|
|
# Merge the new yaml file with values from the old file
|
|
|
|
|
for key in new_yaml_data:
|
|
|
|
|
if key in old_yaml_data:
|
|
|
|
|
if isinstance(new_yaml_data[key], dict) and isinstance(old_yaml_data[key], dict):
|
|
|
|
|
if isinstance(new_yaml_data[key], dict) and isinstance(
|
|
|
|
|
old_yaml_data[key], dict
|
|
|
|
|
):
|
|
|
|
|
new_yaml_data[key].update(old_yaml_data[key])
|
|
|
|
|
else:
|
|
|
|
|
new_yaml_data[key] = old_yaml_data[key]
|
|
|
|
|
@ -69,13 +80,14 @@ def merge_yaml_files(old_file, new_file):
|
|
|
|
|
# Save the merged yaml data back to the new file
|
|
|
|
|
save_yaml_file(new_file, new_yaml_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def remove_duplicate_comments(filename):
|
|
|
|
|
# Keep track of the last comment block
|
|
|
|
|
last_comment_block = []
|
|
|
|
|
new_lines = []
|
|
|
|
|
|
|
|
|
|
# Read the file line by line
|
|
|
|
|
with open(filename, 'r') as f:
|
|
|
|
|
with open(filename, "r") as f:
|
|
|
|
|
lines = f.readlines()
|
|
|
|
|
|
|
|
|
|
current_comment_block = []
|
|
|
|
|
@ -83,7 +95,7 @@ def remove_duplicate_comments(filename):
|
|
|
|
|
stripped_line = line.strip()
|
|
|
|
|
|
|
|
|
|
# If line is a comment or blank, it's part of the current block
|
|
|
|
|
if stripped_line.startswith('#') or not stripped_line:
|
|
|
|
|
if stripped_line.startswith("#") or not stripped_line:
|
|
|
|
|
current_comment_block.append(line)
|
|
|
|
|
else:
|
|
|
|
|
if current_comment_block:
|
|
|
|
|
@ -98,25 +110,33 @@ def remove_duplicate_comments(filename):
|
|
|
|
|
new_lines.extend(current_comment_block)
|
|
|
|
|
|
|
|
|
|
# Write the new lines back to the file
|
|
|
|
|
with open(filename, 'w') as f:
|
|
|
|
|
with open(filename, "w") as f:
|
|
|
|
|
f.writelines(new_lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Check for root privileges
|
|
|
|
|
if os.geteuid() != 0:
|
|
|
|
|
exit("ERROR: This script must be run as root.")
|
|
|
|
|
|
|
|
|
|
# Make sure the script is in the right directory
|
|
|
|
|
if not os.path.isfile('SkywarnPlus.py'):
|
|
|
|
|
print('ERROR: Cannot find SkywarnPlus.py. Make sure this script is in the SkywarnPlus directory.')
|
|
|
|
|
if not os.path.isfile("SkywarnPlus.py"):
|
|
|
|
|
print(
|
|
|
|
|
"ERROR: Cannot find SkywarnPlus.py. Make sure this script is in the SkywarnPlus directory."
|
|
|
|
|
)
|
|
|
|
|
exit()
|
|
|
|
|
|
|
|
|
|
# Prompt for confirmation unless -f flag is present
|
|
|
|
|
if not args.force:
|
|
|
|
|
print("\nThis script will update SkywarnPlus to the latest version.")
|
|
|
|
|
print("It will create a backup of the existing SkywarnPlus directory before updating.")
|
|
|
|
|
print("Be aware that if you've made significant changes to the code or directory structure, this may cause issues.")
|
|
|
|
|
print(
|
|
|
|
|
"It will create a backup of the existing SkywarnPlus directory before updating."
|
|
|
|
|
)
|
|
|
|
|
print(
|
|
|
|
|
"Be aware that if you've made significant changes to the code or directory structure, this may cause issues."
|
|
|
|
|
)
|
|
|
|
|
print("If you've made significant changes, it is recommended to update manually.\n")
|
|
|
|
|
confirmation = input("Do you want to continue with the update? (yes/no) ")
|
|
|
|
|
print("ALWAYS DOUBLE CHECK YOUR CONFIG.YAML AFTER UPDATING! This script is not perfect and may not merge your config.yaml correctly.\n")
|
|
|
|
|
confirmation = input("\nDo you want to continue with the update? (yes/no) ")
|
|
|
|
|
if confirmation.lower() != "yes":
|
|
|
|
|
log("Update cancelled by user.")
|
|
|
|
|
exit()
|
|
|
|
|
@ -126,29 +146,31 @@ root_dir = os.getcwd()
|
|
|
|
|
log("Current directory is {}".format(root_dir))
|
|
|
|
|
|
|
|
|
|
# Full path to the archive
|
|
|
|
|
zip_name = root_dir + '_backup_' + datetime.datetime.now().strftime('%Y%m%d_%H%M')
|
|
|
|
|
zip_name = root_dir + "_backup_" + datetime.datetime.now().strftime("%Y%m%d_%H%M")
|
|
|
|
|
log("Creating backup at {}.zip...".format(zip_name))
|
|
|
|
|
|
|
|
|
|
# Create the zip archive
|
|
|
|
|
shutil.make_archive(zip_name, 'zip', root_dir)
|
|
|
|
|
shutil.make_archive(zip_name, "zip", root_dir)
|
|
|
|
|
|
|
|
|
|
# Download the new zip from GitHub
|
|
|
|
|
url = 'https://github.com/Mason10198/SkywarnPlus/releases/latest/download/SkywarnPlus.zip'
|
|
|
|
|
url = (
|
|
|
|
|
"https://github.com/Mason10198/SkywarnPlus/releases/latest/download/SkywarnPlus.zip"
|
|
|
|
|
)
|
|
|
|
|
log("Downloading SkywarnPlus from {}...".format(url))
|
|
|
|
|
response = requests.get(url)
|
|
|
|
|
|
|
|
|
|
with open('/tmp/SkywarnPlus.zip', 'wb') as out_file:
|
|
|
|
|
with open("/tmp/SkywarnPlus.zip", "wb") as out_file:
|
|
|
|
|
out_file.write(response.content)
|
|
|
|
|
|
|
|
|
|
# Delete /tmp/SkywarnPlus if it already exists
|
|
|
|
|
if os.path.isdir('/tmp/SkywarnPlus'):
|
|
|
|
|
if os.path.isdir("/tmp/SkywarnPlus"):
|
|
|
|
|
log("Removing old /tmp/SkywarnPlus directory...")
|
|
|
|
|
shutil.rmtree('/tmp/SkywarnPlus')
|
|
|
|
|
shutil.rmtree("/tmp/SkywarnPlus")
|
|
|
|
|
|
|
|
|
|
# Unzip the downloaded file
|
|
|
|
|
log("Extracting SkywarnPlus.zip...")
|
|
|
|
|
with zipfile.ZipFile('/tmp/SkywarnPlus.zip', 'r') as zip_ref:
|
|
|
|
|
zip_ref.extractall('/tmp')
|
|
|
|
|
with zipfile.ZipFile("/tmp/SkywarnPlus.zip", "r") as zip_ref:
|
|
|
|
|
zip_ref.extractall("/tmp")
|
|
|
|
|
|
|
|
|
|
# Merge the old config with the new config
|
|
|
|
|
log("Merging old config with new config...")
|
|
|
|
|
@ -159,10 +181,10 @@ remove_duplicate_comments("/tmp/SkywarnPlus/config.yaml")
|
|
|
|
|
|
|
|
|
|
# Replace old directory with updated files
|
|
|
|
|
log("Merging updated files into {}...".format(root_dir))
|
|
|
|
|
for root, dirs, files in os.walk('/tmp/SkywarnPlus'):
|
|
|
|
|
for root, dirs, files in os.walk("/tmp/SkywarnPlus"):
|
|
|
|
|
for file in files:
|
|
|
|
|
old_file_path = os.path.join(root, file)
|
|
|
|
|
relative_path = os.path.relpath(old_file_path, '/tmp/SkywarnPlus')
|
|
|
|
|
relative_path = os.path.relpath(old_file_path, "/tmp/SkywarnPlus")
|
|
|
|
|
new_file_path = os.path.join(root_dir, relative_path)
|
|
|
|
|
|
|
|
|
|
os.makedirs(os.path.dirname(new_file_path), exist_ok=True)
|
|
|
|
|
@ -172,17 +194,17 @@ for root, dirs, files in os.walk('/tmp/SkywarnPlus'):
|
|
|
|
|
log("Setting .py files as executable...")
|
|
|
|
|
for dirpath, dirs, files in os.walk(root_dir):
|
|
|
|
|
for filename in files:
|
|
|
|
|
if filename.endswith('.py'):
|
|
|
|
|
if filename.endswith(".py"):
|
|
|
|
|
os.chmod(os.path.join(dirpath, filename), 0o755) # chmod +x
|
|
|
|
|
|
|
|
|
|
# Delete temporary files and folders
|
|
|
|
|
log("Deleting temporary files and folders...")
|
|
|
|
|
shutil.rmtree('/tmp/SkywarnPlus')
|
|
|
|
|
os.remove('/tmp/SkywarnPlus.zip')
|
|
|
|
|
shutil.rmtree("/tmp/SkywarnPlus")
|
|
|
|
|
os.remove("/tmp/SkywarnPlus.zip")
|
|
|
|
|
|
|
|
|
|
# Delete old TmpDir if it still exists
|
|
|
|
|
if os.path.isdir("/tmp/SkywarnPlus"):
|
|
|
|
|
log("Removing old /tmp/SkywarnPlus directory...")
|
|
|
|
|
shutil.rmtree("/tmp/SkywarnPlus")
|
|
|
|
|
|
|
|
|
|
log("Update complete!")
|
|
|
|
|
log("Update complete!")
|
|
|
|
|
|