diff --git a/src/Services/InfoProviderSystem/Providers/CanopyProvider.php b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php new file mode 100644 index 00000000..e6ca3961 --- /dev/null +++ b/src/Services/InfoProviderSystem/Providers/CanopyProvider.php @@ -0,0 +1,177 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Services\InfoProviderSystem\Providers; + +use App\Services\InfoProviderSystem\DTOs\FileDTO; +use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; +use App\Services\InfoProviderSystem\DTOs\PriceDTO; +use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; +use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; +use App\Settings\InfoProviderSystem\BuerklinSettings; +use App\Settings\InfoProviderSystem\CanopySettings; +use Symfony\Component\DependencyInjection\Attribute\When; +use Symfony\Contracts\HttpClient\HttpClientInterface; + +/** + * Use canopy API to retrieve infos from amazon + */ +class CanopyProvider implements InfoProviderInterface +{ + + public const BASE_URL = "https://rest.canopyapi.co/api"; + public const SEARCH_API_URL = self::BASE_URL . "/amazon/search"; + public const DETAIL_API_URL = self::BASE_URL . "/amazon/product"; + + public const DISTRIBUTOR_NAME = 'Amazon'; + + public function __construct(private readonly CanopySettings $settings, private readonly HttpClientInterface $httpClient) + { + + } + + public function getProviderInfo(): array + { + return [ + 'name' => 'Amazon (Canopy)', + 'description' => 'Retrieves part infos from Amazon using the Canopy API', + 'url' => 'https://canopyapi.co', + 'disabled_help' => 'Set Canopy API key in the provider configuration to enable this provider', + 'settings_class' => CanopySettings::class + ]; + } + + public function getProviderKey(): string + { + return 'canopy'; + } + + public function isActive(): bool + { + return $this->settings->apiKey !== null; + } + + private function productPageFromASIN(string $asin): string + { + return "https://www.amazon.{$this->settings->domain}/dp/{$asin}"; + } + + public function searchByKeyword(string $keyword): array + { + $response = $this->httpClient->request('GET', self::SEARCH_API_URL, [ + 'query' => [ + 'domain' => $this->settings->domain, + 'searchTerm' => $keyword, + ], + 'headers' => [ + 'API-KEY' => $this->settings->apiKey, + ] + ]); + + $data = $response->toArray(); + $results = $data['data']['amazonProductSearchResults']['productResults']['results'] ?? []; + + $out = []; + foreach ($results as $result) { + $out[] = new SearchResultDTO( + provider_key: $this->getProviderKey(), + provider_id: $result['asin'], + name: $result["title"], + description: "", + preview_image_url: $result["mainImageUrl"] ?? null, + provider_url: $this->productPageFromASIN($result['asin']), + ); + } + + return $out; + } + + private function categoriesToCategory(array $categories): ?string + { + if (count($categories) === 0) { + return null; + } + + return implode(" -> ", array_map(static fn($cat) => $cat['name'], $categories)); + } + + private function feauturesBulletsToNotes(array $featureBullets): string + { + $notes = "