some improvements

This commit is contained in:
2025-08-11 21:40:50 +03:00
parent e351803db2
commit 34bcdb062e
12 changed files with 198 additions and 63 deletions
+2 -8
View File
@@ -22,14 +22,8 @@ class MovieController extends Controller
->where('slug', $slug) ->where('slug', $slug)
->firstOrFail(); ->firstOrFail();
// comments $comments = Comment::where('entity_id', $movie->id)
$comments = Comment::where(function($query) use ($movie){ ->where('entity_type', Comment::TYPE_MOVIE)
$query->where(function($query) use ($movie){
$query->where('entity_id', $movie->id)
->where('entity_type', Comment::TYPE_MOVIE);
})
->orWhere('tmdb_id', $movie->tmdb_id);
})
->paginate(15); ->paginate(15);
return view('movie.show', compact('movie', 'comments')); return view('movie.show', compact('movie', 'comments'));
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Livewire\MoviePage;
use App\Models\Movie;
use Livewire\Component;
class Collection extends Component
{
public $movie;
public $collection;
public $collectionMovies;
public function render()
{
return view('livewire.movie-page.collection');
}
public function mount()
{
// Get the collection for this movie
$this->collection = $this->movie->collections()->first();
if ($this->collection) {
// Get all movies in this collection
$this->collectionMovies = $this->collection->movies()
->where('movies.id', '!=', $this->movie->id) // Exclude the current movie
->get();
}
}
}
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace App\Livewire\MoviePage\Tabs;
use App\Models\Movie;
use Livewire\Component;
class Images extends Component
{
public $movie;
public $images;
public function render()
{
return view('livewire.movie-page.tabs.images');
}
public function mount()
{
$this->movie = Movie::with('images')->where('id', $this->movie->id)->first();
$this->images = $this->movie->images;
}
}
@@ -48,22 +48,11 @@ class MovieProcessingService implements ProcessingInterface
public static function getBatch(int $batch, string $job) public static function getBatch(int $batch, string $job)
{ {
if ($job === ItemToFetchJobs::JOB_DETAILS) {
return ItemToFetchJobs::leftJoin('movies', function ($join) {
$join->on('movies.tmdb_id', '=', 'item_to_fetch_jobs.tmdb_id');
})
->whereRaw("FIND_IN_SET('".ItemToFetchJobs::JOB_DETAILS."', item_to_fetch_jobs.jobs)")
->whereIn('item_to_fetch_jobs.type', ['movies', 'movie'])
->whereNull('movies.id')
->take($batch)
->get();
}
return ItemToFetchJobs::leftJoin('movies', function ($join) { return ItemToFetchJobs::leftJoin('movies', function ($join) {
$join->on('movies.tmdb_id', '=', 'item_to_fetch_jobs.tmdb_id'); $join->on('movies.tmdb_id', '=', 'item_to_fetch_jobs.tmdb_id');
}) })
->whereRaw("FIND_IN_SET('".$job."', item_to_fetch_jobs.jobs)") ->whereRaw("FIND_IN_SET('".$job."', item_to_fetch_jobs.jobs)")
->where('item_to_fetch_jobs.type', 'tv_series') ->where('item_to_fetch_jobs.type', 'movie')
->whereNotNull('movies.id') ->whereNotNull('movies.id')
->take($batch) ->take($batch)
->get(); ->get();
@@ -77,50 +66,57 @@ class MovieProcessingService implements ProcessingInterface
// @todo maybe raise an exception here // @todo maybe raise an exception here
return; return;
} }
echo "Processing {$methodName} ".$item->tmdb_id."\n"; echo "Processing {$methodName} ".$item->tmdb_id." (".$item->id.") \n";
$this->$methodName($item); $this->$methodName($item);
// maybe we should sleep for a while so we do not spam the tmdb api
sleep(1);
} }
private function getDetails($item) private function getDetails($item)
{ {
$tmdbMovie = $this->moviesApi->getMovie($item->tmdb_id); $tmdbMovie = $this->moviesApi->getMovie($item->tmdb_id);
if (isset($tmdbMovie['status_code']) && $tmdbMovie['status_code'] == 34) { if (isset($tmdbMovie['status_code']) && $tmdbMovie['status_code'] == 34) {
echo "[N]"; echo "[ApiError-Could not be found]\n]";
return; return;
} }
$tmdbMovie['tmdb_id'] = $tmdbMovie['id']; $tmdbMovie['tmdb_id'] = $tmdbMovie['id'];
Log::channel('fetch_export_items_details')->info("Processing TmdbId ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing TmdbId ".$tmdbMovie['tmdb_id']);
$movie = Movie::where('tmdb_id', $tmdbMovie['tmdb_id'])->first();
if($movie) {
return;
}
$tmdbMovie['slug'] = Str::slug($tmdbMovie['title'].'-'.$tmdbMovie['tmdb_id']); $tmdbMovie['slug'] = Str::slug($tmdbMovie['title'].'-'.$tmdbMovie['tmdb_id']);
$tmdbMovie['release_date'] = $tmdbMovie['release_date'] ? new \DateTime($tmdbMovie['release_date']) : null; $tmdbMovie['release_date'] = $tmdbMovie['release_date'] ? new \DateTime($tmdbMovie['release_date']) : null;
$movieId = Movie::create($tmdbMovie); $movie = Movie::where('tmdb_id', $tmdbMovie['tmdb_id'])->first();
if(!$movie) {
$movie = Movie::create($tmdbMovie);
}
$movieId = $movie->id;
// $movieId = Movie::create($tmdbMovie);
if (!empty($tmdbMovie['belongs_to_collection'])) { if (!empty($tmdbMovie['belongs_to_collection'])) {
Log::channel('fetch_export_items_details')->info("Processing collections for ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing collections for ".$tmdbMovie['tmdb_id']);
$this->processMovieCollection($movieId->id, $tmdbMovie['belongs_to_collection']); $this->processMovieCollection($movieId, $tmdbMovie['belongs_to_collection']);
} }
if (!empty($tmdbMovie['genres'])) { if (!empty($tmdbMovie['genres'])) {
Log::channel('fetch_export_items_details')->info("Processing genres for ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing genres for ".$tmdbMovie['tmdb_id']);
$this->processMovieGenres($movieId->id, $tmdbMovie['genres']); $this->processMovieGenres($movieId, $tmdbMovie['genres']);
} }
if (!empty($tmdbMovie['production_companies'])) { if (!empty($tmdbMovie['production_companies'])) {
Log::channel('fetch_export_items_details')->info("Processing production companies ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing production companies ".$tmdbMovie['tmdb_id']);
$this->processProductionCompanies($movieId->id, $tmdbMovie['production_companies']); $this->processProductionCompanies($movieId, $tmdbMovie['production_companies']);
} }
if (!empty($tmdbMovie['production_countries'])) { if (!empty($tmdbMovie['production_countries'])) {
Log::channel('fetch_export_items_details')->info("Processing production countries ".$tmdbMovie['tmdb_id']); Log::channel('fetch_export_items_details')->info("Processing production countries ".$tmdbMovie['tmdb_id']);
$this->processProductionCountries($movieId->id, $tmdbMovie['production_countries']); $this->processProductionCountries($movieId, $tmdbMovie['production_countries']);
} }
$this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details'); $this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details');
@@ -331,6 +327,7 @@ class MovieProcessingService implements ProcessingInterface
$tmdbMovieReviews = $this->moviesApi->getReviews($item->tmdb_id); $tmdbMovieReviews = $this->moviesApi->getReviews($item->tmdb_id);
if (empty($tmdbMovieReviews) || !isset($tmdbMovieReviews['results'])){ if (empty($tmdbMovieReviews) || !isset($tmdbMovieReviews['results'])){
echo "Nope";
return; return;
} }
@@ -346,6 +343,7 @@ class MovieProcessingService implements ProcessingInterface
$user = User::where('name', $tmdbReview['author'])->first(); $user = User::where('name', $tmdbReview['author'])->first();
if (!$user) { if (!$user) {
echo "Create user ".$tmdbReview['author'];
$user = User::create([ $user = User::create([
'name' => $tmdbReview['author'], 'name' => $tmdbReview['author'],
'slug' => Str::slug($tmdbReview['author']), 'slug' => Str::slug($tmdbReview['author']),
@@ -357,6 +355,7 @@ class MovieProcessingService implements ProcessingInterface
if (!$existingReview) { if (!$existingReview) {
echo "Create comment by user ".$tmdbReview['author']." on movie ".$movie->title;
Comment::create([ Comment::create([
'entity_id' => $movie->id, 'entity_id' => $movie->id,
'entity_type' => Comment::TYPE_MOVIE, 'entity_type' => Comment::TYPE_MOVIE,
@@ -678,7 +677,7 @@ class MovieProcessingService implements ProcessingInterface
->first(); ->first();
if (!$similarLink) { if (!$similarLink) {
MovieRecommendation::create([ MovieSimilar::create([
'movie_id' => $initialMovie->id, 'movie_id' => $initialMovie->id,
'similar_movie_id' => $similarMovie->id, 'similar_movie_id' => $similarMovie->id,
]); ]);
@@ -719,6 +718,8 @@ class MovieProcessingService implements ProcessingInterface
private function processMovieCollection(int $movieId, $belongsToCollection) private function processMovieCollection(int $movieId, $belongsToCollection)
{ {
dd($belongsToCollection);
$movieCollection = MovieCollection::where('tmdb_id', $belongsToCollection['id'])->first(); $movieCollection = MovieCollection::where('tmdb_id', $belongsToCollection['id'])->first();
if (!$movieCollection) { if (!$movieCollection) {
@@ -784,6 +785,7 @@ class MovieProcessingService implements ProcessingInterface
if (is_string($remainingJobs)) { if (is_string($remainingJobs)) {
$remainingJobs = explode(',', $remainingJobs); $remainingJobs = explode(',', $remainingJobs);
} else { } else {
dd($remainingJobs);
return; return;
} }
+1
View File
@@ -1,5 +1,6 @@
import './bootstrap'; import './bootstrap';
import './star_rating'; import './star_rating';
import './theme-switcher';
import $ from 'jquery'; import $ from 'jquery';
import Lightbox from "bs5-lightbox"; import Lightbox from "bs5-lightbox";
-1
View File
@@ -38,7 +38,6 @@
@livewireScripts @livewireScripts
@bukScripts @bukScripts
<script src="{{ asset('js/app.js') }}" defer></script> <script src="{{ asset('js/app.js') }}" defer></script>
<script src="{{ asset('js/theme-switcher.js') }}" defer></script>
@stack('scripts') @stack('scripts')
</body> </body>
</html> </html>
@@ -0,0 +1,34 @@
<div>
@if($collection)
<div class="collection-info mb-3">
<h6 class="text-muted">Part of the {{ $collection->name }} Collection</h6>
</div>
<div class="row">
@foreach($collectionMovies as $collectionMovie)
<div class="col-md-2 mb-3">
<a href="{{ route('movie.show', $collectionMovie->slug) }}" class="text-decoration-none">
@if($collectionMovie->poster_path)
<div class="movie-poster">
<img
src="http://image.tmdb.org/t/p/w185/{{ $collectionMovie->poster_path }}"
alt="{{ $collectionMovie->title }}"
title="{{ $collectionMovie->title }} @if($collectionMovie->release_date) ({{ $collectionMovie->release_date->format('Y') }}) @endif"
class="img-fluid rounded shadow-sm"
>
<div class="movie-title text-center mt-2">
<small>{{ $collectionMovie->title }}</small>
</div>
</div>
@else
<div class="no-poster rounded shadow-sm d-flex align-items-center justify-content-center p-2" style="height: 150px; background-color: #f8f9fa;">
<small class="text-center">
{{ $collectionMovie->title }} @if($collectionMovie->release_date) ({{ $collectionMovie->release_date->format('Y') }}) @endif
</small>
</div>
@endif
</a>
</div>
@endforeach
</div>
@endif
</div>
@@ -1,22 +1,26 @@
<div> <div>
<div class="row"> <div class="row">
@foreach($recommendations as $recommendation) @foreach($recommendations as $recommendation)
<div class="col-md-1"> <div class="col-md-2 mb-3">
<a href="{{ route('movie.show', $recommendation->slug) }}"> <a href="{{ route('movie.show', $recommendation->slug) }}" class="text-decoration-none">
@if($recommendation->poster_path) @if($recommendation->poster_path)
<img <div class="movie-poster">
src="http://image.tmdb.org/t/p/w185/{{ $recommendation->poster_path }}" <img
alt="{{ $recommendation->title }}" src="http://image.tmdb.org/t/p/w185/{{ $recommendation->poster_path }}"
title="{{ $recommendation->title }} @if($recommendation->release_date) ({{ $recommendation->release_date->format('Y') }}) @endif" alt="{{ $recommendation->title }}"
class="img img-fluid" title="{{ $recommendation->title }} @if($recommendation->release_date) ({{ $recommendation->release_date->format('Y') }}) @endif"
> class="img-fluid rounded shadow-sm"
>
<div class="movie-title text-center mt-2">
<small>{{ $recommendation->title }}</small>
</div>
</div>
@else @else
<span <div class="no-poster rounded shadow-sm d-flex align-items-center justify-content-center p-2" style="height: 150px; background-color: #f8f9fa;">
class="no-poster" <small class="text-center">
title="{{ $recommendation->title }} @if($recommendation->release_date) ({{ $recommendation->release_date->format('Y') }}) @endif" {{ $recommendation->title }} @if($recommendation->release_date) ({{ $recommendation->release_date->format('Y') }}) @endif
> </small>
{{ $recommendation->title }} @if($recommendation->release_date) ({{ $recommendation->release_date->format('Y') }}) @endif </div>
</span>
@endif @endif
</a> </a>
</div> </div>
@@ -1,22 +1,26 @@
<div> <div>
<div class="row"> <div class="row">
@foreach($similarMovies as $similarMovie) @foreach($similarMovies as $similarMovie)
<div class="col-md-1"> <div class="col-md-2 mb-3">
<a href="{{ route('movie.show', $similarMovie->slug) }}"> <a href="{{ route('movie.show', $similarMovie->slug) }}" class="text-decoration-none">
@if($similarMovie->poster_path) @if($similarMovie->poster_path)
<img <div class="movie-poster">
src="http://image.tmdb.org/t/p/w185/{{ $similarMovie->poster_path }}" <img
alt="{{ $similarMovie->title }}" src="http://image.tmdb.org/t/p/w185/{{ $similarMovie->poster_path }}"
title="{{ $similarMovie->title }} @if($similarMovie->release_date) ({{ $similarMovie->release_date->format('Y') }}) @endif" alt="{{ $similarMovie->title }}"
class="img img-fluid" title="{{ $similarMovie->title }} @if($similarMovie->release_date) ({{ $similarMovie->release_date->format('Y') }}) @endif"
> class="img-fluid rounded shadow-sm"
>
<div class="movie-title text-center mt-2">
<small>{{ $similarMovie->title }}</small>
</div>
</div>
@else @else
<span <div class="no-poster rounded shadow-sm d-flex align-items-center justify-content-center p-2" style="height: 150px; background-color: #f8f9fa;">
class="no-poster" <small class="text-center">
title="{{ $similarMovie->title }} @if($similarMovie->release_date) ({{ $similarMovie->release_date->format('Y') }}) @endif" {{ $similarMovie->title }} @if($similarMovie->release_date) ({{ $similarMovie->release_date->format('Y') }}) @endif
> </small>
{{ $similarMovie->title }} @if($similarMovie->release_date) ({{ $similarMovie->release_date->format('Y') }}) @endif </div>
</span>
@endif @endif
</a> </a>
</div> </div>
@@ -0,0 +1,25 @@
<div>
<!-- Backdrops -->
<h5 class="mb-3">Backdrops</h5>
<div class="row mb-4">
@foreach($images->where('type', 'backdrops') as $image)
<div class="col-md-4 mb-4">
<a href="http://image.tmdb.org/t/p/original{{ $image->file_path }}" data-toggle="lightbox">
<img src="http://image.tmdb.org/t/p/w500{{ $image->file_path }}" alt="Movie Backdrop" class="img-fluid rounded shadow-sm">
</a>
</div>
@endforeach
</div>
<!-- Posters -->
<h5 class="mb-3">Posters</h5>
<div class="row">
@foreach($images->where('type', 'posters') as $image)
<div class="col-md-3 mb-4">
<a href="http://image.tmdb.org/t/p/original{{ $image->file_path }}" data-toggle="lightbox">
<img src="http://image.tmdb.org/t/p/w342{{ $image->file_path }}" alt="Movie Poster" class="img-fluid rounded shadow-sm">
</a>
</div>
@endforeach
</div>
</div>
+18
View File
@@ -103,6 +103,9 @@
<li class="nav-item" role="presentation"> <li class="nav-item" role="presentation">
<button class="nav-link" id="releases-tab" data-bs-toggle="tab" data-bs-target="#releases" type="button" role="tab">Releases</button> <button class="nav-link" id="releases-tab" data-bs-toggle="tab" data-bs-target="#releases" type="button" role="tab">Releases</button>
</li> </li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="images-tab" data-bs-toggle="tab" data-bs-target="#images" type="button" role="tab">Images</button>
</li>
</ul> </ul>
<div class="tab-content p-3 border border-top-0 rounded-bottom" id="movieTabsContent"> <div class="tab-content p-3 border border-top-0 rounded-bottom" id="movieTabsContent">
<div class="tab-pane fade show active" id="details" role="tabpanel"> <div class="tab-pane fade show active" id="details" role="tabpanel">
@@ -120,6 +123,9 @@
<div class="tab-pane fade" id="releases" role="tabpanel"> <div class="tab-pane fade" id="releases" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Releases::class, ['movie' => $movie]) @livewire(App\Livewire\MoviePage\Tabs\Releases::class, ['movie' => $movie])
</div> </div>
<div class="tab-pane fade" id="images" role="tabpanel">
@livewire(App\Livewire\MoviePage\Tabs\Images::class, ['movie' => $movie])
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -127,6 +133,18 @@
</div> </div>
</div> </div>
<!-- Movie Collection -->
@if($movie->collections()->exists())
<div class="card mb-4">
<div class="card-header bg-white">
<h5 class="mb-0">Movie Collection</h5>
</div>
<div class="card-body">
@livewire(App\Livewire\MoviePage\Collection::class, ['movie' => $movie])
</div>
</div>
@endif
<!-- Similar Movies --> <!-- Similar Movies -->
<div class="card mb-4"> <div class="card mb-4">
<div class="card-header bg-white"> <div class="card-header bg-white">
Binary file not shown.