mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-01-31 07:13:58 +03:00
[EBayBridge] Repair & Augment the eBay Feed (#4157)
* [EBayBridge]: discount details; fix DOM parsing * [EBayBridge] Ending slash. No "www.ebay.commyhijack.net", for example. * [EBayBridge] Trim discountLine details when set. * [EBayBridge] Refactor and update content * shameless self-addition to CONTRIBUTORS.md * [EBayBridge] Toggle original search links w/ checkbox * [EBayBridge] oops: fix introduced XSS vuln * [EBayBridge] Fix linting error: use array_column * [EBayBridge] fix compat with <php8
This commit is contained in:
parent
6d81d6d306
commit
22b39e3fcd
2 changed files with 92 additions and 27 deletions
|
@ -144,6 +144,7 @@
|
||||||
* [Niehztog](https://github.com/Niehztog)
|
* [Niehztog](https://github.com/Niehztog)
|
||||||
* [NikNikYkt](https://github.com/NikNikYkt)
|
* [NikNikYkt](https://github.com/NikNikYkt)
|
||||||
* [Nono-m0le](https://github.com/Nono-m0le)
|
* [Nono-m0le](https://github.com/Nono-m0le)
|
||||||
|
* [NotsoanoNimus](https://github.com/NotsoanoNimus)
|
||||||
* [obsiwitch](https://github.com/obsiwitch)
|
* [obsiwitch](https://github.com/obsiwitch)
|
||||||
* [Ololbu](https://github.com/Ololbu)
|
* [Ololbu](https://github.com/Ololbu)
|
||||||
* [ORelio](https://github.com/ORelio)
|
* [ORelio](https://github.com/ORelio)
|
||||||
|
|
|
@ -5,15 +5,21 @@ class EBayBridge extends BridgeAbstract
|
||||||
const NAME = 'eBay';
|
const NAME = 'eBay';
|
||||||
const DESCRIPTION = 'Returns the search results from the eBay auctioning platforms';
|
const DESCRIPTION = 'Returns the search results from the eBay auctioning platforms';
|
||||||
const URI = 'https://www.eBay.com';
|
const URI = 'https://www.eBay.com';
|
||||||
const MAINTAINER = 'wrobelda';
|
const MAINTAINER = 'NotsoanoNimus, wrobelda';
|
||||||
const PARAMETERS = [[
|
const PARAMETERS = [[
|
||||||
'url' => [
|
'url' => [
|
||||||
'name' => 'Search URL',
|
'name' => 'Search URL',
|
||||||
'title' => 'Copy the URL from your browser\'s address bar after searching for your items and paste it here',
|
'title' => 'Copy the URL from your browser\'s address bar after searching for your items and paste it here',
|
||||||
'pattern' => '^(https:\/\/)?(www\.)?(befr\.|benl\.)?ebay\.(com|com\.au|at|be|ca|ch|cn|es|fr|de|com\.hk|ie|it|com\.my|nl|ph|pl|com\.sg|co\.uk).*$',
|
'pattern' => '^(https:\/\/)?(www\.)?(befr\.|benl\.)?ebay\.(com|com\.au|at|be|ca|ch|cn|es|fr|de|com\.hk|ie|it|com\.my|nl|ph|pl|com\.sg|co\.uk)\/.*$',
|
||||||
'exampleValue' => 'https://www.ebay.com/sch/i.html?_nkw=atom+rss',
|
'exampleValue' => 'https://www.ebay.com/sch/i.html?_nkw=atom+rss',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
]
|
],
|
||||||
|
'includesSearchLink' => [
|
||||||
|
'name' => 'Include Original Search Link',
|
||||||
|
'title' => 'Whether or not each feed item should include the original search query link to eBay which was used to find the given listing.',
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'defaultValue' => false,
|
||||||
|
],
|
||||||
]];
|
]];
|
||||||
|
|
||||||
public function getURI()
|
public function getURI()
|
||||||
|
@ -23,6 +29,10 @@ class EBayBridge extends BridgeAbstract
|
||||||
$uri = trim(preg_replace('/([?&])_sop=[^&]+(&|$)/', '$1', $this->getInput('url')), '?&/');
|
$uri = trim(preg_replace('/([?&])_sop=[^&]+(&|$)/', '$1', $this->getInput('url')), '?&/');
|
||||||
$uri .= (parse_url($uri, PHP_URL_QUERY) ? '&' : '?') . '_sop=10';
|
$uri .= (parse_url($uri, PHP_URL_QUERY) ? '&' : '?') . '_sop=10';
|
||||||
|
|
||||||
|
// Ensure the List View is used instead of the Gallery View.
|
||||||
|
$uri = trim(preg_replace('/[?&]_dmd=[^&]+(&|$)/i', '$1', $uri), '?&/');
|
||||||
|
$uri .= '&_dmd=1';
|
||||||
|
|
||||||
return $uri;
|
return $uri;
|
||||||
} else {
|
} else {
|
||||||
return parent::getURI();
|
return parent::getURI();
|
||||||
|
@ -46,7 +56,7 @@ class EBayBridge extends BridgeAbstract
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($searchQuery) {
|
if ($searchQuery) {
|
||||||
return $searchQuery[0];
|
return 'eBay - ' . $searchQuery[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getName();
|
return parent::getName();
|
||||||
|
@ -61,44 +71,88 @@ class EBayBridge extends BridgeAbstract
|
||||||
$inexactMatches->remove();
|
$inexactMatches->remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove "NEW LISTING" labels: we sort by the newest, so this is redundant.
|
||||||
|
foreach ($html->find('.LIGHT_HIGHLIGHT') as $new_listing_label) {
|
||||||
|
$new_listing_label->remove();
|
||||||
|
}
|
||||||
|
|
||||||
$results = $html->find('ul.srp-results > li.s-item');
|
$results = $html->find('ul.srp-results > li.s-item');
|
||||||
foreach ($results as $listing) {
|
foreach ($results as $listing) {
|
||||||
$item = [];
|
$item = [];
|
||||||
|
|
||||||
// Remove "NEW LISTING" label, we sort by the newest, so this is redundant
|
// Define a closure to shorten the ugliness of querying the current listing.
|
||||||
foreach ($listing->find('.LIGHT_HIGHLIGHT') as $new_listing_label) {
|
$find = function ($query, $altText = '') use ($listing) {
|
||||||
$new_listing_label->remove();
|
return $listing->find($query, 0)->plaintext ?? $altText;
|
||||||
|
};
|
||||||
|
|
||||||
|
$item['title'] = $find('.s-item__title');
|
||||||
|
if (!$item['title']) {
|
||||||
|
// Skip entries where the title cannot be found (for w/e reason).
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$listingTitle = $listing->find('.s-item__title', 0);
|
// It appears there may be more than a single 'subtitle' subclass in the listing. Collate them.
|
||||||
if ($listingTitle) {
|
$subtitles = $listing->find('.s-item__subtitle');
|
||||||
$item['title'] = $listingTitle->plaintext;
|
if (is_array($subtitles)) {
|
||||||
}
|
$subtitle = trim(implode(' ', array_column($subtitles, 'plaintext')));
|
||||||
|
|
||||||
$subtitle = implode('', $listing->find('.s-item__subtitle'));
|
|
||||||
|
|
||||||
$listingUrl = $listing->find('.s-item__link', 0);
|
|
||||||
if ($listingUrl) {
|
|
||||||
$item['uri'] = $listingUrl->href;
|
|
||||||
} else {
|
} else {
|
||||||
$item['uri'] = null;
|
$subtitle = trim($subtitles->plaintext ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the listing's link and uid.
|
||||||
|
$itemUri = $listing->find('.s-item__link', 0);
|
||||||
|
if ($itemUri) {
|
||||||
|
$item['uri'] = $itemUri->href;
|
||||||
|
}
|
||||||
if (preg_match('/.*\/itm\/(\d+).*/i', $item['uri'], $matches)) {
|
if (preg_match('/.*\/itm\/(\d+).*/i', $item['uri'], $matches)) {
|
||||||
$item['uid'] = $matches[1];
|
$item['uid'] = $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
$priceDom = $listing->find('.s-item__details > .s-item__detail > .s-item__price', 0);
|
// Price should be fetched on its own so we can provide the alt text without complication.
|
||||||
$price = $priceDom->plaintext ?? 'N/A';
|
$price = $find('.s-item__price', '[NO PRICE]');
|
||||||
|
|
||||||
$shippingFree = $listing->find('.s-item__details > .s-item__detail > .s-item__freeXDays', 0)->plaintext ?? '';
|
// Map a list of dynamic variable names to their subclasses within the listing.
|
||||||
$localDelivery = $listing->find('.s-item__details > .s-item__detail > .s-item__localDelivery', 0)->plaintext ?? '';
|
// This is just a bit of sugar to make this cleaner and more maintainable.
|
||||||
$logisticsCost = $listing->find('.s-item__details > .s-item__detail > .s-item__logisticsCost', 0)->plaintext ?? '';
|
$propertyMappings = [
|
||||||
|
'additionalPrice' => '.s-item__additional-price',
|
||||||
|
'discount' => '.s-item__discount',
|
||||||
|
'shippingFree' => '.s-item__freeXDays',
|
||||||
|
'localDelivery' => '.s-item__localDelivery',
|
||||||
|
'logisticsCost' => '.s-item__logisticsCost',
|
||||||
|
'location' => '.s-item__location',
|
||||||
|
'obo' => '.s-item__formatBestOfferEnabled',
|
||||||
|
'sellerInfo' => '.s-item__seller-info-text',
|
||||||
|
'bids' => '.s-item__bidCount',
|
||||||
|
'timeLeft' => '.s-item__time-left',
|
||||||
|
'timeEnd' => '.s-item__time-end',
|
||||||
|
];
|
||||||
|
|
||||||
$location = $listing->find('.s-item__details > .s-item__detail > .s-item__location', 0)->plaintext ?? '';
|
foreach ($propertyMappings as $k => $v) {
|
||||||
|
$$k = $find($v);
|
||||||
|
}
|
||||||
|
|
||||||
$sellerInfo = $listing->find('.s-item__seller-info-text', 0)->plaintext ?? '';
|
// When an additional price detail or discount is defined, create the 'discountLine'.
|
||||||
|
if ($additionalPrice || $discount) {
|
||||||
|
$discountLine = '<br /><em>('
|
||||||
|
. trim($additionalPrice ?? '')
|
||||||
|
. '; ' . trim($discount ?? '')
|
||||||
|
. ')</em>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepend the time-left info with a comma if the right details were found.
|
||||||
|
$timeInfo = trim($timeLeft . ' ' . $timeEnd);
|
||||||
|
if ($timeInfo) {
|
||||||
|
$timeInfo = ', ' . $timeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the listing type.
|
||||||
|
if ($bids) {
|
||||||
|
$listingTypeDetails = "Auction: {$bids}{$timeInfo}";
|
||||||
|
} else {
|
||||||
|
$listingTypeDetails = 'Buy It Now';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Acquire the listing's primary image and atach it.
|
||||||
$image = $listing->find('.s-item__image-wrapper > img', 0);
|
$image = $listing->find('.s-item__image-wrapper > img', 0);
|
||||||
if ($image) {
|
if ($image) {
|
||||||
// Not quite sure why append fragment here
|
// Not quite sure why append fragment here
|
||||||
|
@ -106,11 +160,21 @@ class EBayBridge extends BridgeAbstract
|
||||||
$item['enclosures'] = [$imageUrl];
|
$item['enclosures'] = [$imageUrl];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include the original search link, if specified.
|
||||||
|
if ($this->getInput('includesSearchLink')) {
|
||||||
|
$searchLink = '<p><small><a target="_blank" href="' . e($this->getURI()) . '">View Search</a></small></p>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the final item's content to display and add the item onto the list.
|
||||||
$item['content'] = <<<CONTENT
|
$item['content'] = <<<CONTENT
|
||||||
<p>$sellerInfo $location</p>
|
<p>$sellerInfo $location</p>
|
||||||
<p><span style="font-weight:bold">$price</span> $shippingFree $localDelivery $logisticsCost<span></span></p>
|
<p><strong>$price</strong> $obo ($listingTypeDetails)
|
||||||
<p>$subtitle</p>
|
$discountLine
|
||||||
|
<br /><small>$shippingFree $localDelivery $logisticsCost</small></p>
|
||||||
|
<p>{$subtitle}</p>
|
||||||
|
$searchLink
|
||||||
CONTENT;
|
CONTENT;
|
||||||
|
|
||||||
$this->items[] = $item;
|
$this->items[] = $item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue