mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
...
This commit is contained in:
118
app/Controllers/ActorController.php
Normal file
118
app/Controllers/ActorController.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use PDO;
|
||||
use Slim\Views\Twig;
|
||||
|
||||
class ActorController extends Controller
|
||||
{
|
||||
private PDO $pdo;
|
||||
|
||||
public function __construct(PDO $pdo, Twig $view)
|
||||
{
|
||||
parent::__construct($view);
|
||||
$this->pdo = $pdo;
|
||||
}
|
||||
|
||||
public function show(Request $request, Response $response, $args)
|
||||
{
|
||||
$actorId = $args['id'];
|
||||
|
||||
// Get actor details with counts from all media types
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*,
|
||||
COUNT(DISTINCT am.movie_id) as movie_count,
|
||||
COUNT(DISTINCT ats.tv_show_id) as tv_show_count,
|
||||
COUNT(DISTINCT aav.adult_video_id) as adult_video_count,
|
||||
(COUNT(DISTINCT am.movie_id) + COUNT(DISTINCT ats.tv_show_id) + COUNT(DISTINCT aav.adult_video_id)) as total_media_count
|
||||
FROM actors a
|
||||
LEFT JOIN actor_movie am ON a.id = am.actor_id
|
||||
LEFT JOIN actor_tv_show ats ON a.id = ats.actor_id
|
||||
LEFT JOIN actor_adult_video aav ON a.id = aav.actor_id
|
||||
WHERE a.id = :actor_id
|
||||
GROUP BY a.id
|
||||
");
|
||||
$stmt->execute(['actor_id' => $actorId]);
|
||||
$actor = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$actor) {
|
||||
return $response->withStatus(404)->withHeader('Content-Type', 'text/html');
|
||||
}
|
||||
|
||||
// Get actor's adult videos (scenes)
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT av.*, s.display_name as source_name
|
||||
FROM adult_videos av
|
||||
JOIN sources s ON av.source_id = s.id
|
||||
JOIN actor_adult_video aav ON av.id = aav.adult_video_id
|
||||
WHERE aav.actor_id = :actor_id
|
||||
ORDER BY av.release_date DESC, av.title ASC
|
||||
");
|
||||
$stmt->execute(['actor_id' => $actorId]);
|
||||
$scenes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Get actor's movies
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT m.*, s.display_name as source_name
|
||||
FROM movies m
|
||||
JOIN sources s ON m.source_id = s.id
|
||||
JOIN actor_movie am ON m.id = am.movie_id
|
||||
WHERE am.actor_id = :actor_id
|
||||
ORDER BY m.release_date DESC, m.title ASC
|
||||
");
|
||||
$stmt->execute(['actor_id' => $actorId]);
|
||||
$movies = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Get actor's TV shows
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT ts.*, s.display_name as source_name
|
||||
FROM tv_shows ts
|
||||
JOIN sources s ON ts.source_id = s.id
|
||||
JOIN actor_tv_show ats ON ts.id = ats.tv_show_id
|
||||
WHERE ats.actor_id = :actor_id
|
||||
ORDER BY ts.first_air_date DESC, ts.title ASC
|
||||
");
|
||||
$stmt->execute(['actor_id' => $actorId]);
|
||||
$tvShows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return $this->view->render($response, 'actor/show.twig', [
|
||||
'title' => $actor['name'],
|
||||
'actor' => $actor,
|
||||
'scenes' => $scenes,
|
||||
'movies' => $movies,
|
||||
'tv_shows' => $tvShows
|
||||
]);
|
||||
}
|
||||
|
||||
public function index(Request $request, Response $response, $args)
|
||||
{
|
||||
// Get all actors with their media counts from all types
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*,
|
||||
COUNT(DISTINCT aav.adult_video_id) as adult_video_count,
|
||||
COUNT(DISTINCT am.movie_id) as movie_count,
|
||||
COUNT(DISTINCT ats.tv_show_id) as tv_show_count,
|
||||
(COUNT(DISTINCT aav.adult_video_id) + COUNT(DISTINCT am.movie_id) + COUNT(DISTINCT ats.tv_show_id)) as total_media_count,
|
||||
MAX(COALESCE(av.release_date, m.release_date, ts.first_air_date)) as latest_media_date
|
||||
FROM actors a
|
||||
LEFT JOIN actor_adult_video aav ON a.id = aav.actor_id
|
||||
LEFT JOIN adult_videos av ON aav.adult_video_id = av.id
|
||||
LEFT JOIN actor_movie am ON a.id = am.actor_id
|
||||
LEFT JOIN movies m ON am.movie_id = m.id
|
||||
LEFT JOIN actor_tv_show ats ON a.id = ats.actor_id
|
||||
LEFT JOIN tv_shows ts ON ats.tv_show_id = ts.id
|
||||
GROUP BY a.id
|
||||
ORDER BY total_media_count DESC, a.name ASC
|
||||
");
|
||||
$stmt->execute();
|
||||
$actors = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
return $this->view->render($response, 'actor/index.twig', [
|
||||
'title' => 'Actors & Performers',
|
||||
'actors' => $actors
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,26 @@ class AdminController extends Controller
|
||||
return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
// Validate sync type based on source type
|
||||
if ($source['name'] === 'jellyfin') {
|
||||
$validSyncTypes = ['full', 'incremental', 'all', 'movies', 'tvshows'];
|
||||
if (!in_array($syncType, $validSyncTypes)) {
|
||||
return $this->json($response, [
|
||||
'success' => false,
|
||||
'message' => 'Invalid sync type for Jellyfin source. Valid types: ' . implode(', ', $validSyncTypes)
|
||||
], 400);
|
||||
}
|
||||
} else {
|
||||
// For other sources, only allow full/incremental
|
||||
$validSyncTypes = ['full', 'incremental'];
|
||||
if (!in_array($syncType, $validSyncTypes)) {
|
||||
return $this->json($response, [
|
||||
'success' => false,
|
||||
'message' => 'Invalid sync type. Valid types: ' . implode(', ', $validSyncTypes)
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
// Start sync in background (simplified - in production you'd use queues)
|
||||
$syncLogId = $this->startSync($source, $syncType);
|
||||
|
||||
@@ -77,7 +97,7 @@ class AdminController extends Controller
|
||||
'id' => $syncLog['id'],
|
||||
'status' => $syncLog['status'],
|
||||
'sync_type' => $syncLog['sync_type'],
|
||||
'total_items' => $syncLog['total_items'],
|
||||
'total_items' => $syncLog['total_items'] ?? 0,
|
||||
'processed_items' => $syncLog['processed_items'],
|
||||
'new_items' => $syncLog['new_items'],
|
||||
'updated_items' => $syncLog['updated_items'],
|
||||
@@ -85,10 +105,20 @@ class AdminController extends Controller
|
||||
'started_at' => $syncLog['started_at'],
|
||||
'completed_at' => $syncLog['completed_at'],
|
||||
'message' => $syncLog['message'],
|
||||
'errors' => $syncLog['errors'] ? json_decode($syncLog['errors'], true) : []
|
||||
'errors' => $syncLog['errors'] ? json_decode($syncLog['errors'], true) : [],
|
||||
'progress_percentage' => $this->calculateProgressPercentage($syncLog)
|
||||
]);
|
||||
}
|
||||
|
||||
private function calculateProgressPercentage(array $syncLog): float
|
||||
{
|
||||
$total = $syncLog['total_items'] ?? 0;
|
||||
if ($total <= 0) return 0;
|
||||
|
||||
$processed = $syncLog['processed_items'] ?? 0;
|
||||
return min(100, round(($processed / $total) * 100, 2));
|
||||
}
|
||||
|
||||
public function sources(Request $request, Response $response, $args)
|
||||
{
|
||||
$sourceModel = new Source($this->pdo);
|
||||
@@ -116,11 +146,9 @@ class AdminController extends Controller
|
||||
case 'adult':
|
||||
$syncService = new AdultSyncService($this->pdo, $source);
|
||||
break;
|
||||
case 'exophase':
|
||||
$syncService = new ExophaseSyncService($this->pdo, $source);
|
||||
case 'xbvr':
|
||||
$syncService = new XbvrSyncService($this->pdo, $source);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Unsupported source type: ' . $source['name']);
|
||||
}
|
||||
|
||||
// Start sync (this would typically be queued in production)
|
||||
|
||||
@@ -46,11 +46,6 @@ class AdultController extends Controller
|
||||
$video['poster_url'] = $metadata['cover_url'];
|
||||
}
|
||||
|
||||
// Add other local paths if needed
|
||||
if (!empty($metadata['local_screenshot_path'])) {
|
||||
$video['screenshot_url'] = $metadata['local_screenshot_path'];
|
||||
}
|
||||
|
||||
// Add actors data if available
|
||||
if (!empty($metadata['actors'])) {
|
||||
$video['actors'] = $metadata['actors'];
|
||||
@@ -106,7 +101,7 @@ class AdultController extends Controller
|
||||
// Decode metadata for display
|
||||
$metadata = json_decode($adultVideo['metadata'], true);
|
||||
|
||||
// Add local image paths to the video data for template compatibility
|
||||
// Add local image paths and other metadata to the video data for template compatibility
|
||||
if (!empty($metadata['local_cover_path'])) {
|
||||
$adultVideo['poster_url'] = '/public/images/'.$metadata['local_cover_path'];
|
||||
} elseif (!empty($metadata['cover_url'])) {
|
||||
@@ -117,10 +112,27 @@ class AdultController extends Controller
|
||||
$adultVideo['screenshot_url'] = '/public/images/'.$metadata['local_screenshot_path'];
|
||||
}
|
||||
|
||||
// Add actors data if available
|
||||
if (!empty($metadata['actors'])) {
|
||||
$adultVideo['actors'] = $metadata['actors'];
|
||||
}
|
||||
|
||||
// Get actors for this adult video from the pivot table
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*
|
||||
FROM actors a
|
||||
JOIN actor_adult_video aav ON a.id = aav.actor_id
|
||||
WHERE aav.adult_video_id = :adult_video_id
|
||||
ORDER BY a.name ASC
|
||||
");
|
||||
$stmt->execute(['adult_video_id' => $adultVideoId]);
|
||||
$actors = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $this->view->render($response, 'adult/show.twig', [
|
||||
'title' => $adultVideo['title'],
|
||||
'movie' => $adultVideo, // Keep same variable name for template compatibility
|
||||
'metadata' => $metadata
|
||||
'metadata' => $metadata,
|
||||
'actors' => $actors
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,10 +82,22 @@ class MovieController extends Controller
|
||||
// Decode metadata for display
|
||||
$metadata = json_decode($movie['metadata'], true);
|
||||
|
||||
// Get actors for this movie
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*
|
||||
FROM actors a
|
||||
JOIN actor_movie am ON a.id = am.actor_id
|
||||
WHERE am.movie_id = :movie_id
|
||||
ORDER BY a.name ASC
|
||||
");
|
||||
$stmt->execute(['movie_id' => $movieId]);
|
||||
$actors = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
||||
return $this->view->render($response, 'movies/show.twig', [
|
||||
'title' => $movie['title'],
|
||||
'movie' => $movie,
|
||||
'metadata' => $metadata
|
||||
'metadata' => $metadata,
|
||||
'actors' => $actors
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,11 +62,68 @@ class TvShowController extends Controller
|
||||
{
|
||||
$tvShowId = (int) $args['id'];
|
||||
|
||||
// For now, return a placeholder since TV Shows aren't implemented yet
|
||||
// Get TV show details
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT t.*, s.display_name as source_name
|
||||
FROM tv_shows t
|
||||
JOIN sources s ON t.source_id = s.id
|
||||
WHERE t.id = :id
|
||||
");
|
||||
$stmt->execute(['id' => $tvShowId]);
|
||||
$tvShow = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$tvShow) {
|
||||
return $response->withStatus(404);
|
||||
}
|
||||
|
||||
// Decode metadata and other JSON fields
|
||||
$metadata = json_decode($tvShow['metadata'] ?? '{}', true);
|
||||
$cast = json_decode($tvShow['cast'] ?? '[]', true);
|
||||
$genre = json_decode($tvShow['genre'] ?? '[]', true);
|
||||
|
||||
// Get actors for this TV show
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT a.*
|
||||
FROM actors a
|
||||
JOIN actor_tv_show ats ON a.id = ats.actor_id
|
||||
WHERE ats.tv_show_id = :tv_show_id
|
||||
ORDER BY a.name ASC
|
||||
");
|
||||
$stmt->execute(['tv_show_id' => $tvShowId]);
|
||||
$actors = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
/*
|
||||
// Get seasons for this TV show
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM tv_seasons
|
||||
WHERE tv_show_id = :tv_show_id
|
||||
ORDER BY season_number ASC
|
||||
");
|
||||
$stmt->execute(['tv_show_id' => $tvShowId]);
|
||||
$seasons = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
*//*
|
||||
// Get episodes for each season
|
||||
foreach ($seasons as &$season) {
|
||||
$stmt = $this->pdo->prepare("
|
||||
SELECT * FROM tv_episodes
|
||||
WHERE tv_show_id = :tv_show_id AND season_number = :season_number
|
||||
ORDER BY episode_number ASC
|
||||
");
|
||||
$stmt->execute([
|
||||
'tv_show_id' => $tvShowId,
|
||||
'season_number' => $season['season_number']
|
||||
]);
|
||||
$season['episodes'] = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
}
|
||||
unset($season); // Unset reference
|
||||
*/
|
||||
return $this->view->render($response, 'tvshows/show.twig', [
|
||||
'title' => 'TV Show Details',
|
||||
'tvshow' => ['id' => $tvShowId, 'title' => 'Coming Soon'],
|
||||
'message' => 'TV show details page is not yet implemented.'
|
||||
'title' => $tvShow['title'],
|
||||
'tvshow' => $tvShow,
|
||||
'metadata' => $metadata,
|
||||
'cast' => $cast,
|
||||
'genre' => $genre,
|
||||
'actors' => $actors,
|
||||
'seasons' => $seasons
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user