1
0

Added basic Rebrickable service

This commit is contained in:
Richard Dern 2024-04-18 01:52:40 +02:00
parent fd9fdc51f1
commit 214caa263b
5 changed files with 147 additions and 4 deletions

View File

@ -0,0 +1,29 @@
<?php
namespace App\Providers;
use App\Services\Rebrickable\RebrickableClient;
use Illuminate\Support\ServiceProvider;
class RebrickableServiceProvider extends ServiceProvider
{
/**
* Register services.
*/
public function register(): void
{
$this->app->singleton(RebrickableClient::class, function ($app) {
$config = $app['config']->get('services.rebrickable');
return new RebrickableClient($config);
});
}
/**
* Bootstrap services.
*/
public function boot(): void
{
//
}
}

View File

@ -2,25 +2,68 @@
namespace App\Services\BundleCreator\Creators\CollectibleCreators;
use App\Classes\Bundle;
use App\Exceptions\BundleAlreadyExists;
use App\Services\BundleCreator\Creators\BaseBundleCreator;
use App\Services\Rebrickable\RebrickableClient;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Str;
use function Laravel\Prompts\select;
use function Laravel\Prompts\text;
class LegoBundleCreator extends BaseBundleCreator
{
private static string $section = 'collections';
private static string $brand = 'lego';
public function __construct(protected ?array $data, protected FilesystemAdapter $disk)
{
}
/**
* Create a bundle
*/
public function createBundle(): string
{
$rebrickable = app()->make(RebrickableClient::class);
$setData = $rebrickable->getSet($this->data['rebrickable_id']);
$theme = $rebrickable->getTheme($setData['theme_id']);
$themeSlug = Str::slug($theme['name']);
$path = sprintf('%s/%s/%s/%s', static::$section, static::$brand, $themeSlug, $this->data['product_id']);
$bundle = new Bundle($path, $this->disk);
if ($bundle->exists()) {
throw new BundleAlreadyExists(
sprintf('A bundle already exists in %s', $path)
);
}
$bundle->markdown()->set('');
$bundle->metadata()->setMany([
'title' => $setData['name'],
'date' => now()->toIso8601String(),
]);
$bundle->metadata('metadata')->set('details.Identifiant', $this->data['product_id']);
$bundle->metadata('rebrickable')->setMany([
'set' => $setData,
]);
$bundle->save();
return $path;
}
/**
* Return a boolean value indicating if the creator can actually make the
* bundle using known data.
*/
public function canCreateBundle(): bool
{
return !empty($this->data['productId']);
return !empty($this->data['product_id']) && !empty($this->data['rebrickable_id']);
}
/**
@ -31,8 +74,15 @@ public function formSpecs(): ?array
{
$specs = [];
if (empty($this->data['productId'])) {
$specs['productId'] = fn () => text('Product ID', '', '', true);
if (empty($this->data['product_id'])) {
$specs['product_id'] = fn () => text('Product ID', '', '', true);
} else {
if (empty($this->data['rebrickable_id'])) {
$specs['rebrickable_id'] = fn () => select(
'Rebrickable Set ID',
app()->make(RebrickableClient::class)->searchSet($this->data['product_id'])
);
}
}
return $specs;
@ -44,6 +94,6 @@ public function formSpecs(): ?array
*/
public static function handles(string $section, ?array $data = []): bool
{
return $section === 'collections' && !empty($data['brand']) && $data['brand'] === 'lego';
return $section === static::$section && !empty($data['brand']) && $data['brand'] === static::$brand;
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace App\Services\Rebrickable;
use Illuminate\Support\Facades\Http;
class RebrickableClient
{
public function __construct(protected array $config)
{
}
/**
* Search for LEGO set Id, which will return a rebrickable set num
*/
public function searchSet(string $setId)
{
$response = $this->get(sprintf('sets/?search=%s', $setId));
$options = [];
foreach ($response['results'] as $result) {
$options[$result['set_num']] = $result['name'];
}
return $options;
}
/**
* Get a specific set from its rebrickable ID
*/
public function getSet(string $setId)
{
$response = $this->get(sprintf('sets/%s/', $setId));
return $response;
}
/**
* Get a specific theme from its rebrickable ID
*/
public function getTheme(string $themeId)
{
$response = $this->get(sprintf('themes/%s/', $themeId));
return $response;
}
private function get(string $url)
{
$key = $this->config['key'];
$baseUrl = $this->config['baseUrl'];
return Http::throw()
->withHeader('Authorization', sprintf('key %s', $key))
->get(sprintf('%s/%s', $baseUrl, $url))->json();
}
}

View File

@ -3,4 +3,5 @@
return [
App\Providers\AppServiceProvider::class,
App\Providers\BundleCreatorServiceProvider::class,
App\Providers\RebrickableServiceProvider::class,
];

View File

@ -14,6 +14,11 @@
|
*/
'rebrickable' => [
'baseUrl' => 'https://rebrickable.com/api/v3/lego',
'key' => env('REBRICKABLE_API_KEY'),
],
'postmark' => [
'token' => env('POSTMARK_TOKEN'),
],