mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-13 04:30:41 -05:00
Early Mod Import
This commit is contained in:
parent
9f0bfda462
commit
8e11892f57
@ -2,11 +2,15 @@
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\License;
|
||||
use App\Models\Mod;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ImportWoltlabData extends Command
|
||||
{
|
||||
@ -30,6 +34,8 @@ class ImportWoltlabData extends Command
|
||||
public function handle(): void
|
||||
{
|
||||
$this->importUsers();
|
||||
$this->importLicenses();
|
||||
$this->importMods();
|
||||
$this->info('Data imported successfully.');
|
||||
}
|
||||
|
||||
@ -47,6 +53,7 @@ class ImportWoltlabData extends Command
|
||||
$registrationDate->setTimezone('UTC');
|
||||
|
||||
$insertData[] = [
|
||||
'hub_id' => $wolt->userID,
|
||||
'name' => $wolt->username,
|
||||
'email' => mb_convert_case($wolt->email, MB_CASE_LOWER, 'UTF-8'),
|
||||
'password' => $wolt->password,
|
||||
@ -56,15 +63,143 @@ class ImportWoltlabData extends Command
|
||||
}
|
||||
|
||||
if (!empty($insertData)) {
|
||||
User::insert($insertData);
|
||||
User::upsert($insertData, ['hub_id'], ['name', 'email', 'password', 'created_at', 'updated_at']);
|
||||
$totalInserted += count($insertData);
|
||||
$this->info('Inserted ' . count($insertData) . ' users. Total inserted so far: ' . $totalInserted);
|
||||
$this->line('Processed ' . count($insertData) . ' users. Total processed so far: ' . $totalInserted);
|
||||
}
|
||||
|
||||
unset($insertData);
|
||||
unset($users);
|
||||
}, 'userID');
|
||||
|
||||
$this->info('Total users inserted: ' . $totalInserted);
|
||||
$this->info('Total users processed: ' . $totalInserted);
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
protected function importLicenses(): void
|
||||
{
|
||||
$totalInserted = 0;
|
||||
|
||||
DB::connection('mysql_woltlab')->table('filebase1_license')->chunkById(100, function (Collection $licenses) use (&$totalInserted) {
|
||||
$insertData = [];
|
||||
foreach ($licenses as $license) {
|
||||
$insertData[] = [
|
||||
'hub_id' => $license->licenseID,
|
||||
'name' => $license->licenseName,
|
||||
'link' => $license->licenseURL,
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($insertData)) {
|
||||
DB::table('licenses')->upsert($insertData, ['hub_id'], ['name', 'link']);
|
||||
$totalInserted += count($insertData);
|
||||
$this->line('Processed ' . count($insertData) . ' licenses. Total processed so far: ' . $totalInserted);
|
||||
}
|
||||
|
||||
unset($insertData);
|
||||
unset($licenses);
|
||||
}, 'licenseID');
|
||||
|
||||
$this->info('Total licenses processed: ' . $totalInserted);
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
protected function importMods(): void
|
||||
{
|
||||
$command = $this;
|
||||
$totalInserted = 0;
|
||||
|
||||
DB::connection('mysql_woltlab')->table('filebase1_file')->chunkById(5, function (Collection $mods) use (&$command, &$totalInserted) {
|
||||
|
||||
foreach ($mods as $mod)
|
||||
{
|
||||
$modContent = DB::connection('mysql_woltlab')->table('filebase1_file_content')->where('fileID', $mod->fileID)->first();
|
||||
|
||||
$insertData[] = [
|
||||
'hub_id' => $mod->fileID,
|
||||
'user_id' => User::whereName($mod->username)->value('id'),
|
||||
'name' => $modContent->subject,
|
||||
'slug' => Str::slug($modContent->subject),
|
||||
'teaser' => $modContent->teaser,
|
||||
'description' => $modContent->message,
|
||||
'thumbnail' => $this->fetchModThumbnail($command, $mod->fileID, $mod->iconHash, $mod->iconExtension),
|
||||
'license_id' => License::whereHubId($mod->licenseID)->value('id'),
|
||||
'source_code_link' => $this->fetchSourceLinkValue($mod->fileID),
|
||||
'featured' => $mod->isFeatured,
|
||||
'contains_ai_content' => $this->fetchContainsAiContentValue($mod->fileID),
|
||||
'disabled' => $mod->isDisabled,
|
||||
'created_at' => Carbon::parse($mod->time, 'UTC'),
|
||||
'updated_at' => Carbon::parse($mod->lastChangeTime, 'UTC'),
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($insertData)) {
|
||||
Mod::upsert($insertData, ['hub_id'], ['user_id', 'name', 'slug', 'teaser', 'description', 'thumbnail', 'license_id', 'source_code_link', 'featured', 'contains_ai_content', 'disabled', 'created_at', 'updated_at']);
|
||||
$totalInserted += count($insertData);
|
||||
$command->line('Processed ' . count($insertData) . ' mods. Total processed so far: ' . $totalInserted);
|
||||
}
|
||||
|
||||
unset($insertData);
|
||||
unset($mods);
|
||||
}, 'fileID');
|
||||
|
||||
$this->info('Total mods processed: ' . $totalInserted);
|
||||
$this->newLine();
|
||||
}
|
||||
|
||||
protected function fetchSourceLinkValue(string $fileID): string
|
||||
{
|
||||
$options = DB::connection('mysql_woltlab')->table('filebase1_file_option_value')->where('fileID', $fileID)->get();
|
||||
|
||||
// Iterate over the options and find the 'optionID' of 5 or 1. That record will contain the source code link in
|
||||
// the 'optionValue' column. The 'optionID' of 5 should take precedence over 1. If neither are found, return an
|
||||
// empty string.
|
||||
foreach ($options as $option) {
|
||||
if ($option->optionID == 5 && !empty($option->optionValue)) {
|
||||
return $option->optionValue;
|
||||
}
|
||||
if ($option->optionID == 1 && !empty($option->optionValue)) {
|
||||
return $option->optionValue;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function fetchContainsAiContentValue(string $fileID): bool
|
||||
{
|
||||
$options = DB::connection('mysql_woltlab')->table('filebase1_file_option_value')->where('fileID', $fileID)->get();
|
||||
|
||||
// Iterate over the options and find the 'optionID' of 7. That record will contain the AI flag.
|
||||
foreach ($options as $option) {
|
||||
if ($option->optionID == 7) {
|
||||
return (bool) $option->optionValue;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function fetchModThumbnail($command, string $fileID, string $thumbnailHash, string $thumbnailExtension): string
|
||||
{
|
||||
if (empty($fileID) || empty($thumbnailHash) || empty($thumbnailExtension)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Only the first two characters of the icon hash.
|
||||
$hashShort = substr($thumbnailHash, 0, 2);
|
||||
|
||||
$hubUrl = "https://hub.sp-tarkov.com/files/images/file/$hashShort/$fileID.$thumbnailExtension";
|
||||
$localPath = "mods/$thumbnailHash.$thumbnailExtension";
|
||||
|
||||
// Check to make sure the image doesn't already exist.
|
||||
if (Storage::disk('public')->exists($localPath)) {
|
||||
return "/storage/$localPath";
|
||||
}
|
||||
|
||||
$command->output->write("Downloading mod thumbnail: $hubUrl... ");
|
||||
Storage::disk('public')->put($localPath, file_get_contents($hubUrl));
|
||||
$command->info('Done.');
|
||||
|
||||
// Return the path to the saved thumbnail.
|
||||
return "/storage/$localPath";
|
||||
}
|
||||
}
|
||||
|
@ -9,20 +9,20 @@ use Illuminate\View\Component;
|
||||
|
||||
class ModListSection extends Component
|
||||
{
|
||||
public Collection $modsSuggested;
|
||||
public Collection $modsFeatured;
|
||||
public Collection $modsLatest;
|
||||
public Collection $modsUpdated;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->modsSuggested = $this->fetchSuggestedMods();
|
||||
$this->modsFeatured = $this->fetchFeaturedMods();
|
||||
$this->modsLatest = $this->fetchLatestMods();
|
||||
$this->modsUpdated = $this->fetchUpdatedMods();
|
||||
}
|
||||
|
||||
private function fetchSuggestedMods(): Collection
|
||||
private function fetchFeaturedMods(): Collection
|
||||
{
|
||||
return Mod::with('versionLatestSptVersion.sptVersion')->whereSuggested(true)->take(6)->get();
|
||||
return Mod::with('versionLatestSptVersion.sptVersion')->whereFeatured(true)->take(6)->get();
|
||||
}
|
||||
|
||||
private function fetchLatestMods(): Collection
|
||||
@ -39,8 +39,8 @@ class ModListSection extends Component
|
||||
{
|
||||
return [
|
||||
[
|
||||
'title' => 'Suggested Mods',
|
||||
'mods' => $this->modsSuggested,
|
||||
'title' => 'Featured Mods',
|
||||
'mods' => $this->modsFeatured,
|
||||
'versionScope' => 'versionLatestSptVersion'
|
||||
],
|
||||
[
|
||||
|
@ -20,10 +20,11 @@ class ModFactory extends Factory
|
||||
'user_id' => User::factory(),
|
||||
'name' => $name,
|
||||
'slug' => Str::slug($name),
|
||||
'description' => $this->faker->paragraph,
|
||||
'teaser' => $this->faker->sentence,
|
||||
'description' => $this->faker->sentences(6, true),
|
||||
'license_id' => License::factory(),
|
||||
'source_code_link' => $this->faker->url(),
|
||||
'suggested' => $this->faker->boolean,
|
||||
'featured' => $this->faker->boolean,
|
||||
'contains_ai_content' => $this->faker->boolean,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
|
@ -13,6 +13,7 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hub_id')->nullable()->unique();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
|
@ -10,6 +10,7 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('licenses', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hub_id')->nullable()->unique();
|
||||
$table->string('name');
|
||||
$table->string('link');
|
||||
$table->softDeletes();
|
||||
|
@ -12,14 +12,18 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('mods', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hub_id')->nullable()->unique();
|
||||
$table->foreignIdFor(User::class)->constrained('users');
|
||||
$table->string('name');
|
||||
$table->string('slug');
|
||||
$table->string('teaser');
|
||||
$table->longText('description');
|
||||
$table->foreignIdFor(License::class)->constrained('licenses');
|
||||
$table->string('thumbnail')->default('');
|
||||
$table->foreignIdFor(License::class)->nullable()->default(null)->constrained('licenses');
|
||||
$table->string('source_code_link');
|
||||
$table->boolean('suggested')->default(false);
|
||||
$table->boolean('featured')->default(false);
|
||||
$table->boolean('contains_ai_content')->default(false);
|
||||
$table->boolean('disabled')->default(false);
|
||||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
@ -10,6 +10,7 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('spt_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hub_id')->nullable()->unique();
|
||||
$table->string('version');
|
||||
$table->string('color_class');
|
||||
$table->softDeletes();
|
||||
|
@ -12,6 +12,7 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('mod_versions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hub_id')->nullable()->unique();
|
||||
$table->foreignIdFor(Mod::class)->constrained('mods');
|
||||
$table->string('version');
|
||||
$table->longText('description');
|
||||
|
Loading…
x
Reference in New Issue
Block a user