Basic online search with bugs...

This commit is contained in:
2024-02-04 19:35:22 +01:00
parent d1f5810635
commit 354ac8a242
11 changed files with 549 additions and 96 deletions

View File

@@ -12,15 +12,19 @@ use PHPHtmlParser\Dom;
class CountryCompareController extends Controller
{
private $countries = [];
private $cHash = [];
public function __construct()
{
$countries = [];
CountryCode::all()->each(function ($country) use (&$countries) {
$countries[] = $country->country_name;
$cHash = [];
CountryCode::active('Y')->each(function ($country) use (&$countries, &$cHash) {
$countries[] = $country;
$cHash[$country->country_name] = $country->country_code;
});
$this->countries = collect($countries);
$this->cHash = collect($cHash);
}
public function search(Request $request)
{
@@ -31,13 +35,16 @@ class CountryCompareController extends Controller
return $this->processResponse($requests,$ta_codes[0]);
}
public function compare($countries, $cHash, $aCodes){
$requests = $this->makeRequests($aCodes);
return $this->processResponse($requests, $aCodes);
}
public function makeRequests($ta_code)
{
$requests = Http::pool(fn (Pool $pool) => [
CountryCode::all()->each(function ($countryCode) use ($pool, $ta_code) {
$this->countries[] = $countryCode->country_name;
Log::info('Getting page {url}', [ 'url' => $countryCode->search_url . $ta_code ] );
return $pool->as($countryCode->country_name)->get($countryCode->search_url . $ta_code);
$this->countries->each(function ($country) use ($pool, $ta_code) {
Log::info('Getting page {url}', [ 'url' => $country->search_url . $ta_code ] );
return $pool->as($country->country_code)->get($country->search_url . $ta_code);
})
]);
return $requests;
@@ -45,9 +52,9 @@ class CountryCompareController extends Controller
public function makeRequest($ta_code, $country)
{
$countryCode = CountryCode::where('country_name', $country)->first();
$country = CountryCode::where('country_name', $country)->first();
return Http::pool(fn (Pool $pool) => [
$pool->as($countryCode->country_name)->get($countryCode->search_url . $ta_code)
$pool->as($country->country_name)->get($country->search_url . $ta_code)
]);
}
@@ -55,38 +62,49 @@ class CountryCompareController extends Controller
{
$prices = [];
foreach ($this->countries as $country) {
foreach ($this->countries as $c) {
if (isset($responses[$country]) && $responses[$country]->ok()) {
$country = $c->country_code;
if ($responses[$country] instanceof \Illuminate\Http\Client\Response && $responses[$country]->ok()) {
$response = $responses[$country]->body();
switch ($country) {
case "Bulgaria":
case "Cyprus":
case "Greece":
$prices[$country] = $this->parseJson_CY_GR_BG($code, (string) $response);
case "BG":
case "BY":
case "GR":
$prices[$country] = $this->parseJson_CY_GR_BG($code, (string) $response, $country);
break;
case "Iceland":
$prices[$country] = $this->parseJson_IS($country, $code, (string) $response);
case "IS":
$prices[$country] = $this->parseJson_IS($code, (string) $response, $country);
break;
case "Türkiye":
$prices[$country] = $this->parseJson_TR((string) $response);
case "TR":
$prices[$country] = $this->parseJson_TR((string) $response, $country);
break;
case "Lithuania":
case "Estonia":
case "Latvia":
$prices[$country] = $this->parseJson_EE_LT_LV($country, $code, (string) $response);
case "EE":
case "LT":
case "LV":
$prices[$country] = $this->parseJson_EE_LT_LV($code, (string) $response, $country);
break;
default:
$prices[$country] = $this->parseJson((string) $response);
$prices[$country] = $this->parseJson((string) $response, $country);
}
}
}
return $prices;
$products = [];
collect($prices)->each(function ($price) use (&$products) {
if (count($price))
$products[] = $price;
});
return collect($products);
}
public function parseJson($json_raw)
// { "country": "AT", "code": "50161321", "url": "https://www.ikea.com/at/de/p/hol-aufbewahrungstisch-akazie-50161321/", "name": "HOL", "typeName": "Aufbewahrungstisch", "mainImageUrl": "https://www.ikea.com/at/de/images/products/hol-aufbewahrungstisch-akazie__0104310_pe251255_s5.jpg", "itemNoGlobal": "50161321", "salesPrice": "80.99", "tag": "FAMILY_PRICE", "last_mod": "2023-12-03 16:44:24" },
public function parseJson($json_raw, $country)
{
try {
$json_values = array();
$json_decoded = json_decode($json_raw, true);
@@ -103,18 +121,21 @@ class CountryCompareController extends Controller
$numeral = $salesPrice["numeral"];
$json_values = array(
'url_product' => $product['pipUrl'],
'url' => $product['pipUrl'],
'tag' => $product['tag'],
'price' => $numeral,
'price_eur' => 0
'country' => $country,
'salesPrice' => $numeral,
);
break;
}
} catch (\Exception $e) {
return [];
}
return $json_values;
}
public function parseJson_TR($body)
public function parseJson_TR($body,$country)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
@@ -132,16 +153,16 @@ class CountryCompareController extends Controller
$price = floatval(trim(str_replace('.', '', $price)));
$json_values = array(
'url_product' => $url_product,
'url' => $url_product,
'tag' => null,
'price' => floatval($price),
'price_eur' => 0
'country' => $country,
);
return $json_values;
}
public function parseJson_CY_GR_BG($code, $body)
public function parseJson_CY_GR_BG($code, $body , $country)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
@@ -163,16 +184,16 @@ class CountryCompareController extends Controller
$json_values = array(
'url_product' => $url_product,
'url' => $url_product,
'tag' => null,
'price' => floatval($price),
'price_eur' => 0
'country' => $country,
);
return $json_values;
}
public function parseJson_EE_LT_LV($country, $code, $body)
public function parseJson_EE_LT_LV($code, $body, $country)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
@@ -192,13 +213,13 @@ class CountryCompareController extends Controller
}
switch ($country) {
case "Estonia":
case "EE":
$url_product = "https://www.ikea.ee" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
case "Lithuania":
case "LT":
$url_product = "https://www.ikea.lt" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
case "Latvia":
case "LV":
$url_product = "https://www.ikea.lv" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
default:
@@ -215,17 +236,16 @@ class CountryCompareController extends Controller
$price = floatval(trim(str_replace(' ', '', str_replace(',', '.', str_replace(array('€'), '', $price)))));
$json_values = array(
'url_product' => $url_product,
//$url_product,
'url' => $url_product,
'tag' => null,
'price' => $price,
'price_eur' => 0
'country' => $country,
);
return $json_values;
}
public function parseJson_IS($country, $code, $body)
public function parseJson_IS($code, $body, $country)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
@@ -258,11 +278,10 @@ class CountryCompareController extends Controller
$price = floatval(trim(str_replace(' ', '', str_replace(',', '.', str_replace('.', '', str_replace(array('€'), '', $price))))));
$json_values = array(
'url_product' => $url_product,
//$url_product,
'url' => $url_product,
'tag' => null,
'price' => $price,
'price_eur' => 0
'country' => $country,
);
return $json_values;

View File

@@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Log;
class IkeaProductsController extends Controller
{
public function search(Request $request, string $field, string $text, ?string $country = '')
public function search(Request $request, string $field, string $text, ?string $country = '', $online = false)
{
return IkeaProducts::search($field, $text, $country);
}

View File

@@ -0,0 +1,326 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Promise as GuzzlePromise;
use App\Models\CountryCode;
function parseJson($json_raw)
{
$json_values = array();
$json_decoded = json_decode($json_raw, true);
$searchResultPage = $json_decoded["searchResultPage"];
$products = $searchResultPage["products"];
$main = $products["main"];
$items = $main["items"];
foreach ($items as $item) {
$product = $item["product"];
$salesPrice = $product["salesPrice"];
$numeral = $salesPrice["numeral"];
$json_values = array(
'url_product' => $product['pipUrl'],
'tag' => $product['tag'],
'price' => $numeral,
'price_eur' => 0
);
break;
}
return $json_values;
}
function parseJson_TR($body)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
$dochtml = new \DOMDocument();
$dochtml->loadHTML($body);
$xpath = new \DOMXpath($dochtml);
$price = null;
//$c = ltrim($code, "0");
$json_values = array();
$url_product = $xpath->query('/html/head/meta[(@property="og:url")]/@content')[0]->nodeValue;
$price = $xpath->query('/html/head/meta[(@property="og:price:amount")]/@content')[0]->nodeValue;
$price = floatval(trim(str_replace('.', '', $price)));
$json_values = array(
'url_product' => $url_product,
'tag' => null,
'price' => floatval($price),
'price_eur' => 0
);
return $json_values;
}
function parseJson_CY_GR_BG($code, $body)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
$dochtml = new \DOMDocument();
$dochtml->loadHTML($body);
$xpath = new \DOMXpath($dochtml);
$price = null;
$c = ltrim($code, "0");
$json_values = array();
$price = $xpath->query('//*/div[(@class="yotpo yotpo-main-widget" and @data-product-id="' . $code . '")]/@data-price')[0]->nodeValue;
$url_product = $xpath->query('//*/div[(@class="yotpo yotpo-main-widget" and @data-product-id="' . $code . '")]/@data-url')[0]->nodeValue;
$price = floatval($price);
$json_values = array(
'url_product' => $url_product,
'tag' => null,
'price' => floatval($price),
'price_eur' => 0
);
return $json_values;
}
function parseJson_EE_LT_LV($country, $code, $body)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
$dochtml = new \DOMDocument();
$dochtml->loadHTML($body);
$xpath = new \DOMXpath($dochtml);
$price = null;
$c = ltrim($code, "0");
$json_values = array();
$price = $xpath->query('//*/div[(@class="itemPriceBox" and @data-item="' . $c . '")]//p[@class="itemNormalPrice display-6"]/span')[0]->nodeValue;
if (is_null($price) || empty($price)) {
$price = $xpath->query('//*/div[(@class="itemPriceBox" and @data-item="' . $c . '")]//div[@class="itemBTI display-6"]/span')[0]->nodeValue;
}
switch ($country) {
case "Estonia":
$url_product = "https://www.ikea.ee" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
case "Lithuania":
$url_product = "https://www.ikea.lt" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
case "Latvia":
$url_product = "https://www.ikea.lv" . $xpath->query('//*/div[(@class="card-header")]/a/@href')[0]->nodeValue;
break;
default:
$url_product = null;
}
if (is_null($price) || empty($price)) {
$url_product = null;
}
$price = floatval(trim(str_replace(' ', '', str_replace(',', '.', str_replace(array('€'), '', $price)))));
$json_values = array(
'url_product' => $url_product,
//$url_product,
'tag' => null,
'price' => $price,
'price_eur' => 0
);
return $json_values;
}
function parseJson_IS($country, $code, $body)
{
//echo "country: " . $country . ", code: " . $code . "<br>";
$dochtml = new \DOMDocument();
$dochtml->loadHTML($body);
$xpath = new \DOMXpath($dochtml);
$price = null;
$c = ltrim($code, "0");
$json_values = array();
$price = $xpath->query('//*/div[(@class="itemPriceBox")]//p[@class="itemNormalPrice revamp_price price"]/span/span')[0]->nodeValue;
if (is_null($price) || empty($price)) {
$price = $xpath->query('//*/div[(@class="itemPriceBox")]//p[@class="itemBTI display-6 revamp_price price"]/span/span')[0]->nodeValue;
}
$url_product = "https://www.ikea.is" . $xpath->query('/html/head/meta[(@property="og:url")]/@content')[0]->nodeValue;
//echo "url_product: " . $url_product . "<br>";
if (is_null($price) || empty($price)) {
$url_product = null;
}
$price = floatval(trim(str_replace(' ', '', str_replace(',', '.', str_replace('.', '', str_replace(array('€'), '', $price))))));
$json_values = array(
'url_product' => $url_product,
//$url_product,
'tag' => null,
'price' => $price,
'price_eur' => 0
);
return $json_values;
}
class OnlineCompareController extends Controller
{
private $countries = [];
public function __construct()
{
$countries = [];
CountryCode::all()->each(function ($country) use (&$countries) {
$countries[] = $country->country_name;
});
$this->countries = collect($countries);
}
public function compare()
{
// $codes = $request->input("codes");
// $countries = $request->input("countries");
// $currency = $request->input("currency");
$codes = ['00102452',];
$countries = ['Austria', 'Belgium'];
$ta_codes = $codes;
$exch_rates = "EUR";
$item = array();
$codes = array();
// krajiny ktore som pridal do zoznamu z DB
$added_countries[] = null;
// loop cez jednotlive code z textarea a pridanie url
/* ******************************************************************** */
foreach ($ta_codes as $code) {
unset($item);
if (!is_numeric($code) || strlen($code) < 6) {
continue;
}
foreach ($countries as $country) {
if (!in_array($country['country_name'], $added_countries)) {
$item[] = array(
'country_name' => $country['country_name'],
'url_call' => $country['search_url'] . $code,
'price' => 0,
'url_product' => null,
'tag' => null
);
}
}
$codes[] = array(
'code' => $code,
'item' => $item
);
}
//echo var_dump($codes);
/* ******************************************************************** */
// paralelene prevolanie URL
/* ******************************************************************** */
$client = new GuzzleClient(['timeout' => 12.0]);
$promises[] = null;
$prices[] = null;
foreach ($codes as $x => $code) {
//echo "CODE: " . $code_value['code'] . "<BR>";
unset($promises);
unset($responses);
unset($prices);
// naplnenie pola promises URL
foreach ($code['item'] as $i => $i_value) {
if (!is_null($i_value['url_call'])) {
$promises[$i_value['country_name']] = $client->getAsync($i_value['url_call']);
}
}
$responses = GuzzlePromise\settle($promises)->wait();
foreach ($responses as $country => $response) {
if ($response['state'] === 'fulfilled') {
$response_value = $response['value'];
if ($response_value->getStatusCode() == 200) {
switch ($country) {
case "Bulgaria":
case "Cyprus":
case "Greece":
$prices[$country] = parseJson_CY_GR_BG($code['code'], (string) $response_value->body());
break;
case "Iceland":
$prices[$country] = parseJson_IS($country, $code['code'], (string) $response_value->body());
break;
case "Turkey":
$prices[$country] = parseJson_TR((string) $response_value->body());
break;
case "Lithuania":
case "Estonia":
case "Latvia":
$prices[$country] = parseJson_EE_LT_LV($country, $code['code'], (string) $response_value->body());
break;
default:
$prices[$country] = parseJson((string) $response_value->body());
}
}
}
}
/* {"products":{"Illuminate\\Database\\Eloquent\\Collection":[{"country":"AT","code":"00222671","url":"https://www.ikea.com/at
/de/p/vardoe-bettkasten-weiss-00222671/","name":"VARDÖ","typeName":"Bettkasten","mainImageUrl":"https://www.ikea.com/at/de/images/products/vardoe-bettkasten-weiss__0636
223_pe697736_s5.jpg","itemNoGlobal":"00222671","salesPrice":"34.99","tag":"NONE","last_mod":"2024-01-04 15:41:48","mainImageAlt":"VARDÖ Bettkasten, weiß, 65x70 cm","pri
ceUnit":null,"countryName":"Austria"} */
// zistenu cenu doplnim do kolekcie
foreach ($code['item'] as $i => $i_value) {
asort($codes[$x]['item']); // zotriedenie
$codes[$x]['item'][$i]['salesPrice'] = $prices[$i_value['country_name']]['price'] ?? 0;
if ($prices[$i_value['country_name']]['tag'] == 'NONE') {
$codes[$x]['item'][$i]['tag'] = "";
} else {
$codes[$x]['item'][$i]['tag'] = $prices[$i_value['country_name']]['tag'];
}
$codes[$x]['item'][$i]['url'] = $prices[$i_value['country_name']]['url_product'];
}
}
/* ******************************************************************** */
// vypis do tabulky
/* ******************************************************************** */
return $codes;
}
}

View File

@@ -10,50 +10,60 @@ use Illuminate\Support\Facades\Log;
use App\Models\CountryCode;
use App\Models\CurrencyRates;
use Inertia\Inertia;
use App\Http\Controllers\CountryCompareController;
class ProductsCompareController extends Controller
{
public function compare(Request $request)
{
$codes = $request->input("codes");
$countries = $request->input("countries");
$currency = $request->input("currency");
Log::info("{codes} {countries}", ["codes" => $codes, "countries" => $countries]);
$codes = collect($codes);
$countries = collect($countries);
if ($countries != null && count($countries)) {
$hCountry = CountryCode::countryHash();
$countries = $countries->map(function ($country) use ($hCountry) {
return $hCountry[$country];
});
} else {
$countries = [];
private $countryCompareController;
public function __construct(CountryCompareController $countryCompareController)
{
$this->countryCompareController = $countryCompareController;
}
public function compare(Request $request)
{
$codes = $request->input("codes");
$countries = $request->input("countries");
$online = $request->input("online");
$cHash = CountryCode::code_countryHash();
if (is_array($codes) == false)
$aCodes = $codes;
else
$aCodes = $codes->map(function ($code) {
return $code;
});
Log::info("{codes} {countries}", ["codes" => $codes, "countries" => $countries, "online" => $online]);
$products = IkeaProducts::whereIn("code", $aCodes);
if (count($countries)) $products->whereIn("country",$countries);
$products = $products->get();
$codes = collect($codes);
$countries = collect($countries);
if ($countries != null && count($countries)) {
$hCountry = CountryCode::countryHash();
$countries = $countries->map(function ($country) use ($hCountry) {
return $hCountry[$country];
});
} else {
$countries = [];
}
$products = $products->map(function ($product) use ( $cHash) {
$product["countryName"] = $cHash[$product["country"]];
return $product;
});
Log::info("{products}", ["products" => $products]);
return [
'products' => $products,
'countryHash' => $cHash,
];
}
$cHash = CountryCode::code_countryHash();
if (is_array($codes) == false)
$aCodes = $codes;
else
$aCodes = $codes->map(function ($code) {
return $code;
});
if ($online == true) {
Log::info("ONLINE {codes} {countries}", ["codes" => $codes, "countries" => $countries, "online" => $online]);
$products = $this->countryCompareController->compare($countries, $cHash, $aCodes);
} else {
$products = IkeaProducts::whereIn("code", $aCodes);
if (count($countries)) $products->whereIn("country", $countries);
$products = $products->get();
}
$products = $products->map(function ($product) use ($cHash) {
$product["countryName"] = $cHash[$product["country"]];
return $product;
});
Log::info("{products}", ["products" => $products]);
return [
'products' => $products,
'countryHash' => $cHash,
];
}
}