wip
This commit is contained in:
1
.env
1
.env
@@ -48,3 +48,4 @@ MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
|
||||
TMDB_API_TOKEN=eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJkZmE5NDZmMTZmMTcyYmNlMzk0MzZiZmVhZDc2ZTk3NCIsIm5iZiI6MTY0OTE4MjMyNS43NTAwMDAyLCJzdWIiOiI2MjRjODY3NWFmNThjYjAwNTE1NzZiYmEiLCJzY29wZXMiOlsiYXBpX3JlYWQiXSwidmVyc2lvbiI6MX0.KE68nNxPGYWr5WHVaUuILMOH3sPhiAc9CucPVTgRPpM
|
||||
TMDB_HOST=https://api.themoviedb.org/3
|
||||
|
||||
1
.idea/dictionaries/project.xml
generated
1
.idea/dictionaries/project.xml
generated
@@ -1,6 +1,7 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="project">
|
||||
<words>
|
||||
<w>Letterboxd</w>
|
||||
<w>tmdb</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
||||
8
.idea/laravel-idea.xml
generated
Normal file
8
.idea/laravel-idea.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="InertiaPackage">
|
||||
<option name="directoryPaths">
|
||||
<list />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/php.xml
generated
2
.idea/php.xml
generated
@@ -139,7 +139,7 @@
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.5">
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.4">
|
||||
<option name="suggestChangeDefaultLanguageLevel" value="false" />
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
|
||||
6
.idea/symfony2.xml
generated
Normal file
6
.idea/symfony2.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Symfony2PluginSettings">
|
||||
<option name="pluginEnabled" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -14,6 +14,7 @@
|
||||
"phpstan/phpdoc-parser": "^2.3",
|
||||
"symfony/asset": "8.0.*",
|
||||
"symfony/asset-mapper": "8.0.*",
|
||||
"symfony/cache": "8.0.*",
|
||||
"symfony/console": "8.0.*",
|
||||
"symfony/doctrine-messenger": "8.0.*",
|
||||
"symfony/dotenv": "8.0.*",
|
||||
|
||||
4297
composer.lock
generated
4297
composer.lock
generated
File diff suppressed because it is too large
Load Diff
33
src/Context/TMDB/AbstractSearchContext.php
Normal file
33
src/Context/TMDB/AbstractSearchContext.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Context\TMDB;
|
||||
|
||||
abstract class AbstractSearchContext
|
||||
{
|
||||
public function __construct(
|
||||
protected int $page,
|
||||
protected array $results,
|
||||
protected int $total_pages,
|
||||
protected int $total_results,
|
||||
) {}
|
||||
|
||||
public function getPage(): int
|
||||
{
|
||||
return $this->page;
|
||||
}
|
||||
|
||||
public function getResults(): array
|
||||
{
|
||||
return $this->results;
|
||||
}
|
||||
|
||||
public function getTotalPages(): int
|
||||
{
|
||||
return $this->total_pages;
|
||||
}
|
||||
|
||||
public function getTotalResults(): int
|
||||
{
|
||||
return $this->total_results;
|
||||
}
|
||||
}
|
||||
13
src/Context/TMDB/MovieSearchContext.php
Normal file
13
src/Context/TMDB/MovieSearchContext.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Context\TMDB;
|
||||
|
||||
use App\Model\TMDB\TMDBMovie;
|
||||
|
||||
class MovieSearchContext extends AbstractSearchContext
|
||||
{
|
||||
/**
|
||||
* @var TMDBMovie[]
|
||||
*/
|
||||
protected array $results;
|
||||
}
|
||||
@@ -5,26 +5,32 @@ declare(strict_types=1);
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Gateway\TMDBGateway;
|
||||
use App\Model\Ltbxd\LtbxdMovie;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpClient\Exception\ClientException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class HomepageController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly TMDBGateway $TMDBGateway,
|
||||
) {
|
||||
}
|
||||
private readonly TMDBGateway $TMDBGateway, private readonly SerializerInterface $serializer,
|
||||
) {}
|
||||
|
||||
#[Route('/')]
|
||||
public function index(): Response
|
||||
public function index(SerializerInterface $serializer): Response
|
||||
{
|
||||
try {
|
||||
dd($this->TMDBGateway->searchMovie('The Batman'));
|
||||
} catch (ClientException $e) {
|
||||
dd($e->getResponse()->getInfo());
|
||||
$file = file_get_contents('files/watched.csv');
|
||||
$ltbxdMovies = $this->serializer->deserialize($file, LtbxdMovie::class.'[]', 'csv');
|
||||
/** @var LtbxdMovie $ltbxdMovie */
|
||||
$films = [];
|
||||
foreach ($ltbxdMovies as $ltbxdMovie) {
|
||||
// Search movie on TMDB
|
||||
$searchResult = $this->TMDBGateway->searchMovie($ltbxdMovie->getName());
|
||||
$films[] = $searchResult->getResults()[0];
|
||||
}
|
||||
dd($films);
|
||||
|
||||
return $this->render('homepage/index.html.twig');
|
||||
}
|
||||
|
||||
@@ -2,33 +2,43 @@
|
||||
|
||||
namespace App\Gateway;
|
||||
|
||||
use App\Context\TMDB\MovieSearchContext;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use function Symfony\Component\String\u;
|
||||
|
||||
class TMDBGateway
|
||||
{
|
||||
private const TMDB_URL = 'https://api.themoviedb.org/3';
|
||||
private const SEARCH_URI = '/search/movie';
|
||||
private const string SEARCH_URI = '/search/movie';
|
||||
|
||||
public function __construct(
|
||||
private readonly HttpClientInterface $client,
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly CacheInterface $cache,
|
||||
#[Autowire('%env(TMDB_API_TOKEN)%')]
|
||||
private readonly string $apiToken,
|
||||
#[Autowire('%env(TMDB_HOST)%')]
|
||||
private readonly string $host,
|
||||
) {
|
||||
}
|
||||
|
||||
public function findMovie(string $movieName)
|
||||
public function searchMovie(string $movieName): ?MovieSearchContext
|
||||
{
|
||||
$url = self::TMDB_URL.self::SEARCH_URI.'?'.http_build_query(['query' => $movieName]);
|
||||
$cacheKey = 'tmdb_movie.'.u($movieName)->snake();
|
||||
|
||||
try {
|
||||
$response = $this->client->request('GET', $url, ['headers' => $this->getHeaders()]);
|
||||
$result = $response->getContent();
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return json_decode($this->client->request('GET', $url, ['headers' => $this->getHeaders()])->getContent(), associative: true);
|
||||
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($movieName) {
|
||||
$url = $this->host.self::SEARCH_URI.'?'.http_build_query(['query' => $movieName]);
|
||||
try {
|
||||
$response = $this->client->request('GET', $url, ['headers' => $this->getHeaders()]);
|
||||
$result = $response->getContent();
|
||||
return $this->serializer->deserialize($result, MovieSearchContext::class, 'json');
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function getHeaders(): array
|
||||
|
||||
39
src/Model/Ltbxd/LtbxdMovie.php
Normal file
39
src/Model/Ltbxd/LtbxdMovie.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Model\Ltbxd;
|
||||
|
||||
use Symfony\Component\Serializer\Attribute\SerializedName;
|
||||
|
||||
class LtbxdMovie
|
||||
{
|
||||
public function __construct(
|
||||
#[SerializedName('Date')]
|
||||
private readonly \DateTime $date,
|
||||
#[SerializedName('Name')]
|
||||
private readonly string $name,
|
||||
#[SerializedName('Year')]
|
||||
private readonly int $year,
|
||||
#[SerializedName('Letterboxd URI')]
|
||||
private readonly string $ltbxdUri,
|
||||
) {}
|
||||
|
||||
public function getDate(): \DateTime
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getYear(): int
|
||||
{
|
||||
return $this->year;
|
||||
}
|
||||
|
||||
public function getLtbxdUri(): string
|
||||
{
|
||||
return $this->ltbxdUri;
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,90 @@ namespace App\Model\TMDB;
|
||||
|
||||
class TMDBMovie
|
||||
{
|
||||
public function __construct(
|
||||
private readonly bool $adult,
|
||||
private readonly ?string $backdrop_path,
|
||||
private readonly array $genre_ids,
|
||||
private readonly int $id,
|
||||
private readonly string $original_language,
|
||||
private readonly string $original_title,
|
||||
private readonly string $overview,
|
||||
private readonly float $popularity,
|
||||
private readonly ?string $poster_path,
|
||||
private readonly \DateTime|string $release_date,
|
||||
private readonly string $title,
|
||||
private readonly bool $video,
|
||||
private readonly float $vote_average,
|
||||
private readonly int $vote_count,
|
||||
) {}
|
||||
|
||||
public function isAdult(): bool
|
||||
{
|
||||
return $this->adult;
|
||||
}
|
||||
|
||||
public function getBackdropPath(): ?string
|
||||
{
|
||||
return $this->backdrop_path;
|
||||
}
|
||||
|
||||
public function getGenreIds(): array
|
||||
{
|
||||
return $this->genre_ids;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getOriginalLanguage(): string
|
||||
{
|
||||
return $this->original_language;
|
||||
}
|
||||
|
||||
public function getOriginalTitle(): string
|
||||
{
|
||||
return $this->original_title;
|
||||
}
|
||||
|
||||
public function getOverview(): string
|
||||
{
|
||||
return $this->overview;
|
||||
}
|
||||
|
||||
public function getPopularity(): float
|
||||
{
|
||||
return $this->popularity;
|
||||
}
|
||||
|
||||
public function getPosterPath(): ?string
|
||||
{
|
||||
return $this->poster_path;
|
||||
}
|
||||
|
||||
public function getReleaseDate(): \DateTime|string
|
||||
{
|
||||
return $this->release_date;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
public function isVideo(): bool
|
||||
{
|
||||
return $this->video;
|
||||
}
|
||||
|
||||
public function getVoteAverage(): float
|
||||
{
|
||||
return $this->vote_average;
|
||||
}
|
||||
|
||||
public function getVoteCount(): int
|
||||
{
|
||||
return $this->vote_count;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user