add: selective fetching to FetchMeta command

This commit is contained in:
hier0
2025-12-29 01:06:09 -08:00
parent 5098247711
commit 2eae647a70
3 changed files with 149 additions and 47 deletions
+1
View File
@@ -3,6 +3,7 @@ assertdontseetext
dispatchable
doesntcontain
doesntexist
doesntExpectOutput
dontbroadcasttocurrentuser
dontflash
dontrelease
+67 -47
View File
@@ -29,11 +29,11 @@ use Throwable;
class FetchMeta extends Command
{
/**
* The console command name.
* The name and signature of the console command.
*
* @var string
*/
protected $name = 'fetch:meta';
protected $signature = 'fetch:meta {--only= : Comma-separated list of types to fetch (movie,tv,game)}';
/**
* The console command description.
@@ -55,69 +55,89 @@ class FetchMeta extends Command
$tmdbScraper = new TMDBScraper();
$igdbScraper = new IgdbScraper();
$this->info('Querying all tmdb movie ids');
$onlyTypes = $this->option('only');
$tmdbMovieIds = Torrent::query()
->whereRelation('category', 'movie_meta', '=', true)
->select('tmdb_movie_id')
->distinct()
->whereNotNull('tmdb_movie_id')
->pluck('tmdb_movie_id');
if ($onlyTypes !== null) {
$types = array_map(trim(...), explode(',', $onlyTypes));
$fetchMovies = \in_array('movie', $types);
$fetchTv = \in_array('tv', $types);
$fetchGames = \in_array('game', $types);
} else {
// If no specific types are provided, fetch all types
$fetchMovies = true;
$fetchTv = true;
$fetchGames = true;
}
$this->info('Fetching '.$tmdbMovieIds->count().' movies');
if ($fetchMovies) {
$this->info('Querying all tmdb movie ids');
foreach ($tmdbMovieIds as $id) {
usleep(250_000);
$tmdbMovieIds = Torrent::query()
->whereRelation('category', 'movie_meta', '=', true)
->select('tmdb_movie_id')
->distinct()
->whereNotNull('tmdb_movie_id')
->pluck('tmdb_movie_id');
try {
ProcessMovieJob::dispatchSync($id);
$this->info("Movie metadata fetched for tmdb {$id}");
} catch (Exception $e) {
$this->warn("Movie metadata fetch failed for tmdb {$id}: ".$e->getMessage());
$this->info('Fetching '.$tmdbMovieIds->count().' movies');
foreach ($tmdbMovieIds as $id) {
usleep(250_000);
try {
ProcessMovieJob::dispatchSync($id);
$this->info("Movie metadata fetched for tmdb {$id}");
} catch (Exception $e) {
$this->warn("Movie metadata fetch failed for tmdb {$id}: ".$e->getMessage());
}
}
}
$this->info('Querying all tmdb tv ids');
if ($fetchTv) {
$this->info('Querying all tmdb tv ids');
$tmdbTvIds = Torrent::query()
->whereRelation('category', 'tv_meta', '=', true)
->select('tmdb_tv_id')
->distinct()
->whereNotNull('tmdb_tv_id')
->pluck('tmdb_tv_id');
$tmdbTvIds = Torrent::query()
->whereRelation('category', 'tv_meta', '=', true)
->select('tmdb_tv_id')
->distinct()
->whereNotNull('tmdb_tv_id')
->pluck('tmdb_tv_id');
$this->info('Fetching '.$tmdbTvIds->count().' tv series');
$this->info('Fetching '.$tmdbTvIds->count().' tv series');
foreach ($tmdbTvIds as $id) {
usleep(250_000);
foreach ($tmdbTvIds as $id) {
usleep(250_000);
try {
ProcessTvJob::dispatchSync($id);
$this->info("TV metadata fetched for tmdb {$id}");
} catch (Exception $e) {
$this->warn("TV metadata fetch failed for tmdb {$id}: ".$e->getMessage());
try {
ProcessTvJob::dispatchSync($id);
$this->info("TV metadata fetched for tmdb {$id}");
} catch (Exception $e) {
$this->warn("TV metadata fetch failed for tmdb {$id}: ".$e->getMessage());
}
}
}
$this->info('Querying all igdb game ids');
if ($fetchGames) {
$this->info('Querying all igdb game ids');
$igdbGameIds = Torrent::query()
->whereRelation('category', 'game_meta', '=', true)
->select('igdb')
->distinct()
->whereNotNull('igdb')
->pluck('igdb');
$igdbGameIds = Torrent::query()
->whereRelation('category', 'game_meta', '=', true)
->select('igdb')
->distinct()
->whereNotNull('igdb')
->pluck('igdb');
$this->info('Fetching '.$igdbGameIds->count().' games');
$this->info('Fetching '.$igdbGameIds->count().' games');
foreach ($igdbGameIds as $id) {
usleep(250_000);
foreach ($igdbGameIds as $id) {
usleep(250_000);
try {
ProcessIgdbGameJob::dispatchSync($id);
$this->info("Game metadata fetched for igdb {$id}");
} catch (Exception $e) {
$this->warn("Game metadata fetch failed for igdb {$id}: ".$e->getMessage());
try {
ProcessIgdbGameJob::dispatchSync($id);
$this->info("Game metadata fetched for igdb {$id}");
} catch (Exception $e) {
$this->warn("Game metadata fetch failed for igdb {$id}: ".$e->getMessage());
}
}
}
@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author HDVinnie <hdinnovations@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/
/**
* @see App\Console\Commands\FetchMeta
*/
it('fetches all types when no option provided', function (): void {
$this->artisan('fetch:meta')
->expectsOutput('Querying all tmdb movie ids')
->expectsOutput('Querying all tmdb tv ids')
->expectsOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('fetches only movies when movie specified', function (): void {
$this->artisan('fetch:meta', ['--only' => 'movie'])
->expectsOutput('Querying all tmdb movie ids')
->doesntExpectOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('fetches only tv when tv specified', function (): void {
$this->artisan('fetch:meta', ['--only' => 'tv'])
->doesntExpectOutput('Querying all tmdb movie ids')
->expectsOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('fetches only games when game specified', function (): void {
$this->artisan('fetch:meta', ['--only' => 'game'])
->doesntExpectOutput('Querying all tmdb movie ids')
->doesntExpectOutput('Querying all tmdb tv ids')
->expectsOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('fetches multiple types when specified', function (): void {
$this->artisan('fetch:meta', ['--only' => 'movie,tv'])
->expectsOutput('Querying all tmdb movie ids')
->expectsOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('handles whitespace in types', function (): void {
$this->artisan('fetch:meta', ['--only' => ' movie , tv '])
->expectsOutput('Querying all tmdb movie ids')
->expectsOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('ignores invalid types', function (): void {
$this->artisan('fetch:meta', ['--only' => 'invalid'])
->doesntExpectOutput('Querying all tmdb movie ids')
->doesntExpectOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});
it('processes valid types and ignores invalid ones', function (): void {
$this->artisan('fetch:meta', ['--only' => 'movie,invalid,tv'])
->expectsOutput('Querying all tmdb movie ids')
->expectsOutput('Querying all tmdb tv ids')
->doesntExpectOutput('Querying all igdb game ids')
->assertExitCode(0);
});