138
app/Actions/Channels/FetchContentFromLocalDatabase.php
Executable file
138
app/Actions/Channels/FetchContentFromLocalDatabase.php
Executable file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Channels;
|
||||
|
||||
use App\Models\Episode;
|
||||
use App\Models\Genre;
|
||||
use App\Models\Keyword;
|
||||
use App\Models\Person;
|
||||
use App\Models\ProductionCountry;
|
||||
use App\Models\Title;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class FetchContentFromLocalDatabase
|
||||
{
|
||||
public function execute(
|
||||
string $method,
|
||||
string $modelType,
|
||||
?array $filters = [],
|
||||
): Collection {
|
||||
$isSeries = $modelType === Title::SERIES_TYPE;
|
||||
if ($method === 'trendingPeople') {
|
||||
return Person::orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
} elseif ($method === 'mostPopular') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
->orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->where('is_series', $isSeries)
|
||||
->get();
|
||||
} elseif ($method === 'topRated') {
|
||||
return $this->getTopRatedTitles(
|
||||
$this->getTitleBuilder($filters),
|
||||
$isSeries,
|
||||
);
|
||||
} elseif ($method === 'upcoming') {
|
||||
return $this->getMoviesReleasingBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addWeek(),
|
||||
);
|
||||
} elseif ($method === 'nowPlaying') {
|
||||
return $this->getMoviesReleasingBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->subWeek(),
|
||||
);
|
||||
} elseif ($method === 'onTheAir') {
|
||||
$this->getSeriesAiringBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addWeek(),
|
||||
);
|
||||
} elseif ($method === 'airingToday') {
|
||||
return $this->getSeriesAiringBetween(
|
||||
$this->getTitleBuilder($filters),
|
||||
Carbon::now(),
|
||||
Carbon::now()->addDay(),
|
||||
);
|
||||
} elseif ($method === 'latestVideos') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
->join('videos', 'titles.id', '=', 'videos.title_id')
|
||||
->where('videos.origin', 'local')
|
||||
->where('approved', true)
|
||||
->orderBy('videos.created_at', 'desc')
|
||||
->select('titles.*')
|
||||
->distinct()
|
||||
->limit(20)
|
||||
->get();
|
||||
} elseif ($method === 'lastAdded') {
|
||||
return $this->getTitleBuilder($filters)
|
||||
::where('is_series', $isSeries)
|
||||
->orderBy('created_at', 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
private function getTopRatedTitles(mixed $builder, $isSeries): Collection
|
||||
{
|
||||
$ratingCol = config('common.site.rating_column');
|
||||
|
||||
$query = $builder->where('is_series', $isSeries);
|
||||
|
||||
if (Str::contains($ratingCol, 'tmdb_vote_average')) {
|
||||
$query->orderBy(DB::raw('tmdb_vote_count > 100'), 'desc');
|
||||
}
|
||||
|
||||
return $query
|
||||
->orderBy($ratingCol, 'desc')
|
||||
->limit(20)
|
||||
->get();
|
||||
}
|
||||
|
||||
private function getMoviesReleasingBetween(
|
||||
mixed $builder,
|
||||
$from,
|
||||
$to,
|
||||
): Collection {
|
||||
return $builder
|
||||
->whereBetween('release_date', [$from, $to])
|
||||
->orderBy('popularity', 'desc')
|
||||
->limit(20)
|
||||
->where('is_series', false)
|
||||
->get(['id', 'name']);
|
||||
}
|
||||
|
||||
private function getSeriesAiringBetween(
|
||||
mixed $builder,
|
||||
$from,
|
||||
$to,
|
||||
): Collection {
|
||||
$titleIds = Episode::whereBetween('release_date', [$from, $to])
|
||||
->limit(300)
|
||||
->get(['title_id'])
|
||||
->pluck('title_id')
|
||||
->unique()
|
||||
->slice(0, 20);
|
||||
|
||||
return $builder->whereIn('id', $titleIds)->get(['id', 'name']);
|
||||
}
|
||||
|
||||
private function getTitleBuilder(?array $filters = []): mixed
|
||||
{
|
||||
if (isset($filters['keyword'])) {
|
||||
return Keyword::findOrFail($filters['keyword'])->titles();
|
||||
} elseif (isset($filters['genre'])) {
|
||||
return Genre::findOrFail($filters['genre'])->titles();
|
||||
} elseif (isset($filters['country'])) {
|
||||
return ProductionCountry::findOrFail($filters['country'])->titles();
|
||||
} else {
|
||||
return Title::query();
|
||||
}
|
||||
}
|
||||
}
|
||||
160
app/Actions/Channels/FetchContentFromTmdb.php
Executable file
160
app/Actions/Channels/FetchContentFromTmdb.php
Executable file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace App\Actions\Channels;
|
||||
|
||||
use App\Models\Person;
|
||||
use App\Models\Title;
|
||||
use App\Services\Data\Tmdb\TmdbApi;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class FetchContentFromTmdb
|
||||
{
|
||||
public function execute(
|
||||
string $method,
|
||||
string $modelType,
|
||||
?array $filters = [],
|
||||
): Collection {
|
||||
Title::disableSearchSyncing();
|
||||
Person::disableSearchSyncing();
|
||||
if ($modelType === Person::MODEL_TYPE) {
|
||||
return $this->importPeople($method);
|
||||
} else {
|
||||
return $this->ImportTitles($method, $modelType, $filters);
|
||||
}
|
||||
}
|
||||
|
||||
protected function importPeople(string $method)
|
||||
{
|
||||
if ($method === 'trendingPeople') {
|
||||
$people = app(TmdbApi::class)->trendingPeople();
|
||||
return $people
|
||||
->map(
|
||||
fn($personData) => Person::firstOrCreateFromEncodedTmdbId(
|
||||
$personData['id'],
|
||||
)->maybeUpdateFromExternal([
|
||||
'forceAutomation' => true,
|
||||
]),
|
||||
)
|
||||
->filter();
|
||||
}
|
||||
}
|
||||
|
||||
protected function ImportTitles(
|
||||
string $method,
|
||||
string $modelType,
|
||||
?array $extraFilters = [],
|
||||
) {
|
||||
$filters = $this->buildFilters($method, $modelType);
|
||||
|
||||
if (count($extraFilters)) {
|
||||
if (isset($extraFilters['keyword'])) {
|
||||
$filters['with_keywords'] = $extraFilters['keyword'];
|
||||
}
|
||||
if (isset($extraFilters['genre'])) {
|
||||
$filters['with_genres'] = $extraFilters['genre'];
|
||||
}
|
||||
if (isset($extraFilters['country'])) {
|
||||
$filters['with_origin_country'] = $extraFilters['country'];
|
||||
}
|
||||
if (isset($extraFilters['language'])) {
|
||||
$filters['with_original_language'] = $extraFilters['language'];
|
||||
}
|
||||
}
|
||||
|
||||
// fetch from tmdb
|
||||
$titles = app(TmdbApi::class)->browse(1, $modelType, $filters)[
|
||||
'results'
|
||||
];
|
||||
|
||||
// store in local db
|
||||
return $titles
|
||||
->map(function ($titleData) {
|
||||
return Title::firstOrCreateFromEncodedTmdbId(
|
||||
$titleData['id'],
|
||||
)->maybeUpdateFromExternal([
|
||||
'forceAutomation' => true,
|
||||
//'updateLast3Seasons' => true,
|
||||
]);
|
||||
})
|
||||
->filter();
|
||||
}
|
||||
|
||||
protected function buildFilters(string $method, string $modelType): array
|
||||
{
|
||||
$type = "{$modelType}.{$method}";
|
||||
switch ($type) {
|
||||
case 'movie.mostPopular':
|
||||
$from = Carbon::now()
|
||||
->subMonths(6)
|
||||
->format('Y-m-d');
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
'primary_release_date.gte' => $from,
|
||||
];
|
||||
case 'movie.topRated':
|
||||
case 'series.topRated':
|
||||
return [
|
||||
'sort_by' => 'vote_average.desc',
|
||||
'vote_count.gte' => 600,
|
||||
];
|
||||
case 'movie.upcoming':
|
||||
$from = Carbon::now()
|
||||
->addDay()
|
||||
->format('Y-m-d');
|
||||
$to = Carbon::now()
|
||||
->addMonth()
|
||||
->format('Y-m-d');
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
'with_release_type' => '2|3',
|
||||
'primary_release_date.gte' => $from,
|
||||
'primary_release_date.lte' => $to,
|
||||
];
|
||||
case 'movie.nowPlaying':
|
||||
$from = Carbon::now()
|
||||
->subMonths(2)
|
||||
->format('Y-m-d');
|
||||
$to = Carbon::now()
|
||||
->subDays(2)
|
||||
->format('Y-m-d');
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
'with_release_type' => '2|3',
|
||||
'primary_release_date.gte' => $from,
|
||||
'primary_release_date.lte' => $to,
|
||||
];
|
||||
case 'series.mostPopular':
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
];
|
||||
case 'series.airingThisWeek':
|
||||
$from = Carbon::now()
|
||||
->startOfDay()
|
||||
->format('Y-m-d');
|
||||
$to = Carbon::now()
|
||||
->startOfDay()
|
||||
->addDays(6)
|
||||
->format('Y-m-d');
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
'air_date.gte' => $from,
|
||||
'air_date.lte' => $to,
|
||||
];
|
||||
case 'series.airingToday':
|
||||
$from = Carbon::now()
|
||||
->startOfDay()
|
||||
->format('Y-m-d');
|
||||
$to = Carbon::now()
|
||||
->endOfDay()
|
||||
->format('Y-m-d');
|
||||
return [
|
||||
'sort_by' => 'popularity.desc',
|
||||
'air_date.gte' => $from,
|
||||
'air_date.lte' => $to,
|
||||
];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user