diff --git a/main-installer.sh b/main-installer.sh index 5b8f9c7..aa27cf3 100755 --- a/main-installer.sh +++ b/main-installer.sh @@ -95,7 +95,14 @@ done # Source the remaining module files source "${SCRIPT_DIR}/modules/config-module.sh" source "${SCRIPT_DIR}/modules/dependencies-module.sh" -source "${SCRIPT_DIR}/modules/service-setup-module.sh" +# Check if the updated service module exists, use it if available +if [ -f "${SCRIPT_DIR}/modules/service-setup-module-updated.sh" ]; then + log "INFO" "Using updated service setup module" + source "${SCRIPT_DIR}/modules/service-setup-module-updated.sh" +else + log "INFO" "Using standard service setup module" + source "${SCRIPT_DIR}/modules/service-setup-module.sh" +fi source "${SCRIPT_DIR}/modules/file-creator-module.sh" # Function to handle cleanup on error diff --git a/modules/rss-feed-manager.js b/modules/rss-feed-manager.js index 44e775e..d7b5762 100644 --- a/modules/rss-feed-manager.js +++ b/modules/rss-feed-manager.js @@ -18,8 +18,31 @@ class RssFeedManager { this.updateIntervalMinutes = config.updateIntervalMinutes || 60; this.parser = new xml2js.Parser({ explicitArray: false }); - // Ensure dataPath is properly defined - this.dataPath = path.join(__dirname, '..', 'data'); + // Set up the data path - first check if a data path was provided in the config + if (config.dataPath) { + this.dataPath = config.dataPath; + } else { + // Otherwise, use the default path relative to this module + this.dataPath = path.join(__dirname, '..', 'data'); + + // Log the data path for debugging + console.log(`Data directory path set to: ${this.dataPath}`); + + // Create the data directory synchronously to make sure it exists + try { + // Check if fs.mkdirSync is available + if (fs.mkdirSync) { + const fsSync = require('fs'); + if (!fsSync.existsSync(this.dataPath)) { + fsSync.mkdirSync(this.dataPath, { recursive: true }); + console.log(`Created data directory synchronously: ${this.dataPath}`); + } + } + } catch (err) { + console.warn(`Warning: Could not create data directory synchronously: ${err.message}`); + // Will try again asynchronously in ensureDataDirectory + } + } // Maximum items to keep in memory to prevent memory leaks this.maxItemsInMemory = config.maxItemsInMemory || 5000; @@ -31,6 +54,10 @@ class RssFeedManager { } try { + // Make sure the data directory exists first + await this.ensureDataDirectory(); + console.log(`Using data directory: ${this.dataPath}`); + // Load existing feeds and items await this.loadFeeds(); await this.loadItems(); @@ -482,10 +509,22 @@ class RssFeedManager { async ensureDataDirectory() { try { + // Create data directory with recursive option (creates all parent directories if they don't exist) await fs.mkdir(this.dataPath, { recursive: true }); + console.log(`Ensured data directory exists at: ${this.dataPath}`); } catch (error) { - console.error('Error creating data directory:', error); - throw error; + // Log the error details for debugging + console.error(`Error creating data directory ${this.dataPath}:`, error); + + // Try an alternate approach if the first method fails + try { + const { execSync } = require('child_process'); + execSync(`mkdir -p "${this.dataPath}"`); + console.log(`Created data directory using fallback method: ${this.dataPath}`); + } catch (fallbackError) { + console.error('Fallback method for creating data directory also failed:', fallbackError); + throw error; // Throw the original error + } } } diff --git a/modules/service-setup-module-updated.sh b/modules/service-setup-module-updated.sh new file mode 100755 index 0000000..88fe88f --- /dev/null +++ b/modules/service-setup-module-updated.sh @@ -0,0 +1,305 @@ +#!/bin/bash +# Service setup module for Transmission RSS Manager Installation + +# Setup systemd service +function setup_service() { + log "INFO" "Setting up systemd service..." + + # Ensure required variables are set + if [ -z "$SERVICE_NAME" ]; then + log "ERROR" "SERVICE_NAME variable is not set" + exit 1 + fi + + if [ -z "$USER" ]; then + log "ERROR" "USER variable is not set" + exit 1 + fi + + if [ -z "$INSTALL_DIR" ]; then + log "ERROR" "INSTALL_DIR variable is not set" + exit 1 + fi + + if [ -z "$CONFIG_DIR" ]; then + log "ERROR" "CONFIG_DIR variable is not set" + exit 1 + fi + + if [ -z "$PORT" ]; then + log "ERROR" "PORT variable is not set" + exit 1 + fi + + # Check if systemd is available + if ! command -v systemctl &> /dev/null; then + log "ERROR" "systemd is not available on this system" + log "INFO" "Please set up the service manually using your system's service manager" + return 1 + fi + + # Ensure the test-and-start script exists and is executable + TEST_START_SCRIPT="$INSTALL_DIR/scripts/test-and-start.sh" + mkdir -p "$(dirname "$TEST_START_SCRIPT")" + cat > "$TEST_START_SCRIPT" << 'EOF' +#!/bin/bash +# Script to ensure data directory exists and start the application + +# Define paths +APP_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" +DATA_DIR="$APP_DIR/data" + +echo "Starting Transmission RSS Manager..." +echo "Application directory: $APP_DIR" +echo "Data directory: $DATA_DIR" + +# Ensure the data directory exists +if [ ! -d "$DATA_DIR" ]; then + echo "Creating data directory: $DATA_DIR" + mkdir -p "$DATA_DIR" + if [ $? -ne 0 ]; then + echo "Failed to create data directory. Trying alternative method..." + # Try alternative method if standard mkdir fails + cd "$APP_DIR" && mkdir -p data + if [ $? -ne 0 ]; then + echo "ERROR: Both methods to create data directory failed. Please check permissions." + exit 1 + fi + fi +fi + +# Set permissions +chmod -R 755 "$DATA_DIR" + +# Check for RSS files +if [ ! -f "$DATA_DIR/rss-feeds.json" ]; then + echo "Creating initial empty rss-feeds.json file" + echo "[]" > "$DATA_DIR/rss-feeds.json" +fi + +if [ ! -f "$DATA_DIR/rss-items.json" ]; then + echo "Creating initial empty rss-items.json file" + echo "[]" > "$DATA_DIR/rss-items.json" +fi + +# Start the application +cd "$APP_DIR" || { echo "Failed to change to application directory"; exit 1; } +node server.js +EOF + + chmod +x "$TEST_START_SCRIPT" + log "INFO" "Created test-and-start script at $TEST_START_SCRIPT" + + # Check if service file already exists + SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service" + if [ -f "$SERVICE_FILE" ] && [ "$IS_UPDATE" = true ]; then + log "INFO" "Service file already exists. Preserving existing service configuration." + + # Extract existing JWT_SECRET if present to maintain session consistency + EXISTING_JWT_SECRET=$(grep "Environment=JWT_SECRET=" "$SERVICE_FILE" | cut -d'=' -f3) + + # Extract existing PORT if it differs from the configured one + EXISTING_PORT=$(grep "Environment=PORT=" "$SERVICE_FILE" | cut -d'=' -f3) + if [ -n "$EXISTING_PORT" ] && [ "$EXISTING_PORT" != "$PORT" ]; then + log "INFO" "Using existing port configuration: $EXISTING_PORT" + PORT=$EXISTING_PORT + fi + + # Create backup of existing service file + backup_file "$SERVICE_FILE" + + # Update the service file while preserving key settings + cat > "$SERVICE_FILE" << EOF +[Unit] +Description=Transmission RSS Manager +After=network.target transmission-daemon.service +Wants=network-online.target + +[Service] +Type=simple +User=$USER +WorkingDirectory=$INSTALL_DIR +ExecStart=$TEST_START_SCRIPT +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal +Environment=PORT=$PORT +Environment=NODE_ENV=production +Environment=DEBUG_ENABLED=false +Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log +Environment=CONFIG_DIR=$CONFIG_DIR +EOF + + # Preserve the existing JWT_SECRET if available + if [ -n "$EXISTING_JWT_SECRET" ]; then + echo "Environment=JWT_SECRET=$EXISTING_JWT_SECRET" >> "$SERVICE_FILE" + else + echo "# Generate a random JWT secret for security" >> "$SERVICE_FILE" + echo "Environment=JWT_SECRET=$(openssl rand -hex 32)" >> "$SERVICE_FILE" + fi + + # Close the service file definition + cat >> "$SERVICE_FILE" << EOF + +[Install] +WantedBy=multi-user.target +EOF + + else + # For fresh installations, create a new service file + log "INFO" "Creating new service file" + + # Create backup of existing service file if it exists + if [ -f "$SERVICE_FILE" ]; then + backup_file "$SERVICE_FILE" + fi + + # Create systemd service file + cat > "$SERVICE_FILE" << EOF +[Unit] +Description=Transmission RSS Manager +After=network.target transmission-daemon.service +Wants=network-online.target + +[Service] +Type=simple +User=$USER +WorkingDirectory=$INSTALL_DIR +ExecStart=$TEST_START_SCRIPT +Restart=always +RestartSec=10 +StandardOutput=journal +StandardError=journal +Environment=PORT=$PORT +Environment=NODE_ENV=production +Environment=DEBUG_ENABLED=false +Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log +Environment=CONFIG_DIR=$CONFIG_DIR +# Generate a random JWT secret for security +Environment=JWT_SECRET=$(openssl rand -hex 32) + +[Install] +WantedBy=multi-user.target +EOF + fi + + # Create logs directory + mkdir -p "$INSTALL_DIR/logs" + chown -R $USER:$USER "$INSTALL_DIR/logs" + + # Check if file was created successfully + if [ ! -f "$SERVICE_FILE" ]; then + log "ERROR" "Failed to create systemd service file" + return 1 + fi + + log "INFO" "Setting up Nginx reverse proxy..." + + # Check if nginx is installed + if ! command -v nginx &> /dev/null; then + log "ERROR" "Nginx is not installed" + log "INFO" "Skipping Nginx configuration. Please configure your web server manually." + + # Reload systemd and enable service + systemctl daemon-reload + systemctl enable "$SERVICE_NAME" + + log "INFO" "Systemd service has been created and enabled." + log "INFO" "The service will start automatically after installation." + return 0 + fi + + # Detect nginx configuration directory + NGINX_AVAILABLE_DIR="" + NGINX_ENABLED_DIR="" + + if [ -d "/etc/nginx/sites-available" ] && [ -d "/etc/nginx/sites-enabled" ]; then + # Debian/Ubuntu style + NGINX_AVAILABLE_DIR="/etc/nginx/sites-available" + NGINX_ENABLED_DIR="/etc/nginx/sites-enabled" + elif [ -d "/etc/nginx/conf.d" ]; then + # CentOS/RHEL style + NGINX_AVAILABLE_DIR="/etc/nginx/conf.d" + NGINX_ENABLED_DIR="/etc/nginx/conf.d" + else + log "WARN" "Unable to determine Nginx configuration directory" + log "INFO" "Please configure Nginx manually" + + # Reload systemd and enable service + systemctl daemon-reload + systemctl enable "$SERVICE_NAME" + + log "INFO" "Systemd service has been created and enabled." + log "INFO" "The service will start automatically after installation." + return 0 + fi + + # Check if default nginx file exists, back it up if it does + if [ -f "$NGINX_ENABLED_DIR/default" ]; then + backup_file "$NGINX_ENABLED_DIR/default" + if [ -f "$NGINX_ENABLED_DIR/default.bak" ]; then + log "INFO" "Backed up default nginx configuration." + fi + fi + + # Create nginx configuration file + NGINX_CONFIG_FILE="$NGINX_AVAILABLE_DIR/$SERVICE_NAME.conf" + cat > "$NGINX_CONFIG_FILE" << EOF +server { + listen 80; + server_name _; + + location / { + proxy_pass http://127.0.0.1:$PORT; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host \$host; + proxy_cache_bypass \$http_upgrade; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + } +} +EOF + + log "INFO" "Nginx configured to proxy connections from port 80 to port $PORT" + log "INFO" "You can access Transmission RSS Manager at http://your-server-ip/ (port 80) via Nginx" + + # Check if Debian/Ubuntu style (need symlink between available and enabled) + if [ "$NGINX_AVAILABLE_DIR" != "$NGINX_ENABLED_DIR" ]; then + # Create symbolic link to enable the site (if it doesn't already exist) + if [ ! -h "$NGINX_ENABLED_DIR/$SERVICE_NAME.conf" ]; then + ln -sf "$NGINX_CONFIG_FILE" "$NGINX_ENABLED_DIR/" + fi + fi + + # Test nginx configuration + if nginx -t; then + # Reload nginx + systemctl reload nginx + log "INFO" "Nginx configuration has been set up successfully." + else + log "ERROR" "Nginx configuration test failed. Please check the configuration manually." + log "WARN" "You may need to correct the configuration before the web interface will be accessible." + fi + + # Check for port conflicts + if ss -lnt | grep ":$PORT " &> /dev/null; then + log "WARN" "Port $PORT is already in use. This may cause conflicts with the service." + log "WARN" "The service will fail to start. Please stop any service using port $PORT and try again." + else + log "INFO" "You can access the web interface at: http://localhost:$PORT or http://your-server-ip:$PORT" + log "INFO" "You may need to configure your firewall to allow access to port $PORT" + fi + + # Reload systemd + systemctl daemon-reload + + # Enable the service to start on boot + systemctl enable "$SERVICE_NAME" + + log "INFO" "Systemd service has been created and enabled." + log "INFO" "The service will start automatically after installation." +} \ No newline at end of file diff --git a/scripts/test-and-start.sh b/scripts/test-and-start.sh index 3246812..e9073bf 100755 --- a/scripts/test-and-start.sh +++ b/scripts/test-and-start.sh @@ -1,165 +1,43 @@ -#!/bin/bash -# Test and start script for Transmission RSS Manager -# This script checks the installation, dependencies, and starts the application +#\!/bin/bash +# Script to ensure data directory exists and start the application -# Text formatting -BOLD='\033[1m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color +# Define paths +APP_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")" +DATA_DIR="$APP_DIR/data" -# Get directory of this script -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -APP_DIR="$(dirname "$SCRIPT_DIR")" +echo "Starting Transmission RSS Manager..." +echo "Application directory: $APP_DIR" +echo "Data directory: $DATA_DIR" -# Function to check if a command exists -command_exists() { - command -v "$1" &> /dev/null -} - -# Check Node.js and npm -check_node() { - echo -e "${BOLD}Checking Node.js and npm...${NC}" - - if command_exists node; then - NODE_VERSION=$(node -v) - echo -e "${GREEN}Node.js is installed: $NODE_VERSION${NC}" - else - echo -e "${RED}Node.js is not installed. Please install Node.js 14 or later.${NC}" - exit 1 - fi - - if command_exists npm; then - NPM_VERSION=$(npm -v) - echo -e "${GREEN}npm is installed: $NPM_VERSION${NC}" - else - echo -e "${RED}npm is not installed. Please install npm.${NC}" - exit 1 - fi -} - -# Check if Transmission is running -check_transmission() { - echo -e "${BOLD}Checking Transmission...${NC}" - - # Try to get the status of the transmission-daemon service - if command_exists systemctl; then - if systemctl is-active --quiet transmission-daemon; then - echo -e "${GREEN}Transmission daemon is running${NC}" - else - echo -e "${YELLOW}Warning: Transmission daemon does not appear to be running${NC}" - echo -e "${YELLOW}You may need to start it with: sudo systemctl start transmission-daemon${NC}" - fi - else - # Try a different method if systemctl is not available - if pgrep -x "transmission-daemon" > /dev/null; then - echo -e "${GREEN}Transmission daemon is running${NC}" - else - echo -e "${YELLOW}Warning: Transmission daemon does not appear to be running${NC}" - echo -e "${YELLOW}Please start Transmission daemon before using this application${NC}" - fi - fi -} - -# Check dependencies in package.json -check_dependencies() { - echo -e "${BOLD}Checking dependencies...${NC}" - - # Check if node_modules exists - if [ ! -d "$APP_DIR/node_modules" ]; then - echo -e "${YELLOW}Node modules not found. Installing dependencies...${NC}" - cd "$APP_DIR" && npm install - +# Ensure the data directory exists +if [ \! -d "$DATA_DIR" ]; then + echo "Creating data directory: $DATA_DIR" + mkdir -p "$DATA_DIR" + if [ $? -ne 0 ]; then + echo "Failed to create data directory. Trying alternative method..." + # Try alternative method if standard mkdir fails + cd "$APP_DIR" && mkdir -p data if [ $? -ne 0 ]; then - echo -e "${RED}Failed to install dependencies.${NC}" + echo "ERROR: Both methods to create data directory failed. Please check permissions." exit 1 - else - echo -e "${GREEN}Dependencies installed successfully${NC}" fi - else - echo -e "${GREEN}Dependencies are already installed${NC}" fi -} +fi -# Check if config.json exists -check_config() { - echo -e "${BOLD}Checking configuration...${NC}" - - if [ ! -f "$APP_DIR/config.json" ]; then - echo -e "${RED}Configuration file not found: $APP_DIR/config.json${NC}" - echo -e "${YELLOW}Please run the installer or create a config.json file${NC}" - exit 1 - else - echo -e "${GREEN}Configuration file found${NC}" - fi -} +# Set permissions +chmod -R 755 "$DATA_DIR" + +# Check for RSS files +if [ \! -f "$DATA_DIR/rss-feeds.json" ]; then + echo "Creating initial empty rss-feeds.json file" + echo "[]" > "$DATA_DIR/rss-feeds.json" +fi + +if [ \! -f "$DATA_DIR/rss-items.json" ]; then + echo "Creating initial empty rss-items.json file" + echo "[]" > "$DATA_DIR/rss-items.json" +fi # Start the application -start_app() { - echo -e "${BOLD}Starting Transmission RSS Manager...${NC}" - - # Check if running as a service - if command_exists systemctl; then - if systemctl is-active --quiet transmission-rss-manager; then - echo -e "${YELLOW}Transmission RSS Manager is already running as a service${NC}" - echo -e "${YELLOW}To restart it, use: sudo systemctl restart transmission-rss-manager${NC}" - exit 0 - fi - fi - - # Start the application - cd "$APP_DIR" - - # Parse arguments - FOREGROUND=false - DEBUG=false - - while [[ "$#" -gt 0 ]]; do - case $1 in - --foreground|-f) FOREGROUND=true ;; - --debug|-d) DEBUG=true ;; - *) echo "Unknown parameter: $1"; exit 1 ;; - esac - shift - done - - if [ "$FOREGROUND" = true ]; then - echo -e "${GREEN}Starting in foreground mode...${NC}" - - if [ "$DEBUG" = true ]; then - echo -e "${YELLOW}Debug mode enabled${NC}" - DEBUG_ENABLED=true node server.js - else - node server.js - fi - else - echo -e "${GREEN}Starting in background mode...${NC}" - - if [ "$DEBUG" = true ]; then - echo -e "${YELLOW}Debug mode enabled${NC}" - DEBUG_ENABLED=true nohup node server.js > logs/output.log 2>&1 & - else - nohup node server.js > logs/output.log 2>&1 & - fi - - echo $! > "$APP_DIR/transmission-rss-manager.pid" - echo -e "${GREEN}Application started with PID: $!${NC}" - echo -e "${GREEN}Logs available at: $APP_DIR/logs/output.log${NC}" - fi -} - -# Main script -echo -e "${BOLD}==================================================${NC}" -echo -e "${BOLD} Transmission RSS Manager - Test & Start ${NC}" -echo -e "${BOLD}==================================================${NC}" -echo - -# Run checks -check_node -check_transmission -check_dependencies -check_config - -# Start the application -start_app "$@" \ No newline at end of file +cd "$APP_DIR" || { echo "Failed to change to application directory"; exit 1; } +node server.js