Fix code consistency and reliability issues
This commit addresses multiple code consistency and reliability issues across the codebase: 1. Version consistency - use package.json version (2.0.9) throughout 2. Improved module loading with better error handling and consistent symlinks 3. Enhanced data directory handling with better error checking 4. Fixed redundant code in main-installer.sh 5. Improved error handling in transmission-client.js 6. Added extensive module symlink creation 7. Better file path handling and permission checks 8. Enhanced API response handling 💡 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
83222078d9
commit
6dc2df3cee
@ -401,8 +401,14 @@ fi
|
|||||||
# Step 7: Set up update script
|
# Step 7: Set up update script
|
||||||
log "INFO" "Setting up update script..."
|
log "INFO" "Setting up update script..."
|
||||||
mkdir -p "${SCRIPT_DIR}/scripts"
|
mkdir -p "${SCRIPT_DIR}/scripts"
|
||||||
cp "${SCRIPT_DIR}/scripts/update.sh" "${SCRIPT_DIR}/scripts/update.sh" 2>/dev/null || {
|
# Check if update script exists - don't copy it to itself
|
||||||
# If copy fails, it probably doesn't exist, so we'll create it
|
if [ ! -f "${SCRIPT_DIR}/scripts/update.sh" ]; then
|
||||||
|
# First, check if we have an update script to copy
|
||||||
|
if [ -f "${SCRIPT_DIR}/update.sh" ]; then
|
||||||
|
cp "${SCRIPT_DIR}/update.sh" "${SCRIPT_DIR}/scripts/update.sh"
|
||||||
|
log "INFO" "Copied update script from root to scripts directory"
|
||||||
|
else
|
||||||
|
# Create the update script since it doesn't exist
|
||||||
cat > "${SCRIPT_DIR}/scripts/update.sh" << 'EOL'
|
cat > "${SCRIPT_DIR}/scripts/update.sh" << 'EOL'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
@ -491,6 +497,8 @@ echo -e "Changes will take effect immediately."
|
|||||||
EOL
|
EOL
|
||||||
|
|
||||||
chmod +x "${SCRIPT_DIR}/scripts/update.sh"
|
chmod +x "${SCRIPT_DIR}/scripts/update.sh"
|
||||||
|
log "INFO" "Created update script: ${SCRIPT_DIR}/scripts/update.sh"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Step 8: Final setup and permissions
|
# Step 8: Final setup and permissions
|
||||||
|
@ -41,9 +41,13 @@ function create_config_files() {
|
|||||||
# Create initial config.json
|
# Create initial config.json
|
||||||
echo "Creating config.json..."
|
echo "Creating config.json..."
|
||||||
mkdir -p "$CONFIG_DIR"
|
mkdir -p "$CONFIG_DIR"
|
||||||
|
|
||||||
|
# Get version from package.json dynamically
|
||||||
|
VERSION=$(grep -oP '"version": "\K[^"]+' "${SCRIPT_DIR}/package.json" 2>/dev/null || echo "2.0.9")
|
||||||
|
|
||||||
cat > $CONFIG_DIR/config.json << EOF
|
cat > $CONFIG_DIR/config.json << EOF
|
||||||
{
|
{
|
||||||
"version": "2.0.6",
|
"version": "$VERSION",
|
||||||
"installPath": "$INSTALL_DIR",
|
"installPath": "$INSTALL_DIR",
|
||||||
"transmissionConfig": {
|
"transmissionConfig": {
|
||||||
"host": "$TRANSMISSION_HOST",
|
"host": "$TRANSMISSION_HOST",
|
||||||
@ -301,12 +305,13 @@ app.use(bodyParser.urlencoded({ extended: true, limit: '50mb' }));
|
|||||||
//==============================
|
//==============================
|
||||||
|
|
||||||
// Get the version from package.json
|
// Get the version from package.json
|
||||||
let appVersion = '2.0.6'; // Default fallback version
|
let appVersion;
|
||||||
try {
|
try {
|
||||||
const packageJson = require('./package.json');
|
const packageJson = require('./package.json');
|
||||||
appVersion = packageJson.version;
|
appVersion = packageJson.version;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Could not read version from package.json, using default');
|
console.warn('Could not read version from package.json, using default');
|
||||||
|
appVersion = '2.0.9'; // Default fallback version aligned with package.json
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server status API
|
// Server status API
|
||||||
|
@ -27,21 +27,19 @@ class RssFeedManager {
|
|||||||
|
|
||||||
// Log the data path for debugging
|
// Log the data path for debugging
|
||||||
console.log(`Data directory path set to: ${this.dataPath}`);
|
console.log(`Data directory path set to: ${this.dataPath}`);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the data directory synchronously to make sure it exists
|
// We'll always ensure the data directory exists regardless of where it's set
|
||||||
|
// Use synchronous operation to ensure directory exists immediately upon construction
|
||||||
try {
|
try {
|
||||||
// Check if fs.mkdirSync is available
|
|
||||||
if (fs.mkdirSync) {
|
|
||||||
const fsSync = require('fs');
|
const fsSync = require('fs');
|
||||||
if (!fsSync.existsSync(this.dataPath)) {
|
if (!fsSync.existsSync(this.dataPath)) {
|
||||||
fsSync.mkdirSync(this.dataPath, { recursive: true });
|
fsSync.mkdirSync(this.dataPath, { recursive: true });
|
||||||
console.log(`Created data directory synchronously: ${this.dataPath}`);
|
console.log(`Created data directory synchronously: ${this.dataPath}`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(`Warning: Could not create data directory synchronously: ${err.message}`);
|
console.warn(`Warning: Could not create data directory synchronously: ${err.message}`);
|
||||||
// Will try again asynchronously in ensureDataDirectory
|
// Will try again asynchronously in ensureDataDirectory when start() is called
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maximum items to keep in memory to prevent memory leaks
|
// Maximum items to keep in memory to prevent memory leaks
|
||||||
@ -158,10 +156,13 @@ class RssFeedManager {
|
|||||||
console.log(`Updating feed: ${feed.name || 'Unnamed'} (${feed.url})`);
|
console.log(`Updating feed: ${feed.name || 'Unnamed'} (${feed.url})`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Get version from package.json if available, fallback to environment or hardcoded
|
||||||
|
const version = process.env.APP_VERSION || require('../package.json').version || '2.0.9';
|
||||||
|
|
||||||
const response = await fetch(feed.url, {
|
const response = await fetch(feed.url, {
|
||||||
timeout: 30000, // 30 second timeout
|
timeout: 30000, // 30 second timeout
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'Transmission-RSS-Manager/2.0.6'
|
'User-Agent': `Transmission-RSS-Manager/${version}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -507,11 +508,16 @@ class RssFeedManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the data directory exists, using a consistent approach across the application
|
||||||
|
* @returns {Promise<boolean>} true if directory exists or was created
|
||||||
|
*/
|
||||||
async ensureDataDirectory() {
|
async ensureDataDirectory() {
|
||||||
try {
|
try {
|
||||||
// Create data directory with recursive option (creates all parent directories if they don't exist)
|
// Create data directory with recursive option (creates all parent directories if they don't exist)
|
||||||
await fs.mkdir(this.dataPath, { recursive: true });
|
await fs.mkdir(this.dataPath, { recursive: true });
|
||||||
console.log(`Ensured data directory exists at: ${this.dataPath}`);
|
console.log(`Ensured data directory exists at: ${this.dataPath}`);
|
||||||
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Log the error details for debugging
|
// Log the error details for debugging
|
||||||
console.error(`Error creating data directory ${this.dataPath}:`, error);
|
console.error(`Error creating data directory ${this.dataPath}:`, error);
|
||||||
@ -521,9 +527,10 @@ class RssFeedManager {
|
|||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
execSync(`mkdir -p "${this.dataPath}"`);
|
execSync(`mkdir -p "${this.dataPath}"`);
|
||||||
console.log(`Created data directory using fallback method: ${this.dataPath}`);
|
console.log(`Created data directory using fallback method: ${this.dataPath}`);
|
||||||
|
return true;
|
||||||
} catch (fallbackError) {
|
} catch (fallbackError) {
|
||||||
console.error('Fallback method for creating data directory also failed:', fallbackError);
|
console.error('All methods for creating data directory failed:', fallbackError);
|
||||||
throw error; // Throw the original error
|
throw new Error(`Failed to create data directory: ${this.dataPath}. Original error: ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,15 @@ class TransmissionClient {
|
|||||||
*/
|
*/
|
||||||
async addTorrent(url, options = {}) {
|
async addTorrent(url, options = {}) {
|
||||||
try {
|
try {
|
||||||
|
// Verify client is initialized
|
||||||
|
if (!this.client) {
|
||||||
|
await this.initializeConnection();
|
||||||
|
|
||||||
|
if (!this.client) {
|
||||||
|
throw new Error("Failed to initialize Transmission client");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const downloadDir = options.downloadDir || null;
|
const downloadDir = options.downloadDir || null;
|
||||||
const result = await this.client.addUrl(url, {
|
const result = await this.client.addUrl(url, {
|
||||||
"download-dir": downloadDir,
|
"download-dir": downloadDir,
|
||||||
|
@ -101,6 +101,29 @@ function create_dir_if_not_exists() {
|
|||||||
function ensure_npm_packages() {
|
function ensure_npm_packages() {
|
||||||
local install_dir=$1
|
local install_dir=$1
|
||||||
|
|
||||||
|
# First ensure the installation directory exists
|
||||||
|
if [ ! -d "$install_dir" ]; then
|
||||||
|
log "INFO" "Creating installation directory: $install_dir"
|
||||||
|
mkdir -p "$install_dir" || {
|
||||||
|
log "ERROR" "Failed to create installation directory: $install_dir"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure data directory exists
|
||||||
|
if [ ! -d "$install_dir/data" ]; then
|
||||||
|
log "INFO" "Creating data directory: $install_dir/data"
|
||||||
|
mkdir -p "$install_dir/data" || {
|
||||||
|
log "ERROR" "Failed to create data directory: $install_dir/data"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize empty data files
|
||||||
|
echo "[]" > "$install_dir/data/rss-feeds.json"
|
||||||
|
echo "[]" > "$install_dir/data/rss-items.json"
|
||||||
|
log "INFO" "Initialized empty data files"
|
||||||
|
fi
|
||||||
|
|
||||||
# Ensure package.json exists in the installation directory
|
# Ensure package.json exists in the installation directory
|
||||||
if [ ! -f "$install_dir/package.json" ]; then
|
if [ ! -f "$install_dir/package.json" ]; then
|
||||||
log "INFO" "Copying package.json to installation directory..."
|
log "INFO" "Copying package.json to installation directory..."
|
||||||
@ -108,7 +131,7 @@ function ensure_npm_packages() {
|
|||||||
log "ERROR" "Failed to copy package.json to installation directory"
|
log "ERROR" "Failed to copy package.json to installation directory"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
fi
|
}
|
||||||
|
|
||||||
# Install NPM packages if not already installed or if it's an update
|
# Install NPM packages if not already installed or if it's an update
|
||||||
if [ ! -d "$install_dir/node_modules" ] || [ "$IS_UPDATE" = "true" ]; then
|
if [ ! -d "$install_dir/node_modules" ] || [ "$IS_UPDATE" = "true" ]; then
|
||||||
@ -199,9 +222,12 @@ function finalize_setup() {
|
|||||||
# Make sure CONFIG_DIR exists
|
# Make sure CONFIG_DIR exists
|
||||||
mkdir -p "$CONFIG_DIR"
|
mkdir -p "$CONFIG_DIR"
|
||||||
|
|
||||||
|
# Get version from package.json dynamically
|
||||||
|
VERSION=$(grep -oP '"version": "\K[^"]+' "${SCRIPT_DIR}/package.json" 2>/dev/null || echo "2.0.9")
|
||||||
|
|
||||||
cat > $CONFIG_DIR/config.json << EOF
|
cat > $CONFIG_DIR/config.json << EOF
|
||||||
{
|
{
|
||||||
"version": "2.0.6",
|
"version": "$VERSION",
|
||||||
"transmissionConfig": {
|
"transmissionConfig": {
|
||||||
"host": "${TRANSMISSION_HOST}",
|
"host": "${TRANSMISSION_HOST}",
|
||||||
"port": ${TRANSMISSION_PORT},
|
"port": ${TRANSMISSION_PORT},
|
||||||
|
@ -1,49 +1,78 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Create bi-directional symlinks for module compatibility
|
# Script to create symlinks for all modules in different naming styles
|
||||||
|
# This ensures compatibility with different module import styles
|
||||||
|
|
||||||
MODULES_DIR="$(dirname "$(dirname "$0")")/modules"
|
APP_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")"
|
||||||
|
MODULE_DIR="$APP_DIR/modules"
|
||||||
|
|
||||||
echo "Creating module symlinks in $MODULES_DIR..."
|
echo "Creating module symlinks for compatibility..."
|
||||||
|
echo "Module directory: $MODULE_DIR"
|
||||||
|
|
||||||
# Check if modules directory exists
|
# Create a function to make bidirectional symlinks
|
||||||
if [ ! -d "$MODULES_DIR" ]; then
|
create_module_symlinks() {
|
||||||
echo "Error: Modules directory not found: $MODULES_DIR"
|
if [ -d "$MODULE_DIR" ]; then
|
||||||
exit 1
|
# Create symlinks for hyphenated modules
|
||||||
fi
|
for module in "$MODULE_DIR"/*-*.js; do
|
||||||
|
if [ -f "$module" ]; then
|
||||||
|
# Convert hyphenated to camelCase
|
||||||
|
BASE_NAME=$(basename "$module")
|
||||||
|
CAMEL_NAME=$(echo "$BASE_NAME" | sed -E 's/-([a-z])/\U\1/g')
|
||||||
|
|
||||||
# Create bidirectional symlinks
|
# Create camelCase symlink if needed
|
||||||
create_bidirectional_links() {
|
if [ ! -f "$MODULE_DIR/$CAMEL_NAME" ] && [ ! -L "$MODULE_DIR/$CAMEL_NAME" ]; then
|
||||||
local hyphenated="$1"
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$CAMEL_NAME"
|
||||||
local camelCase="$2"
|
echo "Created symlink: $CAMEL_NAME -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
# Check if hyphenated version exists
|
# Create extension-less symlink for both versions
|
||||||
if [ -f "$MODULES_DIR/$hyphenated.js" ]; then
|
NO_EXT_BASE="${BASE_NAME%.js}"
|
||||||
# Create camelCase symlink
|
if [ ! -f "$MODULE_DIR/$NO_EXT_BASE" ] && [ ! -L "$MODULE_DIR/$NO_EXT_BASE" ]; then
|
||||||
ln -sf "$hyphenated.js" "$MODULES_DIR/$camelCase.js"
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_BASE"
|
||||||
echo "Created symlink: $camelCase.js -> $hyphenated.js"
|
echo "Created symlink: $NO_EXT_BASE -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
# Create symlinks without extension
|
NO_EXT_CAMEL="${CAMEL_NAME%.js}"
|
||||||
ln -sf "$hyphenated.js" "$MODULES_DIR/$hyphenated"
|
if [ ! -f "$MODULE_DIR/$NO_EXT_CAMEL" ] && [ ! -L "$MODULE_DIR/$NO_EXT_CAMEL" ]; then
|
||||||
ln -sf "$hyphenated.js" "$MODULES_DIR/$camelCase"
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_CAMEL"
|
||||||
echo "Created extension-less symlinks: $hyphenated, $camelCase -> $hyphenated.js"
|
echo "Created symlink: $NO_EXT_CAMEL -> $BASE_NAME"
|
||||||
# Check if camelCase version exists
|
fi
|
||||||
elif [ -f "$MODULES_DIR/$camelCase.js" ]; then
|
fi
|
||||||
# Create hyphenated symlink
|
done
|
||||||
ln -sf "$camelCase.js" "$MODULES_DIR/$hyphenated.js"
|
|
||||||
echo "Created symlink: $hyphenated.js -> $camelCase.js"
|
|
||||||
|
|
||||||
# Create symlinks without extension
|
# Create symlinks for camelCase modules (only non-symlinked files)
|
||||||
ln -sf "$camelCase.js" "$MODULES_DIR/$hyphenated"
|
for module in "$MODULE_DIR"/[a-z]*[A-Z]*.js; do
|
||||||
ln -sf "$camelCase.js" "$MODULES_DIR/$camelCase"
|
if [ -f "$module" ] && [ ! -L "$module" ]; then
|
||||||
echo "Created extension-less symlinks: $hyphenated, $camelCase -> $camelCase.js"
|
# Convert camelCase to hyphenated
|
||||||
|
BASE_NAME=$(basename "$module")
|
||||||
|
HYPHEN_NAME=$(echo "$BASE_NAME" | sed -E 's/([a-z])([A-Z])/\1-\L\2/g')
|
||||||
|
|
||||||
|
# Create hyphenated symlink if needed
|
||||||
|
if [ ! -f "$MODULE_DIR/$HYPHEN_NAME" ] && [ ! -L "$MODULE_DIR/$HYPHEN_NAME" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$HYPHEN_NAME"
|
||||||
|
echo "Created symlink: $HYPHEN_NAME -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create extension-less symlink for both versions
|
||||||
|
NO_EXT_BASE="${BASE_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_BASE" ] && [ ! -L "$MODULE_DIR/$NO_EXT_BASE" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_BASE"
|
||||||
|
echo "Created symlink: $NO_EXT_BASE -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
NO_EXT_HYPHEN="${HYPHEN_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_HYPHEN" ] && [ ! -L "$MODULE_DIR/$NO_EXT_HYPHEN" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_HYPHEN"
|
||||||
|
echo "Created symlink: $NO_EXT_HYPHEN -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Module symlinks created successfully"
|
||||||
else
|
else
|
||||||
echo "Warning: Neither $hyphenated.js nor $camelCase.js exists in $MODULES_DIR"
|
echo "Error: Module directory not found at $MODULE_DIR"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create symlinks for all modules
|
# Execute the symlink creation function
|
||||||
create_bidirectional_links "rss-feed-manager" "rssFeedManager"
|
create_module_symlinks
|
||||||
create_bidirectional_links "transmission-client" "transmissionClient"
|
|
||||||
create_bidirectional_links "post-processor" "postProcessor"
|
|
||||||
|
|
||||||
echo "Module symlinks created successfully."
|
|
@ -25,17 +25,25 @@ if [ ! -d "$DATA_DIR" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Set permissions
|
# Set permissions
|
||||||
chmod -R 755 "$DATA_DIR"
|
chmod -R 755 "$DATA_DIR" || {
|
||||||
|
echo "Warning: Failed to set permissions on data directory"
|
||||||
|
}
|
||||||
|
|
||||||
# Check for RSS files
|
# Check for RSS files
|
||||||
if [ ! -f "$DATA_DIR/rss-feeds.json" ]; then
|
if [ ! -f "$DATA_DIR/rss-feeds.json" ]; then
|
||||||
echo "Creating initial empty rss-feeds.json file"
|
echo "Creating initial empty rss-feeds.json file"
|
||||||
echo "[]" > "$DATA_DIR/rss-feeds.json"
|
echo "[]" > "$DATA_DIR/rss-feeds.json" || {
|
||||||
|
echo "ERROR: Failed to create rss-feeds.json file"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -f "$DATA_DIR/rss-items.json" ]; then
|
if [ ! -f "$DATA_DIR/rss-items.json" ]; then
|
||||||
echo "Creating initial empty rss-items.json file"
|
echo "Creating initial empty rss-items.json file"
|
||||||
echo "[]" > "$DATA_DIR/rss-items.json"
|
echo "[]" > "$DATA_DIR/rss-items.json" || {
|
||||||
|
echo "ERROR: Failed to create rss-items.json file"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Find the node executable path
|
# Find the node executable path
|
||||||
@ -57,12 +65,74 @@ if [ -z "$NODE_PATH" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Create module symlinks to ensure compatibility
|
# Create module symlinks to ensure compatibility
|
||||||
if [ -f "$APP_DIR/scripts/create-module-links.sh" ]; then
|
echo "Creating module symlinks for compatibility..."
|
||||||
echo "Creating module symlinks for compatibility..."
|
MODULE_DIR="$APP_DIR/modules"
|
||||||
bash "$APP_DIR/scripts/create-module-links.sh"
|
|
||||||
else
|
# Create a function to make bidirectional symlinks
|
||||||
echo "Warning: Module symlink script not found"
|
create_module_symlinks() {
|
||||||
fi
|
if [ -d "$MODULE_DIR" ]; then
|
||||||
|
# Create symlinks for hyphenated modules
|
||||||
|
for module in "$MODULE_DIR"/*-*.js; do
|
||||||
|
if [ -f "$module" ]; then
|
||||||
|
# Convert hyphenated to camelCase
|
||||||
|
BASE_NAME=$(basename "$module")
|
||||||
|
CAMEL_NAME=$(echo "$BASE_NAME" | sed -E 's/-([a-z])/\U\1/g')
|
||||||
|
|
||||||
|
# Create camelCase symlink if needed
|
||||||
|
if [ ! -f "$MODULE_DIR/$CAMEL_NAME" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$CAMEL_NAME"
|
||||||
|
echo "Created symlink: $CAMEL_NAME -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create extension-less symlink for both versions
|
||||||
|
NO_EXT_BASE="${BASE_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_BASE" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_BASE"
|
||||||
|
echo "Created symlink: $NO_EXT_BASE -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
NO_EXT_CAMEL="${CAMEL_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_CAMEL" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_CAMEL"
|
||||||
|
echo "Created symlink: $NO_EXT_CAMEL -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create symlinks for camelCase modules
|
||||||
|
for module in "$MODULE_DIR"/[a-z]*[A-Z]*.js; do
|
||||||
|
if [ -f "$module" ]; then
|
||||||
|
# Convert camelCase to hyphenated
|
||||||
|
BASE_NAME=$(basename "$module")
|
||||||
|
HYPHEN_NAME=$(echo "$BASE_NAME" | sed -E 's/([a-z])([A-Z])/\1-\L\2/g')
|
||||||
|
|
||||||
|
# Create hyphenated symlink if needed
|
||||||
|
if [ ! -f "$MODULE_DIR/$HYPHEN_NAME" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$HYPHEN_NAME"
|
||||||
|
echo "Created symlink: $HYPHEN_NAME -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create extension-less symlink for both versions
|
||||||
|
NO_EXT_BASE="${BASE_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_BASE" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_BASE"
|
||||||
|
echo "Created symlink: $NO_EXT_BASE -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
|
||||||
|
NO_EXT_HYPHEN="${HYPHEN_NAME%.js}"
|
||||||
|
if [ ! -f "$MODULE_DIR/$NO_EXT_HYPHEN" ]; then
|
||||||
|
ln -sf "$BASE_NAME" "$MODULE_DIR/$NO_EXT_HYPHEN"
|
||||||
|
echo "Created symlink: $NO_EXT_HYPHEN -> $BASE_NAME"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Warning: Module directory not found at $MODULE_DIR"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute the symlink creation function
|
||||||
|
create_module_symlinks
|
||||||
|
|
||||||
# Start the application
|
# Start the application
|
||||||
cd "$APP_DIR" || { echo "Failed to change to application directory"; exit 1; }
|
cd "$APP_DIR" || { echo "Failed to change to application directory"; exit 1; }
|
||||||
|
80
server.js
80
server.js
@ -21,60 +21,62 @@ const semver = require('semver'); // For semantic version comparison
|
|||||||
// Import custom modules
|
// Import custom modules
|
||||||
let RssFeedManager, TransmissionClient, PostProcessor;
|
let RssFeedManager, TransmissionClient, PostProcessor;
|
||||||
|
|
||||||
// Helper function to try multiple module paths
|
/**
|
||||||
function tryRequire(modulePaths) {
|
* Helper function to try multiple module paths
|
||||||
|
* This function tries to require a module using different naming conventions
|
||||||
|
* to work around issues with module resolution in different Node.js environments
|
||||||
|
*
|
||||||
|
* @param {string} baseName - The base module name without extension or path
|
||||||
|
* @returns {Object} The loaded module
|
||||||
|
* @throws {Error} If module cannot be loaded from any path
|
||||||
|
*/
|
||||||
|
function loadModule(baseName) {
|
||||||
|
// Generate all possible module paths
|
||||||
|
const paths = [
|
||||||
|
`./modules/${baseName}.js`, // With extension
|
||||||
|
`./modules/${baseName}`, // Without extension
|
||||||
|
|
||||||
|
// Convert hyphenated to camelCase
|
||||||
|
`./modules/${baseName.replace(/-([a-z])/g, (_, c) => c.toUpperCase())}.js`,
|
||||||
|
`./modules/${baseName.replace(/-([a-z])/g, (_, c) => c.toUpperCase())}`,
|
||||||
|
|
||||||
|
// Convert camelCase to hyphenated
|
||||||
|
`./modules/${baseName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()}.js`,
|
||||||
|
`./modules/${baseName.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()}`
|
||||||
|
];
|
||||||
|
|
||||||
let lastError = null;
|
let lastError = null;
|
||||||
for (const modulePath of modulePaths) {
|
for (const modulePath of paths) {
|
||||||
try {
|
try {
|
||||||
return require(modulePath);
|
return require(modulePath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(`Attempted to load module from ${modulePath}, but got error: ${err.message}`);
|
if (err.code !== 'MODULE_NOT_FOUND' || !err.message.includes(modulePath)) {
|
||||||
|
// This is a real error in the module, not just not finding it
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
lastError = err;
|
lastError = err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw lastError;
|
|
||||||
|
// If we get here, we couldn't load the module from any path
|
||||||
|
const error = new Error(`Could not load module '${baseName}' from any path. Original error: ${lastError.message}`);
|
||||||
|
error.original = lastError;
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try loading modules with various namings (with and without .js extension, with hyphens or camelCase)
|
// Try loading modules with improved error reporting
|
||||||
try {
|
try {
|
||||||
const rssPaths = [
|
RssFeedManager = loadModule('rss-feed-manager');
|
||||||
'./modules/rss-feed-manager.js',
|
|
||||||
'./modules/rssFeedManager.js',
|
|
||||||
'./modules/rss-feed-manager',
|
|
||||||
'./modules/rssFeedManager'
|
|
||||||
];
|
|
||||||
RssFeedManager = tryRequire(rssPaths);
|
|
||||||
console.log('Successfully loaded RssFeedManager module');
|
console.log('Successfully loaded RssFeedManager module');
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to load RssFeedManager module:', err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
TransmissionClient = loadModule('transmission-client');
|
||||||
const transmissionPaths = [
|
|
||||||
'./modules/transmission-client.js',
|
|
||||||
'./modules/transmissionClient.js',
|
|
||||||
'./modules/transmission-client',
|
|
||||||
'./modules/transmissionClient'
|
|
||||||
];
|
|
||||||
TransmissionClient = tryRequire(transmissionPaths);
|
|
||||||
console.log('Successfully loaded TransmissionClient module');
|
console.log('Successfully loaded TransmissionClient module');
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to load TransmissionClient module:', err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
PostProcessor = loadModule('post-processor');
|
||||||
const processorPaths = [
|
|
||||||
'./modules/post-processor.js',
|
|
||||||
'./modules/postProcessor.js',
|
|
||||||
'./modules/post-processor',
|
|
||||||
'./modules/postProcessor'
|
|
||||||
];
|
|
||||||
PostProcessor = tryRequire(processorPaths);
|
|
||||||
console.log('Successfully loaded PostProcessor module');
|
console.log('Successfully loaded PostProcessor module');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load PostProcessor module:', err);
|
console.error('Fatal error loading required module:', err.message);
|
||||||
|
console.error('Please make sure all module files exist and are valid JavaScript');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +458,7 @@ app.get('/api/status', authenticateJWT, async (req, res) => {
|
|||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
status: 'running',
|
status: 'running',
|
||||||
version: '2.0.6',
|
version: APP_VERSION, // Use the dynamic APP_VERSION from package.json
|
||||||
transmissionConnected: transmissionStatus.connected,
|
transmissionConnected: transmissionStatus.connected,
|
||||||
transmissionVersion: transmissionStatus.version,
|
transmissionVersion: transmissionStatus.version,
|
||||||
transmissionStats: {
|
transmissionStats: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user