feat: initial commit
This commit is contained in:
commit
e214116e40
253 changed files with 17406 additions and 0 deletions
176
api/watching-import.php
Normal file
176
api/watching-import.php
Normal file
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
|
||||
require __DIR__ . "/Classes/ApiHandler.php";
|
||||
|
||||
use App\Classes\ApiHandler;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class WatchingImportHandler extends ApiHandler
|
||||
{
|
||||
protected string $postgrestUrl;
|
||||
protected string $postgrestApiKey;
|
||||
|
||||
private string $tmdbApiKey;
|
||||
private string $tmdbImportToken;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->ensureCliAccess();
|
||||
$this->loadEnvironment();
|
||||
}
|
||||
|
||||
private function loadEnvironment(): void
|
||||
{
|
||||
$this->postgrestUrl = $_ENV["POSTGREST_URL"] ?? getenv("POSTGREST_URL");
|
||||
$this->postgrestApiKey =
|
||||
$_ENV["POSTGREST_API_KEY"] ?? getenv("POSTGREST_API_KEY");
|
||||
$this->tmdbApiKey = $_ENV["TMDB_API_KEY"] ?? getenv("TMDB_API_KEY");
|
||||
$this->tmdbImportToken =
|
||||
$_ENV["WATCHING_IMPORT_TOKEN"] ?? getenv("WATCHING_IMPORT_TOKEN");
|
||||
}
|
||||
|
||||
public function handleRequest(): void
|
||||
{
|
||||
$input = json_decode(file_get_contents("php://input"), true);
|
||||
|
||||
if (!$input) $this->sendErrorResponse("Invalid or missing JSON body", 400);
|
||||
|
||||
$providedToken = $input["token"] ?? null;
|
||||
|
||||
if (!$providedToken || $providedToken !== $this->tmdbImportToken) $this->sendErrorResponse("Unauthorized access", 401);
|
||||
|
||||
$tmdbId = $input["tmdb_id"] ?? null;
|
||||
$mediaType = $input["media_type"] ?? null;
|
||||
|
||||
if (!$tmdbId || !$mediaType) $this->sendErrorResponse("tmdb_id and media_type are required", 400);
|
||||
|
||||
try {
|
||||
$mediaData = $this->fetchTMDBData($tmdbId, $mediaType);
|
||||
$this->processMedia($mediaData, $mediaType);
|
||||
$this->sendResponse("Media imported successfully", 200);
|
||||
} catch (Exception $e) {
|
||||
$this->sendErrorResponse("Error: " . $e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function fetchTMDBData(string $tmdbId, string $mediaType): array
|
||||
{
|
||||
$client = new Client();
|
||||
$url = "https://api.themoviedb.org/3/{$mediaType}/{$tmdbId}";
|
||||
|
||||
$response = $client->get($url, [
|
||||
"query" => ["api_key" => $this->tmdbApiKey],
|
||||
"headers" => ["Accept" => "application/json"],
|
||||
]);
|
||||
|
||||
$data = json_decode($response->getBody(), true);
|
||||
|
||||
if (empty($data)) throw new Exception("No data found for TMDB ID: {$tmdbId}");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
private function processMedia(array $mediaData, string $mediaType): void
|
||||
{
|
||||
$id = $mediaData["id"];
|
||||
$title = $mediaType === "movie" ? $mediaData["title"] : $mediaData["name"];
|
||||
$year =
|
||||
$mediaData["release_date"] ?? ($mediaData["first_air_date"] ?? null);
|
||||
$year = $year ? substr($year, 0, 4) : null;
|
||||
$description = $mediaData["overview"] ?? "";
|
||||
$tags = array_map(
|
||||
fn($genre) => strtolower(trim($genre["name"])),
|
||||
$mediaData["genres"]
|
||||
);
|
||||
$slug =
|
||||
$mediaType === "movie"
|
||||
? "/watching/movies/{$id}"
|
||||
: "/watching/shows/{$id}";
|
||||
$payload = [
|
||||
"title" => $title,
|
||||
"year" => $year,
|
||||
"description" => $description,
|
||||
"tmdb_id" => $id,
|
||||
"slug" => $slug,
|
||||
];
|
||||
$response = $this->fetchFromPostgREST(
|
||||
$mediaType === "movie" ? "movies" : "shows",
|
||||
"",
|
||||
"POST",
|
||||
$payload
|
||||
);
|
||||
|
||||
if (empty($response["id"])) {
|
||||
$queryResponse = $this->fetchFromPostgREST(
|
||||
$mediaType === "movie" ? "movies" : "shows",
|
||||
"tmdb_id=eq.{$id}",
|
||||
"GET"
|
||||
);
|
||||
$response = $queryResponse[0] ?? [];
|
||||
}
|
||||
|
||||
if (!empty($response["id"])) {
|
||||
$mediaId = $response["id"];
|
||||
$existingTagMap = $this->getTagIds($tags);
|
||||
$updatedTagMap = $this->insertMissingTags($tags, $existingTagMap);
|
||||
$this->associateTagsWithMedia(
|
||||
$mediaType,
|
||||
$mediaId,
|
||||
array_values($updatedTagMap)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function getTagIds(array $tags): array
|
||||
{
|
||||
$existingTagMap = [];
|
||||
foreach ($tags as $tag) {
|
||||
$query = "name=ilike." . urlencode($tag);
|
||||
$existingTags = $this->fetchFromPostgREST("tags", $query, "GET");
|
||||
|
||||
if (!empty($existingTags[0]["id"])) $existingTagMap[strtolower($tag)] = $existingTags[0]["id"];
|
||||
}
|
||||
return $existingTagMap;
|
||||
}
|
||||
|
||||
private function insertMissingTags(array $tags, array $existingTagMap): array
|
||||
{
|
||||
$newTags = array_diff($tags, array_keys($existingTagMap));
|
||||
foreach ($newTags as $newTag) {
|
||||
try {
|
||||
$response = $this->fetchFromPostgREST("tags", "", "POST", [
|
||||
"name" => $newTag,
|
||||
]);
|
||||
if (!empty($response["id"])) $existingTagMap[$newTag] = $response["id"];
|
||||
} catch (Exception $e) {
|
||||
$queryResponse = $this->fetchFromPostgREST(
|
||||
"tags",
|
||||
"name=eq.{$newTag}",
|
||||
"GET"
|
||||
);
|
||||
if (!empty($queryResponse[0]["id"])) $existingTagMap[$newTag] = $queryResponse[0]["id"];
|
||||
}
|
||||
}
|
||||
return $existingTagMap;
|
||||
}
|
||||
|
||||
private function associateTagsWithMedia(
|
||||
string $mediaType,
|
||||
int $mediaId,
|
||||
array $tagIds
|
||||
): void {
|
||||
$junctionTable = $mediaType === "movie" ? "movies_tags" : "shows_tags";
|
||||
$mediaColumn = $mediaType === "movie" ? "movies_id" : "shows_id";
|
||||
|
||||
foreach ($tagIds as $tagId) {
|
||||
$this->fetchFromPostgREST($junctionTable, "", "POST", [
|
||||
$mediaColumn => $mediaId,
|
||||
"tags_id" => $tagId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$handler = new WatchingImportHandler();
|
||||
$handler->handleRequest();
|
Loading…
Add table
Add a link
Reference in a new issue