Expand IGDB data: collections, game modes, themes, perspectives, videos, websites, age ratings, similar games; add backfill command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
0eab3e8dbf
commit
2a724c0ae2
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Game;
|
||||
use App\Services\IgdbService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class BackfillExtendedDataCommand extends Command
|
||||
{
|
||||
protected $signature = 'igdb:backfill-extended
|
||||
{--limit=100 : Max number of games to process}
|
||||
{--offset=0 : Skip the first N games (ordered by id)}';
|
||||
|
||||
protected $description = 'Backfill extended IGDB data (collections, modes, themes, videos, etc.) for existing games';
|
||||
|
||||
public function handle(IgdbService $igdb): int
|
||||
{
|
||||
$limit = (int) $this->option('limit');
|
||||
$offset = (int) $this->option('offset');
|
||||
|
||||
$games = Game::whereNotNull('igdb_id')
|
||||
->orderBy('id')
|
||||
->skip($offset)
|
||||
->take($limit)
|
||||
->get();
|
||||
|
||||
$total = $games->count();
|
||||
|
||||
if ($total === 0) {
|
||||
$this->info('No games found to process.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$this->info("Processing {$total} games (offset: {$offset})…");
|
||||
$this->newLine();
|
||||
|
||||
$n = 0;
|
||||
foreach ($games->chunk(10) as $batch) {
|
||||
$igdbIds = $batch->pluck('igdb_id')->all();
|
||||
|
||||
try {
|
||||
$igdbResults = $igdb->getGamesByIds($igdbIds);
|
||||
} catch (\Exception $e) {
|
||||
$this->error('IGDB request failed: ' . $e->getMessage());
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$indexed = collect($igdbResults)->keyBy('id');
|
||||
|
||||
foreach ($batch as $game) {
|
||||
$n++;
|
||||
$igdbData = $indexed->get($game->igdb_id);
|
||||
|
||||
if (!$igdbData) {
|
||||
$this->warn(" [{$n}/{$total}] No IGDB data for: {$game->title} (igdb_id={$game->igdb_id})");
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$igdb->syncExtendedData($game, $igdbData);
|
||||
$this->line(" [{$n}/{$total}] Processed: {$game->title}");
|
||||
} catch (\Exception $e) {
|
||||
$this->warn(" [{$n}/{$total}] Failed {$game->title}: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
usleep(250000); // 250ms between IGDB batches
|
||||
}
|
||||
|
||||
$this->newLine();
|
||||
$this->info('Extended data sync complete. Resolving similar_games pivot…');
|
||||
|
||||
$this->resolveSimilarGames();
|
||||
|
||||
$this->info('Done.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function resolveSimilarGames(): void
|
||||
{
|
||||
$resolved = 0;
|
||||
Game::whereNotNull('similar_game_igdb_ids')->chunk(100, function ($games) use (&$resolved) {
|
||||
foreach ($games as $game) {
|
||||
$ids = $game->similar_game_igdb_ids;
|
||||
if (empty($ids)) continue;
|
||||
|
||||
$similarIds = Game::whereIn('igdb_id', $ids)->pluck('id');
|
||||
$game->similarGames()->sync($similarIds);
|
||||
$resolved++;
|
||||
}
|
||||
});
|
||||
$this->line(" Resolved similar_games for {$resolved} games.");
|
||||
}
|
||||
}
|
||||
@@ -89,5 +89,7 @@ trait UpsertsGames
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$igdb->syncExtendedData($game, $data);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user