- 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>
153 lines
No EOL
5.8 KiB
PHP
153 lines
No EOL
5.8 KiB
PHP
<?php
|
|
require_once 'cleanup.php';
|
|
|
|
// Prevent duplicate class definition
|
|
if (!class_exists('VideoUploader')) {
|
|
class VideoUploader {
|
|
private $apiClient;
|
|
|
|
public function __construct($apiClient) {
|
|
$this->apiClient = $apiClient;
|
|
}
|
|
|
|
public function processUpload($file) {
|
|
// Clean up old files first (older than 24 hours)
|
|
Logger::log('Starting automatic cleanup of old upload files');
|
|
$cleanupStats = FileCleanup::cleanupOldFiles(24, 'uploads/');
|
|
if ($cleanupStats['files_deleted'] > 0) {
|
|
Logger::log("Cleanup completed: {$cleanupStats['files_deleted']} old files removed, " .
|
|
FileCleanup::formatBytes($cleanupStats['bytes_freed']) . " freed");
|
|
}
|
|
|
|
Logger::log('Starting video upload process');
|
|
Logger::log('File info: ' . print_r($file, true));
|
|
|
|
if (!isset($file['tmp_name']) || !file_exists($file['tmp_name'])) {
|
|
throw new Exception('Invalid file data or file not found');
|
|
}
|
|
|
|
// Get video information from session
|
|
if (!isset($_SESSION['video_request']['info'])) {
|
|
throw new Exception('Video request information not found in session');
|
|
}
|
|
$videoInfo = $_SESSION['video_request']['info'];
|
|
Logger::log('Using video info: ' . json_encode($videoInfo));
|
|
|
|
// Accept the request and get upload URLs
|
|
$requestId = $_SESSION['video_request']['requestId'] ?? null;
|
|
if (!$requestId) {
|
|
throw new Exception('Request ID not found in session');
|
|
}
|
|
|
|
Logger::log("Accepting request ID: $requestId");
|
|
$acceptResponse = $this->apiClient->acceptVideoRequest($requestId);
|
|
Logger::log('Accept response: ' . json_encode($acceptResponse));
|
|
|
|
if (!isset($acceptResponse['urls']) || !is_array($acceptResponse['urls'])) {
|
|
throw new Exception('Invalid upload URLs received from API');
|
|
}
|
|
|
|
$uploadUrls = $acceptResponse['urls'];
|
|
$uploadId = $acceptResponse['uploadId'] ?? null;
|
|
|
|
// Upload file parts
|
|
$uploadResults = $this->uploadParts($file, $uploadUrls);
|
|
|
|
// Complete the upload
|
|
$this->apiClient->completeUpload($requestId, $uploadResults);
|
|
Logger::log('Upload completed successfully');
|
|
|
|
return $requestId;
|
|
}
|
|
|
|
private function uploadParts($file, $urls) {
|
|
$results = [];
|
|
$fileSize = filesize($file['tmp_name']);
|
|
$partSize = ceil($fileSize / count($urls));
|
|
|
|
Logger::log("Uploading file parts. Total size: $fileSize, Part size: $partSize");
|
|
|
|
foreach ($urls as $index => $url) {
|
|
$partNum = $index + 1;
|
|
$start = $index * $partSize;
|
|
$length = min($partSize, $fileSize - $start);
|
|
|
|
Logger::log("Uploading part $partNum. Start: $start, Length: $length");
|
|
|
|
// Upload the part and get ETag
|
|
$eTag = $this->uploadFilePart($file['tmp_name'], $url, $start, $length);
|
|
|
|
$results[] = [
|
|
'partNum' => $partNum,
|
|
'eTag' => $eTag
|
|
];
|
|
|
|
Logger::log("Uploaded part $partNum with ETag: $eTag");
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
private function uploadFilePart($filePath, $url, $start, $length) {
|
|
Logger::log("Uploading file part to URL: $url");
|
|
|
|
$handle = fopen($filePath, 'rb');
|
|
if (!$handle) {
|
|
throw new Exception('Could not open file for reading');
|
|
}
|
|
|
|
// Seek to the start position
|
|
fseek($handle, $start);
|
|
|
|
// Read the chunk
|
|
$data = fread($handle, $length);
|
|
fclose($handle);
|
|
|
|
if ($data === false) {
|
|
throw new Exception('Failed to read file chunk');
|
|
}
|
|
|
|
// Create curl handle
|
|
$ch = curl_init($url);
|
|
|
|
// Setup curl options
|
|
curl_setopt_array($ch, [
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => $data,
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_HEADER => true,
|
|
CURLOPT_NOBODY => false,
|
|
CURLOPT_HTTPHEADER => [
|
|
'Content-Type: application/octet-stream',
|
|
'Content-Length: ' . strlen($data)
|
|
]
|
|
]);
|
|
|
|
// Execute the request
|
|
$response = curl_exec($ch);
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
if ($httpCode !== 200) {
|
|
Logger::log("Upload failed with HTTP code $httpCode. Response: $response", 'ERROR');
|
|
throw new Exception("Failed to upload file part. HTTP Code: $httpCode");
|
|
}
|
|
|
|
// Extract ETag from headers
|
|
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
|
$headers = substr($response, 0, $headerSize);
|
|
|
|
preg_match('/ETag: "(.*?)"/', $headers, $matches);
|
|
$eTag = $matches[1] ?? null;
|
|
|
|
curl_close($ch);
|
|
|
|
if (!$eTag) {
|
|
throw new Exception('No ETag received from upload');
|
|
}
|
|
|
|
Logger::log("Successfully uploaded part. ETag: $eTag");
|
|
return $eTag;
|
|
}
|
|
}
|
|
}
|
|
?>
|