Major Update to v0.7

This commit is contained in:
fr33n0w
2025-11-05 12:01:16 +01:00
parent 6b15448632
commit 53bdfe3d01
5 changed files with 664 additions and 129 deletions

179
README.md
View File

@@ -1,57 +1,162 @@
# frup
FAST RETICULUM NETWORK PACKAGES UPDATER v0.6 by F.
# Fast Reticulum Updater (F.R.U.) v0.7
#frup v0.6 - 12/10/2024 - frup.py
--------------------------------------------------------------------
A Python tool to check and update Reticulum ecosystem packages.
#FAST RETICULUM NETWORK PACKAGES UPDATER v0.6 by F.
## New Features in v0.7
SIMPLE PYTHON SCRIPT TO CHECK FOR UPDATED VERSIONS OF RETICULUM NETWORK RELATED PACKAGES.
### 🚀 Performance
- **Single API call per package** - Caches GitHub version checks
- **Timeouts** on all network and subprocess operations
- **Efficient version checking** with normalized comparison
CHECK FOR ONLINE UPDATES, CHECKS FOR LOCAL INSTALLED VERSIONS AND COMPARE THEM TO CONTROL IF YOU ARE UP TO DATE OR ASK TO INSTALL NEW PACKAGES IF MISSING.
### 🎨 User Experience
- **Colored output** (automatic, with fallback if colorama not installed)
- **Progress indicators** (✓ ✗ ⚠ )
- **Config status display** - Shows whether using default or custom config
- **Summary report** showing updated, skipped, and failed packages
- **Clear status messages** throughout the process
--------------------------------------------------------------------
### ⚙️ Command Line Arguments
- `--auto` / `-a` : Automatically update all packages without prompting
- `--check-only` / `-c` : Only check versions without updating
- `--quiet` / `-q` : Minimal output (errors and summary only)
- `--save-config` : Generate example configuration file
- `--version` / `-v` : Show version information
- `--help` / `-h` : Show help message
WHAT'S NEW IN THIS VERSION:
### 📁 Configuration Files
Supports custom package lists via JSON configuration. Checks for config in:
1. `frup_config.json` (current directory)
2. `.frup_config.json` (hidden file in current directory)
3. `~/.frup_config.json` (user home directory)
** CORRECTED LINUX ERROR BUG ON SCRIPT ENDING, DUE TO KEYBOARD MODULE REQUESTING SUDO, NOW REMOVED.
When starting, the script shows whether it's using default or custom configuration.
### 🛡️ Error Handling
- Network timeouts (10 seconds for API calls)
- Process timeouts (120 seconds for pip operations)
- Graceful failure handling with clear error messages
- Keyboard interrupt handling (Ctrl+C)
--------------------------------------------------------------------
CHECKING OFFICIAL GITHUBS REPOS FOR THESE RETICULUM NETWORK SOFTWARES PACKAGE UPDATES:
## Installation
* RNS
* LXMF
* NOMADNET
* RETICULUM MESHCHAT
* SIDEBAND
* RNODE STOCK
* RNODE CE
* RNODE TN
### Requirements
- Python 3.6+
- pip
- requests library (`pip install requests`)
- colorama library (optional, for colored output: `pip install colorama`)
--------------------------------------------------------------------
### Setup
```bash
# Make executable (optional)
chmod +x frup.py
#INSTALLATION:
# Install optional colorama for colored output
pip install colorama
```
1) DOWNLOAD FRUP.PY FROM THE LAST RELEASE ON THIS REPOSITORY
## Usage Examples
2) INSTALL REQUIREMENST:
pip install requests subprocess
### Interactive Mode (default)
```bash
python3 frup.py
```
Shows all information and prompts for each update.
3) RUN THE SCRIPT:
python frup.py
(or python3 frup.py, based on your python version)
### Auto-Update All Packages
```bash
python3 frup.py --auto
```
Automatically updates all out-of-date packages without prompting.
--------------------------------------------------------------------
### Check Only (no updates)
```bash
python3 frup.py --check-only
```
Shows version comparison without performing any updates.
NOTE:
### Quiet Auto-Update
```bash
python3 frup.py --quiet --auto
```
Silently updates all packages, showing only the summary.
AUTO UPDATES ONLY WORKS FOR: RNS, LXMF AND NOMADNET PACKAGES.
### Generate Config File
```bash
python3 frup.py --save-config
```
Creates `frup_config_example.json` that you can customize and rename to `frup_config.json`.
FOR MESHCHAT, SIDEBAND , RNODE AND RNODE CE & TN,
YOU GET ONLY THE NEW VERSION CHECKUP,
THEN YOU NEED TO INSTALL THEM MANUALLY!
## Configuration File Format
--------------------------------------------------------------------
FRUP.PY V0.5 SCREENSHOT (v0.6 screenshot coming soon):
![frup](https://github.com/user-attachments/assets/7917a54e-83a6-4b1c-84d7-1d4b66a51985)
Create a `frup_config.json` file to customize which packages to check:
```json
{
"packages": [
{
"name": "RNS",
"url": "https://github.com/markqvist/Reticulum"
},
{
"name": "CustomPackage",
"url": "https://github.com/user/repo",
"manual_install": true,
"skip_local_check": false
}
]
}
```
### Package Options
- `name`: Package name (used for pip)
- `url`: GitHub repository URL
- `manual_install`: If true, only shows available version
- `skip_local_check`: Skip checking local installation
- `skip_version_comparison`: Skip version comparison
- `online_only`: Only check GitHub version
## Output Symbols
- ✓ Success / Up to date
- ✗ Error / Failed
- ⚠ Warning / Timeout
- Not installed / Skipped
- Information
## Status Messages
When starting, the script displays which configuration it's using:
- `Using default configuration` - No config file found, using built-in packages
- `Using custom config: [path]` - Found and loaded custom configuration
## Version History
- **v0.7** - Major rewrite with CLI args, config files, colored output, better error handling
- **v0.6** - Fixed Linux keyboard permission issue
- **v0.5** - Initial version
## Author
Created by F
## License
Open source - feel free to modify and distribute
## Troubleshooting
### No colored output?
Install colorama: `pip install colorama`
### Permission errors?
No longer requires sudo! The keyboard dependency was removed in v0.6+
### Network timeouts?
The tool has a 10-second timeout for GitHub API calls. Check your internet connection.
### Custom packages not updating?
Make sure the package name matches exactly what's used in pip.
### Want to reset to default packages?
Simply delete or rename your `frup_config.json` file.

57
README0.6.md Normal file
View File

@@ -0,0 +1,57 @@
# frup
FAST RETICULUM NETWORK PACKAGES UPDATER v0.6 by F.
#frup v0.6 - 12/10/2024 - frup.py
--------------------------------------------------------------------
#FAST RETICULUM NETWORK PACKAGES UPDATER v0.6 by F.
SIMPLE PYTHON SCRIPT TO CHECK FOR UPDATED VERSIONS OF RETICULUM NETWORK RELATED PACKAGES.
CHECK FOR ONLINE UPDATES, CHECKS FOR LOCAL INSTALLED VERSIONS AND COMPARE THEM TO CONTROL IF YOU ARE UP TO DATE OR ASK TO INSTALL NEW PACKAGES IF MISSING.
--------------------------------------------------------------------
WHAT'S NEW IN THIS VERSION:
** CORRECTED LINUX ERROR BUG ON SCRIPT ENDING, DUE TO KEYBOARD MODULE REQUESTING SUDO, NOW REMOVED.
--------------------------------------------------------------------
CHECKING OFFICIAL GITHUBS REPOS FOR THESE RETICULUM NETWORK SOFTWARES PACKAGE UPDATES:
* RNS
* LXMF
* NOMADNET
* RETICULUM MESHCHAT
* SIDEBAND
* RNODE STOCK
* RNODE CE
* RNODE TN
--------------------------------------------------------------------
#INSTALLATION:
1) DOWNLOAD FRUP.PY FROM THE LAST RELEASE ON THIS REPOSITORY
2) INSTALL REQUIREMENST:
pip install requests subprocess
3) RUN THE SCRIPT:
python frup.py
(or python3 frup.py, based on your python version)
--------------------------------------------------------------------
NOTE:
AUTO UPDATES ONLY WORKS FOR: RNS, LXMF AND NOMADNET PACKAGES.
FOR MESHCHAT, SIDEBAND , RNODE AND RNODE CE & TN,
YOU GET ONLY THE NEW VERSION CHECKUP,
THEN YOU NEED TO INSTALL THEM MANUALLY!
--------------------------------------------------------------------
FRUP.PY V0.5 SCREENSHOT (v0.6 screenshot coming soon):
![frup](https://github.com/user-attachments/assets/7917a54e-83a6-4b1c-84d7-1d4b66a51985)

492
frup.py
View File

@@ -1,92 +1,400 @@
import requests
import subprocess
# Print the title
print()
print("==============================================")
print(" Fast Reticulum Updater v0.6 by F")
print("==============================================")
# List of packages to check
packages = [
{'name': 'RNS', 'url': 'https://github.com/markqvist/Reticulum'},
{'name': 'LXMF', 'url': 'https://github.com/markqvist/lxmf'},
{'name': 'NomadNet', 'url': 'https://github.com/markqvist/nomadnet'},
{'name': 'MeshChat', 'url': 'https://github.com/liamcottle/reticulum-meshchat', 'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'Sideband', 'url': 'https://github.com/markqvist/Sideband', 'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode Stock', 'url': 'https://github.com/markqvist/RNode_Firmware', 'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode CE', 'url': 'https://github.com/liberatedsystems/RNode_Firmware_CE', 'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode Micro TN', 'url': 'https://github.com/attermann/microReticulum_Firmware', 'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True}
]
# Online versions
print("\n**Latest GitHub Versions:**")
for package in packages:
github_repo = package['url'].split('/')[-2] + '/' + package['url'].split('/')[-1]
try:
response = requests.get(f"https://api.github.com/repos/{github_repo}/releases/latest")
response.raise_for_status() # Raise an exception for 4xx or 5xx status codes
latest_version = response.json()["tag_name"]
print(f"* {package['name']}: {latest_version}")
except requests.exceptions.RequestException as e:
print(f"* {package['name']}: Failed to retrieve latest version from GitHub ({e})")
# Local versions
print("\n**Local Installed Versions:**")
for package in packages:
if not ('skip_local_check' in package and package['skip_local_check']) and not ('online_only' in package and package['online_only']):
try:
pip_version = subprocess.check_output(["pip", "show", package['name']]).decode("utf-8")
pip_version = [line.split(":")[1].strip() for line in pip_version.splitlines() if "Version:" in line][0]
print(f"* {package['name']}: {pip_version}")
except subprocess.CalledProcessError:
print(f"* {package['name']}: Not installed via pip")
# Compare versions and ask to install/update
print("\n**Version Comparison for Update Installation:**")
for package in packages:
if not ('skip_local_check' in package and package['skip_local_check']) and not ('skip_version_comparison' in package and package['skip_version_comparison']) and not ('online_only' in package and package['online_only']):
github_repo = package['url'].split('/')[-2] + '/' + package['url'].split('/')[-1]
try:
response = requests.get(f"https://api.github.com/repos/{github_repo}/releases/latest")
response.raise_for_status() # Raise an exception for 4xx or 5xx status codes
latest_version = response.json()["tag_name"]
except requests.exceptions.RequestException as e:
print(f"Error fetching latest version: {e}")
latest_version = None
try:
pip_version = subprocess.check_output(["pip", "show", package['name']]).decode("utf-8")
pip_version = [line.split(":")[1].strip() for line in pip_version.splitlines() if "Version:" in line][0]
except subprocess.CalledProcessError:
pip_version = None
print(f"* {package['name']}:")
if pip_version == latest_version:
print(f" Up to date!")
else:
if 'manual_install' in package and package['manual_install']:
print(f" New version ({latest_version}) available. Please install it manually.")
else:
print(f" New version ({latest_version}) available.")
if pip_version is None:
print(f" {package['name']} is not installed. Do you want to install it? (y/n)")
else:
print(f" Do you want to update {package['name']} to the latest version? (y/n)")
response = input()
if response.lower() == 'y':
print(f" Installing/Updating {package['name']}...")
subprocess.run(["pip", "install", "--upgrade", package['name']])
print(f" {package['name']} installed/updated successfully!")
else:
print(f" Skipping update of {package['name']}")
# Final message
print("\n=====================================================")
print(" Update process complete! F.R.U. v0.6 END")
print("======================================================")
# Wait for a key press to exit
print()
print("------------- Press ENTER to exit... ---------------")
input()
#!/usr/bin/env python3
"""
Fast Reticulum Updater v0.7
Author: F
Improvements: Efficiency, error handling, CLI arguments, colored output, summary
"""
import requests
import subprocess
import sys
import argparse
import json
import os
from typing import Dict, List, Optional
# Try to import colorama for colored output
try:
from colorama import init, Fore, Style
init()
GREEN = Fore.GREEN
RED = Fore.RED
YELLOW = Fore.YELLOW
CYAN = Fore.CYAN
RESET = Style.RESET_ALL
BRIGHT = Style.BRIGHT
except ImportError:
# Fallback if colorama not installed
GREEN = RED = YELLOW = CYAN = RESET = BRIGHT = ""
class ReticulumUpdater:
def __init__(self, auto_update=False, quiet=False, check_only=False):
self.auto_update = auto_update
self.quiet = quiet
self.check_only = check_only
self.github_versions = {}
self.local_versions = {}
self.updated = []
self.skipped = []
self.failed = []
self.already_updated = []
self.using_custom_config = False
self.config_path = None
# Default packages - can be overridden by config file
self.packages = [
{'name': 'RNS', 'url': 'https://github.com/markqvist/Reticulum'},
{'name': 'LXMF', 'url': 'https://github.com/markqvist/lxmf'},
{'name': 'NomadNet', 'url': 'https://github.com/markqvist/nomadnet'},
{'name': 'MeshChat', 'url': 'https://github.com/liamcottle/reticulum-meshchat',
'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'Sideband', 'url': 'https://github.com/markqvist/Sideband',
'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode Stock', 'url': 'https://github.com/markqvist/RNode_Firmware',
'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode CE', 'url': 'https://github.com/liberatedsystems/RNode_Firmware_CE',
'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True},
{'name': 'RNode Micro TN', 'url': 'https://github.com/attermann/microReticulum_Firmware',
'manual_install': True, 'skip_local_check': True, 'skip_version_comparison': True, 'online_only': True}
]
# Load custom config if available
self.load_config()
def load_config(self):
"""Load configuration from file if it exists"""
config_files = ['frup_config.json', '.frup_config.json', '~/.frup_config.json']
for config_file in config_files:
config_path = os.path.expanduser(config_file)
if os.path.exists(config_path):
try:
with open(config_path, 'r') as f:
config = json.load(f)
if 'packages' in config:
self.packages = config['packages']
self.using_custom_config = True
self.config_path = config_path
break
except Exception as e:
print(f"{RED}Error loading config from {config_path}: {e}{RESET}")
print(f"{YELLOW}Using default configuration instead{RESET}")
def save_example_config(self):
"""Save an example configuration file"""
example_config = {
"packages": self.packages,
"comment": "Customize this file to add/remove packages to check"
}
with open('frup_config_example.json', 'w') as f:
json.dump(example_config, f, indent=2)
print(f"{GREEN}Example config saved to: frup_config_example.json{RESET}")
print(f"{CYAN}Rename to 'frup_config.json' to use it{RESET}")
def normalize_version(self, version: Optional[str]) -> Optional[str]:
"""Remove common prefixes from version strings for comparison"""
if version:
return version.lstrip('v').lstrip('V').strip()
return version
def print_header(self):
"""Print the application header"""
if not self.quiet:
print()
print(f"{BRIGHT}=============================================={RESET}")
print(f"{BRIGHT} Fast Reticulum Updater v0.7 by F{RESET}")
print(f"{BRIGHT}=============================================={RESET}")
# Show config status
if self.using_custom_config:
print(f"{CYAN}Using custom config: {self.config_path}{RESET}")
else:
print(f"{CYAN}Using default configuration{RESET}")
def fetch_github_versions(self):
"""Fetch all GitHub versions in one pass"""
if not self.quiet:
print(f"\n{BRIGHT}** Fetching Latest GitHub Versions **{RESET}")
for package in self.packages:
repo_parts = package['url'].split('/')
repo = f"{repo_parts[-2]}/{repo_parts[-1]}"
try:
response = requests.get(
f"https://api.github.com/repos/{repo}/releases/latest",
timeout=10,
headers={'Accept': 'application/vnd.github.v3+json'}
)
response.raise_for_status()
version = response.json().get("tag_name", "Unknown")
self.github_versions[package['name']] = version
if not self.quiet:
print(f" {GREEN}{RESET} {package['name']}: {CYAN}{version}{RESET}")
except requests.exceptions.Timeout:
self.github_versions[package['name']] = None
if not self.quiet:
print(f" {YELLOW}{RESET} {package['name']}: Timeout")
except requests.exceptions.RequestException as e:
self.github_versions[package['name']] = None
if not self.quiet:
print(f" {RED}{RESET} {package['name']}: Failed to fetch")
def check_local_versions(self):
"""Check locally installed versions"""
if not self.quiet:
print(f"\n{BRIGHT}** Local Installed Versions **{RESET}")
for package in self.packages:
# Skip packages marked as online_only or skip_local_check
if package.get('skip_local_check') or package.get('online_only'):
self.local_versions[package['name']] = None
if not self.quiet and not package.get('online_only'):
print(f" {YELLOW}{RESET} {package['name']}: Skipped")
continue
try:
result = subprocess.run(
["pip", "show", package['name']],
capture_output=True,
text=True,
timeout=5
)
if result.returncode == 0:
for line in result.stdout.splitlines():
if "Version:" in line:
version = line.split(":")[1].strip()
self.local_versions[package['name']] = version
if not self.quiet:
print(f" {GREEN}{RESET} {package['name']}: {CYAN}{version}{RESET}")
break
else:
self.local_versions[package['name']] = None
if not self.quiet:
print(f" {YELLOW}{RESET} {package['name']}: Not installed")
except subprocess.TimeoutExpired:
self.local_versions[package['name']] = None
if not self.quiet:
print(f" {YELLOW}{RESET} {package['name']}: Check timeout")
except Exception as e:
self.local_versions[package['name']] = None
if not self.quiet:
print(f" {RED}{RESET} {package['name']}: Error checking")
def compare_and_update(self):
"""Compare versions and optionally update packages"""
if self.check_only:
print(f"\n{BRIGHT}** Version Comparison (Check Only Mode) **{RESET}")
else:
print(f"\n{BRIGHT}** Version Comparison & Update **{RESET}")
for package in self.packages:
# Skip certain packages
if package.get('skip_version_comparison') or package.get('online_only'):
continue
name = package['name']
github_version = self.github_versions.get(name)
local_version = self.local_versions.get(name)
# Normalize versions for comparison
norm_github = self.normalize_version(github_version)
norm_local = self.normalize_version(local_version)
print(f"\n{BRIGHT}{name}:{RESET}")
# Check if versions could be retrieved
if github_version is None:
print(f" {RED}Cannot compare - GitHub version unavailable{RESET}")
self.failed.append(name)
continue
# Compare versions
if local_version is None:
print(f" {YELLOW}Not installed{RESET} (Available: {CYAN}{github_version}{RESET})")
action = "install"
should_update = True
elif norm_local == norm_github:
print(f" {GREEN}✓ Up to date!{RESET} ({CYAN}{local_version}{RESET})")
self.already_updated.append(name)
continue
else:
print(f" {YELLOW}Update available:{RESET} {local_version}{CYAN}{github_version}{RESET}")
action = "update"
should_update = True
# Handle manual install packages
if package.get('manual_install'):
print(f" {CYAN} Please {action} manually from: {package['url']}{RESET}")
self.skipped.append(name)
continue
# Skip if check-only mode
if self.check_only:
continue
# Handle updates
if should_update:
if self.auto_update:
response = 'y'
print(f" {CYAN}Auto-{action}ing...{RESET}")
else:
response = input(f" Do you want to {action} {name}? (y/n): ").strip().lower()
if response == 'y':
print(f" {CYAN}{action.capitalize()}ing {name}...{RESET}")
try:
result = subprocess.run(
["pip", "install", "--upgrade", name],
capture_output=True,
text=True,
timeout=120
)
if result.returncode == 0:
print(f" {GREEN}{name} {action}d successfully!{RESET}")
self.updated.append(name)
else:
print(f" {RED}✗ Failed to {action} {name}{RESET}")
if result.stderr:
print(f" Error: {result.stderr[:200]}")
self.failed.append(name)
except subprocess.TimeoutExpired:
print(f" {RED}{action.capitalize()} timeout for {name}{RESET}")
self.failed.append(name)
except Exception as e:
print(f" {RED}✗ Error {action}ing {name}: {str(e)}{RESET}")
self.failed.append(name)
else:
print(f" {YELLOW}Skipped {name}{RESET}")
self.skipped.append(name)
def print_summary(self):
"""Print a summary of actions taken"""
print(f"\n{BRIGHT}=============================================={RESET}")
print(f"{BRIGHT} SUMMARY{RESET}")
print(f"{BRIGHT}=============================================={RESET}")
if self.already_updated:
print(f"{GREEN}✓ Up to date:{RESET} {', '.join(self.already_updated)}")
if self.updated:
print(f"{GREEN}✓ Updated:{RESET} {', '.join(self.updated)}")
if self.skipped:
print(f"{YELLOW} Skipped:{RESET} {', '.join(self.skipped)}")
if self.failed:
print(f"{RED}✗ Failed:{RESET} {', '.join(self.failed)}")
if not any([self.updated, self.skipped, self.failed, self.already_updated]):
print(f"{CYAN}No actions taken.{RESET}")
# Final status
print(f"\n{BRIGHT}=============================================={RESET}")
if self.check_only:
print(f"{BRIGHT} Check Complete! F.R.U. v0.7 END{RESET}")
else:
print(f"{BRIGHT} Update Process Complete! F.R.U. v0.7 END{RESET}")
print(f"{BRIGHT}=============================================={RESET}")
def run(self):
"""Main execution flow"""
self.print_header()
# Fetch all versions
self.fetch_github_versions()
self.check_local_versions()
# Compare and potentially update
self.compare_and_update()
# Show summary
self.print_summary()
def main():
"""Main entry point with argument parsing"""
parser = argparse.ArgumentParser(
description='Fast Reticulum Updater v0.7 - Update Reticulum ecosystem packages',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
frup.py # Interactive mode
frup.py --auto # Auto-update all packages
frup.py --check-only # Only check versions without updating
frup.py --quiet --auto # Silent auto-update
frup.py --save-config # Save example config file
"""
)
parser.add_argument(
'--auto', '-a',
action='store_true',
help='Automatically update all packages without prompting'
)
parser.add_argument(
'--check-only', '-c',
action='store_true',
help='Only check versions without updating'
)
parser.add_argument(
'--quiet', '-q',
action='store_true',
help='Minimal output (errors and summary only)'
)
parser.add_argument(
'--save-config',
action='store_true',
help='Save an example configuration file and exit'
)
parser.add_argument(
'--version', '-v',
action='version',
version='Fast Reticulum Updater v0.7'
)
args = parser.parse_args()
# Create updater instance
updater = ReticulumUpdater(
auto_update=args.auto,
quiet=args.quiet,
check_only=args.check_only
)
# Handle config save
if args.save_config:
updater.save_example_config()
sys.exit(0)
try:
# Run the updater
updater.run()
except KeyboardInterrupt:
print(f"\n{YELLOW}Interrupted by user{RESET}")
sys.exit(1)
except Exception as e:
print(f"\n{RED}Unexpected error: {e}{RESET}")
sys.exit(1)
# Wait for user input before exiting (unless in quiet mode)
if not args.quiet:
print()
print("------------- Press ENTER to exit... ---------------")
input()
if __name__ == "__main__":
main()

BIN
frup0.7.release.zip Normal file
View File

Binary file not shown.

65
frup_config_example.json Normal file
View File

@@ -0,0 +1,65 @@
{
"comment": "Fast Reticulum Updater Configuration - Customize packages to check/update",
"packages": [
{
"name": "RNS",
"url": "https://github.com/markqvist/Reticulum"
},
{
"name": "LXMF",
"url": "https://github.com/markqvist/lxmf"
},
{
"name": "NomadNet",
"url": "https://github.com/markqvist/nomadnet"
},
{
"name": "MeshChat",
"url": "https://github.com/liamcottle/reticulum-meshchat",
"manual_install": true,
"skip_local_check": true,
"skip_version_comparison": true,
"online_only": true
},
{
"name": "Sideband",
"url": "https://github.com/markqvist/Sideband",
"manual_install": true,
"skip_local_check": true,
"skip_version_comparison": true,
"online_only": true
},
{
"name": "RNode Stock",
"url": "https://github.com/markqvist/RNode_Firmware",
"manual_install": true,
"skip_local_check": true,
"skip_version_comparison": true,
"online_only": true
},
{
"name": "RNode CE",
"url": "https://github.com/liberatedsystems/RNode_Firmware_CE",
"manual_install": true,
"skip_local_check": true,
"skip_version_comparison": true,
"online_only": true
},
{
"name": "RNode Micro TN",
"url": "https://github.com/attermann/microReticulum_Firmware",
"manual_install": true,
"skip_local_check": true,
"skip_version_comparison": true,
"online_only": true
}
],
"additional_packages_example": [
{
"name": "some-other-package",
"url": "https://github.com/user/repo",
"manual_install": false,
"comment": "Add your own packages here"
}
]
}