Move config file to /etc/transmission-rss-manager

- Changed config location to /etc/transmission-rss-manager/config.json
- Added fallback to maintain backward compatibility
- Updated installers to create and use the new location
- Added installPath property to configuration for updates
- Enhanced documentation with new config location
- Bumped version to 2.0.3

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MasterDraco 2025-03-05 00:48:57 +00:00
parent 3cfc5f3489
commit c495bce21f
7 changed files with 164 additions and 14 deletions

View File

@ -1,9 +1,14 @@
# Transmission RSS Manager v2.0.2 # Transmission RSS Manager v2.0.3
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. Now with automatic updates and easy installation!
## Changelog ## Changelog
### v2.0.3 (2025-03-05)
- **New**: Configuration file now stored in `/etc/transmission-rss-manager/`
- **Improved**: Installer creates config directory with proper permissions
- **Improved**: Application now stores path to installation directory for easier updates
### v2.0.2 (2025-03-05) ### v2.0.2 (2025-03-05)
- **Fixed**: Bug in installer that would prompt to install Transmission for remote configurations - **Fixed**: Bug in installer that would prompt to install Transmission for remote configurations
- **Improved**: Better detection of remote vs local Transmission installations - **Improved**: Better detection of remote vs local Transmission installations
@ -132,10 +137,11 @@ If you prefer to install manually:
### Main Configuration Options ### Main Configuration Options
The system can be configured through the web interface or by editing the `config.json` file: The system can be configured through the web interface or by editing the configuration file, which is located at `/etc/transmission-rss-manager/config.json` (or at the application's installation directory as a fallback):
```json ```json
{ {
"installPath": "/opt/transmission-rss-manager",
"transmissionConfig": { "transmissionConfig": {
"host": "localhost", "host": "localhost",
"port": 9091, "port": 9091,

View File

@ -3,6 +3,7 @@
# Configuration variables with defaults # Configuration variables with defaults
INSTALL_DIR="/opt/transmission-rss-manager" INSTALL_DIR="/opt/transmission-rss-manager"
CONFIG_DIR="/etc/transmission-rss-manager"
SERVICE_NAME="transmission-rss-manager" SERVICE_NAME="transmission-rss-manager"
PORT=3000 PORT=3000

View File

@ -163,6 +163,12 @@ function create_directories() {
exit 1 exit 1
fi fi
# Check if CONFIG_DIR is defined
if [ -z "$CONFIG_DIR" ]; then
log "ERROR" "CONFIG_DIR is not defined"
exit 1
fi
# Create directories and check for errors # Create directories and check for errors
DIRECTORIES=( DIRECTORIES=(
"$INSTALL_DIR" "$INSTALL_DIR"
@ -171,6 +177,7 @@ function create_directories() {
"$INSTALL_DIR/public/css" "$INSTALL_DIR/public/css"
"$INSTALL_DIR/modules" "$INSTALL_DIR/modules"
"$INSTALL_DIR/data" "$INSTALL_DIR/data"
"$CONFIG_DIR"
) )
for dir in "${DIRECTORIES[@]}"; do for dir in "${DIRECTORIES[@]}"; do
@ -180,5 +187,9 @@ function create_directories() {
fi fi
done done
# Set permissions for configuration directory
chown -R "$USER:$USER" "$CONFIG_DIR"
chmod 755 "$CONFIG_DIR"
log "INFO" "Directories created successfully." log "INFO" "Directories created successfully."
} }

View File

@ -4,6 +4,63 @@
function create_config_files() { function create_config_files() {
echo -e "${YELLOW}Creating configuration files...${NC}" echo -e "${YELLOW}Creating configuration files...${NC}"
# Create initial config.json
echo "Creating config.json..."
cat > $CONFIG_DIR/config.json << EOF
{
"version": "2.0.3",
"installPath": "$INSTALL_DIR",
"transmissionConfig": {
"host": "$TRANSMISSION_HOST",
"port": $TRANSMISSION_PORT,
"username": "$TRANSMISSION_USER",
"password": "$TRANSMISSION_PASS",
"path": "$TRANSMISSION_RPC_PATH"
},
"remoteConfig": {
"isRemote": $TRANSMISSION_REMOTE,
"directoryMapping": $TRANSMISSION_DIR_MAPPING
},
"destinationPaths": {
"movies": "$MEDIA_DIR/movies",
"tvShows": "$MEDIA_DIR/tvshows",
"music": "$MEDIA_DIR/music",
"books": "$MEDIA_DIR/books",
"magazines": "$MEDIA_DIR/magazines",
"software": "$MEDIA_DIR/software"
},
"seedingRequirements": {
"minRatio": 1.0,
"minTimeMinutes": 60,
"checkIntervalSeconds": 300
},
"processingOptions": {
"enableBookSorting": $ENABLE_BOOK_SORTING,
"extractArchives": true,
"deleteArchives": true,
"createCategoryFolders": true,
"ignoreSample": true,
"ignoreExtras": true,
"renameFiles": true,
"autoReplaceUpgrades": true,
"removeDuplicates": true,
"keepOnlyBestVersion": true
},
"rssFeeds": [],
"rssUpdateIntervalMinutes": 60,
"autoProcessing": false,
"securitySettings": {
"authEnabled": false,
"httpsEnabled": false,
"sslCertPath": "",
"sslKeyPath": "",
"users": []
},
"port": $PORT,
"logLevel": "info"
}
EOF
# Create package.json # Create package.json
echo "Creating package.json..." echo "Creating package.json..."
cat > $INSTALL_DIR/package.json << EOF cat > $INSTALL_DIR/package.json << EOF

View File

@ -21,6 +21,11 @@ function setup_service() {
exit 1 exit 1
fi fi
if [ -z "$CONFIG_DIR" ]; then
log "ERROR" "CONFIG_DIR variable is not set"
exit 1
fi
if [ -z "$PORT" ]; then if [ -z "$PORT" ]; then
log "ERROR" "PORT variable is not set" log "ERROR" "PORT variable is not set"
exit 1 exit 1
@ -71,6 +76,7 @@ Environment=PORT=$PORT
Environment=NODE_ENV=production Environment=NODE_ENV=production
Environment=DEBUG_ENABLED=false Environment=DEBUG_ENABLED=false
Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log
Environment=CONFIG_DIR=$CONFIG_DIR
EOF EOF
# Preserve the existing JWT_SECRET if available # Preserve the existing JWT_SECRET if available
@ -117,6 +123,7 @@ Environment=PORT=$PORT
Environment=NODE_ENV=production Environment=NODE_ENV=production
Environment=DEBUG_ENABLED=false Environment=DEBUG_ENABLED=false
Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log Environment=LOG_FILE=$INSTALL_DIR/logs/transmission-rss-manager.log
Environment=CONFIG_DIR=$CONFIG_DIR
# Generate a random JWT secret for security # Generate a random JWT secret for security
Environment=JWT_SECRET=$(openssl rand -hex 32) Environment=JWT_SECRET=$(openssl rand -hex 32)

View File

@ -1,6 +1,6 @@
{ {
"name": "transmission-rss-manager", "name": "transmission-rss-manager",
"version": "2.0.2", "version": "2.0.3",
"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": {

View File

@ -20,7 +20,8 @@ const TransmissionClient = require('./modules/transmission-client.js');
const PostProcessor = require('./modules/post-processor.js'); const PostProcessor = require('./modules/post-processor.js');
// Constants and configuration // Constants and configuration
const DEFAULT_CONFIG_PATH = path.join(__dirname, 'config.json'); const DEFAULT_CONFIG_PATH = '/etc/transmission-rss-manager/config.json';
const FALLBACK_CONFIG_PATH = path.join(__dirname, 'config.json');
const DEFAULT_PORT = 3000; const DEFAULT_PORT = 3000;
const JWT_SECRET = process.env.JWT_SECRET || 'transmission-rss-manager-secret'; const JWT_SECRET = process.env.JWT_SECRET || 'transmission-rss-manager-secret';
const JWT_EXPIRY = '24h'; const JWT_EXPIRY = '24h';
@ -97,6 +98,7 @@ async function loadConfig() {
// Define default configuration // Define default configuration
const defaultConfig = { const defaultConfig = {
version: APP_VERSION, // Use the version from package.json version: APP_VERSION, // Use the version from package.json
installPath: __dirname, // Store the path to the installation directory
transmissionConfig: { transmissionConfig: {
host: 'localhost', host: 'localhost',
port: 9091, port: 9091,
@ -147,8 +149,10 @@ async function loadConfig() {
logLevel: "info" logLevel: "info"
}; };
// Try primary config location first
try { try {
// Try to read existing config // Try to read existing config from primary location
console.log(`Trying to load config from: ${DEFAULT_CONFIG_PATH}`);
const configData = await fs.readFile(DEFAULT_CONFIG_PATH, 'utf8'); const configData = await fs.readFile(DEFAULT_CONFIG_PATH, 'utf8');
const loadedConfig = JSON.parse(configData); const loadedConfig = JSON.parse(configData);
@ -162,17 +166,68 @@ async function loadConfig() {
await saveConfig(mergedConfig); await saveConfig(mergedConfig);
} }
console.log(`Config loaded from ${DEFAULT_CONFIG_PATH}`);
return mergedConfig; return mergedConfig;
} catch (readError) { } catch (primaryError) {
// If file not found, create default config // If file not found in primary location, try fallback location
if (readError.code === 'ENOENT') { if (primaryError.code === 'ENOENT') {
console.log('Config file not found, creating default configuration'); console.log(`Config not found at ${DEFAULT_CONFIG_PATH}, trying fallback location...`);
await saveConfig(defaultConfig);
return defaultConfig; try {
const fallbackData = await fs.readFile(FALLBACK_CONFIG_PATH, 'utf8');
const fallbackConfig = JSON.parse(fallbackData);
// Merge configs
const mergedConfig = mergeConfigs(defaultConfig, fallbackConfig);
// If version is different, save updated config
if (fallbackConfig.version !== APP_VERSION) {
console.log(`Updating config from version ${fallbackConfig.version || 'unknown'} to ${APP_VERSION}`);
mergedConfig.version = APP_VERSION;
}
// Try to save to primary location, but don't fail if we can't
try {
// Create directory if it doesn't exist
await fs.mkdir(path.dirname(DEFAULT_CONFIG_PATH), { recursive: true });
await fs.writeFile(DEFAULT_CONFIG_PATH, JSON.stringify(mergedConfig, null, 2), 'utf8');
console.log(`Migrated config from ${FALLBACK_CONFIG_PATH} to ${DEFAULT_CONFIG_PATH}`);
} catch (saveError) {
console.warn(`Could not save config to ${DEFAULT_CONFIG_PATH}: ${saveError.message}`);
console.warn('Continuing with fallback config location');
}
console.log(`Config loaded from fallback location: ${FALLBACK_CONFIG_PATH}`);
return mergedConfig;
} catch (fallbackError) {
// If file not found in fallback location, create default config
if (fallbackError.code === 'ENOENT') {
console.log('Config file not found in either location, creating default configuration');
// Try to save to primary location first
try {
await fs.mkdir(path.dirname(DEFAULT_CONFIG_PATH), { recursive: true });
await fs.writeFile(DEFAULT_CONFIG_PATH, JSON.stringify(defaultConfig, null, 2), 'utf8');
console.log(`Created default config at ${DEFAULT_CONFIG_PATH}`);
} catch (saveError) {
console.warn(`Could not save config to ${DEFAULT_CONFIG_PATH}: ${saveError.message}`);
console.warn('Saving to fallback location instead');
// Save to fallback location instead
await fs.writeFile(FALLBACK_CONFIG_PATH, JSON.stringify(defaultConfig, null, 2), 'utf8');
console.log(`Created default config at ${FALLBACK_CONFIG_PATH}`);
}
return defaultConfig;
}
// For other errors, rethrow
throw fallbackError;
}
} }
// For other errors, rethrow // For other errors, rethrow
throw readError; throw primaryError;
} }
} catch (error) { } catch (error) {
console.error('Error loading configuration:', error); console.error('Error loading configuration:', error);
@ -231,8 +286,21 @@ function mergeConfigs(defaultConfig, userConfig) {
*/ */
async function saveConfig(config) { async function saveConfig(config) {
try { try {
await fs.writeFile(DEFAULT_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8'); // Always try to save to the primary config location first
console.log('Configuration saved'); try {
// Make sure directory exists
await fs.mkdir(path.dirname(DEFAULT_CONFIG_PATH), { recursive: true });
await fs.writeFile(DEFAULT_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
console.log(`Configuration saved to ${DEFAULT_CONFIG_PATH}`);
return;
} catch (primaryError) {
console.warn(`Could not save config to ${DEFAULT_CONFIG_PATH}: ${primaryError.message}`);
console.warn('Trying fallback location...');
// If we couldn't save to the primary location, try the fallback
await fs.writeFile(FALLBACK_CONFIG_PATH, JSON.stringify(config, null, 2), 'utf8');
console.log(`Configuration saved to fallback location: ${FALLBACK_CONFIG_PATH}`);
}
} catch (error) { } catch (error) {
console.error('Error saving configuration:', error); console.error('Error saving configuration:', error);
throw error; throw error;