minor updates
This commit is contained in:
parent
af0c9914ab
commit
7180b0a3f7
6 changed files with 167 additions and 28 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -27,6 +27,7 @@ venv/
|
|||
ENV/
|
||||
|
||||
# Configuration and Secrets
|
||||
config.test.yaml
|
||||
config.yaml
|
||||
!config.example.yaml
|
||||
|
||||
|
|
|
|||
51
README.md
51
README.md
|
|
@ -4,31 +4,6 @@ Fluxer Reaper is a simple tool to help you move your Discord server content over
|
|||
|
||||

|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Prerequisites
|
||||
Make sure you have Python installed on your computer.
|
||||
|
||||
### 2. Download or Clone
|
||||
Clone the repository using git:
|
||||
```bash
|
||||
git clone https://github.com/rambros3d/fluxer-reaper.git
|
||||
cd fluxer-reaper
|
||||
```
|
||||
Alternatively, you can download the project as a ZIP file and extract its contents.
|
||||
|
||||
### 3. Install the tool
|
||||
Open your terminal and run:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 4. Run it!
|
||||
Start the tool by running:
|
||||
```bash
|
||||
python fluxer-reaper.py
|
||||
```
|
||||
|
||||
|
||||
## Features
|
||||
* **Clone Server Structure**: Automatically creates all your Discord categories and channels in Fluxer.
|
||||
|
|
@ -38,3 +13,29 @@ python fluxer-reaper.py
|
|||
* **Server Identity**: Syncs your server name, icon, and banner.
|
||||
* **Danger Zone**: Option to wipe existing channels, roles, and content in the fluxer community.
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
### 1. Download
|
||||
Download the latest executable from the [Releases](https://github.com/rambros3d/fluxer-reaper/releases) page.
|
||||
|
||||
### 2. Run
|
||||
Simply run the downloaded file to start the tool. No Python installation is required.
|
||||
|
||||
|
||||
## Build tool
|
||||
To create a standalone executable, simply run:
|
||||
|
||||
```bash
|
||||
chmod +x build.sh
|
||||
./build.sh
|
||||
```
|
||||
|
||||
The script will automatically set up a virtual environment, install dependencies, and generate the binary in the `dist/` folder.
|
||||
|
||||
|
||||
## Vibe Code Notice
|
||||
|
||||
Code is provided as is; This tool was developed largely by AI.
|
||||
|
||||
Take it, use it, modify it, feel free to whatever you wish.
|
||||
65
build.sh
Executable file
65
build.sh
Executable file
|
|
@ -0,0 +1,65 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
echo "--- Fluxer Reaper Cross-Distro Build Script ---"
|
||||
echo "NOTE: For maximum compatibility (glibc), run this on your oldest target Linux distribution."
|
||||
|
||||
# Check for venv
|
||||
if [ ! -d "venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
python3 -m venv venv || {
|
||||
echo "Error: Failed to create venv. You might need to install 'python3-venv'."
|
||||
echo "Try: sudo apt install python3-venv"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Activating virtual environment..."
|
||||
source venv/bin/activate
|
||||
|
||||
# Self-healing pip check
|
||||
if ! python3 -m pip --version > /dev/null 2>&1; then
|
||||
echo "Warning: pip is missing or broken in venv. Attempting repair..."
|
||||
python3 -m ensurepip --default-pip || {
|
||||
echo "Error: Failed to repair pip automatically."
|
||||
echo "Try recreating the venv: rm -rf venv && python3 -m venv venv"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Ensuring build dependencies are up to date..."
|
||||
pip install --upgrade pip --quiet
|
||||
pip install pyinstaller --quiet
|
||||
pip install -r requirements.txt --quiet
|
||||
|
||||
echo "Cleaning previous build artifacts..."
|
||||
rm -rf build/ dist/
|
||||
|
||||
echo "Starting PyInstaller build..."
|
||||
pyinstaller --clean fluxer-reaper.spec
|
||||
|
||||
echo "Generating Launch-Reaper.sh launcher..."
|
||||
cat << 'EOF' > dist/Launch-Reaper.sh
|
||||
#!/bin/bash
|
||||
# Convenient launcher for Fluxer Reaper
|
||||
# Ensures it runs in a terminal if possible, but the binary also has internal auto-terminal logic.
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
cd "$BASEDIR"
|
||||
|
||||
if [ -f "./fluxer-reaper" ]; then
|
||||
./fluxer-reaper
|
||||
else
|
||||
echo "Error: fluxer-reaper binary not found in $(pwd)"
|
||||
read -p "Press enter to exit..."
|
||||
fi
|
||||
EOF
|
||||
chmod +x dist/Launch-Reaper.sh
|
||||
|
||||
echo "-----------------------------------"
|
||||
echo "Build complete!"
|
||||
echo "Standalone executable: dist/fluxer-reaper"
|
||||
echo "Launcher script: dist/Launch-Reaper.sh"
|
||||
echo "---"
|
||||
|
|
@ -23,7 +23,70 @@ def setup_logging():
|
|||
handlers=handlers
|
||||
)
|
||||
|
||||
def relaunch_in_terminal():
|
||||
"""Detects if running without a terminal on Linux and relaunches in one."""
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
# Only attempt on Linux
|
||||
if sys.platform != "linux":
|
||||
return
|
||||
|
||||
# Check if we have a TTY on stdin or stdout, or if already relaunched
|
||||
is_tty = sys.stdin.isatty() or sys.stdout.isatty()
|
||||
if is_tty or os.environ.get("FLUXER_REAPER_RELAUNCHED"):
|
||||
return
|
||||
|
||||
# Diagnostic logging to help debug why it fails on some distros
|
||||
debug_log = "/tmp/reaper_terminal_debug.log"
|
||||
with open(debug_log, "a") as f:
|
||||
f.write(f"Relaunching... isatty={is_tty}, env={os.environ.get('FLUXER_REAPER_RELAUNCHED')}\n")
|
||||
|
||||
# List of terminals to try with their specific execution flags
|
||||
terminals = [
|
||||
("gnome-terminal", ["--"]), # Modern GNOME Terminal
|
||||
("ptyxis", ["--"]), # Fedora/Modern GNOME
|
||||
("x-terminal-emulator", ["-e"]), # Ubuntu/Debian standard
|
||||
("kgx", ["-e"]), # GNOME Console
|
||||
("konsole", ["-e"]),
|
||||
("xfce4-terminal", ["-e"]),
|
||||
("lxterminal", ["-e"]),
|
||||
("mate-terminal", ["-e"]),
|
||||
("alacritty", ["-e"]),
|
||||
("kitty", []),
|
||||
("xterm", ["-e"]),
|
||||
]
|
||||
|
||||
# Resolve the absolute path to ourselves.
|
||||
# frozen=True means we are running from a PyInstaller bundle.
|
||||
if getattr(sys, 'frozen', False):
|
||||
executable = os.path.abspath(sys.argv[0])
|
||||
else:
|
||||
executable = sys.executable
|
||||
|
||||
args = [executable] + sys.argv[1:]
|
||||
|
||||
# Set env var to prevent loops
|
||||
env = os.environ.copy()
|
||||
env["FLUXER_REAPER_RELAUNCHED"] = "1"
|
||||
|
||||
for term, cmd_args in terminals:
|
||||
if shutil.which(term):
|
||||
with open(debug_log, "a") as f:
|
||||
f.write(f"Found terminal: {term}\n")
|
||||
try:
|
||||
# Construct command: term [args] executable [sys.argv]
|
||||
subprocess.Popen([term] + cmd_args + args, env=env)
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
with open(debug_log, "a") as f:
|
||||
f.write(f"Failed to launch {term}: {e}\n")
|
||||
continue
|
||||
|
||||
def main():
|
||||
relaunch_in_terminal()
|
||||
setup_logging()
|
||||
try:
|
||||
asyncio.run(run_cli())
|
||||
|
|
|
|||
|
|
@ -17,7 +17,16 @@ class AppConfig(BaseModel):
|
|||
def load_config(config_path: str | Path = "config.yaml") -> AppConfig:
|
||||
path = Path(config_path)
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
||||
# Create dummy config if missing
|
||||
config = AppConfig(
|
||||
discord_bot_token="YOUR_DISCORD_TOKEN",
|
||||
fluxer_bot_token="YOUR_FLUXER_TOKEN",
|
||||
discord_server_id="000000000000000000",
|
||||
fluxer_community_id="000000000000000000"
|
||||
)
|
||||
save_config(config, path)
|
||||
print(f"Created default configuration: {config_path}")
|
||||
return config
|
||||
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class MigrationCLI:
|
|||
|
||||
console.print("(Q) Exit")
|
||||
|
||||
choice = Prompt.ask("Select an option", choices=["1", "2", "3", "4", "5", "6", "7", "Q", "q"], default="Q").upper()
|
||||
choice = Prompt.ask("\nSelect an option", choices=["1", "2", "3", "4", "5", "6", "7", "Q", "q"], default="Q").upper()
|
||||
|
||||
if choice == "1":
|
||||
await self.clone_server_template()
|
||||
|
|
@ -272,7 +272,7 @@ class MigrationCLI:
|
|||
fluxer_cat_id = self.engine.state.get_fluxer_category_id(cat_id_str)
|
||||
|
||||
status = f"[cyan]{fluxer_cat_id}[/cyan]" if fluxer_cat_id else "[bold red]Missing[/bold red]"
|
||||
table.add_row("Category", f"[bold yellow]{cat.name}[/bold yellow]", status)
|
||||
table.add_row("[bold yellow]Category[/bold yellow]", f"[bold yellow]{cat.name}[/bold yellow]", status)
|
||||
|
||||
# Show ALL channels under this category
|
||||
cat_channels = [ch for ch in channels if str(ch.category_id) == cat_id_str]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue