[DealabsBride] Fix for the new site (#595)

* [DealabsBride] Fix for the new site
This commit is contained in:
sysadminstory 2018-02-14 12:03:44 +01:00 committed by Teromene
parent 85ac9001d6
commit ef402bb5c3

View file

@ -2,8 +2,7 @@
class DealabsBridge extends BridgeAbstract { class DealabsBridge extends BridgeAbstract {
const NAME = 'Dealabs search bridge'; const NAME = 'Dealabs search bridge';
const URI = 'https://www.dealabs.com/'; const URI = 'https://www.dealabs.com/';
const DESCRIPTION = 'Return the Dealabs search result using keywords, const DESCRIPTION = 'Return the Dealabs search result using keywords';
with/without expired deals, with/without shop deals and by category';
const MAINTAINER = 'sysadminstory'; const MAINTAINER = 'sysadminstory';
const PARAMETERS = array( array ( const PARAMETERS = array( array (
'q' => array( 'q' => array(
@ -11,97 +10,56 @@ class DealabsBridge extends BridgeAbstract {
'type' => 'text', 'type' => 'text',
'required' => true 'required' => true
), ),
'expired_choice' => array( 'hide_expired' => array(
'name' => 'Afficher deals expirés', 'name' => 'Masquer les éléments expirés',
'type' => 'checkbox' 'type' => 'checkbox',
'required' => 'true'
), ),
'instore_choice' => array( 'hide_local' => array(
'name' => 'Afficher deals en magasin', 'name' => 'Masquer les deals locaux',
'type' => 'checkbox' 'type' => 'checkbox',
'title' => 'Masquer les deals en magasins physiques',
'required' => 'true'
),
'priceFrom' => array(
'name' => 'Prix minimum',
'type' => 'text',
'title' => 'Prix mnimum en euros',
'required' => 'false',
'defaultValue' => ''
),
'priceTo' => array(
'name' => 'Prix maximum',
'type' => 'text',
'title' => 'Prix maximum en euros',
'required' => 'false',
'defaultValue' => ''
), ),
'cat' => array(
'name' => 'Catégorie',
'type' => 'list',
'values' => array(
'Toutes les catégories' => '',
'High-tech' => array(
'Tous' => 'c2',
'Informatique' => 's3',
'Téléphonie' => 's4',
'Accessoires, consommables' => 's6',
'Gadgets' => 's8',
'Applications, logiciels' => 's46'
),
'Audiovisuel' => array(
'Tous' => 'c5',
'Image et son' => 's9',
'Photo, caméscopes' => 's10',
'CD, DVD, Blu-ray' => 's11',
'Jeux vidéo, consoles' => 's12'
),
'Loisirs' => array(
'Tous' => 'c7',
'Jeux, jouets' => 's13',
'Livres, papeterie' => 's14',
'Plein air' => 's15',
'Sport' => 's35',
'Auto/Moto, accessoires' => 's37',
'Animaux, accessoires' => 's47',
'Instruments de musique' => 's48'
),
'Mode' => array(
'Tous' => 'c16',
'Homme' => 's17',
'Femme' => 's18',
'Mixte' => 's50',
'Enfants' => 's19',
'Puériculture' => 's36',
'Beauté, santé' => 's21',
'Bijoux, accessoires' => 's20',
'Bagagerie' => 's38'
),
'Maison' => array(
'Tous' => 'c23',
'Meuble, literie, déco' => 's24',
'Cuisine, art de la table' => 's25',
'Électroménager' => 's26',
'Bricolage' => 's27',
'Jardin' => 's28'
),
'Services' => array(
'Tous' => 'c51',
'Voyages' => 's57',
'Hébergement, restauration' => 's52',
'Sorties' => 's53',
'Presse' => 's24',
'Bien-être' => 's55',
'Transport, expédition' => 's56',
'Autres' => 's58'
),
'Épicerie' => 'c31'
)
)
)); ));
const CACHE_TIMEOUT = 3600; const CACHE_TIMEOUT = 3600;
public function collectData(){ public function collectData(){
$q = $this->getInput('q'); $q = $this->getInput('q');
$hide_expired = $this->getInput('hide_expired');
$hide_local = $this->getInput('hide_local');
$priceFrom = $this->getInput('priceFrom');
$priceTo = $this->getInput('priceFrom');
$expired_choice = $this->getInput('expired_choice'); /* Event if the original website uses POST with the search page, GET works too */
$instore_choice = $this->getInput('instore_choice');
$cat_subcat = $this->getInput('cat');
$html = getSimpleHTMLDOM(self::URI $html = getSimpleHTMLDOM(self::URI
. '/search/?q=' . '/search/advanced?q='
. urlencode($q) . urlencode($q)
. '&hide_expired=' . '&hide_expired='. $hide_expired
. $expired_choice . '&hide_local='. $hide_local
. '&hide_instore=' . '&priceFrom='. $priceFrom
. $instore_choice . '&priceTo='. $priceTo
. '&' . $this->getCatSubcatParam($cat_subcat)) /* Some default parameters
* search_fields : Search in Titres & Descriptions & Codes
* sort_by : Sort the search by new deals
* time_frame : Search will not be on a limited timeframe
*/
. '&search_fields[]=1&search_fields[]=2&search_fields[]=3&sort_by=new&time_frame=0')
or returnServerError('Could not request Dealabs.'); or returnServerError('Could not request Dealabs.');
$list = $html->find('article'); $list = $html->find('article');
if($list === null) { if($list === null) {
@ -110,24 +68,232 @@ class DealabsBridge extends BridgeAbstract {
foreach($list as $deal) { foreach($list as $deal) {
$item = array(); $item = array();
$item['uri'] = $deal->find('a.title', 0)->href; $item['uri'] = $deal->find('div[class=threadGrid-title]', 0)->find('a', 0)->href;
$item['title'] = $deal->find('a.title', 0)->plaintext; $item['title'] = $deal->find(
$item['author'] = $deal->find('a.poster_link', 0)->plaintext; 'a[class=cept-tt thread-link linkPlain space--r-1 size--all-s size--fromW3-m]', 0
$item['content'] = '<table><tr><td>' )->plaintext;
. $deal->find('div.image_part', 0)->outertext $item['author'] = $deal->find('span.thread-username', 0)->plaintext;
$item['content'] = '<table><tr><td><a href="'
. $deal->find(
'a[class*=cept-thread-image-link imgFrame imgFrame--noBorder box--all-i thread-listImgCell]', 0)->href
. '"><img src="'
. $this->getImage($deal)
. '"/></td><td><h2><a href="'
. $deal->find('a[class=cept-tt thread-link linkPlain space--r-1 size--all-s size--fromW3-m]', 0)->href
. '">'
. $deal->find('a[class=cept-tt thread-link linkPlain space--r-1 size--all-s size--fromW3-m]', 0)->innertext
. '</a></h2>'
. $this->getPrix($deal)
. $this->getReduction($deal)
. $this->getExpedition($deal)
. $this->getLivraison($deal)
. $this->getOrigine($deal)
. $deal->find(
'div[class=cept-description-container overflow--wrap-break size--all-s size--fromW3-m]', 0
)->innertext
. '</td><td>' . '</td><td>'
. $deal->find('a.title', 0)->outertext . $deal->find('div[class=flex flex--align-c flex--justify-space-between space--b-2]', 0)->children(0)->outertext
. $deal->find('p.description', 0)->outertext
. '</td><td>'
. $deal->find('div.vote_part', 0)->outertext
. '</td></table>'; . '</td></table>';
$item['timestamp'] = $this->relativeDateToTimestamp( $dealDateDiv = $deal->find('div[class=size--all-s flex flex--wrap flex--justify-e flex--grow-1]', 0)
$deal->find('p.date_deal', 0)->plaintext); ->find('span[class=hide--toW3]');
$itemDate = end($dealDateDiv)->plaintext;
if(substr( $itemDate, 0, 6 ) === 'il y a') {
$item['timestamp'] = $this->relativeDateToTimestamp($itemDate);
} else {
$item['timestamp'] = $this->parseDate($itemDate);
}
$this->items[] = $item; $this->items[] = $item;
} }
} }
/**
* Get the Price from a Deal if it exists
* @return string String of the deal price
*/
private function getPrix($deal)
{
if($deal->find(
'span[class*=thread-price]', 0) != null) {
return '<div>Prix : '
. $deal->find(
'span[class*=thread-price]', 0
)->plaintext
. '</div>';
} else {
return '';
}
}
/**
* Get the Shipping costs from a Deal if it exists
* @return string String of the deal shipping Cost
*/
private function getLivraison($deal)
{
if($deal->find('span[class*=cept-shipping-price]', 0) != null) {
if($deal->find('span[class*=cept-shipping-price]', 0)->children(0) != null) {
return '<div>Livraison : '
. $deal->find('span[class*=cept-shipping-price]', 0)->children(0)->innertext
. '</div>';
} else {
return '<div>Livraison : '
. $deal->find('span[class*=cept-shipping-price]', 0)->innertext
. '</div>';
}
} else {
return '';
}
}
/**
* Get the source of a Deal if it exists
* @return string String of the deal source
*/
private function getOrigine($deal)
{
if($deal->find('a[class=text--color-greyShade]', 0) != null) {
return '<div>Origine : '
. $deal->find('a[class=text--color-greyShade]', 0)->outertext
. '</div>';
} else {
return '';
}
}
/**
* Get the original Price and discout from a Deal if it exists
* @return string String of the deal original price and discount
*/
private function getReduction($deal)
{
if($deal->find('span[class*=mute--text text--lineThrough]', 0) != null) {
return '<div>Réduction : <span style="text-decoration: line-through;">'
. $deal->find(
'span[class*=mute--text text--lineThrough]', 0
)->plaintext
. '</span>&nbsp;'
. $deal->find('span[class=space--ml-1 size--all-l size--fromW3-xl]', 0)->plaintext
. '</div>';
} else {
return '';
}
}
/**
* Get the Picture URL from a Deal if it exists
* @return string String of the deal Picture URL
*/
private function getImage($deal)
{
$selectorLazy = implode(
' ', /* Notice this is a space! */
array(
'thread-image',
'width--all-auto',
'height--all-auto',
'imgFrame-img',
'cept-thread-img',
'img--dummy',
'js-lazy-img'
)
);
$selectorPlain = implode(
' ', /* Notice this is a space! */
array(
'thread-image',
'width--all-auto',
'height--all-auto',
'imgFrame-img',
'cept-thread-img'
)
);
if($deal->find('img[class='. $selectorLazy .']', 0) != null) {
return json_decode(
html_entity_decode(
$deal->find('img[class='. $selectorLazy .']', 0)
->getAttribute('data-lazy-img')))->{'src'};
} else {
return $deal->find('img[class='. $selectorPlain .']', 0 )->src;
}
}
/**
* Get the originating country from a Deal if it existsa
* @return string String of the deal originating country
*/
private function getExpedition($deal)
{
$selector = implode(
' ', /* Notice this is a space! */
array(
'meta-ribbon',
'overflow--wrap-off',
'space--l-3',
'text--color-greyShade'
)
);
if($deal->find('span[class='. $selector .']', 0) != null) {
return '<div>'
. $deal->find('span[class='. $selector .']', 0)->children(2)->plaintext
. '</div>';
} else {
return '';
}
}
/**
* Transforms a French date into a timestam
* @return int timestamp of the input date
*/
private function parseDate($string)
{
$month_fr = array(
'janvier',
'février',
'mars',
'avril',
'mai',
'juin',
'juillet',
'août',
'septembre',
'octobre',
'novembre',
'décembre'
);
$month_en = array(
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
);
$date_str = trim(str_replace($month_fr, $month_en, $string));
if(!preg_match('/[0-9]{4}/', $string)) {
$date_str .= ' ' . date('Y');
}
$date_str .= ' 00:00';
$date = DateTime::createFromFormat('j F Y H:i', $date_str);
return $date->getTimestamp();
}
/**
* Transforms a relate French date into a timestam
* @return int timestamp of the input date
*/
private function relativeDateToTimestamp($str) { private function relativeDateToTimestamp($str) {
$date = new DateTime(); $date = new DateTime();
$search = array( $search = array(
@ -137,7 +303,8 @@ class DealabsBridge extends BridgeAbstract {
'jour', 'jour',
'jours', 'jours',
'mois', 'mois',
'ans' 'ans',
'et '
); );
$replace = array( $replace = array(
'-', '-',
@ -145,25 +312,12 @@ class DealabsBridge extends BridgeAbstract {
'hour', 'hour',
'day', 'day',
'month', 'month',
'year' 'year',
''
); );
$date->modify(str_replace($search, $replace, $str)); $date->modify(str_replace($search, $replace, $str));
return $date->getTimestamp(); return $date->getTimestamp();
} }
private function getCatSubcatParam($str) {
if(strlen($str) >= 2) {
if(substr($str, 0, 1) == 'c') {
$var_name = 'cat[]';
} else if(substr($str, 0, 1) == 's') {
$var_name = 'sub_cat[]';
}
$value = substr($str, 1);
return $var_name .'='. $value;
} else {
return '';
}
}
} }