mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
first commit
This commit is contained in:
257
app/Services/XbvrSyncService.php
Normal file
257
app/Services/XbvrSyncService.php
Normal file
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Utils\ImageDownloader;
|
||||
use App\Models\AdultVideo;
|
||||
use GuzzleHttp\Client;
|
||||
use Exception;
|
||||
|
||||
class XbvrSyncService extends BaseSyncService
|
||||
{
|
||||
private Client $httpClient;
|
||||
private ?string $apiKey;
|
||||
private string $baseUrl;
|
||||
private ImageDownloader $imageDownloader;
|
||||
private int $processedCount = 0;
|
||||
private int $newCount = 0;
|
||||
private int $updatedCount = 0;
|
||||
|
||||
public function __construct(\PDO $pdo, array $source)
|
||||
{
|
||||
parent::__construct($pdo, $source);
|
||||
$this->httpClient = new Client([
|
||||
'timeout' => 30,
|
||||
'headers' => [
|
||||
'User-Agent' => 'MediaCollector/1.0',
|
||||
'X-API-Key' => $source['api_key']
|
||||
]
|
||||
]);
|
||||
$this->apiKey = $source['api_key'];
|
||||
$this->baseUrl = rtrim($source['api_url'], '/');
|
||||
$this->imageDownloader = new ImageDownloader();
|
||||
}
|
||||
|
||||
protected function executeSync(string $syncType): void
|
||||
{
|
||||
if (empty($this->apiKey) || empty($this->baseUrl)) {
|
||||
throw new Exception('XBVR API key and URL not configured');
|
||||
}
|
||||
|
||||
$this->logProgress('Starting XBVR library sync...');
|
||||
|
||||
// Sync VR scenes
|
||||
$this->syncScenes();
|
||||
|
||||
$this->logProgress("Processed {$this->processedCount} XBVR items");
|
||||
}
|
||||
|
||||
private function syncScenes(): void
|
||||
{
|
||||
try {
|
||||
$scenes = $this->getXbvrScenes();
|
||||
|
||||
foreach ($scenes as $sceneData) {
|
||||
$this->syncScene($sceneData);
|
||||
$this->processedCount++;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->logProgress('Error syncing XBVR scenes: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function getXbvrScenes(): array
|
||||
{
|
||||
try {
|
||||
// XBVR API endpoint for scenes
|
||||
$response = $this->httpClient->get("{$this->baseUrl}/api/scene");
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
|
||||
if (!isset($data['scenes'])) {
|
||||
throw new Exception('No scenes found in XBVR');
|
||||
}
|
||||
|
||||
return $data['scenes'];
|
||||
} catch (Exception $e) {
|
||||
throw new Exception('Failed to fetch XBVR scenes: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function syncScene(array $sceneData): void
|
||||
{
|
||||
$adultVideoModel = new AdultVideo($this->pdo);
|
||||
|
||||
// Check if scene already exists by xbvr_id in metadata
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT id, metadata FROM adult_videos
|
||||
WHERE source_id = :source_id
|
||||
");
|
||||
$stmt->execute(['source_id' => $this->source['id']]);
|
||||
$existingScenes = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
$existingScene = null;
|
||||
foreach ($existingScenes as $scene) {
|
||||
$metadata = json_decode($scene['metadata'], true);
|
||||
if (isset($metadata['xbvr_id']) && $metadata['xbvr_id'] === $sceneData['id']) {
|
||||
$existingScene = $scene;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function syncScene(array $sceneData): void
|
||||
{
|
||||
$adultVideoModel = new AdultVideo($this->pdo);
|
||||
|
||||
// Check if scene already exists by xbvr_id in metadata
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT id, metadata FROM adult_videos
|
||||
WHERE source_id = :source_id
|
||||
");
|
||||
$stmt->execute(['source_id' => $this->source['id']]);
|
||||
$existingScenes = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
$existingScene = null;
|
||||
foreach ($existingScenes as $scene) {
|
||||
$metadata = json_decode($scene['metadata'], true);
|
||||
if (isset($metadata['xbvr_id']) && $metadata['xbvr_id'] === $sceneData['id']) {
|
||||
$existingScene = $scene;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Download images locally
|
||||
$coverFilename = null;
|
||||
$screenshotFilename = null;
|
||||
|
||||
if (!empty($sceneData['cover_url'])) {
|
||||
$coverFilename = $this->imageDownloader->generateFilename($sceneData['cover_url'], 'cover');
|
||||
$localCoverPath = $this->imageDownloader->downloadImage($sceneData['cover_url'], $coverFilename, 'adult_videos');
|
||||
if ($localCoverPath) {
|
||||
$sceneData['local_cover_path'] = $this->imageDownloader->getPublicUrl($localCoverPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($sceneData['screenshot_url'])) {
|
||||
$screenshotFilename = $this->imageDownloader->generateFilename($sceneData['screenshot_url'], 'screenshot');
|
||||
$localScreenshotPath = $this->imageDownloader->downloadImage($sceneData['screenshot_url'], $screenshotFilename, 'adult_videos');
|
||||
if ($localScreenshotPath) {
|
||||
$sceneData['local_screenshot_path'] = $this->imageDownloader->getPublicUrl($localScreenshotPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle actors
|
||||
$actors = $this->syncActors($sceneData['cast'] ?? []);
|
||||
|
||||
$sceneData = [
|
||||
'title' => $sceneData['title'] ?: 'Untitled VR Scene',
|
||||
'overview' => $sceneData['synopsis'] ?? null,
|
||||
'release_date' => $sceneData['release_date'] ? date('Y-m-d', strtotime($sceneData['release_date'])) : null,
|
||||
'runtime_minutes' => $sceneData['duration'] ?? null,
|
||||
'rating' => $sceneData['rating'] ?? null,
|
||||
'source_id' => $this->source['id'],
|
||||
'external_id' => $sceneData['id'],
|
||||
'metadata' => json_encode([
|
||||
'xbvr_id' => $sceneData['id'],
|
||||
'xbvr_url' => $sceneData['scene_url'] ?? null,
|
||||
'cast' => $sceneData['cast'] ?? [],
|
||||
'actors' => $actors,
|
||||
'tags' => $sceneData['tags'] ?? [],
|
||||
'is_available' => $sceneData['is_available'] ?? true,
|
||||
'is_watched' => $sceneData['is_watched'] ?? false,
|
||||
'watch_count' => $sceneData['watch_count'] ?? 0,
|
||||
'video_length' => $sceneData['video_length'] ?? null,
|
||||
'video_width' => $sceneData['video_width'] ?? null,
|
||||
'video_height' => $sceneData['video_height'] ?? null,
|
||||
'video_codec' => $sceneData['video_codec'] ?? null,
|
||||
'file_path' => $sceneData['file_path'] ?? null,
|
||||
'cover_url' => $sceneData['cover_url'] ?? null,
|
||||
'local_cover_path' => $sceneData['local_cover_path'] ?? null,
|
||||
'screenshot_url' => $sceneData['screenshot_url'] ?? null,
|
||||
'local_screenshot_path' => $sceneData['local_screenshot_path'] ?? null
|
||||
])
|
||||
];
|
||||
|
||||
if ($existingScene) {
|
||||
$adultVideoModel->update($existingScene['id'], $sceneData);
|
||||
$this->updatedCount++;
|
||||
} else {
|
||||
$adultVideoModel->create($sceneData);
|
||||
$this->newCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private function syncActors(array $cast): array
|
||||
{
|
||||
$actors = [];
|
||||
|
||||
foreach ($cast as $actorName) {
|
||||
if (empty($actorName)) continue;
|
||||
|
||||
$actor = $this->getOrCreateActor($actorName);
|
||||
if ($actor) {
|
||||
$actors[] = $actor;
|
||||
}
|
||||
}
|
||||
|
||||
return $actors;
|
||||
}
|
||||
|
||||
private function getOrCreateActor(string $name): ?array
|
||||
{
|
||||
// Check if actor already exists
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT id, name, thumbnail_path FROM actors WHERE name = :name
|
||||
");
|
||||
$stmt->execute(['name' => $name]);
|
||||
$existingActor = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if ($existingActor) {
|
||||
return [
|
||||
'id' => $existingActor['id'],
|
||||
'name' => $existingActor['name'],
|
||||
'thumbnail_path' => $existingActor['thumbnail_path']
|
||||
];
|
||||
}
|
||||
|
||||
// For now, we'll create actor without thumbnail
|
||||
// In a full implementation, you'd fetch actor details from XBVR API
|
||||
try {
|
||||
$stmt = $this->pdo->prepare("
|
||||
INSERT INTO actors (name, created_at, updated_at)
|
||||
VALUES (:name, NOW(), NOW())
|
||||
");
|
||||
$stmt->execute(['name' => $name]);
|
||||
$actorId = $this->pdo->lastInsertId();
|
||||
|
||||
return [
|
||||
'id' => $actorId,
|
||||
'name' => $name,
|
||||
'thumbnail_path' => null
|
||||
];
|
||||
} catch (Exception $e) {
|
||||
$this->logProgress("Failed to create actor {$name}: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getProcessedCount(): int
|
||||
{
|
||||
return $this->processedCount;
|
||||
}
|
||||
|
||||
protected function getNewCount(): int
|
||||
{
|
||||
return $this->newCount;
|
||||
}
|
||||
|
||||
protected function getUpdatedCount(): int
|
||||
{
|
||||
return $this->updatedCount;
|
||||
}
|
||||
|
||||
protected function getDeletedCount(): int
|
||||
{
|
||||
return 0; // XBVR doesn't provide deletion info in this context
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user