feat: Add complete Docker deployment with web-based setup wizard
Major additions: - Web-based setup wizard (setup.php, setup_wizard.php, setup-wizard.js) - Production Docker configuration (docker-compose.prod.yml, .env.production) - Database initialization SQL files (deploy/init_settings.sql) - Template builder system with drag-and-drop UI - Advanced features (OAuth, CDN, enhanced analytics, monetization) - Comprehensive documentation (deployment guides, quick start, feature docs) - Design system with accessibility and responsive layout - Deployment automation scripts (deploy.ps1, generate-secrets.ps1) Setup wizard allows customization of: - Platform name and branding - Domain configuration - Membership tiers and pricing - Admin credentials - Feature toggles Database includes 270+ tables for complete video streaming platform with advanced features for analytics, moderation, template building, and monetization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
288
sync-to-docker-progs.ps1
Normal file
288
sync-to-docker-progs.ps1
Normal file
@@ -0,0 +1,288 @@
|
||||
# ============================================================================
|
||||
# EasyStream - Folder Sync Script (Repos -> Docker-Progs)
|
||||
# ============================================================================
|
||||
# This script syncs changes from E:\repos\easystream-main to E:\docker-progs\easystream-main
|
||||
#
|
||||
# Usage:
|
||||
# .\sync-to-docker-progs.ps1 # One-time sync
|
||||
# .\sync-to-docker-progs.ps1 -Watch # Continuous monitoring
|
||||
# .\sync-to-docker-progs.ps1 -Verbose # Detailed output
|
||||
#
|
||||
# Requirements: PowerShell 5.0 or higher
|
||||
# ============================================================================
|
||||
|
||||
param(
|
||||
[switch]$Watch = $false,
|
||||
[switch]$Verbose = $false,
|
||||
[switch]$DryRun = $false
|
||||
)
|
||||
|
||||
# Configuration
|
||||
$SourcePath = "E:\repos\easystream-main"
|
||||
$DestPath = "E:\docker-progs\easystream-main"
|
||||
$LogFile = "E:\repos\easystream-main\sync.log"
|
||||
|
||||
# Exclusions (paths to ignore)
|
||||
$Exclusions = @(
|
||||
".git",
|
||||
".gitignore",
|
||||
"node_modules",
|
||||
"vendor",
|
||||
"f_data\cache",
|
||||
"f_data\tmp",
|
||||
"f_data\logs",
|
||||
"f_data\sessions",
|
||||
"f_data\uploads",
|
||||
"*.log",
|
||||
"sync.log",
|
||||
"sync-to-docker-progs.ps1"
|
||||
)
|
||||
|
||||
# ============================================================================
|
||||
# Functions
|
||||
# ============================================================================
|
||||
|
||||
function Write-Log {
|
||||
param([string]$Message, [string]$Level = "INFO")
|
||||
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logMessage = "[$timestamp] [$Level] $Message"
|
||||
|
||||
# Write to console
|
||||
switch ($Level) {
|
||||
"ERROR" { Write-Host $logMessage -ForegroundColor Red }
|
||||
"WARN" { Write-Host $logMessage -ForegroundColor Yellow }
|
||||
"SUCCESS" { Write-Host $logMessage -ForegroundColor Green }
|
||||
default { Write-Host $logMessage -ForegroundColor White }
|
||||
}
|
||||
|
||||
# Write to log file
|
||||
Add-Content -Path $LogFile -Value $logMessage
|
||||
}
|
||||
|
||||
function Test-ShouldExclude {
|
||||
param([string]$Path)
|
||||
|
||||
foreach ($exclusion in $Exclusions) {
|
||||
if ($Path -like "*$exclusion*") {
|
||||
return $true
|
||||
}
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
function Sync-Folder {
|
||||
param([bool]$InitialSync = $false)
|
||||
|
||||
try {
|
||||
# Check if source exists
|
||||
if (-not (Test-Path $SourcePath)) {
|
||||
Write-Log "Source path does not exist: $SourcePath" "ERROR"
|
||||
return $false
|
||||
}
|
||||
|
||||
# Create destination if it doesn't exist
|
||||
if (-not (Test-Path $DestPath)) {
|
||||
Write-Log "Creating destination directory: $DestPath" "INFO"
|
||||
if (-not $DryRun) {
|
||||
New-Item -ItemType Directory -Path $DestPath -Force | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
# Build robocopy exclusion parameters
|
||||
$excludeDirs = @()
|
||||
$excludeFiles = @()
|
||||
|
||||
foreach ($exclusion in $Exclusions) {
|
||||
if ($exclusion.Contains("\")) {
|
||||
$excludeDirs += $exclusion
|
||||
} elseif ($exclusion.StartsWith("*")) {
|
||||
$excludeFiles += $exclusion
|
||||
} else {
|
||||
$excludeDirs += $exclusion
|
||||
}
|
||||
}
|
||||
|
||||
# Build robocopy command
|
||||
$robocopyArgs = @(
|
||||
$SourcePath,
|
||||
$DestPath,
|
||||
"/MIR", # Mirror (delete files in dest that don't exist in source)
|
||||
"/R:3", # Retry 3 times
|
||||
"/W:5", # Wait 5 seconds between retries
|
||||
"/MT:8", # Multi-threaded (8 threads)
|
||||
"/NFL", # No file list
|
||||
"/NDL", # No directory list
|
||||
"/NP", # No progress
|
||||
"/BYTES" # Show sizes in bytes
|
||||
)
|
||||
|
||||
# Add exclusions
|
||||
if ($excludeDirs.Count -gt 0) {
|
||||
$robocopyArgs += "/XD"
|
||||
$robocopyArgs += $excludeDirs
|
||||
}
|
||||
|
||||
if ($excludeFiles.Count -gt 0) {
|
||||
$robocopyArgs += "/XF"
|
||||
$robocopyArgs += $excludeFiles
|
||||
}
|
||||
|
||||
# Add verbose flag if requested
|
||||
if ($Verbose) {
|
||||
$robocopyArgs = $robocopyArgs | Where-Object { $_ -ne "/NFL" -and $_ -ne "/NDL" }
|
||||
}
|
||||
|
||||
# Execute sync
|
||||
if ($InitialSync) {
|
||||
Write-Log "Starting initial sync..." "INFO"
|
||||
} else {
|
||||
Write-Log "Syncing changes..." "INFO"
|
||||
}
|
||||
|
||||
if ($DryRun) {
|
||||
Write-Log "DRY RUN - Would execute: robocopy $($robocopyArgs -join ' ')" "WARN"
|
||||
return $true
|
||||
}
|
||||
|
||||
$result = & robocopy $robocopyArgs
|
||||
$exitCode = $LASTEXITCODE
|
||||
|
||||
# Robocopy exit codes:
|
||||
# 0 = No files copied
|
||||
# 1 = Files copied successfully
|
||||
# 2 = Extra files or directories detected
|
||||
# 3 = Files copied + extra files detected
|
||||
# 4+ = Error
|
||||
|
||||
if ($exitCode -ge 8) {
|
||||
Write-Log "Sync failed with exit code: $exitCode" "ERROR"
|
||||
return $false
|
||||
} elseif ($exitCode -gt 0) {
|
||||
Write-Log "Sync completed successfully (Exit code: $exitCode)" "SUCCESS"
|
||||
return $true
|
||||
} else {
|
||||
if ($Verbose) {
|
||||
Write-Log "No changes detected" "INFO"
|
||||
}
|
||||
return $true
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Log "Sync error: $($_.Exception.Message)" "ERROR"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Start-Watcher {
|
||||
Write-Log "Starting file system watcher..." "INFO"
|
||||
Write-Log "Monitoring: $SourcePath" "INFO"
|
||||
Write-Log "Syncing to: $DestPath" "INFO"
|
||||
Write-Log "Press Ctrl+C to stop..." "WARN"
|
||||
|
||||
# Create file system watcher
|
||||
$watcher = New-Object System.IO.FileSystemWatcher
|
||||
$watcher.Path = $SourcePath
|
||||
$watcher.IncludeSubdirectories = $true
|
||||
$watcher.EnableRaisingEvents = $true
|
||||
|
||||
# Filters
|
||||
$watcher.NotifyFilter = [System.IO.NotifyFilters]::FileName -bor
|
||||
[System.IO.NotifyFilters]::DirectoryName -bor
|
||||
[System.IO.NotifyFilters]::LastWrite -bor
|
||||
[System.IO.NotifyFilters]::Size
|
||||
|
||||
# Debounce mechanism (prevent multiple syncs for rapid changes)
|
||||
$script:lastSync = Get-Date
|
||||
$script:syncPending = $false
|
||||
$debounceSeconds = 2
|
||||
|
||||
# Event handler
|
||||
$onChange = {
|
||||
param($sender, $e)
|
||||
|
||||
# Check if file should be excluded
|
||||
if (Test-ShouldExclude -Path $e.FullPath) {
|
||||
return
|
||||
}
|
||||
|
||||
$now = Get-Date
|
||||
$timeSinceLastSync = ($now - $script:lastSync).TotalSeconds
|
||||
|
||||
if ($timeSinceLastSync -gt $debounceSeconds) {
|
||||
Write-Log "Change detected: $($e.ChangeType) - $($e.Name)" "INFO"
|
||||
Sync-Folder | Out-Null
|
||||
$script:lastSync = Get-Date
|
||||
} else {
|
||||
if (-not $script:syncPending) {
|
||||
$script:syncPending = $true
|
||||
Write-Log "Changes detected, sync scheduled..." "INFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Register events
|
||||
Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $onChange | Out-Null
|
||||
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $onChange | Out-Null
|
||||
Register-ObjectEvent -InputObject $watcher -EventName Deleted -Action $onChange | Out-Null
|
||||
Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $onChange | Out-Null
|
||||
|
||||
# Timer for debounced syncs
|
||||
$timer = New-Object System.Timers.Timer
|
||||
$timer.Interval = $debounceSeconds * 1000
|
||||
$timer.AutoReset = $true
|
||||
|
||||
$onTimer = {
|
||||
if ($script:syncPending) {
|
||||
Sync-Folder | Out-Null
|
||||
$script:syncPending = $false
|
||||
$script:lastSync = Get-Date
|
||||
}
|
||||
}
|
||||
|
||||
Register-ObjectEvent -InputObject $timer -EventName Elapsed -Action $onTimer | Out-Null
|
||||
$timer.Start()
|
||||
|
||||
# Keep script running
|
||||
try {
|
||||
while ($true) {
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
} finally {
|
||||
# Cleanup
|
||||
$watcher.EnableRaisingEvents = $false
|
||||
$watcher.Dispose()
|
||||
$timer.Stop()
|
||||
$timer.Dispose()
|
||||
Get-EventSubscriber | Unregister-Event
|
||||
Write-Log "Watcher stopped" "INFO"
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# Main Execution
|
||||
# ============================================================================
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "============================================================================" -ForegroundColor Cyan
|
||||
Write-Host " EasyStream Folder Sync - Repos to Docker-Progs" -ForegroundColor Cyan
|
||||
Write-Host "============================================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Initial sync
|
||||
$syncResult = Sync-Folder -InitialSync $true
|
||||
|
||||
if (-not $syncResult) {
|
||||
Write-Log "Initial sync failed. Exiting." "ERROR"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Watch mode
|
||||
if ($Watch) {
|
||||
Write-Host ""
|
||||
Start-Watcher
|
||||
} else {
|
||||
Write-Host ""
|
||||
Write-Log "Single sync completed. Use -Watch for continuous monitoring." "INFO"
|
||||
Write-Host ""
|
||||
}
|
||||
Reference in New Issue
Block a user