Compare commits

..

No commits in common. "57342e04507435565828d6a6933c1ec8e53db34b" and "1b97e3ba6871e97fc465e0738b717b7afa33a4b1" have entirely different histories.

10 changed files with 208 additions and 614 deletions

View File

@ -1,6 +1,6 @@
# Transmission RSS Manager v2.0.0 # Transmission RSS Manager
A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration, intelligent media organization, and enhanced security features. Now with automatic updates and easy installation! A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration, intelligent media organization, and enhanced security features.
## Features ## Features
@ -12,16 +12,15 @@ A comprehensive web-based tool to automate and manage your Transmission torrent
- 🔄 **Remote Support**: Connect to remote Transmission instances with local path mapping - 🔄 **Remote Support**: Connect to remote Transmission instances with local path mapping
- 🔒 **Enhanced Security**: Authentication, HTTPS support, and secure password storage - 🔒 **Enhanced Security**: Authentication, HTTPS support, and secure password storage
- 📱 **Mobile-Friendly UI**: Responsive design works on desktop and mobile devices - 📱 **Mobile-Friendly UI**: Responsive design works on desktop and mobile devices
- 🔧 **One-Click Updates**: Built-in version checking and automated update system
- 🚀 **Automatic Transmission Installation**: Installs and configures Transmission if needed
## Installation ## Installation
### Prerequisites ### Prerequisites
- Ubuntu/Debian-based system (may work on other Linux distributions) - Ubuntu/Debian-based system (may work on other Linux distributions)
- Git (will be automatically installed by the bootstrap installer if needed) - Node.js 14+ and npm
- Internet connection (for downloading and updates) - Transmission daemon installed and running
- Nginx (for reverse proxy, optional)
### System Requirements ### System Requirements
@ -32,26 +31,20 @@ A comprehensive web-based tool to automate and manage your Transmission torrent
### Automatic Installation ### Automatic Installation
The easiest way to install Transmission RSS Manager is with the bootstrap installer: The easiest way to install Transmission RSS Manager is with the installation script:
```bash ```bash
# Download the bootstrap installer # Download the installation script
wget https://git.powerdata.dk/masterdraco/transmission-rss-manager/raw/main/bootstrap-installer.sh wget https://raw.githubusercontent.com/username/transmission-rss-manager/main/install.sh
# Make it executable # Make it executable
chmod +x bootstrap-installer.sh chmod +x install.sh
# Run it with sudo # Run it with sudo
sudo ./bootstrap-installer.sh sudo ./install.sh
``` ```
The bootstrap installer will: The script will guide you through the configuration process and set up everything you need.
1. Install git if needed
2. Clone the latest version from the repository
3. Run the main installer which guides you through configuration
4. Set up the service and web interface
**New in v2.0.0:** The installer now detects if Transmission is installed and offers to install and configure it automatically if needed.
### Manual Installation ### Manual Installation
@ -59,7 +52,7 @@ If you prefer to install manually:
1. Clone the repository: 1. Clone the repository:
```bash ```bash
git clone https://git.powerdata.dk/masterdraco/transmission-rss-manager.git git clone https://github.com/username/transmission-rss-manager.git
cd transmission-rss-manager cd transmission-rss-manager
``` ```
@ -230,25 +223,11 @@ Full support for remote Transmission instances:
## Updating ## Updating
### Using the Web Interface (New in v2.0.0) To update to the latest version:
The easiest way to update is through the web interface: ### Using the Built-in Update Script
1. Navigate to the Dashboard If you've already installed Transmission RSS Manager, you can use the built-in update script:
2. Look for the "System Status" section
3. If an update is available, an "Update Now" button will appear
4. Click the button to automatically update to the latest version
The system will:
- Back up your configuration
- Pull the latest code from the repository
- Install any new dependencies
- Restore your configuration
- Restart the service automatically
### Using the Command Line
If you prefer to update via command line:
```bash ```bash
cd /opt/transmission-rss-manager cd /opt/transmission-rss-manager
@ -266,7 +245,7 @@ sudo scripts/update.sh --force
Alternatively, you can download and run the update script: Alternatively, you can download and run the update script:
```bash ```bash
wget https://git.powerdata.dk/masterdraco/transmission-rss-manager/raw/main/scripts/update.sh wget https://raw.githubusercontent.com/username/transmission-rss-manager/main/scripts/update.sh
chmod +x update.sh chmod +x update.sh
sudo ./update.sh sudo ./update.sh
``` ```
@ -280,17 +259,10 @@ transmission-rss-manager/
│ ├── post-processor.js # Media processing module │ ├── post-processor.js # Media processing module
│ ├── rss-feed-manager.js # RSS feed management module │ ├── rss-feed-manager.js # RSS feed management module
│ ├── transmission-client.js # Transmission API integration │ ├── transmission-client.js # Transmission API integration
│ ├── config-module.sh # Installation configuration │ └── config-module.sh # Installation configuration
│ ├── dependencies-module.sh # Dependency installation ├── install-script.sh # Initial installer that creates modules
│ ├── file-creator-module.sh # File creation for installation
│ ├── service-setup-module.sh # Service setup
│ └── utils-module.sh # Utility functions
├── bootstrap-installer.sh # Minimal installer that clones the repository
├── main-installer.sh # Main installation script ├── main-installer.sh # Main installation script
├── config.json # Configuration file ├── config.json # Configuration file
├── scripts/ # Utility scripts
│ ├── update.sh # Update script
│ └── test-and-start.sh # Test and start script
├── public/ # Web interface files ├── public/ # Web interface files
│ ├── index.html # Main web interface │ ├── index.html # Main web interface
│ ├── js/ # JavaScript files │ ├── js/ # JavaScript files

View File

@ -1,72 +0,0 @@
#!/bin/bash
# Transmission RSS Manager - Bootstrap Installer
# This script downloads the latest version from git and runs the setup
# Color and formatting
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Installation directory
INSTALL_DIR="/opt/trans-install"
REPO_URL="https://git.powerdata.dk/masterdraco/transmission-rss-manager.git"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}This script must be run as root or with sudo privileges.${NC}"
exit 1
fi
# Display welcome message
echo -e "${GREEN}${BOLD}Transmission RSS Manager - Bootstrap Installer${NC}"
echo -e "This script will install the latest version from the git repository."
echo
# Check for git installation
echo -e "${YELLOW}Checking dependencies...${NC}"
if ! command -v git &> /dev/null; then
echo -e "Git not found. Installing git..."
apt-get update
apt-get install -y git
fi
# Check if installation directory exists
if [ -d "$INSTALL_DIR" ]; then
echo -e "${YELLOW}Installation directory already exists.${NC}"
read -p "Do you want to remove it and perform a fresh install? (y/n): " choice
if [[ "$choice" =~ ^[Yy]$ ]]; then
echo "Removing existing installation..."
rm -rf "$INSTALL_DIR"
else
echo -e "${RED}Installation aborted.${NC}"
exit 1
fi
fi
# Create installation directory
echo -e "${YELLOW}Creating installation directory...${NC}"
mkdir -p "$INSTALL_DIR"
# Clone the repository
echo -e "${YELLOW}Cloning the latest version from git...${NC}"
git clone "$REPO_URL" "$INSTALL_DIR"
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to clone the repository.${NC}"
exit 1
fi
# Run the main installer
echo -e "${YELLOW}Running the main installer...${NC}"
cd "$INSTALL_DIR"
chmod +x main-installer.sh
./main-installer.sh
# Installation complete
echo -e "${GREEN}${BOLD}Bootstrap installation complete!${NC}"
echo -e "Transmission RSS Manager has been installed in $INSTALL_DIR"
echo -e "You can access the web interface at http://localhost:3000"
echo
echo -e "To update in the future, use the update button in the System Status section of the web interface."

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Transmission RSS Manager Modular Installer # Transmission RSS Manager Modular Installer
# Modified to work with the git-based approach # Main installer script that coordinates the installation process
# Set script to exit on error # Set script to exit on error
set -e set -e
@ -15,7 +15,7 @@ NC='\033[0m' # No Color
# Print header # Print header
echo -e "${BOLD}==================================================${NC}" echo -e "${BOLD}==================================================${NC}"
echo -e "${BOLD} Transmission RSS Manager Installer ${NC}" echo -e "${BOLD} Transmission RSS Manager Installer ${NC}"
echo -e "${BOLD} Version 1.2.0 - Git Edition ${NC}" echo -e "${BOLD} Version 1.2.0 - Enhanced Edition ${NC}"
echo -e "${BOLD}==================================================${NC}" echo -e "${BOLD}==================================================${NC}"
echo echo
@ -44,13 +44,14 @@ REQUIRED_MODULES=(
"${SCRIPT_DIR}/modules/config-module.sh" "${SCRIPT_DIR}/modules/config-module.sh"
"${SCRIPT_DIR}/modules/utils-module.sh" "${SCRIPT_DIR}/modules/utils-module.sh"
"${SCRIPT_DIR}/modules/dependencies-module.sh" "${SCRIPT_DIR}/modules/dependencies-module.sh"
"${SCRIPT_DIR}/modules/file-creator-module.sh"
"${SCRIPT_DIR}/modules/service-setup-module.sh" "${SCRIPT_DIR}/modules/service-setup-module.sh"
) )
for module in "${REQUIRED_MODULES[@]}"; do for module in "${REQUIRED_MODULES[@]}"; do
if [ ! -f "$module" ]; then if [ ! -f "$module" ]; then
echo -e "${RED}Error: Required module file not found: $module${NC}" echo -e "${RED}Error: Required module file not found: $module${NC}"
echo -e "${YELLOW}The module files should be included in the git repository.${NC}" echo -e "${YELLOW}Please run the install-script.sh first to generate module files.${NC}"
exit 1 exit 1
fi fi
done done
@ -59,6 +60,7 @@ done
source "${SCRIPT_DIR}/modules/utils-module.sh" # Load utilities first for logging source "${SCRIPT_DIR}/modules/utils-module.sh" # Load utilities first for logging
source "${SCRIPT_DIR}/modules/config-module.sh" source "${SCRIPT_DIR}/modules/config-module.sh"
source "${SCRIPT_DIR}/modules/dependencies-module.sh" source "${SCRIPT_DIR}/modules/dependencies-module.sh"
source "${SCRIPT_DIR}/modules/file-creator-module.sh"
source "${SCRIPT_DIR}/modules/service-setup-module.sh" source "${SCRIPT_DIR}/modules/service-setup-module.sh"
# Function to handle cleanup on error # Function to handle cleanup on error
@ -99,7 +101,7 @@ create_directories || {
exit 1 exit 1
} }
# Step 4: Create configuration files only (no application files since they're from git) # Step 4: Create configuration files and scripts
log "INFO" "Creating configuration files..." log "INFO" "Creating configuration files..."
create_config_files || { create_config_files || {
log "ERROR" "Configuration file creation failed" log "ERROR" "Configuration file creation failed"
@ -113,110 +115,7 @@ setup_service || {
exit 1 exit 1
} }
# Step 6: Install npm dependencies # Step 6: Final setup and permissions
log "INFO" "Installing npm dependencies..."
cd "$SCRIPT_DIR"
npm install || {
log "ERROR" "NPM installation failed"
exit 1
}
# Step 7: Set up update script
log "INFO" "Setting up update script..."
mkdir -p "${SCRIPT_DIR}/scripts"
cp "${SCRIPT_DIR}/scripts/update.sh" "${SCRIPT_DIR}/scripts/update.sh" 2>/dev/null || {
# If copy fails, it probably doesn't exist, so we'll create it
cat > "${SCRIPT_DIR}/scripts/update.sh" << 'EOL'
#!/bin/bash
# Transmission RSS Manager - Update Script
# This script pulls the latest version from git and runs necessary updates
# Color and formatting
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# Installation directory (should be current directory)
INSTALL_DIR=$(pwd)
# Check if we're in the right directory
if [ ! -f "$INSTALL_DIR/package.json" ] || [ ! -d "$INSTALL_DIR/modules" ]; then
echo -e "${RED}Error: This script must be run from the installation directory.${NC}"
exit 1
fi
# Get the current version
CURRENT_VERSION=$(grep -oP '"version": "\K[^"]+' package.json)
echo -e "${YELLOW}Current version: ${BOLD}$CURRENT_VERSION${NC}"
# Check for git repository
if [ ! -d ".git" ]; then
echo -e "${RED}Error: This installation was not set up using git.${NC}"
echo -e "Please use the bootstrap installer to perform a fresh installation."
exit 1
fi
# Stash any local changes
echo -e "${YELLOW}Backing up any local configuration changes...${NC}"
git stash -q
# Pull the latest changes
echo -e "${YELLOW}Pulling latest updates from git...${NC}"
git pull
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to pull updates. Restoring original state...${NC}"
git stash pop -q
exit 1
fi
# Get the new version
NEW_VERSION=$(grep -oP '"version": "\K[^"]+' package.json)
echo -e "${GREEN}New version: ${BOLD}$NEW_VERSION${NC}"
# Check if update is needed
if [ "$CURRENT_VERSION" == "$NEW_VERSION" ]; then
echo -e "${GREEN}You already have the latest version.${NC}"
exit 0
fi
# Install any new npm dependencies
echo -e "${YELLOW}Installing dependencies...${NC}"
npm install
# Apply any local configuration changes
if git stash list | grep -q "stash@{0}"; then
echo -e "${YELLOW}Restoring local configuration changes...${NC}"
git stash pop -q
# Handle conflicts if any
if [ $? -ne 0 ]; then
echo -e "${RED}There were conflicts when restoring your configuration.${NC}"
echo -e "Please check the files and resolve conflicts manually."
echo -e "Your original configuration is saved in .git/refs/stash"
fi
fi
# Restart the service
echo -e "${YELLOW}Restarting service...${NC}"
if command -v systemctl &> /dev/null; then
sudo systemctl restart transmission-rss-manager
else
echo -e "${RED}Could not restart service automatically.${NC}"
echo -e "Please restart the service manually."
fi
# Update complete
echo -e "${GREEN}${BOLD}Update complete!${NC}"
echo -e "Updated from version $CURRENT_VERSION to $NEW_VERSION"
echo -e "Changes will take effect immediately."
EOL
chmod +x "${SCRIPT_DIR}/scripts/update.sh"
}
# Step 8: Final setup and permissions
log "INFO" "Finalizing setup..." log "INFO" "Finalizing setup..."
finalize_setup || { finalize_setup || {
log "ERROR" "Setup finalization failed" log "ERROR" "Setup finalization failed"
@ -235,7 +134,6 @@ echo -e "${BOLD}Useful Commands:${NC}"
echo -e " To check the service status: ${YELLOW}systemctl status $SERVICE_NAME${NC}" echo -e " To check the service status: ${YELLOW}systemctl status $SERVICE_NAME${NC}"
echo -e " To view logs: ${YELLOW}journalctl -u $SERVICE_NAME${NC}" echo -e " To view logs: ${YELLOW}journalctl -u $SERVICE_NAME${NC}"
echo -e " To restart the service: ${YELLOW}systemctl restart $SERVICE_NAME${NC}" echo -e " To restart the service: ${YELLOW}systemctl restart $SERVICE_NAME${NC}"
echo -e " To update the application: ${YELLOW}Use the Update button in the System Status section${NC}"
echo echo
echo -e "Thank you for installing Transmission RSS Manager!" echo -e "Thank you for installing Transmission RSS Manager!"
echo -e "${BOLD}==================================================${NC}" echo -e "${BOLD}==================================================${NC}"

View File

@ -88,10 +88,18 @@ function gather_configuration() {
fi fi
fi fi
# Using fixed port 3000 to avoid permission issues with ports below 1024 # Get and validate port
log "INFO" "Using port 3000 for the web interface" while true; do
log "INFO" "This is to avoid permission issues with ports below 1024 (like port 80)" read -p "Web interface port [$PORT]: " input_port
PORT=3000 if [ -z "$input_port" ]; then
break
elif validate_port "$input_port"; then
PORT="$input_port"
break
else
log "WARN" "Invalid port number. Port must be between 1 and 65535."
fi
done
# Get user # Get user
read -p "Run as user [$USER]: " input_user read -p "Run as user [$USER]: " input_user
@ -225,43 +233,6 @@ function gather_configuration() {
# Set Transmission download dir for configuration # Set Transmission download dir for configuration
TRANSMISSION_DOWNLOAD_DIR=$REMOTE_DOWNLOAD_DIR TRANSMISSION_DOWNLOAD_DIR=$REMOTE_DOWNLOAD_DIR
else else
# Local Transmission selected
echo -e "${YELLOW}You've selected to use a local Transmission installation.${NC}"
# Check if Transmission is already installed
if command -v transmission-daemon &> /dev/null; then
echo -e "${GREEN}Transmission is already installed on this system.${NC}"
else
echo -e "${YELLOW}NOTE: Transmission does not appear to be installed on this system.${NC}"
echo -e "${YELLOW}You will be prompted to install it during the dependency installation step.${NC}"
fi
# Get and validate port
while true; do
read -p "Local Transmission port [9091]: " input_trans_port
if [ -z "$input_trans_port" ]; then
break
elif validate_port "$input_trans_port"; then
TRANSMISSION_PORT="$input_trans_port"
break
else
log "WARN" "Invalid port number. Port must be between 1 and 65535."
fi
done
# Get credentials if any
read -p "Local Transmission username (leave empty if authentication is disabled) []: " input_trans_user
TRANSMISSION_USER=${input_trans_user:-$TRANSMISSION_USER}
if [ -n "$input_trans_user" ]; then
# Use read -s for password to hide it
read -s -p "Local Transmission password []: " input_trans_pass
echo # Add a newline after the password input
if [ -n "$input_trans_pass" ]; then
TRANSMISSION_PASS="$input_trans_pass"
fi
fi
read -p "Transmission download directory [/var/lib/transmission-daemon/downloads]: " input_trans_dir read -p "Transmission download directory [/var/lib/transmission-daemon/downloads]: " input_trans_dir
if [ -n "$input_trans_dir" ]; then if [ -n "$input_trans_dir" ]; then
if [[ ! "$input_trans_dir" =~ ^/ ]]; then if [[ ! "$input_trans_dir" =~ ^/ ]]; then

View File

@ -35,61 +35,9 @@ function install_dependencies() {
log "INFO" "Node.js is already installed." log "INFO" "Node.js is already installed."
fi fi
# Check if we need to install Transmission (only if local transmission was selected)
if [ "$TRANSMISSION_HOST" = "localhost" ] || [ "$TRANSMISSION_HOST" = "127.0.0.1" ]; then
if ! command_exists transmission-daemon; then
log "INFO" "Local Transmission installation selected, but transmission-daemon is not installed."
read -p "Would you like to install Transmission now? (y/n): " install_transmission
if [[ "$install_transmission" =~ ^[Yy]$ ]]; then
log "INFO" "Installing Transmission..."
if ! apt-get install -y transmission-daemon; then
log "ERROR" "Failed to install Transmission"
log "WARN" "You will need to install Transmission manually before using this application."
else
# Stop transmission-daemon to allow configuration changes
systemctl stop transmission-daemon
# Set default settings
TRANSMISSION_SETTINGS_DIR="/var/lib/transmission-daemon/info"
if [ -f "$TRANSMISSION_SETTINGS_DIR/settings.json" ]; then
# Backup original settings
cp "$TRANSMISSION_SETTINGS_DIR/settings.json" "$TRANSMISSION_SETTINGS_DIR/settings.json.bak"
# Update RPC settings to allow our app to connect
sed -i 's/"rpc-authentication-required": true,/"rpc-authentication-required": false,/g' "$TRANSMISSION_SETTINGS_DIR/settings.json"
sed -i 's/"rpc-whitelist-enabled": true,/"rpc-whitelist-enabled": false,/g' "$TRANSMISSION_SETTINGS_DIR/settings.json"
log "INFO" "Transmission has been configured for local access."
else
log "WARN" "Could not find Transmission settings file. You may need to configure Transmission manually."
fi
# Start transmission-daemon
systemctl start transmission-daemon
log "INFO" "Transmission has been installed and started."
fi
else
log "WARN" "Transmission installation skipped. You will need to install it manually."
fi
else
log "INFO" "Transmission is already installed."
fi
fi
# Install additional dependencies # Install additional dependencies
log "INFO" "Installing additional dependencies..." log "INFO" "Installing additional dependencies..."
# Try to install unrar-free if unrar is not available apt-get install -y unrar unzip p7zip-full nginx
if ! apt-get install -y unrar 2>/dev/null; then
log "INFO" "unrar not available, trying unrar-free instead..."
apt-get install -y unrar-free
fi
# Install other dependencies
apt-get install -y unzip p7zip-full
# Try to install nginx
apt-get install -y nginx || log "WARN" "Nginx installation failed, web interface may not be accessible"
else else
log "ERROR" "This installer requires apt-get package manager" log "ERROR" "This installer requires apt-get package manager"
log "INFO" "Please install the following dependencies manually:" log "INFO" "Please install the following dependencies manually:"
@ -99,37 +47,19 @@ function install_dependencies() {
log "INFO" "- unzip" log "INFO" "- unzip"
log "INFO" "- p7zip-full" log "INFO" "- p7zip-full"
log "INFO" "- nginx" log "INFO" "- nginx"
if [ "$TRANSMISSION_HOST" = "localhost" ] || [ "$TRANSMISSION_HOST" = "127.0.0.1" ]; then
log "INFO" "- transmission-daemon"
fi
exit 1 exit 1
fi fi
# Check if all dependencies were installed successfully # Check if all dependencies were installed successfully
local dependencies=("node" "npm" "unzip" "nginx") local dependencies=("node" "npm" "unrar" "unzip" "7z" "nginx")
local missing_deps=() local missing_deps=()
# Add transmission to dependencies check if local installation was selected
if [ "$TRANSMISSION_HOST" = "localhost" ] || [ "$TRANSMISSION_HOST" = "127.0.0.1" ]; then
dependencies+=("transmission-daemon")
fi
for dep in "${dependencies[@]}"; do for dep in "${dependencies[@]}"; do
if ! command_exists "$dep"; then if ! command_exists "$dep"; then
missing_deps+=("$dep") missing_deps+=("$dep")
fi fi
done done
# Check for either unrar or unrar-free
if ! command_exists "unrar" && ! command_exists "unrar-free"; then
missing_deps+=("unrar")
fi
# Check for either 7z or 7za (from p7zip-full)
if ! command_exists "7z" && ! command_exists "7za"; then
missing_deps+=("p7zip")
fi
if [ ${#missing_deps[@]} -eq 0 ]; then if [ ${#missing_deps[@]} -eq 0 ]; then
log "INFO" "All dependencies installed successfully." log "INFO" "All dependencies installed successfully."
else else
@ -145,11 +75,6 @@ function install_dependencies() {
log "INFO" "To install nginx manually: sudo apt-get install nginx" log "INFO" "To install nginx manually: sudo apt-get install nginx"
fi fi
if [[ " ${missing_deps[*]} " =~ " transmission-daemon " ]]; then
log "INFO" "To install Transmission manually: sudo apt-get install transmission-daemon"
log "INFO" "After installation, you may need to configure it by editing /var/lib/transmission-daemon/info/settings.json"
fi
exit 1 exit 1
fi fi
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "transmission-rss-manager", "name": "transmission-rss-manager",
"version": "2.0.0", "version": "1.2.0",
"description": "A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration and intelligent media organization", "description": "A comprehensive web-based tool to automate and manage your Transmission torrent downloads with RSS feed integration and intelligent media organization",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
@ -11,7 +11,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://git.powerdata.dk/masterdraco/transmission-rss-manager.git" "url": "git+https://github.com/yourusername/transmission-rss-manager.git"
}, },
"keywords": [ "keywords": [
"transmission", "transmission",

View File

@ -105,48 +105,6 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<div id="status-container"> <div id="status-container">
<!-- System Status Card -->
<div class="row">
<div class="col-md-4 mb-3">
<div class="card">
<div class="card-header">
<h4><i class="fas fa-info-circle"></i> System Status</h4>
</div>
<div class="card-body">
<div class="status-item">
<span class="status-label">Version:</span>
<span id="system-version" class="status-value">Loading...</span>
</div>
<div class="status-item">
<span class="status-label">Running since:</span>
<span id="uptime" class="status-value">Loading...</span>
</div>
<div class="status-item">
<span class="status-label">Transmission:</span>
<span id="transmission-status" class="status-value">
<i class="fas fa-circle-notch fa-spin"></i> Checking...
</span>
</div>
<div class="status-item">
<span class="status-label">Update:</span>
<span id="update-status" class="status-value">
<i class="fas fa-circle-notch fa-spin"></i> Checking...
</span>
</div>
<div id="update-available" class="mt-3 d-none">
<div class="alert alert-info">
<i class="fas fa-arrow-circle-up"></i>
<span>A new version is available!</span>
<button id="btn-update-now" class="btn btn-sm btn-primary ml-2">
<i class="fas fa-download"></i> Update Now
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Original Status Content -->
<p>Loading system status...</p> <p>Loading system status...</p>
</div> </div>
@ -541,10 +499,10 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<p>Transmission RSS Manager v2.0.0</p> <p>Transmission RSS Manager v1.2.0</p>
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<p><a href="https://git.powerdata.dk/masterdraco/transmission-rss-manager" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="#" id="show-about-modal">About</a></p> <p><a href="https://github.com/your-repo/transmission-rss-manager" target="_blank" rel="noopener noreferrer">GitHub</a> | <a href="#" id="show-about-modal">About</a></p>
</div> </div>
</div> </div>
</div> </div>
@ -552,7 +510,6 @@
</div> </div>
<!-- JavaScript Files --> <!-- JavaScript Files -->
<script src="/js/system-status.js"></script>
<script src="/js/app.js"></script> <script src="/js/app.js"></script>
</body> </body>
</html> </html>

View File

@ -41,11 +41,6 @@ function initializeApp() {
// Initialize notifications system // Initialize notifications system
initNotifications(); initNotifications();
// Initialize system status (new in v2.0.0)
if (typeof initSystemStatus === 'function') {
initSystemStatus();
}
} }
/** /**

View File

@ -1,84 +1,178 @@
#!/bin/bash #!/bin/bash
# Update script for Transmission RSS Manager
# Transmission RSS Manager - Update Script # Text formatting
# This script pulls the latest version from git and runs necessary updates
# Color and formatting
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
BOLD='\033[1m' BOLD='\033[1m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Installation directory (should be current directory) # Get script directory
INSTALL_DIR=$(pwd) SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
APP_DIR="$(dirname "$SCRIPT_DIR")"
# Check if we're in the right directory # Check if script is run with sudo
if [ ! -f "$INSTALL_DIR/package.json" ] || [ ! -d "$INSTALL_DIR/modules" ]; then if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Error: This script must be run from the installation directory.${NC}" echo -e "${RED}Please run as root (use sudo)${NC}"
exit 1 exit 1
fi fi
# Get the current version # Print header
CURRENT_VERSION=$(grep -oP '"version": "\K[^"]+' package.json) echo -e "${BOLD}==================================================${NC}"
echo -e "${YELLOW}Current version: ${BOLD}$CURRENT_VERSION${NC}" echo -e "${BOLD} Transmission RSS Manager Updater ${NC}"
echo -e "${BOLD} Version 1.2.0 ${NC}"
echo -e "${BOLD}==================================================${NC}"
echo
# Check for git repository # Function to check if a service is running
if [ ! -d ".git" ]; then service_is_running() {
echo -e "${RED}Error: This installation was not set up using git.${NC}" systemctl is-active --quiet "$1"
echo -e "Please use the bootstrap installer to perform a fresh installation." return $?
exit 1 }
fi
# Stash any local changes # Backup existing files
echo -e "${YELLOW}Backing up any local configuration changes...${NC}" backup_app() {
git stash -q echo -e "${BOLD}Backing up existing installation...${NC}"
# Pull the latest changes TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo -e "${YELLOW}Pulling latest updates from git...${NC}" BACKUP_DIR="${APP_DIR}_backup_${TIMESTAMP}"
git pull
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to pull updates. Restoring original state...${NC}"
git stash pop -q
exit 1
fi
# Get the new version # Create backup directory
NEW_VERSION=$(grep -oP '"version": "\K[^"]+' package.json) mkdir -p "$BACKUP_DIR"
echo -e "${GREEN}New version: ${BOLD}$NEW_VERSION${NC}"
# Check if update is needed # Copy files to backup directory
if [ "$CURRENT_VERSION" == "$NEW_VERSION" ]; then cp -rf "$APP_DIR"/* "$BACKUP_DIR"
echo -e "${GREEN}You already have the latest version.${NC}"
exit 0
fi
# Install any new npm dependencies echo -e "${GREEN}Backup created at: $BACKUP_DIR${NC}"
echo -e "${YELLOW}Installing dependencies...${NC}" }
npm install
# Apply any local configuration changes # Update the application
if git stash list | grep -q "stash@{0}"; then update_app() {
echo -e "${YELLOW}Restoring local configuration changes...${NC}" echo -e "${BOLD}Updating application...${NC}"
git stash pop -q
# Handle conflicts if any # Get user account that owns the files
if [ $? -ne 0 ]; then APP_USER=$(stat -c '%U' "$APP_DIR")
echo -e "${RED}There were conflicts when restoring your configuration.${NC}"
echo -e "Please check the files and resolve conflicts manually." # Check if app is running as a service
echo -e "Your original configuration is saved in .git/refs/stash" WAS_RUNNING=false
if service_is_running transmission-rss-manager; then
WAS_RUNNING=true
echo -e "${YELLOW}Stopping service during update...${NC}"
systemctl stop transmission-rss-manager
fi fi
fi
# Restart the service # Set environment variable to indicate it's an update
echo -e "${YELLOW}Restarting service...${NC}" export IS_UPDATE=true
if command -v systemctl &> /dev/null; then
sudo systemctl restart transmission-rss-manager # Backup config files before update
if [ -f "$APP_DIR/config.json" ]; then
echo -e "${YELLOW}Backing up configuration file...${NC}"
CONFIG_BACKUP="${APP_DIR}/config.json.bak.$(date +%Y%m%d%H%M%S)"
cp "$APP_DIR/config.json" "$CONFIG_BACKUP"
echo -e "${GREEN}Configuration backed up to $CONFIG_BACKUP${NC}"
fi
# Update npm dependencies
cd "$APP_DIR"
echo -e "${YELLOW}Updating dependencies...${NC}"
npm install
# Fix permissions
chown -R $APP_USER:$APP_USER "$APP_DIR"
# Check if update script was successful
UPDATE_SUCCESS=true
# Restart service if it was running before
if [ "$WAS_RUNNING" = true ]; then
echo -e "${YELLOW}Restarting service...${NC}"
systemctl daemon-reload
systemctl start transmission-rss-manager
# Check if service started successfully
if service_is_running transmission-rss-manager; then
echo -e "${GREEN}Service restarted successfully.${NC}"
else
echo -e "${RED}Failed to restart service. Check logs with: journalctl -u transmission-rss-manager${NC}"
UPDATE_SUCCESS=false
fi
else
echo -e "${YELLOW}Service was not running before update. Not restarting.${NC}"
fi
# Provide info about configuration changes
if [ -f "$APP_DIR/config.json" ]; then
# Check if the configuration was updated by the service
if [ $(stat -c %Y "$APP_DIR/config.json") -gt $(stat -c %Y "$CONFIG_BACKUP") ]; then
echo -e "${GREEN}Configuration updated successfully with new options.${NC}"
echo -e "${YELLOW}Your existing settings have been preserved.${NC}"
else
echo -e "${YELLOW}Configuration was not modified during update.${NC}"
echo -e "${YELLOW}If you experience issues, check for new configuration options.${NC}"
fi
fi
if [ "$UPDATE_SUCCESS" = true ]; then
echo -e "${GREEN}Update completed successfully.${NC}"
else
echo -e "${RED}Update completed with some issues.${NC}"
echo -e "${YELLOW}If needed, you can restore configuration from: $CONFIG_BACKUP${NC}"
fi
}
# Check for updates in Git repository
check_git_updates() {
echo -e "${BOLD}Checking for updates in Git repository...${NC}"
# Check if git is installed
if ! command -v git &> /dev/null; then
echo -e "${YELLOW}Git is not installed, skipping Git update check.${NC}"
return 1
fi
# Check if app directory is a git repository
if [ ! -d "$APP_DIR/.git" ]; then
echo -e "${YELLOW}Not a Git repository, skipping Git update check.${NC}"
return 1
fi
# Check for updates
cd "$APP_DIR"
git fetch
# Check if we're behind the remote
BEHIND=$(git rev-list HEAD..origin/main --count)
if [ "$BEHIND" -gt 0 ]; then
echo -e "${GREEN}Updates available: $BEHIND new commit(s)${NC}"
# Confirm update
read -p "Do you want to pull the latest changes? (y/n) [y]: " CONFIRM
CONFIRM=${CONFIRM:-y}
if [[ $CONFIRM =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Pulling latest changes...${NC}"
git pull
return 0
else
echo -e "${YELLOW}Skipping Git update.${NC}"
return 1
fi
else
echo -e "${GREEN}Already up to date.${NC}"
return 1
fi
}
# Main update process
backup_app
if check_git_updates || [ "$1" = "--force" ]; then
update_app
else else
echo -e "${RED}Could not restart service automatically.${NC}" echo -e "${YELLOW}No updates needed or available.${NC}"
echo -e "Please restart the service manually." echo -e "${YELLOW}Use --force flag to update dependencies anyway.${NC}"
fi fi
# Update complete echo -e "${BOLD}==================================================${NC}"
echo -e "${GREEN}${BOLD}Update complete!${NC}" echo -e "${BOLD} Update process completed ${NC}"
echo -e "Updated from version $CURRENT_VERSION to $NEW_VERSION" echo -e "${BOLD}==================================================${NC}"
echo -e "Changes will take effect immediately."

View File

@ -1,146 +0,0 @@
// Version and update endpoints for server.js
// Add these imports at the top of server.js
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
const fs = require('fs');
const path = require('path');
// Add these endpoints
// Get system status including version and uptime
app.get('/api/system/status', async (req, res) => {
try {
// Get package.json for version info
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
const version = packageJson.version;
// Get system uptime
const uptimeSeconds = Math.floor(process.uptime());
const hours = Math.floor(uptimeSeconds / 3600);
const minutes = Math.floor((uptimeSeconds % 3600) / 60);
const seconds = uptimeSeconds % 60;
const uptime = `${hours}h ${minutes}m ${seconds}s`;
// Check transmission connection
let transmissionStatus = 'Connected';
try {
await transmissionClient.sessionGet();
} catch (err) {
transmissionStatus = 'Disconnected';
}
res.json({
status: 'success',
data: {
version,
uptime,
transmissionStatus
}
});
} catch (error) {
console.error('Error getting system status:', error);
res.status(500).json({
status: 'error',
message: 'Failed to get system status'
});
}
});
// Check for updates
app.get('/api/system/check-updates', async (req, res) => {
try {
// Check if git is available and if this is a git repository
const isGitRepo = fs.existsSync(path.join(__dirname, '.git'));
if (!isGitRepo) {
return res.json({
status: 'error',
message: 'This installation is not set up for updates. Please use the bootstrap installer.'
});
}
// Get current version
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
const currentVersion = packageJson.version;
// Fetch latest updates without applying them
await execAsync('git fetch');
// Check if we're behind the remote repository
const { stdout } = await execAsync('git rev-list HEAD..origin/main --count');
const behindCount = parseInt(stdout.trim());
if (behindCount > 0) {
// Get the new version from the remote package.json
const { stdout: remotePackageJson } = await execAsync('git show origin/main:package.json');
const remotePackage = JSON.parse(remotePackageJson);
const remoteVersion = remotePackage.version;
return res.json({
status: 'success',
data: {
updateAvailable: true,
currentVersion,
remoteVersion,
commitsBehind: behindCount
}
});
} else {
return res.json({
status: 'success',
data: {
updateAvailable: false,
currentVersion
}
});
}
} catch (error) {
console.error('Error checking for updates:', error);
res.status(500).json({
status: 'error',
message: 'Failed to check for updates'
});
}
});
// Apply updates
app.post('/api/system/update', async (req, res) => {
try {
// Check if git is available and if this is a git repository
const isGitRepo = fs.existsSync(path.join(__dirname, '.git'));
if (!isGitRepo) {
return res.status(400).json({
status: 'error',
message: 'This installation is not set up for updates. Please use the bootstrap installer.'
});
}
// Run the update script
const updateScriptPath = path.join(__dirname, 'scripts', 'update.sh');
// Make sure the update script is executable
await execAsync(`chmod +x ${updateScriptPath}`);
// Execute the update script
const { stdout, stderr } = await execAsync(updateScriptPath);
// If we get here, the update was successful
// The service will be restarted by the update script
res.json({
status: 'success',
message: 'Update applied successfully. The service will restart.',
data: {
output: stdout,
errors: stderr
}
});
} catch (error) {
console.error('Error applying update:', error);
res.status(500).json({
status: 'error',
message: 'Failed to apply update',
error: error.message
});
}
});