lots of progress

This commit is contained in:
2025-01-26 21:36:05 +02:00
parent bbd082fd8f
commit 6a014c403c
44 changed files with 976 additions and 104 deletions
@@ -45,18 +45,9 @@ class FetchItemDataCommand extends Command
private function getBatch(string $type, int $batch, string $job)
{
return ItemToFetch::has('jobs')
->with([
// 'jobs' => fn ($jobs) => dd($jobs->first()->remaining_jobs) /*array_search($job, $jobs->first()->remaining_jobs, true)*/,
'jobs' => function ($jobs) use ($job) {
$remainingJobs = $jobs->first()->remaining_jobs;
if (is_string($remainingJobs)) {
$remainingJobs = json_decode($jobs->first()->remaining_jobs, true);
}
return array_search($job, $remainingJobs, true);
},
])
return ItemToFetch::whereHas('jobs', function($query) use ($job){
return $query->where('jobs', '<>', null)->whereRaw('FIND_IN_SET(?, jobs)', [$job]);
})->with(['jobs'])
->where('type', $type)
->take($batch)
->get();
@@ -57,6 +57,7 @@ class FetchUpcomingMoviesCommand extends Command
$oldUpcomingIds = UpcomingMovie::all()->pluck('movie_id');
foreach ($upcomingMovies['results'] as $upcomingMovie) {
echo ".";
$movie = $this->process($upcomingMovie);
if ($movie) {
@@ -69,11 +70,13 @@ class FetchUpcomingMoviesCommand extends Command
if (!empty($newUpcomingIds)) {
UpcomingMovie::whereIn('id', $oldUpcomingIds)->delete();
UpcomingMovie::insert($newUpcomingIds);
echo "+";
}
DB::commit();
} catch (\Throwable $e) {
DB::rollBack();
dump($e);
}
}
@@ -86,14 +89,14 @@ class FetchUpcomingMoviesCommand extends Command
return $movie;
}
$itemToFetch = ItemToFetch::where('tmdb_id', $upcomingMovie['id'])->where('type', $type)->first();
$itemToFetch = ItemToFetch::where('tmdb_id', $upcomingMovie['id'])->where('type', ItemToFetch::TYPE_MOVIE)->first();
if ($itemToFetch) {
$this->movieProcessingService->process($itemToFetch, ItemToFetchJobs::JOB_DETAILS);
return Movie::where('tmdb_id', $upcomingMovie['id'])->first();
}
ItemToFetch::create([
$itemToFetch = ItemToFetch::create([
'tmdb_id' => $upcomingMovie['id'],
'type' => ItemToFetch::TYPE_MOVIE,
]);
@@ -107,6 +110,7 @@ class FetchUpcomingMoviesCommand extends Command
'remaining_jobs' => json_encode($jobs),
]);
return null;
$this->movieProcessingService->process($itemToFetch, ItemToFetchJobs::JOB_DETAILS);
return Movie::where('tmdb_id', $upcomingMovie['id'])->first();
}
}
@@ -88,13 +88,11 @@ class FetchExportItemsCommand extends Command
'type' => $type,
]);
// $jobs = ItemToFetchJobs::JOBS;
// $jobs[] = "Details";
ItemToFetchJobs::create([
'tmdb_id' => $decodedLine['id'],
'type' => $type,
'remaining_jobs' => json_encode($jobs),
'jobs' => implode(',', $jobs),
]);
}
}
@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\MediaList;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
@@ -64,11 +65,27 @@ class RegisterController extends Controller
*/
protected function create(array $data)
{
return User::create([
$user = User::create([
'name' => $data['name'],
'slug' => Str::slug($data['name']),
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$this->createMediaList('Watchlist', $user);
$this->createMediaList('Collection', $user);
$this->createMediaList('Watched', $user);
$this->createMediaList('Liked', $user);
return $user;
}
private function createMediaList(string $name, $user)
{
return MediaList::create([
'name' => $name,
'slug' => Str::slug($name),
'user_id' => $user->id,
]);
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\MediaListRequest;
use App\Models\MediaList;
use App\Models\MediaListItem;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
class MediaListController extends Controller
{
public function index()
{
$lists = MediaList::whereNotIn('name', MediaList::SPECIAL_LISTS)
->where('user_id', Auth::user()->id)
->get();
return view('profile.lists.index', compact('lists'));
}
public function show(string $userSlug, string $listSlug)
{
$user = User::where('slug', $userSlug)->first();
$list = MediaList::where('user_id', $user->id)->where('slug', $listSlug)->first();
$items = MediaListItem::where('media_list_id', $list->id)->paginate(15);
return view('profile.lists.show', compact('list', 'items'));
}
public function create()
{
return view('profile.lists.create');
}
public function store(MediaListRequest $request)
{
$slug = Str::slug($request->get('name'));
$mediaList = MediaList::create([
'description' => $request->get('description'),
'name' => $request->get('name'),
'slug' => $slug,
'user_id' => Auth::user()->id,
]);
return redirect()->route('profile.list.show', [Auth::user()->slug, $slug]);
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers;
use App\Models\Movie;
use Illuminate\Http\Request;
class MovieController extends Controller
{
public function index()
{
$movies = Movie::orderBy('release_date', 'ASC')->paginate(60);
return view('movie.index', compact('movies'));
}
public function show(string $slug)
{
$movie = Movie::with('director', 'watchProviders')
->where('slug', $slug)
->firstOrFail();
return view('movie.show', compact('movie'));
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MediaListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|min:2|max:255',
'description' => 'sometimes|nullable',
];
}
}
@@ -2,12 +2,20 @@
namespace App\Livewire\Homepage\Movies;
use App\Models\Movie;
use Livewire\Component;
class NewMoviesComponent extends Component
{
public $newMovies;
public function render()
{
return view('livewire.homepage.movies.new-movies-component');
}
public function mount()
{
$this->newMovies = Movie::orderBy('created_at', 'desc')->take(6)->get();
}
}
@@ -2,12 +2,23 @@
namespace App\Livewire\Homepage\Movies;
use App\Models\Movie;
use App\Models\UpcomingMovie;
use Livewire\Component;
class UpcomingMoviesComponent extends Component
{
public $upcomingMovies;
public function render()
{
return view('livewire.homepage.movies.upcoming-movies-component');
}
public function mount()
{
$this->upcomingMovies = Movie::whereIn('id', UpcomingMovie::orderBy('id', 'desc')->get()->pluck('movie_id'))
->take(6)
->get();
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Livewire\MoviePage\Tabs;
use App\Models\Movie;
use App\Models\Person;
use Livewire\Component;
class Cast extends Component
{
public $movie;
public $peopleByDepartment;
public function render()
{
return view('livewire.movie-page.tabs.cast');
}
public function mount()
{
$this->movie = Movie::with('castList')->where('id', $this->movie->id)->first();
$peopleByDepartment = [];
foreach ($this->movie->castList as $castMember) {
if (!isset($peopleByDepartment[$castMember->pivot->known_for_department])) {
$peopleByDepartment[$castMember->pivot->known_for_department] = [];
}
$peopleByDepartment[$castMember->pivot->known_for_department][] = [
Person::find($castMember->pivot->person_id),
$castMember->pivot->character,
];
}
$this->peopleByDepartment = $peopleByDepartment;
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Livewire\MoviePage\Tabs;
use Livewire\Component;
class Crew extends Component
{
public function render()
{
return view('livewire.movie-page.tabs.crew');
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Livewire\MoviePage\Tabs;
use App\Models\Movie;
use App\Models\MovieAlternativeTitle;
use Livewire\Component;
class Details extends Component
{
public $movie;
public $productionCompanies;
public $productionCountries;
public $alternativeTitles;
public function render()
{
return view('livewire.movie-page.tabs.details');
}
public function mount()
{
$this->alternativeTitles = MovieAlternativeTitle::where('movie_id', $this->movie->id)->get();
$movie = Movie::with('productionCompanies', 'productionCountries')->find($this->movie->id);
$this->productionCompanies = $movie->productionCompanies;
$this->productionCountries = $movie->productionCountries;
// $this->productionCompanies = Movie::
// alt titles
// prod company
// prod country
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Livewire\MoviePage\Tabs;
use Livewire\Component;
class Releases extends Component
{
public function render()
{
return view('livewire.movie-page.tabs.releases');
}
}
+1
View File
@@ -76,6 +76,7 @@ class ItemToFetchJobs extends Model
'item_id',
'type',
'remaining_jobs',
'jobs',
];
protected function casts(): array
+14
View File
@@ -6,6 +6,18 @@ use Illuminate\Database\Eloquent\Model;
class MediaList extends Model
{
public const WATCHLIST = 'Watchlist';
public const COLLECTION = 'Collection';
public const WATCHED = 'Watched';
public const LIKED = 'Liked';
public const SPECIAL_LISTS = [
self::WATCHLIST,
self::COLLECTION,
self::WATCHED,
self::LIKED,
];
protected $fillable = [
'description',
'favorites_count',
@@ -15,6 +27,8 @@ class MediaList extends Model
'iso_3166_1',
'list_type',
'name',
'slug',
'poster_path',
'user_id',
];
}
+22 -1
View File
@@ -28,6 +28,17 @@ class Movie extends Model
'vote_count',
];
protected $casts = [
'release_date' => 'date'
];
public function director()
{
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id')
->where('movie_cast.known_for_department', 'Directing')
;
}
public function collections()
{
return $this->belongsToMany(MovieCollection::class, 'movies_in_collection', 'movie_id', 'collection_id');
@@ -40,7 +51,7 @@ class Movie extends Model
public function castList()
{
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id');
return $this->belongsToMany(Person::class, 'movie_cast', 'movie_id', 'person_id')->withPivot('known_for_department', 'character', 'order');
}
public function crewList()
@@ -72,4 +83,14 @@ class Movie extends Model
{
return $this->belongsToMany(Video::class, 'movie_videos', 'movie_id', 'video_id');
}
public function productionCompanies()
{
return $this->belongsToMany(ProductionCompany::class, 'movie_production_companies', 'movie_id', 'production_company_id');
}
public function productionCountries()
{
return $this->belongsToMany(ProductionCountry::class, 'movie_production_countries', 'movie_id', 'production_country_id');
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
namespace App\Providers;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@@ -19,6 +20,6 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot(): void
{
//
Paginator::useBootstrapFour();
}
}
@@ -17,6 +17,8 @@ use App\Models\MovieCollection;
use App\Models\MovieRecommendation;
use App\Models\MovieSimilar;
use App\Models\Person;
use App\Models\ProductionCompany;
use App\Models\ProductionCountry;
use App\Models\ReleaseDate;
use App\Models\Translation;
use App\Models\User;
@@ -79,6 +81,14 @@ class MovieProcessingService implements ProcessingInterface
$this->processMovieGenres($movieId->id, $tmdbMovie['genres']);
}
if (!empty($tmdbMovie['production_companies'])) {
$this->processProductionCompanies($movieId->id, $tmdbMovie['production_companies']);
}
if (!empty($tmdbMovie['production_countries'])) {
$this->processProductionCountries($movieId->id, $tmdbMovie['production_countries']);
}
$this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details');
}
@@ -112,9 +122,11 @@ class MovieProcessingService implements ProcessingInterface
private function getCredits($item)
{
echo "Credits for TMDBID ".$item->tmdb_id." \n";
$tmdbCredits = $this->moviesApi->getCredits($item->tmdb_id);
if (empty($tmdbCredits)) {
echo "Empty for ".$item->tmdb_id." \n";
return;
}
@@ -701,10 +713,16 @@ class MovieProcessingService implements ProcessingInterface
{
$itemToFetchJobs = ItemToFetchJobs::where('tmdb_id', $tmdbId)->first();
$remainingJobs = $itemToFetchJobs->remaining_jobs;
if (!$itemToFetchJobs) {
return;
}
$remainingJobs = $itemToFetchJobs->jobs;
if (is_string($remainingJobs)) {
$remainingJobs = json_decode($remainingJobs, true);
$remainingJobs = explode(',', $remainingJobs);
} else {
dd($remainingJobs, $tmdbId);
}
$remainingJobKey = array_search($job, $remainingJobs);
@@ -715,13 +733,14 @@ class MovieProcessingService implements ProcessingInterface
$itemToFetchJobs->delete();
}
$itemToFetchJobs->remaining_jobs = $remainingJobs;
// $itemToFetchJobs->remaining_jobs = $remainingJobs;
$itemToFetchJobs->jobs = implode(',', $remainingJobs);
$itemToFetchJobs->save();
}
private function processCast($movie, array $castList)
{
if (empty($castList)) {
if (empty($castList) || $movie === null) {
return;
}
@@ -753,15 +772,12 @@ class MovieProcessingService implements ProcessingInterface
'place_of_birth' => $tmdbPerson['place_of_birth'],
]);
}
$person = Person::create($personData);
}
if ($movie->whereHas('castList', function ($query) use ($person) {
$query->where('tmdb_id', '=', $person->tmdb_id);
if (!$movie->whereHas('castList', function ($query) use ($person) {
$query->where('person_id', '=', $person->id);
})->exists()) {
return;
} else {
$movie->castList()->attach($person, [
'known_for_department' => $castPerson['known_for_department'],
'character' => $castPerson['character'],
@@ -825,6 +841,56 @@ class MovieProcessingService implements ProcessingInterface
}
}
private function processProductionCompanies(int $movieId, array $productionCompanies)
{
$movie = Movie::find($movieId);
foreach ($productionCompanies as $productionCompany) {
$existingProductionCompany = ProductionCompany::where('tmdb_id', $productionCompany['id'])->first();
if (!$existingProductionCompany) {
$existingProductionCompany = ProductionCompany::create([
'tmdb_id' => $productionCompany['id'],
'logo_path' => $productionCompany['logo_path'],
'name' => $productionCompany['name'],
'origin_country' => $productionCompany['origin_country'],
]);
}
if ($movie->whereHas('productionCompanies', function ($query) use ($existingProductionCompany) {
$query->where('production_company_id', '=', $existingProductionCompany->id);
})->exists()) {
return;
} else {
$movie->productionCompanies()->attach($existingProductionCompany);
}
}
}
private function processProductionCountries(int $movieId, array $productionCountries)
{
$movie = Movie::find($movieId);
foreach ($productionCountries as $productionCountry) {
$existingProductionCountry = ProductionCountry::where('iso_3166', $productionCountry['iso_3166_1'])->first();
if (!$existingProductionCountry) {
$existingProductionCountry = ProductionCountry::create([
'iso_3166' => $productionCountry['iso_3166_1'],
'name' => $productionCountry['name'],
]);
}
if ($movie->whereHas('productionCountries', function ($query) use ($existingProductionCountry) {
$query->where('production_country_id', '=', $existingProductionCountry->id);
})->exists()) {
return;
} else {
$movie->productionCountries()->attach($existingProductionCountry);
}
}
}
private function createJob($tmdbId)
{
$itemToFetch = ItemToFetch::where('tmdb_id', $tmdbId)->where('type', ItemToFetch::TYPE_MOVIE)->first();