From 0e523299db8b2d6c225929d5b2bc9ad09dc1b668 Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Wed, 8 Jul 2026 23:52:21 +0200 Subject: [PATCH 1/7] =?UTF-8?q?=E2=9C=A8(feat)=20Add=20new=20bridge=20Wawa?= =?UTF-8?q?city?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 184 +++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 bridges/WawacityBridge.php diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php new file mode 100644 index 00000000000..b325245df34 --- /dev/null +++ b/bridges/WawacityBridge.php @@ -0,0 +1,184 @@ + [ + 'categorie' => [ + 'name' => 'Catégorie', + 'type' => 'list', + 'title' => 'Catégorie', + 'values' => [ + 'Derniers ajouts (accueil)' => 'accueil', + 'Films' => 'films', + 'Séries' => 'series', + 'Jeux' => 'jeux', + 'Musiques' => 'musiques', + 'Ebooks' => 'ebooks', + 'Animés' => 'mangas', + 'Logiciels' => 'logiciels', + 'Mobiles' => 'mobiles', + 'Autres vidéos' => 'autres-videos', + 'Divers' => 'divers', + ] + ], + 'sous_categorie' => [ + 'name' => 'Sous-catégorie', + 'type' => 'text', + 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, "vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). Pour "Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, films-4k, series-vostfr, series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, autres-videos, divers (laisser vide = tous les widgets, avec la mention "Ajout de l\'épisode X" pour les séries/animés).', + 'exampleValue' => 'series-vostfr', + 'required' => false, + ] + ] + ]; + const CACHE_TIMEOUT = 18000; // every 5h + + // wawacity is behind Cloudflare, which returns a 520 error to + // requests that don't look like they come from a real browser. + const REQUEST_HEADERS = [ + 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0', + 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', + 'Accept-Language: en-US,en;q=0.5', + 'Upgrade-Insecure-Requests: 1', + ]; + + // Slug (used as sous_categorie) => exact "wa-block-title" text of the matching homepage widget + const HOMEPAGE_WIDGETS = [ + 'exclusivites' => 'Exclusivités (populaires)', + 'films' => 'Télécharger Films', + 'films-bluray' => 'Télécharger Films Blu-Ray', + 'films-4k' => 'Télécharger Films ULTRA HD 4K', + 'series-vostfr' => 'Télécharger Séries VOSTFR', + 'series-vf' => 'Télécharger Séries VF', + 'series-4k' => 'Télécharger Séries MULTI 4K', + 'jeux' => 'Télécharger Jeux', + 'musiques' => 'Télécharger Musiques', + 'ebooks' => 'Télécharger Ebooks', + 'animes' => 'Télécharger Animés', + 'logiciels' => 'Télécharger Logiciels', + 'mobiles' => 'Télécharger Mobiles', + 'autres-videos' => 'Télécharger Autres vidéo', + 'divers' => 'Télécharger divers', + ]; + + public function collectData() { + $categorie = $this->getInput('categorie'); + $sousCategorie = trim((string) $this->getInput('sous_categorie')); + + if ($categorie === 'accueil') { + $this->collectHomepageData($sousCategorie); + } else { + $this->collectCatalogueData($categorie, $sousCategorie); + } + } + + private function collectCatalogueData($categorie, $sousCategorie) { + $query = 'p=' . rawurlencode($categorie); + if ($sousCategorie !== '') { + $query .= '&s=' . rawurlencode($sousCategorie); + } + $url = self::URI . '/?' . $query; + + $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or returnServerError('Could not request ' . $url); + + $elementsDom = $html->find('#wa-mid-blocks .wa-post-detail-item'); + foreach ($elementsDom as $elementDom) { + $titleDom = $elementDom->find('.wa-sub-block-title a', 0); + $uri = $this->toAbsoluteUri($titleDom->href); + $title = html_entity_decode(trim($titleDom->plaintext), ENT_QUOTES); + + $imgDom = $elementDom->find('.cover img', 0); + $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + + $descriptionDom = $elementDom->find('.col-md-10 p', 0); + $description = $descriptionDom ? html_entity_decode(trim($descriptionDom->plaintext), ENT_QUOTES) : ''; + + $content = ''; + if ($imgSrc) { + $content .= '
'; + } + $content .= $title . '
'; + if ($description !== '') { + $content .= '
' . $description; + } + + $item = []; + $item['uri'] = $uri; + $item['title'] = 'Wawacity : ' . $title; + $item['author'] = 'floviolleau'; + $item['content'] = $content; + $item['uid'] = hash('sha256', $uri); + + $this->items[] = $item; + } + } + + private function collectHomepageData($widget) { + if ($widget !== '' && !array_key_exists($widget, self::HOMEPAGE_WIDGETS)) { + returnServerError( + 'Sous-catégorie inconnue pour "Derniers ajouts (accueil)": ' . $widget + . '. Valeurs possibles: ' . implode(', ', array_keys(self::HOMEPAGE_WIDGETS)) . '.' + ); + } + + $url = self::URI; + $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or returnServerError('Could not request ' . $url); + + $blocksDom = $html->find('#wa-mid-blocks .wa-block'); + foreach ($blocksDom as $blockDom) { + $blockTitleDom = $blockDom->find('.wa-block-title', 0); + if (!$blockTitleDom) { + continue; + } + $blockTitle = html_entity_decode(trim($blockTitleDom->plaintext), ENT_QUOTES); + + if ($widget !== '' && $blockTitle !== self::HOMEPAGE_WIDGETS[$widget]) { + continue; + } + + foreach ($blockDom->find('a.thumbnail') as $thumbnailDom) { + $uri = $this->toAbsoluteUri($thumbnailDom->href); + $title = html_entity_decode(trim($thumbnailDom->title ?: ''), ENT_QUOTES); + + $imgDom = $thumbnailDom->find('img', 0); + $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + if ($title === '' && $imgDom) { + $title = html_entity_decode(trim($imgDom->attr['alt'] ?? ''), ENT_QUOTES); + } + + $episode = null; + foreach ($thumbnailDom->find('div') as $divDom) { + $text = html_entity_decode(trim($divDom->plaintext), ENT_QUOTES); + if (stripos($text, 'Ajout de') !== false) { + $episode = $text; + break; + } + } + + $displayTitle = $episode ? $title . ' - ' . $episode : $title; + + $content = ''; + if ($imgSrc) { + $content .= '
'; + } + $content .= $displayTitle . '
'; + + $item = []; + $item['uri'] = $uri; + $item['title'] = 'Wawacity : ' . $blockTitle . ' : ' . $displayTitle; + $item['author'] = 'floviolleau'; + $item['content'] = $content; + $item['uid'] = hash('sha256', $blockTitle . '|' . $uri . '|' . $episode); + + $this->items[] = $item; + } + } + } + + private function toAbsoluteUri($link) { + return self::URI . (substr($link, 0, 1) === '/' ? $link : '/' . $link); + } +} From 39db08b35b49a951655698585f7676c89fb073d8 Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Thu, 9 Jul 2026 00:06:28 +0200 Subject: [PATCH 2/7] =?UTF-8?q?=E2=9C=A8(feat)=20Add=20new=20bridge=20Wawa?= =?UTF-8?q?city=20-=20fix=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 317 +++++++++++++++++++------------------ 1 file changed, 164 insertions(+), 153 deletions(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index b325245df34..0032f0de067 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -1,10 +1,13 @@ [ 'categorie' => [ @@ -28,157 +31,165 @@ class WawacityBridge extends BridgeAbstract { 'sous_categorie' => [ 'name' => 'Sous-catégorie', 'type' => 'text', - 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, "vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). Pour "Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, films-4k, series-vostfr, series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, autres-videos, divers (laisser vide = tous les widgets, avec la mention "Ajout de l\'épisode X" pour les séries/animés).', + 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, ' . + '"vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). Pour ' . + '"Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, films-4k, series-vostfr, ' . + 'series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, autres-videos, divers (laisser vide = tous les widgets, avec ' . + 'la mention "Ajout de l\'épisode X" pour les séries/animés).', 'exampleValue' => 'series-vostfr', 'required' => false, ] ] ]; - const CACHE_TIMEOUT = 18000; // every 5h - - // wawacity is behind Cloudflare, which returns a 520 error to - // requests that don't look like they come from a real browser. - const REQUEST_HEADERS = [ - 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0', - 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', - 'Accept-Language: en-US,en;q=0.5', - 'Upgrade-Insecure-Requests: 1', - ]; - - // Slug (used as sous_categorie) => exact "wa-block-title" text of the matching homepage widget - const HOMEPAGE_WIDGETS = [ - 'exclusivites' => 'Exclusivités (populaires)', - 'films' => 'Télécharger Films', - 'films-bluray' => 'Télécharger Films Blu-Ray', - 'films-4k' => 'Télécharger Films ULTRA HD 4K', - 'series-vostfr' => 'Télécharger Séries VOSTFR', - 'series-vf' => 'Télécharger Séries VF', - 'series-4k' => 'Télécharger Séries MULTI 4K', - 'jeux' => 'Télécharger Jeux', - 'musiques' => 'Télécharger Musiques', - 'ebooks' => 'Télécharger Ebooks', - 'animes' => 'Télécharger Animés', - 'logiciels' => 'Télécharger Logiciels', - 'mobiles' => 'Télécharger Mobiles', - 'autres-videos' => 'Télécharger Autres vidéo', - 'divers' => 'Télécharger divers', - ]; - - public function collectData() { - $categorie = $this->getInput('categorie'); - $sousCategorie = trim((string) $this->getInput('sous_categorie')); - - if ($categorie === 'accueil') { - $this->collectHomepageData($sousCategorie); - } else { - $this->collectCatalogueData($categorie, $sousCategorie); - } - } - - private function collectCatalogueData($categorie, $sousCategorie) { - $query = 'p=' . rawurlencode($categorie); - if ($sousCategorie !== '') { - $query .= '&s=' . rawurlencode($sousCategorie); - } - $url = self::URI . '/?' . $query; - - $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or returnServerError('Could not request ' . $url); - - $elementsDom = $html->find('#wa-mid-blocks .wa-post-detail-item'); - foreach ($elementsDom as $elementDom) { - $titleDom = $elementDom->find('.wa-sub-block-title a', 0); - $uri = $this->toAbsoluteUri($titleDom->href); - $title = html_entity_decode(trim($titleDom->plaintext), ENT_QUOTES); - - $imgDom = $elementDom->find('.cover img', 0); - $imgSrc = $imgDom ? self::URI . $imgDom->src : null; - - $descriptionDom = $elementDom->find('.col-md-10 p', 0); - $description = $descriptionDom ? html_entity_decode(trim($descriptionDom->plaintext), ENT_QUOTES) : ''; - - $content = ''; - if ($imgSrc) { - $content .= '
'; - } - $content .= $title . '
'; - if ($description !== '') { - $content .= '
' . $description; - } - - $item = []; - $item['uri'] = $uri; - $item['title'] = 'Wawacity : ' . $title; - $item['author'] = 'floviolleau'; - $item['content'] = $content; - $item['uid'] = hash('sha256', $uri); - - $this->items[] = $item; - } - } - - private function collectHomepageData($widget) { - if ($widget !== '' && !array_key_exists($widget, self::HOMEPAGE_WIDGETS)) { - returnServerError( - 'Sous-catégorie inconnue pour "Derniers ajouts (accueil)": ' . $widget - . '. Valeurs possibles: ' . implode(', ', array_keys(self::HOMEPAGE_WIDGETS)) . '.' - ); - } - - $url = self::URI; - $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or returnServerError('Could not request ' . $url); - - $blocksDom = $html->find('#wa-mid-blocks .wa-block'); - foreach ($blocksDom as $blockDom) { - $blockTitleDom = $blockDom->find('.wa-block-title', 0); - if (!$blockTitleDom) { - continue; - } - $blockTitle = html_entity_decode(trim($blockTitleDom->plaintext), ENT_QUOTES); - - if ($widget !== '' && $blockTitle !== self::HOMEPAGE_WIDGETS[$widget]) { - continue; - } - - foreach ($blockDom->find('a.thumbnail') as $thumbnailDom) { - $uri = $this->toAbsoluteUri($thumbnailDom->href); - $title = html_entity_decode(trim($thumbnailDom->title ?: ''), ENT_QUOTES); - - $imgDom = $thumbnailDom->find('img', 0); - $imgSrc = $imgDom ? self::URI . $imgDom->src : null; - if ($title === '' && $imgDom) { - $title = html_entity_decode(trim($imgDom->attr['alt'] ?? ''), ENT_QUOTES); - } - - $episode = null; - foreach ($thumbnailDom->find('div') as $divDom) { - $text = html_entity_decode(trim($divDom->plaintext), ENT_QUOTES); - if (stripos($text, 'Ajout de') !== false) { - $episode = $text; - break; - } - } - - $displayTitle = $episode ? $title . ' - ' . $episode : $title; - - $content = ''; - if ($imgSrc) { - $content .= '
'; - } - $content .= $displayTitle . '
'; - - $item = []; - $item['uri'] = $uri; - $item['title'] = 'Wawacity : ' . $blockTitle . ' : ' . $displayTitle; - $item['author'] = 'floviolleau'; - $item['content'] = $content; - $item['uid'] = hash('sha256', $blockTitle . '|' . $uri . '|' . $episode); - - $this->items[] = $item; - } - } - } - - private function toAbsoluteUri($link) { - return self::URI . (substr($link, 0, 1) === '/' ? $link : '/' . $link); - } + const CACHE_TIMEOUT = 18000; // every 5h + + // wawacity is behind Cloudflare, which returns a 520 error to + // requests that don't look like they come from a real browser. + const REQUEST_HEADERS = [ + 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0', + 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8', + 'Accept-Language: en-US,en;q=0.5', + 'Upgrade-Insecure-Requests: 1', + ]; + + // Slug (used as sous_categorie) => exact "wa-block-title" text of the matching homepage widget + const HOMEPAGE_WIDGETS = [ + 'exclusivites' => 'Exclusivités (populaires)', + 'films' => 'Télécharger Films', + 'films-bluray' => 'Télécharger Films Blu-Ray', + 'films-4k' => 'Télécharger Films ULTRA HD 4K', + 'series-vostfr' => 'Télécharger Séries VOSTFR', + 'series-vf' => 'Télécharger Séries VF', + 'series-4k' => 'Télécharger Séries MULTI 4K', + 'jeux' => 'Télécharger Jeux', + 'musiques' => 'Télécharger Musiques', + 'ebooks' => 'Télécharger Ebooks', + 'animes' => 'Télécharger Animés', + 'logiciels' => 'Télécharger Logiciels', + 'mobiles' => 'Télécharger Mobiles', + 'autres-videos' => 'Télécharger Autres vidéo', + 'divers' => 'Télécharger divers', + ]; + + public function collectData() + { + $categorie = $this->getInput('categorie'); + $sousCategorie = trim((string) $this->getInput('sous_categorie')); + + if ($categorie === 'accueil') { + $this->collectHomepageData($sousCategorie); + } else { + $this->collectCatalogueData($categorie, $sousCategorie); + } + } + + private function collectCatalogueData($categorie, $sousCategorie) + { + $query = 'p=' . rawurlencode($categorie); + if ($sousCategorie !== '') { + $query .= '&s=' . rawurlencode($sousCategorie); + } + $url = self::URI . '/?' . $query; + + $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or throwServerException('Could not request ' . $url); + + $elementsDom = $html->find('#wa-mid-blocks .wa-post-detail-item'); + foreach ($elementsDom as $elementDom) { + $titleDom = $elementDom->find('.wa-sub-block-title a', 0); + $uri = $this->toAbsoluteUri($titleDom->href); + $title = html_entity_decode(trim($titleDom->plaintext), ENT_QUOTES); + + $imgDom = $elementDom->find('.cover img', 0); + $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + + $descriptionDom = $elementDom->find('.col-md-10 p', 0); + $description = $descriptionDom ? html_entity_decode(trim($descriptionDom->plaintext), ENT_QUOTES) : ''; + + $content = ''; + if ($imgSrc) { + $content .= '
'; + } + $content .= $title . '
'; + if ($description !== '') { + $content .= '
' . $description; + } + + $item = []; + $item['uri'] = $uri; + $item['title'] = 'Wawacity : ' . $title; + $item['author'] = 'floviolleau'; + $item['content'] = $content; + $item['uid'] = hash('sha256', $uri); + + $this->items[] = $item; + } + } + + private function collectHomepageData($widget) + { + if ($widget !== '' && !array_key_exists($widget, self::HOMEPAGE_WIDGETS)) { + throwServerException( + 'Sous-catégorie inconnue pour "Derniers ajouts (accueil)": ' . $widget + . '. Valeurs possibles: ' . implode(', ', array_keys(self::HOMEPAGE_WIDGETS)) . '.' + ); + } + + $url = self::URI; + $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or throwServerException('Could not request ' . $url); + + $blocksDom = $html->find('#wa-mid-blocks .wa-block'); + foreach ($blocksDom as $blockDom) { + $blockTitleDom = $blockDom->find('.wa-block-title', 0); + if (!$blockTitleDom) { + continue; + } + $blockTitle = html_entity_decode(trim($blockTitleDom->plaintext), ENT_QUOTES); + + if ($widget !== '' && $blockTitle !== self::HOMEPAGE_WIDGETS[$widget]) { + continue; + } + + foreach ($blockDom->find('a.thumbnail') as $thumbnailDom) { + $uri = $this->toAbsoluteUri($thumbnailDom->href); + $title = html_entity_decode(trim($thumbnailDom->title ?: ''), ENT_QUOTES); + + $imgDom = $thumbnailDom->find('img', 0); + $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + if ($title === '' && $imgDom) { + $title = html_entity_decode(trim($imgDom->attr['alt'] ?? ''), ENT_QUOTES); + } + + $episode = null; + foreach ($thumbnailDom->find('div') as $divDom) { + $text = html_entity_decode(trim($divDom->plaintext), ENT_QUOTES); + if (stripos($text, 'Ajout de') !== false) { + $episode = $text; + break; + } + } + + $displayTitle = $episode ? $title . ' - ' . $episode : $title; + + $content = ''; + if ($imgSrc) { + $content .= '
'; + } + $content .= $displayTitle . '
'; + + $item = []; + $item['uri'] = $uri; + $item['title'] = 'Wawacity : ' . $blockTitle . ' : ' . $displayTitle; + $item['author'] = 'floviolleau'; + $item['content'] = $content; + $item['uid'] = hash('sha256', $blockTitle . '|' . $uri . '|' . $episode); + + $this->items[] = $item; + } + } + } + + private function toAbsoluteUri($link) + { + return self::URI . (substr($link, 0, 1) === '/' ? $link : '/' . $link); + } } From b5f402ec3dbf379d0a401a1c45fd7d60e676c6e0 Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Thu, 9 Jul 2026 00:10:39 +0200 Subject: [PATCH 3/7] =?UTF-8?q?=E2=9C=A8(feat)=20Add=20new=20bridge=20Wawa?= =?UTF-8?q?city=20-=20fix=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index 0032f0de067..d56c1c88c8e 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -31,11 +31,11 @@ class WawacityBridge extends BridgeAbstract 'sous_categorie' => [ 'name' => 'Sous-catégorie', 'type' => 'text', - 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, ' . - '"vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). Pour ' . - '"Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, films-4k, series-vostfr, ' . - 'series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, autres-videos, divers (laisser vide = tous les widgets, avec ' . - 'la mention "Ajout de l\'épisode X" pour les séries/animés).', + 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, ' + . '"vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). ' + . 'Pour "Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, ' + . 'films-4k, series-vostfr, series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, ' + . 'autres-videos, divers (laisser vide = tous les widgets, avec la mention "Ajout de l\'épisode X" pour les séries/animés).', 'exampleValue' => 'series-vostfr', 'required' => false, ] @@ -72,7 +72,7 @@ class WawacityBridge extends BridgeAbstract ]; public function collectData() - { + { $categorie = $this->getInput('categorie'); $sousCategorie = trim((string) $this->getInput('sous_categorie')); @@ -84,7 +84,7 @@ public function collectData() } private function collectCatalogueData($categorie, $sousCategorie) - { + { $query = 'p=' . rawurlencode($categorie); if ($sousCategorie !== '') { $query .= '&s=' . rawurlencode($sousCategorie); @@ -126,7 +126,7 @@ private function collectCatalogueData($categorie, $sousCategorie) } private function collectHomepageData($widget) - { + { if ($widget !== '' && !array_key_exists($widget, self::HOMEPAGE_WIDGETS)) { throwServerException( 'Sous-catégorie inconnue pour "Derniers ajouts (accueil)": ' . $widget @@ -189,7 +189,7 @@ private function collectHomepageData($widget) } private function toAbsoluteUri($link) - { + { return self::URI . (substr($link, 0, 1) === '/' ? $link : '/' . $link); } } From be1bd1a4a6065f1dff1ca3e9daa95a6c01c05541 Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Thu, 9 Jul 2026 00:21:01 +0200 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=A8(feat)=20Add=20new=20bridge=20Wawa?= =?UTF-8?q?city=20-=20fix=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index d56c1c88c8e..dd883206c2f 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -31,11 +31,13 @@ class WawacityBridge extends BridgeAbstract 'sous_categorie' => [ 'name' => 'Sous-catégorie', 'type' => 'text', - 'title' => 'Optionnel. Pour une catégorie du catalogue, reprend le paramètre "s" du site (ex: "bd" ou "mangas" pour Ebooks, ' - . '"vf" ou "vostfr" pour Séries, "ps4" ou "pc" pour Jeux ; voir le menu de navigation du site pour la liste complète). ' - . 'Pour "Derniers ajouts (accueil)", choisit le widget de la page d\'accueil : exclusivites, films, films-bluray, ' - . 'films-4k, series-vostfr, series-vf, series-4k, jeux, musiques, ebooks, animes, logiciels, mobiles, ' - . 'autres-videos, divers (laisser vide = tous les widgets, avec la mention "Ajout de l\'épisode X" pour les séries/animés).', + 'title' => << 'series-vostfr', 'required' => false, ] From 3b7a384e7ffb0aced40b04620e5135155d33fefa Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Wed, 15 Jul 2026 13:05:49 +0200 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=90=9B(fix)=20Update=20WawacityBridge?= =?UTF-8?q?=20to=20use=20wawacity-info.com=20mirror=20and=20get=20laste=20?= =?UTF-8?q?wawacity=20domain=20because=20it=20changes=20often?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 61 +++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index dd883206c2f..805cb2abee3 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -5,7 +5,9 @@ class WawacityBridge extends BridgeAbstract { const NAME = 'Wawacity'; - const URI = 'https://www.wawacity.codes'; + // Last known-good mirror, used only as a fallback if the domain can't be + // resolved dynamically (see resolveBaseUri()) + const URI = 'https://www.wawacity.toto'; const DESCRIPTION = 'Fetches the latest on wawacity'; const MAINTAINER = 'floviolleau'; const PARAMETERS = [ @@ -43,7 +45,7 @@ class WawacityBridge extends BridgeAbstract ] ] ]; - const CACHE_TIMEOUT = 18000; // every 5h + const CACHE_TIMEOUT = 0;//18000; // every 5h // wawacity is behind Cloudflare, which returns a 520 error to // requests that don't look like they come from a real browser. @@ -73,8 +75,20 @@ class WawacityBridge extends BridgeAbstract 'divers' => 'Télécharger divers', ]; + // wawacity's domain changes often (blocking, DNS seizures...). This + // "we moved" landing page stays stable and always links to the current + // mirror through its #manual-redirect button, so we resolve the real + // domain from there instead of hard-coding it. + const INFO_URI = 'https://wawacity-info.com/'; + const BASE_URI_CACHE_KEY = 'base_uri'; + const BASE_URI_CACHE_TTL = 18000; // re-check every 5h + + private string $baseUri; + public function collectData() { + $this->baseUri = $this->resolveBaseUri(); + $categorie = $this->getInput('categorie'); $sousCategorie = trim((string) $this->getInput('sous_categorie')); @@ -85,13 +99,46 @@ public function collectData() } } + public function getURI(): string + { + return $this->baseUri ?? parent::getURI(); + } + + /** + * Resolves the current wawacity mirror domain from wawacity-info.com's + * #manual-redirect link, caching the result so we don't hit that page on + * every single request. Falls back to the last known-good domain (the + * cached value if we have one, otherwise the hard-coded const URI) if the + * landing page itself is unreachable or has changed shape. + */ + private function resolveBaseUri(): string + { + $cached = $this->loadCacheValue(self::BASE_URI_CACHE_KEY); + + try { + $html = getSimpleHTMLDOM(self::INFO_URI, self::REQUEST_HEADERS); + $redirectDom = $html->find('#manual-redirect', 0); + $href = $redirectDom ? trim($redirectDom->href) : ''; + + if ($href !== '' && preg_match('#^https://[^/]+#', $href, $matches)) { + $resolved = $matches[0]; + $this->saveCacheValue(self::BASE_URI_CACHE_KEY, $resolved, self::BASE_URI_CACHE_TTL); + return $resolved; + } + } catch (\Throwable $e) { + // Fall through to the cached/hard-coded fallback below. + } + + return $cached ?? self::URI; + } + private function collectCatalogueData($categorie, $sousCategorie) { $query = 'p=' . rawurlencode($categorie); if ($sousCategorie !== '') { $query .= '&s=' . rawurlencode($sousCategorie); } - $url = self::URI . '/?' . $query; + $url = $this->baseUri . '/?' . $query; $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or throwServerException('Could not request ' . $url); @@ -102,7 +149,7 @@ private function collectCatalogueData($categorie, $sousCategorie) $title = html_entity_decode(trim($titleDom->plaintext), ENT_QUOTES); $imgDom = $elementDom->find('.cover img', 0); - $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + $imgSrc = $imgDom ? $this->baseUri . $imgDom->src : null; $descriptionDom = $elementDom->find('.col-md-10 p', 0); $description = $descriptionDom ? html_entity_decode(trim($descriptionDom->plaintext), ENT_QUOTES) : ''; @@ -136,7 +183,7 @@ private function collectHomepageData($widget) ); } - $url = self::URI; + $url = $this->baseUri; $html = getSimpleHTMLDOM($url, self::REQUEST_HEADERS) or throwServerException('Could not request ' . $url); $blocksDom = $html->find('#wa-mid-blocks .wa-block'); @@ -156,7 +203,7 @@ private function collectHomepageData($widget) $title = html_entity_decode(trim($thumbnailDom->title ?: ''), ENT_QUOTES); $imgDom = $thumbnailDom->find('img', 0); - $imgSrc = $imgDom ? self::URI . $imgDom->src : null; + $imgSrc = $imgDom ? $this->baseUri . $imgDom->src : null; if ($title === '' && $imgDom) { $title = html_entity_decode(trim($imgDom->attr['alt'] ?? ''), ENT_QUOTES); } @@ -192,6 +239,6 @@ private function collectHomepageData($widget) private function toAbsoluteUri($link) { - return self::URI . (substr($link, 0, 1) === '/' ? $link : '/' . $link); + return $this->baseUri . (substr($link, 0, 1) === '/' ? $link : '/' . $link); } } From 473e4418785ea249181b6ebfab455373dbff9863 Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Wed, 15 Jul 2026 13:06:31 +0200 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=90=9B(fix)=20Update=20WawacityBridge?= =?UTF-8?q?=20revert=20bad=20cache=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index 805cb2abee3..5e324a3327e 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -45,7 +45,7 @@ class WawacityBridge extends BridgeAbstract ] ] ]; - const CACHE_TIMEOUT = 0;//18000; // every 5h + const CACHE_TIMEOUT = 18000; // every 5h // wawacity is behind Cloudflare, which returns a 520 error to // requests that don't look like they come from a real browser. From 141f1f95dca56aadfb244be768f1178cc7edfd7f Mon Sep 17 00:00:00 2001 From: Florent VIOLLEAU Date: Wed, 15 Jul 2026 13:07:13 +0200 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=90=9B(fix)=20Update=20WawacityBridge?= =?UTF-8?q?=20revert=20bad=20URI=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bridges/WawacityBridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/WawacityBridge.php b/bridges/WawacityBridge.php index 5e324a3327e..5651687ba5a 100644 --- a/bridges/WawacityBridge.php +++ b/bridges/WawacityBridge.php @@ -7,7 +7,7 @@ class WawacityBridge extends BridgeAbstract const NAME = 'Wawacity'; // Last known-good mirror, used only as a fallback if the domain can't be // resolved dynamically (see resolveBaseUri()) - const URI = 'https://www.wawacity.toto'; + const URI = 'https://www.wawacity.poker'; const DESCRIPTION = 'Fetches the latest on wawacity'; const MAINTAINER = 'floviolleau'; const PARAMETERS = [