Files
HickLab3D_Dashboard/app/Console/Commands/RefreshFilamentPrices.php
T
Hickmeister 88dd00551f
Deploy HickLab3D Dashboard / Deploy to production (push) Failing after 19s
Migrate HickLab3D dashboard and add production auto deployment
2026-10-10 18:51:23 +01:00

68 lines
3.0 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Filament;
use App\Models\FilamentPrice;
use App\Models\User;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Mail;
use Throwable;
#[Signature('filaments:refresh')]
#[Description('Collect current Amazon prices for tracked filament')]
class RefreshFilamentPrices extends Command
{
public function handle(): int
{
$drops = [];
foreach (Filament::cursor() as $filament) {
$host = strtolower((string) parse_url($filament->amazonUrl, PHP_URL_HOST));
if (! in_array($host, ['amazon.co.uk', 'www.amazon.co.uk', 'amazon.com', 'www.amazon.com'], true)) {
$this->warn($filament->filamentName.': unsupported product host');
continue;
}
try {
$html = Http::timeout(15)->withHeaders(['User-Agent' => 'Mozilla/5.0 HickLab3D/1.0'])
->get($filament->amazonUrl)->throw()->body();
if (! preg_match('/class="[^"]*a-price-whole[^"]*"[^>]*>([0-9,.]+)/', $html, $whole)
|| ! preg_match('/class="[^"]*a-price-fraction[^"]*"[^>]*>([0-9]{2})/', $html, $fraction)) {
$this->warn($filament->filamentName.': price unavailable');
continue;
}
$price = (float) (str_replace(',', '', $whole[1]).'.'.$fraction[1]);
if ($price <= 0) {
continue;
}
preg_match('/class="[^"]*savingsPercentage[^"]*"[^>]*>[^0-9]*([0-9]+)%/', $html, $discount);
$previous = FilamentPrice::where('filamentId', $filament->id)->orderByDesc('recordedAt')->orderByDesc('id')->first();
FilamentPrice::create([
'filamentId' => $filament->id,
'price' => $price,
'currentDiscount' => ['discount' => ['value' => (int) ($discount[1] ?? 0), 'type' => 'percentage'], 'voucher' => ['value' => 0, 'type' => 'none']],
]);
if ($previous && $price < (float) $previous->price) {
$drops[] = $filament->filamentName.': £'.number_format((float) $previous->price, 2).' → £'.number_format($price, 2).' ('.$filament->amazonUrl.')';
}
$this->line($filament->filamentName.': £'.number_format($price, 2));
} catch (Throwable $exception) {
report($exception);
$this->warn($filament->filamentName.': collection failed');
}
}
if ($drops) {
$body = "HickLab3D filament price drops\n\n".implode("\n", $drops);
foreach (User::where('alertEmails', true)->where('disabled', false)->pluck('email') as $email) {
Mail::raw($body, fn ($message) => $message->to($email)->subject('HickLab3D filament price drops'));
}
}
return self::SUCCESS;
}
}