diff --git a/app/downloader.py b/app/downloader.py index 62e0830..645099e 100644 --- a/app/downloader.py +++ b/app/downloader.py @@ -21,6 +21,7 @@ def main(): save_apks = config.get("SAVE_APKS", False) save_firmware = config.get("SAVE_FIRMWARE", False) ntfy_server = config.get("NTFY_SERVER", "") + ntfy_topic = config.get("NTFY_TOPIC", "") android_versions_to_keep = config.get("ANDROID_VERSIONS_TO_KEEP", 2) firmware_versions_to_keep = config.get("FIRMWARE_VERSIONS_TO_KEEP", 2) auto_extract = config.get("AUTO_EXTRACT", False) @@ -49,12 +50,15 @@ def log_message(message): print(message) def send_ntfy_notification(message): - if ntfy_server: + if ntfy_server and ntfy_topic: try: - response = requests.post(ntfy_server, data=message.encode('utf-8')) + ntfy_url = f"{ntfy_server.rstrip('/')}/{ntfy_topic}" + response = requests.post(ntfy_url, data=message.encode('utf-8')) response.raise_for_status() except requests.exceptions.RequestException as e: log_message(f"Error sending notification: {e}") + else: + log_message("Notifications are not configured.") # Function to get the latest releases and sort by date def get_latest_releases(url, versions_to_keep, scan_count=5): @@ -175,6 +179,9 @@ def check_and_download(releases, latest_release_file, release_type, download_dir # Scan for the last 5 releases, download the latest versions_to_download releases_to_scan = 5 + latest_firmware_releases = [] + latest_android_releases = [] + if save_firmware and selected_firmware_assets: versions_to_download = firmware_versions_to_keep latest_firmware_releases = get_latest_releases(firmware_releases_url, versions_to_download, releases_to_scan) @@ -208,7 +215,8 @@ def check_and_download(releases, latest_release_file, release_type, download_dir log_message("No APK assets selected. Skipping APK download.") end_time = time.time() - log_message(f"Finished the Meshtastic downloader. Total time taken: {end_time - start_time:.2f} seconds") + total_time = end_time - start_time + log_message(f"Finished the Meshtastic downloader. Total time taken: {total_time:.2f} seconds") # Send notification if there are new downloads if downloaded_firmwares or downloaded_apks: @@ -220,13 +228,16 @@ def check_and_download(releases, latest_release_file, release_type, download_dir message += f"{datetime.now()}" send_ntfy_notification(message) else: - message = ( - f"All Firmware and Android APK versions are up to date.\n" - f"Latest Firmware releases: {', '.join(release['tag_name'] for release in latest_firmware_releases)}\n" - f"Latest Android APK releases: {', '.join(release['tag_name'] for release in latest_android_releases)}\n" - f"{datetime.now()}" - ) - send_ntfy_notification(message) + if latest_firmware_releases or latest_android_releases: + message = ( + f"All Firmware and Android APK versions are up to date.\n" + f"Latest Firmware releases: {', '.join(release['tag_name'] for release in latest_firmware_releases)}\n" + f"Latest Android APK releases: {', '.join(release['tag_name'] for release in latest_android_releases)}\n" + f"{datetime.now()}" + ) + send_ntfy_notification(message) + else: + log_message("No releases found to check for updates.") if __name__ == "__main__": main() diff --git a/app/setup_config.py b/app/setup_config.py index b73f80d..d4effb6 100644 --- a/app/setup_config.py +++ b/app/setup_config.py @@ -5,6 +5,7 @@ import subprocess import random import string +import shutil # Added for shutil.which() from . import menu_apk from . import menu_firmware from . import downloader # Import downloader to perform first run @@ -119,12 +120,6 @@ def run_setup(): else: print("Skipping cron job setup.") - # Ask if the user wants to perform a first run - perform_first_run = input("Do you want to perform a first run now? [y/n] (default: y): ").strip().lower() or 'y' - if perform_first_run == 'y': - print("Performing first run, this may take a few minutes...") - downloader.main() - # Prompt for NTFY server configuration notifications = input("Do you want to set up notifications via NTFY? [y/n] (default: y): ").strip().lower() or 'y' if notifications == 'y': @@ -135,14 +130,16 @@ def run_setup(): # Generate a random topic name if the user doesn't provide one default_topic = 'fetchtastic-' + ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)) topic_name = input(f"Enter a unique topic name (default: {default_topic}): ").strip() or default_topic - ntfy_topic = f"{ntfy_server}/{topic_name}" - config['NTFY_SERVER'] = ntfy_topic + # Save only the topic name in the config + config['NTFY_TOPIC'] = topic_name + config['NTFY_SERVER'] = ntfy_server # Save updated configuration with open(CONFIG_FILE, 'w') as f: yaml.dump(config, f) print(f"Notifications have been set up using the topic: {topic_name}") + print(f"You can subscribe to this topic in the ntfy app by pasting the topic name.") # Ask if the user wants to copy the topic name to the clipboard copy_to_clipboard = input("Do you want to copy the topic name to the clipboard? [y/n] (default: y): ").strip().lower() or 'y' if copy_to_clipboard == 'y': @@ -154,12 +151,21 @@ def run_setup(): print("You can view your current topic at any time by running 'fetchtastic topic'.") print("You can change the topic by running 'fetchtastic setup' again or editing the YAML file.") else: + config['NTFY_TOPIC'] = '' config['NTFY_SERVER'] = '' # Save updated configuration with open(CONFIG_FILE, 'w') as f: yaml.dump(config, f) print("Notifications have not been set up.") + # Ask if the user wants to perform a first run + perform_first_run = input("Do you want to perform a first run now? [y/n] (default: y): ").strip().lower() or 'y' + if perform_first_run == 'y': + print("Performing first run, this may take a few minutes...") + downloader.main() + else: + print("Setup complete. You can run 'fetchtastic download' to start downloading.") + def is_termux(): return 'com.termux' in os.environ.get('PREFIX', '') @@ -172,8 +178,8 @@ def copy_to_clipboard_termux(text): def install_crond(): try: # Check if crond is installed - result = subprocess.run(['command', '-v', 'crond'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) - if result.returncode != 0 or not result.stdout.strip(): + crond_path = shutil.which('crond') + if crond_path is None: print("Installing crond...") subprocess.run(['pkg', 'install', 'termux-services', '-y'], check=True) subprocess.run(['sv-enable', 'crond'], check=True) @@ -246,7 +252,6 @@ def run_clean(): # Remove download directory if os.path.exists(DEFAULT_CONFIG_DIR): - import shutil shutil.rmtree(DEFAULT_CONFIG_DIR) print(f"Removed download directory: {DEFAULT_CONFIG_DIR}")