Skip to main content
Glama
joelmnz

Article Manager MCP Server

by joelmnz
backup-automation.ps111 kB
# Automated backup script for Article Manager PostgreSQL database (PowerShell/Windows) # This script can be run manually or scheduled via Task Scheduler for regular backups param( [string]$Command = "backup", [string]$BackupDir = "./backups", [int]$RetentionDays = 30, [bool]$CompressBackups = $true, [string]$BackupPrefix = "article-manager" ) $ErrorActionPreference = "Stop" # Database configuration from environment $DbHost = $env:DB_HOST ?? "localhost" $DbPort = $env:DB_PORT ?? "5432" $DbName = $env:DB_NAME ?? "article_manager" $DbUser = $env:DB_USER ?? "article_user" $DbPassword = $env:DB_PASSWORD ?? $env:PGPASSWORD # Logging functions function Write-Log { param([string]$Message) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" Write-Host "[$timestamp] $Message" -ForegroundColor Blue } function Write-Error-Log { param([string]$Message) Write-Host "[ERROR] $Message" -ForegroundColor Red } function Write-Success { param([string]$Message) Write-Host "[SUCCESS] $Message" -ForegroundColor Green } function Write-Warning-Log { param([string]$Message) Write-Host "[WARNING] $Message" -ForegroundColor Yellow } # Check if required tools are available function Test-Dependencies { $missingTools = @() try { $null = Get-Command pg_dump -ErrorAction Stop } catch { $missingTools += "pg_dump" } if ($CompressBackups) { try { $null = Get-Command 7z -ErrorAction SilentlyContinue if (-not $?) { # Try built-in Compress-Archive as fallback try { $null = Get-Command Compress-Archive -ErrorAction Stop } catch { $missingTools += "7z or Compress-Archive" } } } catch { $missingTools += "7z" } } if ($missingTools.Count -gt 0) { Write-Error-Log "Missing required tools: $($missingTools -join ', ')" Write-Error-Log "Please install PostgreSQL client tools and 7-Zip (optional for compression)" exit 1 } } # Create backup directory if it doesn't exist function Initialize-BackupDirectory { if (-not (Test-Path $BackupDir)) { Write-Log "Creating backup directory: $BackupDir" New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null } # Test if directory is writable $testFile = Join-Path $BackupDir "test_write.tmp" try { "test" | Out-File -FilePath $testFile -ErrorAction Stop Remove-Item $testFile -ErrorAction SilentlyContinue } catch { Write-Error-Log "Backup directory is not writable: $BackupDir" exit 1 } } # Generate backup filename with timestamp function Get-BackupFilename { $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $filename = "${BackupPrefix}_${timestamp}.sql" if ($CompressBackups) { $filename += ".zip" } return Join-Path $BackupDir $filename } # Create database backup function New-DatabaseBackup { param([string]$BackupFile) $tempFile = "$BackupFile.tmp" Write-Log "Creating database backup..." Write-Log "Database: ${DbHost}:${DbPort}/${DbName}" Write-Log "Output: $BackupFile" try { # Set password environment variable $env:PGPASSWORD = $DbPassword # Build pg_dump arguments $pgDumpArgs = @( "--host=$DbHost", "--port=$DbPort", "--username=$DbUser", "--dbname=$DbName", "--verbose", "--no-password", "--format=plain", "--no-privileges", "--no-owner" ) # Execute backup if ($CompressBackups) { # Create uncompressed backup first $sqlFile = $tempFile -replace '\.zip$', '' & pg_dump @pgDumpArgs --file="$sqlFile" if ($LASTEXITCODE -ne 0) { throw "pg_dump failed with exit code $LASTEXITCODE" } # Compress the backup if (Get-Command 7z -ErrorAction SilentlyContinue) { & 7z a "$tempFile" "$sqlFile" | Out-Null Remove-Item "$sqlFile" -ErrorAction SilentlyContinue } else { Compress-Archive -Path "$sqlFile" -DestinationPath "$tempFile" Remove-Item "$sqlFile" -ErrorAction SilentlyContinue } } else { & pg_dump @pgDumpArgs --file="$tempFile" if ($LASTEXITCODE -ne 0) { throw "pg_dump failed with exit code $LASTEXITCODE" } } # Move temp file to final location Move-Item $tempFile $BackupFile # Verify backup file was created and has content if (-not (Test-Path $BackupFile) -or (Get-Item $BackupFile).Length -eq 0) { throw "Backup file is empty or was not created" } $fileSize = [math]::Round((Get-Item $BackupFile).Length / 1MB, 2) Write-Success "Backup created successfully: $BackupFile ($fileSize MB)" return $true } catch { Write-Error-Log "Backup failed: $($_.Exception.Message)" Remove-Item $tempFile -ErrorAction SilentlyContinue return $false } finally { # Clear password from environment $env:PGPASSWORD = $null } } # Clean up old backups based on retention policy function Remove-OldBackups { Write-Log "Cleaning up backups older than $RetentionDays days..." $cutoffDate = (Get-Date).AddDays(-$RetentionDays) $deletedCount = 0 Get-ChildItem -Path $BackupDir -Filter "${BackupPrefix}_*.sql*" | Where-Object { $_.LastWriteTime -lt $cutoffDate } | ForEach-Object { Write-Log "Deleting old backup: $($_.Name)" Remove-Item $_.FullName -Force $deletedCount++ } if ($deletedCount -gt 0) { Write-Success "Deleted $deletedCount old backup(s)" } else { Write-Log "No old backups to clean up" } } # List existing backups function Show-Backups { Write-Log "Existing backups in $BackupDir:" $backupFiles = Get-ChildItem -Path $BackupDir -Filter "${BackupPrefix}_*.sql*" | Sort-Object LastWriteTime if ($backupFiles.Count -eq 0) { Write-Log "No backups found" return } foreach ($file in $backupFiles) { $size = [math]::Round($file.Length / 1MB, 2) $date = $file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") Write-Log " $($file.Name) - $size MB - $date" } } # Verify database connectivity before backup function Test-DatabaseConnection { Write-Log "Verifying database connection..." try { $env:PGPASSWORD = $DbPassword & pg_isready -h $DbHost -p $DbPort -U $DbUser -d $DbName | Out-Null if ($LASTEXITCODE -ne 0) { throw "pg_isready failed" } Write-Success "Database connection verified" return $true } catch { Write-Error-Log "Cannot connect to database: ${DbHost}:${DbPort}/${DbName}" Write-Error-Log "Please check database configuration and ensure it's running" return $false } finally { $env:PGPASSWORD = $null } } # Main backup function function Invoke-Backup { $backupFile = Get-BackupFilename if (New-DatabaseBackup -BackupFile $backupFile) { Remove-OldBackups return $true } else { return $false } } # Show usage information function Show-Usage { Write-Host "Article Manager Database Backup Automation (PowerShell)" -ForegroundColor Magenta Write-Host "Usage: .\backup-automation.ps1 [-Command <command>] [options]" -ForegroundColor White Write-Host "" Write-Host "Commands:" -ForegroundColor Cyan Write-Host " backup Create a new database backup (default)" -ForegroundColor White Write-Host " list List existing backups" -ForegroundColor White Write-Host " cleanup Clean up old backups only" -ForegroundColor White Write-Host " verify Verify database connection" -ForegroundColor White Write-Host "" Write-Host "Parameters:" -ForegroundColor Cyan Write-Host " -BackupDir Backup directory (default: ./backups)" -ForegroundColor White Write-Host " -RetentionDays Days to keep backups (default: 30)" -ForegroundColor White Write-Host " -CompressBackups Compress backups with zip (default: true)" -ForegroundColor White Write-Host " -BackupPrefix Backup filename prefix (default: article-manager)" -ForegroundColor White Write-Host "" Write-Host "Environment Variables:" -ForegroundColor Cyan Write-Host " DB_HOST Database host (default: localhost)" -ForegroundColor White Write-Host " DB_PORT Database port (default: 5432)" -ForegroundColor White Write-Host " DB_NAME Database name (default: article_manager)" -ForegroundColor White Write-Host " DB_USER Database user (default: article_user)" -ForegroundColor White Write-Host " DB_PASSWORD Database password (required)" -ForegroundColor White Write-Host "" Write-Host "Examples:" -ForegroundColor Cyan Write-Host " .\backup-automation.ps1 # Create backup" -ForegroundColor White Write-Host " .\backup-automation.ps1 -Command list # List backups" -ForegroundColor White Write-Host " .\backup-automation.ps1 -Command cleanup -RetentionDays 7 # Clean old backups" -ForegroundColor White } # Main script logic function Main { switch ($Command.ToLower()) { "backup" { Test-Dependencies Initialize-BackupDirectory if (Test-DatabaseConnection) { Invoke-Backup Show-Backups } else { exit 1 } } "list" { Initialize-BackupDirectory Show-Backups } "cleanup" { Initialize-BackupDirectory Remove-OldBackups } "verify" { if (-not (Test-DatabaseConnection)) { exit 1 } } "help" { Show-Usage } default { Write-Error-Log "Unknown command: $Command" Show-Usage exit 1 } } } # Handle script interruption trap { Write-Host "" Write-Error-Log "Backup interrupted" exit 1 } # Check for required environment variables if (-not $DbPassword) { Write-Error-Log "Database password not set. Please set DB_PASSWORD environment variable" exit 1 } # Run main function try { Main } catch { Write-Error-Log "Script failed: $($_.Exception.Message)" exit 1 }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/joelmnz/mcp-markdown-manager'

If you have feedback or need assistance with the MCP directory API, please join our Discord server