btg-sandbox-video-upscaler/cleanup.php
DJP d49ecf1527 Add automatic file cleanup for uploads directory
- Created FileCleanup utility class to manage old upload files
- Automatically removes files older than 24 hours on each request
- Added cleanup calls to both estimate.php and uploader.php processes
- Includes detailed logging and statistics for cleanup operations
- Provides formatBytes utility for human-readable file size reporting
- Includes directory statistics functionality for monitoring

This prevents the uploads directory from growing indefinitely and ensures
proper disk space management for the video processing system.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-17 14:43:03 -04:00

180 lines
No EOL
6.4 KiB
PHP

<?php
require_once 'logger.php';
class FileCleanup {
/**
* Clean up files older than specified hours in the uploads directory
*
* @param int $hoursOld Files older than this many hours will be deleted
* @param string $uploadsDir Path to uploads directory
* @return array Statistics about the cleanup operation
*/
public static function cleanupOldFiles($hoursOld = 24, $uploadsDir = 'uploads/') {
$stats = [
'files_deleted' => 0,
'files_failed' => 0,
'bytes_freed' => 0,
'errors' => []
];
try {
// Ensure uploads directory exists
if (!is_dir($uploadsDir)) {
Logger::log("Uploads directory does not exist: $uploadsDir", 'WARN');
return $stats;
}
// Calculate cutoff time (24 hours ago by default)
$cutoffTime = time() - ($hoursOld * 3600);
Logger::log("Starting cleanup of files older than $hoursOld hours (before " . date('Y-m-d H:i:s', $cutoffTime) . ")");
// Get all files in uploads directory
$files = glob($uploadsDir . '*');
if ($files === false) {
Logger::log("Failed to read uploads directory: $uploadsDir", 'ERROR');
return $stats;
}
$totalFiles = 0;
$oldFiles = 0;
foreach ($files as $file) {
// Skip directories and special files
if (is_dir($file) || basename($file) === '.gitkeep' || basename($file) === '.htaccess') {
continue;
}
$totalFiles++;
$fileModTime = filemtime($file);
if ($fileModTime === false) {
Logger::log("Could not get modification time for file: $file", 'WARN');
$stats['errors'][] = "Could not get modification time for: " . basename($file);
continue;
}
// If file is older than cutoff time, delete it
if ($fileModTime < $cutoffTime) {
$oldFiles++;
$fileSize = filesize($file);
if (unlink($file)) {
$stats['files_deleted']++;
if ($fileSize !== false) {
$stats['bytes_freed'] += $fileSize;
}
Logger::log("Deleted old file: " . basename($file) . " (age: " .
round((time() - $fileModTime) / 3600, 1) . " hours)");
} else {
$stats['files_failed']++;
$error = "Failed to delete: " . basename($file);
$stats['errors'][] = $error;
Logger::log($error, 'ERROR');
}
}
}
// Log cleanup summary
$summary = "Cleanup completed - Total files: $totalFiles, Old files: $oldFiles, " .
"Deleted: {$stats['files_deleted']}, Failed: {$stats['files_failed']}, " .
"Space freed: " . self::formatBytes($stats['bytes_freed']);
Logger::log($summary);
} catch (Exception $e) {
Logger::log("Error during file cleanup: " . $e->getMessage(), 'ERROR');
$stats['errors'][] = $e->getMessage();
}
return $stats;
}
/**
* Format bytes into human readable format
*
* @param int $bytes
* @return string
*/
public static function formatBytes($bytes) {
if ($bytes == 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB'];
$pow = floor(log($bytes, 1024));
$pow = min($pow, count($units) - 1);
return round($bytes / (1024 ** $pow), 2) . ' ' . $units[$pow];
}
/**
* Get statistics about the uploads directory
*
* @param string $uploadsDir Path to uploads directory
* @return array Directory statistics
*/
public static function getDirectoryStats($uploadsDir = 'uploads/') {
$stats = [
'total_files' => 0,
'total_size' => 0,
'oldest_file' => null,
'newest_file' => null,
'files_over_24h' => 0
];
try {
if (!is_dir($uploadsDir)) {
return $stats;
}
$files = glob($uploadsDir . '*');
if ($files === false) {
return $stats;
}
$cutoffTime = time() - (24 * 3600);
$oldestTime = PHP_INT_MAX;
$newestTime = 0;
foreach ($files as $file) {
if (is_dir($file) || basename($file) === '.gitkeep' || basename($file) === '.htaccess') {
continue;
}
$stats['total_files']++;
$fileSize = filesize($file);
$fileTime = filemtime($file);
if ($fileSize !== false) {
$stats['total_size'] += $fileSize;
}
if ($fileTime !== false) {
if ($fileTime < $cutoffTime) {
$stats['files_over_24h']++;
}
if ($fileTime < $oldestTime) {
$oldestTime = $fileTime;
$stats['oldest_file'] = [
'name' => basename($file),
'age_hours' => round((time() - $fileTime) / 3600, 1)
];
}
if ($fileTime > $newestTime) {
$newestTime = $fileTime;
$stats['newest_file'] = [
'name' => basename($file),
'age_hours' => round((time() - $fileTime) / 3600, 1)
];
}
}
}
} catch (Exception $e) {
Logger::log("Error getting directory stats: " . $e->getMessage(), 'ERROR');
}
return $stats;
}
}
?>