From 50924b92138a3f60ccc5a73e591e1930ff5021d5 Mon Sep 17 00:00:00 2001 From: Joe Digilio Date: Fri, 15 Jun 2018 14:02:06 -0500 Subject: [PATCH 001/146] Abort on parse error of config.default.ini.php (#714) If there is an error parsing the default config file, then abort. --- index.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.php b/index.php index f61f884d..bcf1dae2 100644 --- a/index.php +++ b/index.php @@ -14,6 +14,8 @@ if(!file_exists('config.default.ini.php')) die('The default configuration file "config.default.ini.php" is missing!'); $config = parse_ini_file('config.default.ini.php', true, INI_SCANNER_TYPED); +if(!$config) + die('Error parsing config.default.ini.php'); if(file_exists('config.ini.php')) { // Replace default configuration with custom settings From 8e468a9ca7fdf7c919aec2ef52249ddc5a21f72d Mon Sep 17 00:00:00 2001 From: Corentin Garcia Date: Fri, 15 Jun 2018 21:05:31 +0200 Subject: [PATCH 002/146] [SuperSmashBlogBridge] Added bridge (#716) --- bridges/SuperSmashBlogBridge.php | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 bridges/SuperSmashBlogBridge.php diff --git a/bridges/SuperSmashBlogBridge.php b/bridges/SuperSmashBlogBridge.php new file mode 100644 index 00000000..06c58fca --- /dev/null +++ b/bridges/SuperSmashBlogBridge.php @@ -0,0 +1,45 @@ +'); + } else { + $picture = ''; + } + + $video = $article['acf']['link_url']; + if (strlen($video) != 0) { + $video = str_get_html('Youtube video'); + } else { + $video = ''; + } + $text = str_get_html($article['acf']['editor']); + $content = $picture . $video . $text; + + // Build final item + $item = array(); + $item['title'] = $article['title']['rendered']; + $item['timestamp'] = strtotime($article['date']); + $item['content'] = $content; + $item['uri'] = self::URI . '?post=' . $article['id']; + + $this->items[] = $item; + } + } +} From 7493e2b5b8466b6702e775663abacb518349b724 Mon Sep 17 00:00:00 2001 From: Corentin Garcia Date: Fri, 15 Jun 2018 21:09:09 +0200 Subject: [PATCH 003/146] [GrandComicsDatabaseBridge] Add bridge (#717) closes #709 --- bridges/GrandComicsDatabaseBridge.php | 61 +++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 bridges/GrandComicsDatabaseBridge.php diff --git a/bridges/GrandComicsDatabaseBridge.php b/bridges/GrandComicsDatabaseBridge.php new file mode 100644 index 00000000..2b2fdfe1 --- /dev/null +++ b/bridges/GrandComicsDatabaseBridge.php @@ -0,0 +1,61 @@ + array( + 'name' => 'Series id (from the timeline URL)', + 'required' => true, + 'exampleValue' => '63051', + ), + )); + + public function collectData(){ + + $url = self::URI . 'series/' . $this->getInput('series') . '/details/timeline/'; + $html = getSimpleHTMLDOM($url) + or returnServerError('Error while downloading the website content'); + + $table = $html->find('table', 0); + $list = array_reverse($table->find('[class^=row_even]')); + $seriesName = $html->find('span[id=series_name]', 0)->innertext; + + // Get row headers + $rowHeaders = $table->find('th'); + foreach($list as $article) { + + // Skip empty rows + $emptyRow = $article->find('td.empty_month'); + if (count($emptyRow) != 0) { + continue; + } + + $rows = $article->find('td'); + $key_date = $rows[0]->innertext; + + // Get URL too + $uri = 'https://www.comics.org' . $article->find('a')[0]->href; + + // Build content + $content = ''; + for($i = 0; $i < count($rowHeaders); $i++) { + $headerItem = $rowHeaders[$i]->innertext; + $rowItem = $rows[$i]->innertext; + $content = $content . $headerItem . ': ' . $rowItem . '
'; + } + + // Build final item + $item = array(); + $item['title'] = $seriesName . ' - ' . $key_date; + $item['timestamp'] = strtotime($key_date); + $item['content'] = str_get_html($content); + $item['uri'] = $uri; + + $this->items[] = $item; + } + } +} From 9fa74a36c63b8f006f9a524d21b40f9ebca696c8 Mon Sep 17 00:00:00 2001 From: Nemo Date: Wed, 20 Jun 2018 00:09:08 +0530 Subject: [PATCH 004/146] Adds Container Linux releases RSS Feed (#718) * Adds Container Linux releases RSS Feed --- bridges/ContainerLinuxReleasesBridge.php | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 bridges/ContainerLinuxReleasesBridge.php diff --git a/bridges/ContainerLinuxReleasesBridge.php b/bridges/ContainerLinuxReleasesBridge.php new file mode 100644 index 00000000..c5f64a15 --- /dev/null +++ b/bridges/ContainerLinuxReleasesBridge.php @@ -0,0 +1,76 @@ + [ + 'name' => 'Release Channel', + 'type' => 'list', + 'required' => true, + 'defaultValue' => self::STABLE, + 'values' => [ + 'Stable' => self::STABLE, + 'Beta' => self::BETA, + 'Alpha' => self::ALPHA, + ], + ] + ] + ]; + + public function getReleaseFeed($jsonUrl) { + $json = getContents($jsonUrl) + or returnServerError('Could not request Core OS Website.'); + return json_decode($json, true); + } + + public function collectData() { + $data = $this->getReleaseFeed($this->getJsonUri()); + + foreach ($data as $releaseVersion => $release) { + $item = []; + + $item['uri'] = "https://coreos.com/releases/#$releaseVersion"; + $item['title'] = $releaseVersion; + $item['content'] = nl2br($release['release_notes']); + + $item['content'] .= << +Major Software: +
+- Kernel: {$release['major_software']['kernel'][0]}
+- Docker: {$release['major_software']['docker'][0]}
+- etcd: {$release['major_software']['etcd'][0]}
+EOT; + $item['timestamp'] = strtotime($release['release_date']); + + $this->items[] = $item; + } + } + + private function getJsonUri() { + $channel = $this->getInput('channel'); + + return "https://coreos.com/releases/releases-$channel.json"; + } + + public function getURI() { + return self::URI; + } + + public function getName(){ + if(!is_null($this->getInput('channel'))) { + return 'Container Linux Releases: ' . $this->getInput('channel') . ' Channel'; + } + + return parent::getName(); + } +} From 1b08bce77911af2469ea0ed1a21170cca4d9ba76 Mon Sep 17 00:00:00 2001 From: sysadminstory Date: Thu, 21 Jun 2018 14:14:59 +0200 Subject: [PATCH 005/146] [DealabsBridge] Follow site changes (#721) - Changed some CSS class to follow the website changes (again) --- bridges/DealabsBridge.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/bridges/DealabsBridge.php b/bridges/DealabsBridge.php index 0381d885..2876aab2 100644 --- a/bridges/DealabsBridge.php +++ b/bridges/DealabsBridge.php @@ -178,10 +178,9 @@ class DealabsBridge extends BridgeAbstract { ' ', /* Notice this is a space! */ array( 'cept-description-container', - 'userHtml', 'overflow--wrap-break', 'size--all-s', - 'size--fromW3-m', + 'size--fromW3-m' ) ); @@ -191,7 +190,6 @@ class DealabsBridge extends BridgeAbstract { array( 'size--all-s', 'flex', - 'flex--wrap', 'flex--justify-e', 'flex--grow-1', ) @@ -223,11 +221,11 @@ class DealabsBridge extends BridgeAbstract { . $this->getExpedition($deal) . $this->getLivraison($deal) . $this->getOrigine($deal) - . $deal->find('div[class='. $selectorDescription .']', 0)->innertext + . $deal->find('div[class*='. $selectorDescription .']', 0)->innertext . '' . $deal->find('div[class='. $selectorHot .']', 0)->children(0)->outertext . ''; - $dealDateDiv = $deal->find('div[class='. $selectorDate .']', 0) + $dealDateDiv = $deal->find('div[class*='. $selectorDate .']', 0) ->find('span[class=hide--toW3]'); $itemDate = end($dealDateDiv)->plaintext; if(substr( $itemDate, 0, 6 ) === 'il y a') { From f4a60c1777dc6726dd3ce5ea34b54f643ae3fb07 Mon Sep 17 00:00:00 2001 From: Nemo Date: Sat, 23 Jun 2018 20:21:48 +0530 Subject: [PATCH 006/146] Add dockerfile to create an official docker image (#720) --- .dockerignore | 8 ++++++++ Dockerfile | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..15154f0d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +cache/* +DEBUG +Dockerfile +whitelist.txt +phpcs.xml +CHANGELOG.md +CONTRIBUTING.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..35caac84 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,5 @@ +FROM ulsmith/alpine-apache-php7 + +COPY ./ /app/public/ + +RUN chown -R apache:root /app/public \ No newline at end of file From 01a27467156a79e1254761c26f64d095a1634eea Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Sat, 23 Jun 2018 21:28:27 +0200 Subject: [PATCH 007/146] [YoutubeBridge] Fix sniff violation This is a fix for a sniff violation not detected by newer versions of phpcs (not sure why though, it's detected in version 2.7.1). --- bridges/YoutubeBridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/YoutubeBridge.php b/bridges/YoutubeBridge.php index 302a59a5..043d965e 100644 --- a/bridges/YoutubeBridge.php +++ b/bridges/YoutubeBridge.php @@ -226,5 +226,5 @@ class YoutubeBridge extends BridgeAbstract { default: return parent::getName(); } - } + } } From 4a5f190e0e2dd83f89bf60a6c7598d6c64e4a5c3 Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Sun, 24 Jun 2018 10:52:00 +0200 Subject: [PATCH 008/146] [FacebookBridge] Add option to skip reviews Reviews are provided the same way as summary posts and therefore returned as separate feed item for each review. This commit adds a new option '&skip_reviews=on' to skip reviews entirely. References #706 --- bridges/FacebookBridge.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bridges/FacebookBridge.php b/bridges/FacebookBridge.php index a5b328dc..63c93467 100644 --- a/bridges/FacebookBridge.php +++ b/bridges/FacebookBridge.php @@ -23,6 +23,13 @@ class FacebookBridge extends BridgeAbstract { 'No Video' => 'novideo' ), 'defaultValue' => 'all' + ), + 'skip_reviews' => array( + 'name' => 'Skip reviews', + 'type' => 'checkbox', + 'required' => false, + 'defaultValue' => false, + 'title' => 'Feed includes reviews when checked' ) )); @@ -195,6 +202,12 @@ EOD; $posts = array($cell); } + // Optionally skip reviews + if($this->getInput('skip_reviews') + && !is_null($cell->find('#review_composer_container', 0))) { + continue; + } + foreach($posts as $post) { // Check media type switch($this->getInput('media_type')) { From 5087f5f79e64c648765384fdc952efc68c57243a Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Sun, 24 Jun 2018 11:03:43 +0200 Subject: [PATCH 009/146] [FacebookBridge] Support facebook links as user name Allows users to paste facebook links as user name. The link must contain the correct host (www.facebook.com) and a valid path (/user-name/...). The first part of the path is used for the user name. Errors are returned in case something went wrong. References #706 --- bridges/FacebookBridge.php | 45 ++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/bridges/FacebookBridge.php b/bridges/FacebookBridge.php index 63c93467..ce3275ea 100644 --- a/bridges/FacebookBridge.php +++ b/bridges/FacebookBridge.php @@ -127,17 +127,44 @@ application/x-www-form-urlencoded\r\nReferer: $captcha_action\r\nCookie: noscrip if(is_null($html)) { $header = array('Accept-Language: ' . getEnv('HTTP_ACCEPT_LANGUAGE') . "\r\n"); - // First character cannot be a forward slash - if(strpos($this->getInput('u'), "/") === 0) { - returnClientError('Remove leading slash "/" from the username!'); - } + // Check if the user provided a fully qualified URL + if (filter_var($this->getInput('u'), FILTER_VALIDATE_URL)) { + + $urlparts = parse_url($this->getInput('u')); + + if($urlparts['host'] !== parse_url(self::URI)['host']) { + returnClientError('The host you provided is invalid! Received "' + . $urlparts['host'] + . '", expected "' + . parse_url(self::URI)['host'] + . '"!'); + } + + if(!array_key_exists('path', $urlparts) + || $urlparts['path'] === '/') { + returnClientError('The URL you provided doesn\'t contain the user name!'); + } + + $user = explode('/', $urlparts['path'])[1]; + + $html = getSimpleHTMLDOM(self::URI . urlencode($user) . '?_fb_noscript=1', $header) + or returnServerError('No results for this query.'); - if(!strpos($this->getInput('u'), "/")) { - $html = getSimpleHTMLDOM(self::URI . urlencode($this->getInput('u')) . '?_fb_noscript=1', $header) - or returnServerError('No results for this query.'); } else { - $html = getSimpleHTMLDOM(self::URI . 'pages/' . $this->getInput('u') . '?_fb_noscript=1', $header) - or returnServerError('No results for this query.'); + + // First character cannot be a forward slash + if(strpos($this->getInput('u'), "/") === 0) { + returnClientError('Remove leading slash "/" from the username!'); + } + + if(!strpos($this->getInput('u'), "/")) { + $html = getSimpleHTMLDOM(self::URI . urlencode($this->getInput('u')) . '?_fb_noscript=1', $header) + or returnServerError('No results for this query.'); + } else { + $html = getSimpleHTMLDOM(self::URI . 'pages/' . $this->getInput('u') . '?_fb_noscript=1', $header) + or returnServerError('No results for this query.'); + } + } } From 95686b803c073c653a5cfad45d81c6e6980e5dbf Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Sun, 24 Jun 2018 18:27:11 +0200 Subject: [PATCH 010/146] [IsoHuntBridge] Remove bridge isoHunt has discontinued services due to legal reasons and is now accessible via https://isohunts.to While it is certainly possible to rewrite the bridge to fetch some information from the new site, it wouldn't be able to provide as much functionality as before. This is due to isoHunt having removed all searching and filtering options, only providing static HTML pages for general categories (anime, movies, etc...). Those pages, however, are heavily broken. Unless someone is interested in monitoring the general categories the effort of upgrading the bridge to the new site is not worth taking time for. Users of isoHunt are asked to make use of their client application, as they don't provide online services anymore (it's now in the darknet) Here is the statement from isoHunt: "Due to hard regulations and security issues for bittorrent users, we have moved into a more secure and even faster district of the internet! [...] Torrent Downloads have a high risk of getting legal problems. That is why we do not offer torrentfiles any more. [...]" -- source: https://isohunts.to --- bridges/IsoHuntBridge.php | 465 -------------------------------------- 1 file changed, 465 deletions(-) delete mode 100644 bridges/IsoHuntBridge.php diff --git a/bridges/IsoHuntBridge.php b/bridges/IsoHuntBridge.php deleted file mode 100644 index 57038fcc..00000000 --- a/bridges/IsoHuntBridge.php +++ /dev/null @@ -1,465 +0,0 @@ - array( - 'latest_category' => array( - 'name' => 'Latest category', - 'type' => 'list', - 'required' => true, - 'title' => 'Select your category', - 'defaultValue' => 'news', - 'values' => array( - 'Hot Torrents' => 'hot_torrents', - 'News' => 'news', - 'Releases' => 'releases', - 'Torrents' => 'torrents' - ) - ) - ), - - /* - * Get feeds for one of the "torrent" categories - * Make sure to add new categories also to get_torrent_category_index($)! - * Elements are sorted by name ascending! - */ - 'By "Torrent" category' => array( - 'torrent_category' => array( - 'name' => 'Torrent category', - 'type' => 'list', - 'required' => true, - 'title' => 'Select your category', - 'defaultValue' => 'anime', - 'values' => array( - 'Adult' => 'adult', - 'Anime' => 'anime', - 'Books' => 'books', - 'Games' => 'games', - 'Movies' => 'movies', - 'Music' => 'music', - 'Other' => 'other', - 'Series & TV' => 'series_tv', - 'Software' => 'software' - ) - ), - 'torrent_popularity' => array( - 'name' => 'Sort by popularity', - 'type' => 'checkbox', - 'title' => 'Activate to receive results by popularity' - ) - ), - - /* - * Get feeds for a specific search request - */ - 'Search torrent by name' => array( - 'search_name' => array( - 'name' => 'Name', - 'required' => true, - 'title' => 'Insert your search query', - 'exampleValue' => 'Bridge' - ), - 'search_category' => array( - 'name' => 'Category', - 'type' => 'list', - 'title' => 'Select your category', - 'defaultValue' => 'all', - 'values' => array( - 'Adult' => 'adult', - 'All' => 'all', - 'Anime' => 'anime', - 'Books' => 'books', - 'Games' => 'games', - 'Movies' => 'movies', - 'Music' => 'music', - 'Other' => 'other', - 'Series & TV' => 'series_tv', - 'Software' => 'software' - ) - ) - ) - ); - - public function getURI(){ - $uri = self::URI; - switch($this->queriedContext) { - case 'By "Latest" category': - switch($this->getInput('latest_category')) { - case 'hot_torrents': - $uri .= 'statistic/hot/torrents'; - break; - case 'news': - break; - case 'releases': - $uri .= 'releases.php'; - break; - case 'torrents': - $uri .= 'latest.php'; - break; - } - break; - case 'By "Torrent" category': - $uri .= $this->buildCategoryUri( - $this->getInput('torrent_category'), - $this->getInput('torrent_popularity') - ); - break; - case 'Search torrent by name': - $category = $this->getInput('search_category'); - $uri .= $this->buildCategoryUri($category); - if($category !== 'movies') - $uri .= '&ihq=' . urlencode($this->getInput('search_name')); - break; - - default: parent::getURI(); - } - - return $uri; - } - - public function getName(){ - switch($this->queriedContext) { - case 'By "Latest" category': - $categoryName = array_search( - $this->getInput('latest_category'), - self::PARAMETERS['By "Latest" category']['latest_category']['values'] - ); - $name = 'Latest ' . $categoryName . ' - ' . self::NAME; - break; - case 'By "Torrent" category': - $categoryName = array_search( - $this->getInput('torrent_category'), - self::PARAMETERS['By "Torrent" category']['torrent_category']['values'] - ); - $name = 'Category: ' . $categoryName . ' - ' . self::NAME; - break; - case 'Search torrent by name': - $categoryName = array_search( - $this->getInput('search_category'), - self::PARAMETERS['Search torrent by name']['search_category']['values'] - ); - $name = 'Search: "' - . $this->getInput('search_name') - . '" in category: ' - . $categoryName . ' - ' - . self::NAME; - break; - default: return parent::getName(); - } - - return $name; - } - - public function collectData(){ - $html = $this->loadHtml($this->getURI()); - - switch($this->queriedContext) { - case 'By "Latest" category': - switch($this->getInput('latest_category')) { - case 'hot_torrents': - $this->getLatestHotTorrents($html); - break; - case 'news': - $this->getLatestNews($html); - break; - case 'releases': - case 'torrents': - $this->getLatestTorrents($html); - break; - } - break; - case 'By "Torrent" category': - if($this->getInput('torrent_category') === 'movies') { - // This one is special (content wise) - $this->getMovieTorrents($html); - } else { - $this->getLatestTorrents($html); - } - break; - case 'Search torrent by name': - if($this->getInput('search_category') === 'movies') { - // This one is special (content wise) - $this->getMovieTorrents($html); - } else { - $this->getLatestTorrents($html); - } - break; - } - } - - #region Helper functions for "Movie Torrents" - - private function getMovieTorrents($html){ - $container = $html->find('div#w0', 0); - if(!$container) - returnServerError('Unable to find torrent container!'); - - $torrents = $container->find('article'); - if(!$torrents) - returnServerError('Unable to find torrents!'); - - foreach($torrents as $torrent) { - - $anchor = $torrent->find('a', 0); - if(!$anchor) - returnServerError('Unable to find anchor!'); - - $date = $torrent->find('small', 0); - if(!$date) - returnServerError('Unable to find date!'); - - $item = array(); - - $item['uri'] = $this->fixRelativeUri($anchor->href); - $item['title'] = $anchor->title; - // $item['author'] = - $item['timestamp'] = strtotime($date->plaintext); - $item['content'] = $this->fixRelativeUri($torrent->innertext); - - $this->items[] = $item; - } - } - - #endregion - - #region Helper functions for "Latest Hot Torrents" - - private function getLatestHotTorrents($html){ - $container = $html->find('div#serps', 0); - if(!$container) - returnServerError('Unable to find torrent container!'); - - $torrents = $container->find('tr'); - if(!$torrents) - returnServerError('Unable to find torrents!'); - - // Remove first element (header row) - $torrents = array_slice($torrents, 1); - - foreach($torrents as $torrent) { - - $cell = $torrent->find('td', 0); - if(!$cell) - returnServerError('Unable to find cell!'); - - $element = $cell->find('a', 0); - if(!$element) - returnServerError('Unable to find element!'); - - $item = array(); - - $item['uri'] = $element->href; - $item['title'] = $element->plaintext; - // $item['author'] = - // $item['timestamp'] = - // $item['content'] = - - $this->items[] = $item; - } - } - - #endregion - - #region Helper functions for "Latest News" - - private function getLatestNews($html){ - $container = $html->find('div#postcontainer', 0); - if(!$container) - returnServerError('Unable to find post container!'); - - $posts = $container->find('div.index-post'); - if(!$posts) - returnServerError('Unable to find posts!'); - - foreach($posts as $post) { - $item = array(); - - $item['uri'] = $this->latestNewsExtractUri($post); - $item['title'] = $this->latestNewsExtractTitle($post); - $item['author'] = $this->latestNewsExtractAuthor($post); - $item['timestamp'] = $this->latestNewsExtractTimestamp($post); - $item['content'] = $this->latestNewsExtractContent($post); - - $this->items[] = $item; - } - } - - private function latestNewsExtractAuthor($post){ - $author = $post->find('small', 0); - if(!$author) - returnServerError('Unable to find author!'); - - // The author is hidden within a string like: 'Posted by {author} on {date}' - preg_match('/Posted\sby\s(.*)\son/i', $author->innertext, $matches); - - return $matches[1]; - } - - private function latestNewsExtractTimestamp($post){ - $date = $post->find('small', 0); - if(!$date) - returnServerError('Unable to find date!'); - - // The date is hidden within a string like: 'Posted by {author} on {date}' - preg_match('/Posted\sby\s.*\son\s(.*)/i', $date->innertext, $matches); - - $timestamp = strtotime($matches[1]); - - // Make sure date is not in the future (dates are given like 'Nov. 20' without year) - if($timestamp > time()) { - $timestamp = strtotime('-1 year', $timestamp); - } - - return $timestamp; - } - - private function latestNewsExtractTitle($post){ - $title = $post->find('a', 0); - if(!$title) - returnServerError('Unable to find title!'); - - return $title->plaintext; - } - - private function latestNewsExtractUri($post){ - $uri = $post->find('a', 0); - if(!$uri) - returnServerError('Unable to find uri!'); - - return $uri->href; - } - - private function latestNewsExtractContent($post){ - $content = $post->find('div', 0); - if(!$content) - returnServerError('Unable to find content!'); - - // Remove

...

(title) - foreach($content->find('h2') as $element) { - $element->outertext = ''; - } - - // Remove ... (author) - foreach($content->find('small') as $element) { - $element->outertext = ''; - } - - return $content->innertext; - } - - #endregion - - #region Helper functions for "Latest Torrents", "Latest Releases" and "Torrent Category" - - private function getLatestTorrents($html){ - $container = $html->find('div#serps', 0); - if(!$container) - returnServerError('Unable to find torrent container!'); - - $torrents = $container->find('tr[data-key]'); - if(!$torrents) - returnServerError('Unable to find torrents!'); - - foreach($torrents as $torrent) { - $item = array(); - - $item['uri'] = $this->latestTorrentsExtractUri($torrent); - $item['title'] = $this->latestTorrentsExtractTitle($torrent); - $item['author'] = $this->latestTorrentsExtractAuthor($torrent); - $item['timestamp'] = $this->latestTorrentsExtractTimestamp($torrent); - $item['content'] = ''; // There is no valuable content - - $this->items[] = $item; - } - } - - private function latestTorrentsExtractTitle($torrent){ - $cell = $torrent->find('td.title-row', 0); - if(!$cell) - returnServerError('Unable to find title cell!'); - - $title = $cell->find('span', 0); - if(!$title) - returnServerError('Unable to find title!'); - - return $title->plaintext; - } - - private function latestTorrentsExtractUri($torrent){ - $cell = $torrent->find('td.title-row', 0); - if(!$cell) - returnServerError('Unable to find title cell!'); - - $uri = $cell->find('a', 0); - if(!$uri) - returnServerError('Unable to find uri!'); - - return $this->fixRelativeUri($uri->href); - } - - private function latestTorrentsExtractAuthor($torrent){ - $cell = $torrent->find('td.user-row', 0); - if(!$cell) - return; // No author - - $user = $cell->find('a', 0); - if(!$user) - returnServerError('Unable to find user!'); - - return $user->plaintext; - } - - private function latestTorrentsExtractTimestamp($torrent){ - $cell = $torrent->find('td.date-row', 0); - if(!$cell) - returnServerError('Unable to find date cell!'); - - return strtotime('-' . $cell->plaintext, time()); - } - - #endregion - - #region Generic helper functions - - private function loadHtml($uri){ - $html = getSimpleHTMLDOM($uri); - if(!$html) - returnServerError('Unable to load ' . $uri . '!'); - - return $html; - } - - private function fixRelativeUri($uri){ - return preg_replace('/\//i', self::URI, $uri, 1); - } - - private function buildCategoryUri($category, $order_popularity = false){ - switch($category) { - case 'anime': $index = 1; break; - case 'software' : $index = 2; break; - case 'games' : $index = 3; break; - case 'adult' : $index = 4; break; - case 'movies' : $index = 5; break; - case 'music' : $index = 6; break; - case 'other' : $index = 7; break; - case 'series_tv' : $index = 8; break; - case 'books': $index = 9; break; - case 'all': - default: $index = 0; break; - } - - return 'torrents/?iht=' . $index . '&ihs=' . ($order_popularity ? 1 : 0) . '&age=0'; - } - - #endregion -} From 937ea492716b9251211a2a0f73f3afd1ac871505 Mon Sep 17 00:00:00 2001 From: Teromene Date: Wed, 27 Jun 2018 18:09:41 +0100 Subject: [PATCH 011/146] Add basic authentication support (#728) * Move configuration in its own class in order to reduce the verbosity of index.php * Add authentication mechanism using HTTP auth * Add a method to get the config parameters * Remove the installation checks from the index page * Log all failed authentication attempts --- config.default.ini.php | 19 +++++++- index.php | 96 ++++--------------------------------- lib/Authentication.php | 31 ++++++++++++ lib/Configuration.php | 105 +++++++++++++++++++++++++++++++++++++++++ lib/RssBridge.php | 2 + 5 files changed, 164 insertions(+), 89 deletions(-) create mode 100644 lib/Authentication.php create mode 100644 lib/Configuration.php diff --git a/config.default.ini.php b/config.default.ini.php index d27ead18..5909ad88 100644 --- a/config.default.ini.php +++ b/config.default.ini.php @@ -24,4 +24,21 @@ name = "Hidden proxy name" ; Allow users to disable proxy usage for specific requests. ; true = enabled ; false = disabled (default) -by_bridge = false \ No newline at end of file +by_bridge = false + +[authentication] + +; Enables authentication for all requests to this RSS-Bridge instance. +; +; Warning: You'll have to upgrade existing feeds after enabling this option! +; +; true = enabled +; false = disabled (default) +enable = false + +; The username for authentication. Insert this name when prompted for login. +username = "" + +; The password for authentication. Insert this password when prompted for login. +; Use a strong password to prevent others from guessing your login! +password = "" diff --git a/index.php b/index.php index bcf1dae2..8cb8908e 100644 --- a/index.php +++ b/index.php @@ -1,67 +1,21 @@ $section) { - foreach($section as $key => $value) { - // Skip unknown sections and keys - if(array_key_exists($header, $config) && array_key_exists($key, $config[$header])) { - $config[$header][$key] = $value; - } - } - } -} - -if(!is_string($config['proxy']['url'])) - die('Parameter [proxy] => "url" is not a valid string! Please check "config.ini.php"!'); - -if(!empty($config['proxy']['url'])) - define('PROXY_URL', $config['proxy']['url']); - -if(!is_bool($config['proxy']['by_bridge'])) - die('Parameter [proxy] => "by_bridge" is not a valid Boolean! Please check "config.ini.php"!'); - -define('PROXY_BYBRIDGE', $config['proxy']['by_bridge']); - -if(!is_string($config['proxy']['name'])) - die('Parameter [proxy] => "name" is not a valid string! Please check "config.ini.php"!'); - -define('PROXY_NAME', $config['proxy']['name']); - -if(!is_bool($config['cache']['custom_timeout'])) - die('Parameter [cache] => "custom_timeout" is not a valid Boolean! Please check "config.ini.php"!'); - -define('CUSTOM_CACHE_TIMEOUT', $config['cache']['custom_timeout']); - -// Defines the minimum required PHP version for RSS-Bridge define('PHP_VERSION_REQUIRED', '5.6.0'); -date_default_timezone_set('UTC'); -error_reporting(0); - // Specify directory for cached files (using FileCache) define('CACHE_DIR', __DIR__ . '/cache'); // Specify path for whitelist file define('WHITELIST_FILE', __DIR__ . '/whitelist.txt'); +Configuration::verifyInstallation(); +Configuration::loadConfiguration(); + +Authentication::showPromptIfNeeded(); + +date_default_timezone_set('UTC'); +error_reporting(0); /* Move the CLI arguments to the $_GET array, in order to be able to use @@ -91,40 +45,6 @@ if(file_exists('DEBUG')) { } } -require_once __DIR__ . '/lib/RssBridge.php'; - -// Check PHP version -if(version_compare(PHP_VERSION, PHP_VERSION_REQUIRED) === -1) - die('RSS-Bridge requires at least PHP version ' . PHP_VERSION_REQUIRED . '!'); - -// extensions check -if(!extension_loaded('openssl')) - die('"openssl" extension not loaded. Please check "php.ini"'); - -if(!extension_loaded('libxml')) - die('"libxml" extension not loaded. Please check "php.ini"'); - -if(!extension_loaded('mbstring')) - die('"mbstring" extension not loaded. Please check "php.ini"'); - -if(!extension_loaded('simplexml')) - die('"simplexml" extension not loaded. Please check "php.ini"'); - -if(!extension_loaded('curl')) - die('"curl" extension not loaded. Please check "php.ini"'); - -// configuration checks -if(ini_get('allow_url_fopen') !== "1") - die('"allow_url_fopen" is not set to "1". Please check "php.ini'); - -// Check cache folder permissions (write permissions required) -if(!is_writable(CACHE_DIR)) - die('RSS-Bridge does not have write permissions for ' . CACHE_DIR . '!'); - -// Check whitelist file permissions (only in DEBUG mode) -if(!file_exists(WHITELIST_FILE) && !is_writable(dirname(WHITELIST_FILE))) - die('RSS-Bridge does not have write permissions for ' . WHITELIST_FILE . '!'); - // FIXME : beta test UA spoofing, please report any blacklisting by PHP-fopen-unfriendly websites $userAgent = 'Mozilla/5.0(X11; Linux x86_64; rv:30.0)'; diff --git a/lib/Authentication.php b/lib/Authentication.php new file mode 100644 index 00000000..dc75d28e --- /dev/null +++ b/lib/Authentication.php @@ -0,0 +1,31 @@ + $section) { + foreach($section as $key => $value) { + // Skip unknown sections and keys + if(array_key_exists($header, Configuration::$config) && array_key_exists($key, Configuration::$config[$header])) { + Configuration::$config[$header][$key] = $value; + } + } + } + } + + if(!is_string(self::getConfig('proxy', 'url'))) + die('Parameter [proxy] => "url" is not a valid string! Please check "config.ini.php"!'); + + if(!empty(self::getConfig('proxy', 'url'))) + define('PROXY_URL', self::getConfig('proxy', 'url')); + + if(!is_bool(self::getConfig('proxy', 'by_bridge'))) + die('Parameter [proxy] => "by_bridge" is not a valid Boolean! Please check "config.ini.php"!'); + + define('PROXY_BYBRIDGE', self::getConfig('proxy', 'by_bridge')); + + if(!is_string(self::getConfig('proxy', 'name'))) + die('Parameter [proxy] => "name" is not a valid string! Please check "config.ini.php"!'); + + define('PROXY_NAME', self::getConfig('proxy', 'name')); + + if(!is_bool(self::getConfig('cache', 'custom_timeout'))) + die('Parameter [cache] => "custom_timeout" is not a valid Boolean! Please check "config.ini.php"!'); + + define('CUSTOM_CACHE_TIMEOUT', self::getConfig('cache', 'custom_timeout')); + + if(!is_bool(self::getConfig('authentication', 'enable'))) + die('Parameter [authentication] => "enable" is not a valid Boolean! Please check "config.ini.php"!'); + + if(!is_string(self::getConfig('authentication', 'username'))) + die('Parameter [authentication] => "username" is not a valid string! Please check "config.ini.php"!'); + + if(!is_string(self::getConfig('authentication', 'password'))) + die('Parameter [authentication] => "password" is not a valid string! Please check "config.ini.php"!'); + + } + + public static function getConfig($category, $key) { + + if(array_key_exists($category, self::$config) && array_key_exists($key, self::$config[$category])) { + return self::$config[$category][$key]; + } + + return null; + + } + +} diff --git a/lib/RssBridge.php b/lib/RssBridge.php index e2f9be3a..8d0ef902 100644 --- a/lib/RssBridge.php +++ b/lib/RssBridge.php @@ -14,6 +14,8 @@ require __DIR__ . '/Bridge.php'; require __DIR__ . '/BridgeAbstract.php'; require __DIR__ . '/FeedExpander.php'; require __DIR__ . '/Cache.php'; +require __DIR__ . '/Authentication.php'; +require __DIR__ . '/Configuration.php'; require __DIR__ . '/validation.php'; require __DIR__ . '/html.php'; From 5ea79ac1fc488ce0e57de9f9c44f9dbd5f9f1e26 Mon Sep 17 00:00:00 2001 From: Nemo Date: Fri, 29 Jun 2018 00:24:42 +0530 Subject: [PATCH 012/146] Add markdown support to Container Linux Feed (#730) --- bridges/ContainerLinuxReleasesBridge.php | 31 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/bridges/ContainerLinuxReleasesBridge.php b/bridges/ContainerLinuxReleasesBridge.php index c5f64a15..bcb421d2 100644 --- a/bridges/ContainerLinuxReleasesBridge.php +++ b/bridges/ContainerLinuxReleasesBridge.php @@ -40,18 +40,35 @@ class ContainerLinuxReleasesBridge extends BridgeAbstract { $item['uri'] = "https://coreos.com/releases/#$releaseVersion"; $item['title'] = $releaseVersion; - $item['content'] = nl2br($release['release_notes']); - $item['content'] .= << + $content = $release['release_notes']; + $content .= << -- Kernel: {$release['major_software']['kernel'][0]}
-- Docker: {$release['major_software']['docker'][0]}
-- etcd: {$release['major_software']['etcd'][0]}
+* Kernel: {$release['major_software']['kernel'][0]} +* Docker: {$release['major_software']['docker'][0]} +* etcd: {$release['major_software']['etcd'][0]} EOT; $item['timestamp'] = strtotime($release['release_date']); + // Based on https://gist.github.com/jbroadway/2836900 + // Links + $regex = '/\[([^\[]+)\]\(([^\)]+)\)/'; + $replacement = '\1'; + $item['content'] = preg_replace($regex, $replacement, $content); + + // Headings + $regex = '/^(.*)\:\s?$/m'; + $replacement = '

\1

'; + $item['content'] = preg_replace($regex, $replacement, $item['content']); + + // Lists + $regex = '/\n\s*[\*|\-](.*)/'; + $item['content'] = preg_replace_callback ($regex, function($regs) { + $item = $regs[1]; + return sprintf ("
  • %s
", trim ($item)); + }, $item['content']); + $this->items[] = $item; } } From 193ca87afae84bf50730ae8d006949efe5c251ea Mon Sep 17 00:00:00 2001 From: LogMANOriginal Date: Fri, 29 Jun 2018 23:55:33 +0200 Subject: [PATCH 013/146] [phpcs] enforce single quotes (#732) * [phpcs] Add rule to enforce single quoted strings --- bridges/BlaguesDeMerdeBridge.php | 2 +- bridges/CADBridge.php | 6 +- bridges/CopieDoubleBridge.php | 2 +- bridges/CourrierInternationalBridge.php | 2 +- bridges/CpasbienBridge.php | 2 +- bridges/DanbooruBridge.php | 2 +- bridges/DemoBridge.php | 10 +- bridges/DiscogsBridge.php | 68 ++++----- bridges/ETTVBridge.php | 4 +- bridges/EZTVBridge.php | 10 +- bridges/FB2Bridge.php | 52 +++---- bridges/FacebookBridge.php | 8 +- bridges/FootitoBridge.php | 18 +-- bridges/FourchanBridge.php | 2 +- bridges/GithubIssueBridge.php | 2 +- bridges/GoComicsBridge.php | 12 +- bridges/GoogleSearchBridge.php | 2 +- bridges/InstagramBridge.php | 2 +- bridges/KununuBridge.php | 4 +- bridges/LeBonCoinBridge.php | 2 +- bridges/LesJoiesDuCodeBridge.php | 6 +- bridges/MangareaderBridge.php | 26 ++-- bridges/NasaApodBridge.php | 4 +- bridges/NotAlwaysBridge.php | 2 +- bridges/PinterestBridge.php | 6 +- bridges/PixivBridge.php | 28 ++-- bridges/RainbowSixSiegeBridge.php | 6 +- bridges/ReadComicsBridge.php | 2 +- bridges/ReporterreBridge.php | 2 +- bridges/Rue89Bridge.php | 6 +- bridges/SexactuBridge.php | 2 +- bridges/ShanaprojectBridge.php | 2 +- bridges/Shimmie2Bridge.php | 2 +- bridges/SuperSmashBlogBridge.php | 2 +- bridges/VkBridge.php | 48 +++---- bridges/WhydBridge.php | 4 +- bridges/YGGTorrentBridge.php | 180 ++++++++++++------------ bridges/YoutubeBridge.php | 6 +- caches/FileCache.php | 2 +- lib/Configuration.php | 2 +- lib/FeedExpander.php | 6 +- lib/html.php | 2 +- phpcs.xml | 4 + 43 files changed, 283 insertions(+), 279 deletions(-) diff --git a/bridges/BlaguesDeMerdeBridge.php b/bridges/BlaguesDeMerdeBridge.php index 25c018a8..3ae59a10 100644 --- a/bridges/BlaguesDeMerdeBridge.php +++ b/bridges/BlaguesDeMerdeBridge.php @@ -19,7 +19,7 @@ class BlaguesDeMerdeBridge extends BridgeAbstract { $item['content'] = trim($element->find('div.joke_text_contener', 0)->innertext); $uri = $temp[2]->href; $item['uri'] = $uri; - $item['title'] = substr($uri, (strrpos($uri, "/") + 1)); + $item['title'] = substr($uri, (strrpos($uri, '/') + 1)); $date = $element->find('li.bdm_date', 0)->innertext; $time = mktime(0, 0, 0, substr($date, 3, 2), substr($date, 0, 2), substr($date, 6, 4)); $item['timestamp'] = $time; diff --git a/bridges/CADBridge.php b/bridges/CADBridge.php index 09e3e65a..e88cbbb2 100644 --- a/bridges/CADBridge.php +++ b/bridges/CADBridge.php @@ -23,14 +23,14 @@ class CADBridge extends FeedExpander { if($html3 == false) return 'Daily comic not released yet'; - $htmlpart = explode("/", $url); + $htmlpart = explode('/', $url); switch ($htmlpart[3]) { case 'cad': - preg_match_all("/http:\/\/cdn2\.cad-comic\.com\/comics\/cad-\S*png/", $html3, $url2); + preg_match_all('/http:\/\/cdn2\.cad-comic\.com\/comics\/cad-\S*png/', $html3, $url2); break; case 'sillies': - preg_match_all("/http:\/\/cdn2\.cad-comic\.com\/comics\/sillies-\S*gif/", $html3, $url2); + preg_match_all('/http:\/\/cdn2\.cad-comic\.com\/comics\/sillies-\S*gif/', $html3, $url2); break; default: return 'Daily comic not released yet'; diff --git a/bridges/CopieDoubleBridge.php b/bridges/CopieDoubleBridge.php index 767cdce3..3545c6fc 100644 --- a/bridges/CopieDoubleBridge.php +++ b/bridges/CopieDoubleBridge.php @@ -25,7 +25,7 @@ class CopieDoubleBridge extends BridgeAbstract { } elseif(strpos($element->innertext, '/images/suivant.gif') === false) { $a = $element->find('a', 0); $item['uri'] = self::URI . $a->href; - $content = str_replace('src="/', 'src="/' . self::URI, $element->find("td", 0)->innertext); + $content = str_replace('src="/', 'src="/' . self::URI, $element->find('td', 0)->innertext); $content = str_replace('href="/', 'href="' . self::URI, $content); $item['content'] = $content; $this->items[] = $item; diff --git a/bridges/CourrierInternationalBridge.php b/bridges/CourrierInternationalBridge.php index 15738633..1e7c93e8 100644 --- a/bridges/CourrierInternationalBridge.php +++ b/bridges/CourrierInternationalBridge.php @@ -11,7 +11,7 @@ class CourrierInternationalBridge extends BridgeAbstract { $html = getSimpleHTMLDOM(self::URI) or returnServerError('Error.'); - $element = $html->find("article"); + $element = $html->find('article'); $article_count = 1; foreach($element as $article) { diff --git a/bridges/CpasbienBridge.php b/bridges/CpasbienBridge.php index 19efd84a..f9b4b502 100644 --- a/bridges/CpasbienBridge.php +++ b/bridges/CpasbienBridge.php @@ -16,7 +16,7 @@ class CpasbienBridge extends BridgeAbstract { )); public function collectData(){ - $request = str_replace(" ", "-", trim($this->getInput('q'))); + $request = str_replace(' ', '-', trim($this->getInput('q'))); $html = getSimpleHTMLDOM(self::URI . '/recherche/' . urlencode($request) . '.html') or returnServerError('No results for this query.'); diff --git a/bridges/DanbooruBridge.php b/bridges/DanbooruBridge.php index 36b8c08a..82f21674 100644 --- a/bridges/DanbooruBridge.php +++ b/bridges/DanbooruBridge.php @@ -41,7 +41,7 @@ class DanbooruBridge extends BridgeAbstract { $item = array(); $item['uri'] = $element->find('a', 0)->href; - $item['postid'] = (int)preg_replace("/[^0-9]/", '', $element->getAttribute(static::IDATTRIBUTE)); + $item['postid'] = (int)preg_replace('/[^0-9]/', '', $element->getAttribute(static::IDATTRIBUTE)); $item['timestamp'] = time(); $thumbnailUri = $element->find('img', 0)->src; $item['tags'] = $this->getTags($element); diff --git a/bridges/DemoBridge.php b/bridges/DemoBridge.php index ea2088eb..f48b4510 100644 --- a/bridges/DemoBridge.php +++ b/bridges/DemoBridge.php @@ -35,11 +35,11 @@ class DemoBridge extends BridgeAbstract { public function collectData(){ $item = array(); - $item['author'] = "Me!"; - $item['title'] = "Test"; - $item['content'] = "Awesome content !"; - $item['id'] = "Lalala"; - $item['uri'] = "http://example.com/test"; + $item['author'] = 'Me!'; + $item['title'] = 'Test'; + $item['content'] = 'Awesome content !'; + $item['id'] = 'Lalala'; + $item['uri'] = 'http://example.com/test'; $this->items[] = $item; } diff --git a/bridges/DiscogsBridge.php b/bridges/DiscogsBridge.php index 1fa58405..9fe4f51f 100644 --- a/bridges/DiscogsBridge.php +++ b/bridges/DiscogsBridge.php @@ -42,59 +42,59 @@ class DiscogsBridge extends BridgeAbstract { if(!empty($this->getInput('artistid')) || !empty($this->getInput('labelid'))) { if(!empty($this->getInput('artistid'))) { - $data = getContents("https://api.discogs.com/artists/" + $data = getContents('https://api.discogs.com/artists/' . $this->getInput('artistid') - . "/releases?sort=year&sort_order=desc") - or returnServerError("Unable to query discogs !"); + . '/releases?sort=year&sort_order=desc') + or returnServerError('Unable to query discogs !'); } elseif(!empty($this->getInput('labelid'))) { - $data = getContents("https://api.discogs.com/labels/" + $data = getContents('https://api.discogs.com/labels/' . $this->getInput('labelid') - . "/releases?sort=year&sort_order=desc") - or returnServerError("Unable to query discogs !"); + . '/releases?sort=year&sort_order=desc') + or returnServerError('Unable to query discogs !'); } $jsonData = json_decode($data, true); - foreach($jsonData["releases"] as $release) { + foreach($jsonData['releases'] as $release) { $item = array(); - $item["author"] = $release["artist"]; - $item["title"] = $release["title"]; - $item["id"] = $release["id"]; - $resId = array_key_exists("main_release", $release) ? $release["main_release"] : $release["id"]; - $item["uri"] = self::URI . $this->getInput('artistid') . "/release/" . $resId; - $item["timestamp"] = DateTime::createFromFormat("Y", $release["year"])->getTimestamp(); - $item["content"] = $item["author"] . " - " . $item["title"]; + $item['author'] = $release['artist']; + $item['title'] = $release['title']; + $item['id'] = $release['id']; + $resId = array_key_exists('main_release', $release) ? $release['main_release'] : $release['id']; + $item['uri'] = self::URI . $this->getInput('artistid') . '/release/' . $resId; + $item['timestamp'] = DateTime::createFromFormat('Y', $release['year'])->getTimestamp(); + $item['content'] = $item['author'] . ' - ' . $item['title']; $this->items[] = $item; } - } elseif(!empty($this->getInput("username_wantlist")) || !empty($this->getInput("username_folder"))) { + } elseif(!empty($this->getInput('username_wantlist')) || !empty($this->getInput('username_folder'))) { - if(!empty($this->getInput("username_wantlist"))) { - $data = getContents("https://api.discogs.com/users/" + if(!empty($this->getInput('username_wantlist'))) { + $data = getContents('https://api.discogs.com/users/' . $this->getInput('username_wantlist') - . "/wants?sort=added&sort_order=desc") - or returnServerError("Unable to query discogs !"); - $jsonData = json_decode($data, true)["wants"]; + . '/wants?sort=added&sort_order=desc') + or returnServerError('Unable to query discogs !'); + $jsonData = json_decode($data, true)['wants']; - } elseif(!empty($this->getInput("username_folder"))) { - $data = getContents("https://api.discogs.com/users/" + } elseif(!empty($this->getInput('username_folder'))) { + $data = getContents('https://api.discogs.com/users/' . $this->getInput('username_folder') - . "/collection/folders/" - . $this->getInput("folderid") - ."/releases?sort=added&sort_order=desc") - or returnServerError("Unable to query discogs !"); - $jsonData = json_decode($data, true)["releases"]; + . '/collection/folders/' + . $this->getInput('folderid') + .'/releases?sort=added&sort_order=desc') + or returnServerError('Unable to query discogs !'); + $jsonData = json_decode($data, true)['releases']; } foreach($jsonData as $element) { - $infos = $element["basic_information"]; + $infos = $element['basic_information']; $item = array(); - $item["title"] = $infos["title"]; - $item["author"] = $infos["artists"][0]["name"]; - $item["id"] = $infos["artists"][0]["id"]; - $item["uri"] = self::URI . $infos["artists"][0]["id"] . "/release/" . $infos["id"]; - $item["timestamp"] = strtotime($element["date_added"]); - $item["content"] = $item["author"] . " - " . $item["title"]; + $item['title'] = $infos['title']; + $item['author'] = $infos['artists'][0]['name']; + $item['id'] = $infos['artists'][0]['id']; + $item['uri'] = self::URI . $infos['artists'][0]['id'] . '/release/' . $infos['id']; + $item['timestamp'] = strtotime($element['date_added']); + $item['content'] = $item['author'] . ' - ' . $item['title']; $this->items[] = $item; } diff --git a/bridges/ETTVBridge.php b/bridges/ETTVBridge.php index 6da6d5e8..ab90bf7f 100644 --- a/bridges/ETTVBridge.php +++ b/bridges/ETTVBridge.php @@ -1,7 +1,7 @@ find('td', 1)->find('a', 0); // retrieve result page to get more details - $link = rtrim(self::URI, "/") . $entry->href; + $link = rtrim(self::URI, '/') . $entry->href; $page = getSimpleHTMLDOM($link) or returnServerError('Could not request page ' . $link); diff --git a/bridges/EZTVBridge.php b/bridges/EZTVBridge.php index 4fb9e578..c016ff33 100644 --- a/bridges/EZTVBridge.php +++ b/bridges/EZTVBridge.php @@ -1,7 +1,7 @@ getInput('i')); + $showList = explode(',', $this->getInput('i')); foreach($showList as $showID) { // Get show page diff --git a/bridges/FB2Bridge.php b/bridges/FB2Bridge.php index 7d78b87f..d8fb6b41 100644 --- a/bridges/FB2Bridge.php +++ b/bridges/FB2Bridge.php @@ -103,19 +103,19 @@ EOD; $html = $this->buildContent($fileContent); $author = $this->getInput('u'); - foreach($html->find("article") as $content) { + foreach($html->find('article') as $content) { $item = array(); - $item['uri'] = "http://touch.facebook.com" - . $content->find("div[class='_52jc _5qc4 _24u0 _36xo']", 0)->find("a", 0)->getAttribute("href"); + $item['uri'] = 'http://touch.facebook.com' + . $content->find("div[class='_52jc _5qc4 _24u0 _36xo']", 0)->find('a', 0)->getAttribute('href'); - if($content->find("header", 0) !== null) { - $content->find("header", 0)->innertext = ""; + if($content->find('header', 0) !== null) { + $content->find('header', 0)->innertext = ''; } - if($content->find("footer", 0) !== null) { - $content->find("footer", 0)->innertext = ""; + if($content->find('footer', 0) !== null) { + $content->find('footer', 0)->innertext = ''; } //Remove html nodes, keep only img, links, basic formatting @@ -168,7 +168,7 @@ EOD; $regex = implode( '', array( - "/timeline_unit", + '/timeline_unit', "\\\\\\\\u00253A1", "\\\\\\\\u00253A([0-9]*)", "\\\\\\\\u00253A([0-9]*)", @@ -182,18 +182,18 @@ EOD; return implode( '', array( - "https://touch.facebook.com/pages_reaction_units/more/?page_id=", + 'https://touch.facebook.com/pages_reaction_units/more/?page_id=', $pageID, - "&cursor=%7B%22timeline_cursor%22%3A%22timeline_unit%3A1%3A", + '&cursor=%7B%22timeline_cursor%22%3A%22timeline_unit%3A1%3A', $result[1], - "%3A", + '%3A', $result[2], - "%3A", + '%3A', $result[3], - "%3A", + '%3A', $result[4], - "%22%2C%22timeline_section_cursor%22%3A%7B%7D%2C%22", - "has_next_page%22%3Atrue%7D&surface=mobile_page_home&unit_count=3" + '%22%2C%22timeline_section_cursor%22%3A%7B%7D%2C%22', + 'has_next_page%22%3Atrue%7D&surface=mobile_page_home&unit_count=3' ) ); } @@ -201,7 +201,7 @@ EOD; //Builds the HTML from the encoded JS that Facebook provides. private function buildContent($pageContent){ - $regex = "/\\\"html\\\":\\\"(.*?)\\\",\\\"replace/"; + $regex = '/\\"html\\":\\"(.*?)\\",\\"replace/'; preg_match($regex, $pageContent, $result); return str_get_html(html_entity_decode(json_decode('"' . $result[1] . '"'))); @@ -214,7 +214,7 @@ EOD; $ctx = stream_context_create(array( 'http' => array( - 'user_agent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0", + 'user_agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0', 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' ) ) @@ -222,12 +222,12 @@ EOD; $a = file_get_contents($pageURL, 0, $ctx); //First request to get the cookie - $cookies = ""; + $cookies = ''; foreach($http_response_header as $hdr) { - if(strpos($hdr, "Set-Cookie") !== false) { - $cLine = explode(":", $hdr)[1]; - $cLine = explode(";", $cLine)[0]; - $cookies .= ";" . $cLine; + if(strpos($hdr, 'Set-Cookie') !== false) { + $cLine = explode(':', $hdr)[1]; + $cLine = explode(';', $cLine)[0]; + $cookies .= ';' . $cLine; } } @@ -239,7 +239,7 @@ EOD; $context = stream_context_create(array( 'http' => array( - 'user_agent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0", + 'user_agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0', 'header' => 'Cookie: ' . $cookies ) ) @@ -247,12 +247,12 @@ EOD; $pageContent = file_get_contents($page, 0, $context); - if(strpos($pageContent, "signup-button") != false) { + if(strpos($pageContent, 'signup-button') != false) { return -1; } //Get the page ID if we don't have a captcha - $regex = "/page_id=([0-9]*)&/"; + $regex = '/page_id=([0-9]*)&/'; preg_match($regex, $pageContent, $matches); if(count($matches) > 0) { @@ -260,7 +260,7 @@ EOD; } //Get the page ID if we do have a captcha - $regex = "/\"pageID\":\"([0-9]*)\"/"; + $regex = '/"pageID":"([0-9]*)"/'; preg_match($regex, $pageContent, $matches); return $matches[1]; diff --git a/bridges/FacebookBridge.php b/bridges/FacebookBridge.php index ce3275ea..4771225a 100644 --- a/bridges/FacebookBridge.php +++ b/bridges/FacebookBridge.php @@ -102,7 +102,7 @@ class FacebookBridge extends BridgeAbstract { if (isset($_SESSION['captcha_fields'], $_SESSION['captcha_action'])) { $captcha_action = $_SESSION['captcha_action']; $captcha_fields = $_SESSION['captcha_fields']; - $captcha_fields['captcha_response'] = preg_replace("/[^a-zA-Z0-9]+/", "", $_POST['captcha_response']); + $captcha_fields['captcha_response'] = preg_replace('/[^a-zA-Z0-9]+/', '', $_POST['captcha_response']); $header = array("Content-type: application/x-www-form-urlencoded\r\nReferer: $captcha_action\r\nCookie: noscript=1\r\n"); @@ -153,11 +153,11 @@ application/x-www-form-urlencoded\r\nReferer: $captcha_action\r\nCookie: noscrip } else { // First character cannot be a forward slash - if(strpos($this->getInput('u'), "/") === 0) { + if(strpos($this->getInput('u'), '/') === 0) { returnClientError('Remove leading slash "/" from the username!'); } - if(!strpos($this->getInput('u'), "/")) { + if(!strpos($this->getInput('u'), '/')) { $html = getSimpleHTMLDOM(self::URI . urlencode($this->getInput('u')) . '?_fb_noscript=1', $header) or returnServerError('No results for this query.'); } else { @@ -305,7 +305,7 @@ EOD; ); //Retrieve date of the post - $date = $post->find("abbr")[0]; + $date = $post->find('abbr')[0]; if(isset($date) && $date->hasAttribute('data-utime')) { $date = $date->getAttribute('data-utime'); } else { diff --git a/bridges/FootitoBridge.php b/bridges/FootitoBridge.php index ac06cd53..22aead4a 100644 --- a/bridges/FootitoBridge.php +++ b/bridges/FootitoBridge.php @@ -15,47 +15,47 @@ class FootitoBridge extends BridgeAbstract { $content = trim($element->innertext); $content = str_replace( - "getURI()) - or returnServerError("Could not request 4chan, thread not found"); + or returnServerError('Could not request 4chan, thread not found'); foreach($html->find('div.postContainer') as $element) { $item = array(); diff --git a/bridges/GithubIssueBridge.php b/bridges/GithubIssueBridge.php index 4f121d8a..0ed775de 100644 --- a/bridges/GithubIssueBridge.php +++ b/bridges/GithubIssueBridge.php @@ -106,7 +106,7 @@ class GithubIssueBridge extends BridgeAbstract { $content = $comment->parent()->innertext; } else { $title .= ' / ' . trim($comment->firstChild()->plaintext); - $content = "
" . $comment->find('.comment-body', 0)->innertext . "
"; + $content = '
' . $comment->find('.comment-body', 0)->innertext . '
'; } $item = array(); diff --git a/bridges/GoComicsBridge.php b/bridges/GoComicsBridge.php index 7a103f4b..3223d19a 100644 --- a/bridges/GoComicsBridge.php +++ b/bridges/GoComicsBridge.php @@ -19,26 +19,26 @@ class GoComicsBridge extends BridgeAbstract { or returnServerError('Could not request GoComics: ' . $this->getURI()); //Get info from first page - $author = preg_replace('/By /', '', $html->find(".media-subheading", 0)->plaintext); + $author = preg_replace('/By /', '', $html->find('.media-subheading', 0)->plaintext); - $link = self::URI . $html->find(".gc-deck--cta-0", 0)->find('a', 0)->href; + $link = self::URI . $html->find('.gc-deck--cta-0', 0)->find('a', 0)->href; for($i = 0; $i < 5; $i++) { $item = array(); $page = getSimpleHTMLDOM($link) or returnServerError('Could not request GoComics: ' . $link); - $imagelink = $page->find(".img-fluid", 1)->src; - $date = explode("/", $link); + $imagelink = $page->find('.img-fluid', 1)->src; + $date = explode('/', $link); $item['id'] = $imagelink; $item['uri'] = $link; $item['author'] = $author; $item['title'] = 'GoComics ' . $this->getInput('comicname'); - $item['timestamp'] = DateTime::createFromFormat("Ymd", $date[5] . $date[6] . $date[7])->getTimestamp(); + $item['timestamp'] = DateTime::createFromFormat('Ymd', $date[5] . $date[6] . $date[7])->getTimestamp(); $item['content'] = ''; - $link = self::URI . $page->find(".js-previous-comic", 0)->href; + $link = self::URI . $page->find('.js-previous-comic', 0)->href; $this->items[] = $item; } } diff --git a/bridges/GoogleSearchBridge.php b/bridges/GoogleSearchBridge.php index 2c4a5f1b..2eb58411 100644 --- a/bridges/GoogleSearchBridge.php +++ b/bridges/GoogleSearchBridge.php @@ -17,7 +17,7 @@ class GoogleSearchBridge extends BridgeAbstract { const PARAMETERS = array(array( 'q' => array( - 'name' => "keyword", + 'name' => 'keyword', 'required' => true ) )); diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php index c763128f..2539da25 100644 --- a/bridges/InstagramBridge.php +++ b/bridges/InstagramBridge.php @@ -85,7 +85,7 @@ class InstagramBridge extends BridgeAbstract { $item['content'] = $data[0]; $item['enclosures'] = $data[1]; } else { - $item['content'] = ''. $item['; + $item['content'] = ''. $item['title'] . ''; $item['enclosures'] = array($media->display_url); } diff --git a/bridges/KununuBridge.php b/bridges/KununuBridge.php index e99e1350..c0cf68a8 100644 --- a/bridges/KununuBridge.php +++ b/bridges/KununuBridge.php @@ -135,8 +135,8 @@ class KununuBridge extends BridgeAbstract { * Encodes unmlauts in the given text */ private function encodeUmlauts($text){ - $umlauts = Array("/ä/","/ö/","/ü/","/Ä/","/Ö/","/Ü/","/ß/"); - $replace = Array("ae","oe","ue","Ae","Oe","Ue","ss"); + $umlauts = Array('/ä/','/ö/','/ü/','/Ä/','/Ö/','/Ü/','/ß/'); + $replace = Array('ae','oe','ue','Ae','Oe','Ue','ss'); return preg_replace($umlauts, $replace, $text); } diff --git a/bridges/LeBonCoinBridge.php b/bridges/LeBonCoinBridge.php index d4da546e..bb89d612 100644 --- a/bridges/LeBonCoinBridge.php +++ b/bridges/LeBonCoinBridge.php @@ -172,7 +172,7 @@ region, and optionally a category and a keyword .'; if($content_image !== null) { $content = 'thumbnail'; } else { - $content = ""; + $content = ''; } $date = $element->find('aside.item_absolute', 0)->find('p.item_sup', 0); diff --git a/bridges/LesJoiesDuCodeBridge.php b/bridges/LesJoiesDuCodeBridge.php index 34145a1d..5f61f955 100644 --- a/bridges/LesJoiesDuCodeBridge.php +++ b/bridges/LesJoiesDuCodeBridge.php @@ -22,16 +22,16 @@ class LesJoiesDuCodeBridge extends BridgeAbstract { // retrieve .gif instead of static .jpg $images = $temp->find('p img'); foreach($images as $image) { - $img_src = str_replace(".jpg", ".gif", $image->src); + $img_src = str_replace('.jpg', '.gif', $image->src); $image->src = $img_src; } $content = $temp->innertext; $auteur = $temp->find('i', 0); - $pos = strpos($auteur->innertext, "by"); + $pos = strpos($auteur->innertext, 'by'); if($pos > 0) { - $auteur = trim(str_replace("*/", "", substr($auteur->innertext, ($pos + 2)))); + $auteur = trim(str_replace('*/', '', substr($auteur->innertext, ($pos + 2)))); $item['author'] = $auteur; } diff --git a/bridges/MangareaderBridge.php b/bridges/MangareaderBridge.php index cd7dddc1..91537069 100644 --- a/bridges/MangareaderBridge.php +++ b/bridges/MangareaderBridge.php @@ -100,7 +100,7 @@ class MangareaderBridge extends BridgeAbstract { case 'Get popular mangas': // Find manga name within "Popular mangas for ..." $pagetitle = $xpath->query(".//*[@id='bodyalt']/h1")->item(0)->nodeValue; - $this->request = substr($pagetitle, 0, strrpos($pagetitle, " -")); + $this->request = substr($pagetitle, 0, strrpos($pagetitle, ' -')); $this->getPopularMangas($xpath); break; case 'Get manga updates': @@ -120,7 +120,7 @@ class MangareaderBridge extends BridgeAbstract { // Return some dummy-data if no content available if(empty($this->items)) { $item = array(); - $item['content'] = "

No updates available

"; + $item['content'] = '

No updates available

'; $this->items[] = $item; } @@ -143,18 +143,18 @@ class MangareaderBridge extends BridgeAbstract { $item['title'] = htmlspecialchars($manga->nodeValue); // Add each chapter to the feed - $item['content'] = ""; + $item['content'] = ''; foreach ($chapters as $chapter) { - if($item['content'] <> "") { - $item['content'] .= "
"; + if($item['content'] <> '') { + $item['content'] .= '
'; } $item['content'] .= "" . htmlspecialchars($chapter->nodeValue) - . ""; + . ''; } $this->items[] = $item; @@ -211,13 +211,13 @@ EOD; foreach ($chapters as $chapter) { $item = array(); - $item['title'] = htmlspecialchars($xpath->query("td[1]", $chapter) + $item['title'] = htmlspecialchars($xpath->query('td[1]', $chapter) ->item(0) ->nodeValue); - $item['uri'] = self::URI . $xpath->query("td[1]/a", $chapter) + $item['uri'] = self::URI . $xpath->query('td[1]/a', $chapter) ->item(0) ->getAttribute('href'); - $item['timestamp'] = strtotime($xpath->query("td[2]", $chapter) + $item['timestamp'] = strtotime($xpath->query('td[2]', $chapter) ->item(0) ->nodeValue); array_unshift($this->items, $item); @@ -227,12 +227,12 @@ EOD; public function getURI(){ switch($this->queriedContext) { case 'Get latest updates': - $path = "latest"; + $path = 'latest'; break; case 'Get popular mangas': - $path = "popular"; - if($this->getInput('category') !== "all") { - $path .= "/" . $this->getInput('category'); + $path = 'popular'; + if($this->getInput('category') !== 'all') { + $path .= '/' . $this->getInput('category'); } break; case 'Get manga updates': diff --git a/bridges/NasaApodBridge.php b/bridges/NasaApodBridge.php index 74fd219b..8e293e0f 100644 --- a/bridges/NasaApodBridge.php +++ b/bridges/NasaApodBridge.php @@ -12,7 +12,7 @@ class NasaApodBridge extends BridgeAbstract { $html = getSimpleHTMLDOM(self::URI . 'archivepix.html') or returnServerError('Error while downloading the website content'); - $list = explode("
", $html->find('b', 0)->innertext); + $list = explode('
', $html->find('b', 0)->innertext); for($i = 0; $i < 3; $i++) { $line = $list[$i]; @@ -32,7 +32,7 @@ class NasaApodBridge extends BridgeAbstract { $explanation = $picture_html->find('p', 2)->innertext; //Extract date from the picture page - $date = explode(" ", $picture_html->find('p', 1)->innertext); + $date = explode(' ', $picture_html->find('p', 1)->innertext); $item['timestamp'] = strtotime($date[4] . $date[3] . $date[2]); //Other informations diff --git a/bridges/NotAlwaysBridge.php b/bridges/NotAlwaysBridge.php index 45727a70..f5efff4c 100644 --- a/bridges/NotAlwaysBridge.php +++ b/bridges/NotAlwaysBridge.php @@ -49,7 +49,7 @@ class NotAlwaysBridge extends BridgeAbstract { public function getURI(){ if(!is_null($this->getInput('filter'))) { - return self::URI . $this->getInput('filter') . "/"; + return self::URI . $this->getInput('filter') . '/'; } return parent::getURI(); diff --git a/bridges/PinterestBridge.php b/bridges/PinterestBridge.php index 7eeafc1a..d2dd8907 100644 --- a/bridges/PinterestBridge.php +++ b/bridges/PinterestBridge.php @@ -44,7 +44,7 @@ class PinterestBridge extends FeedExpander { $pattern = '/https\:\/\/i\.pinimg\.com\/[a-zA-Z0-9]*x\//'; foreach($this->items as $item) { - $item["content"] = preg_replace($pattern, 'https://i.pinimg.com/originals/', $item["content"]); + $item['content'] = preg_replace($pattern, 'https://i.pinimg.com/originals/', $item['content']); $newitems[] = $item; } $this->items = $newitems; @@ -64,10 +64,10 @@ class PinterestBridge extends FeedExpander { // provide even less info. Thus we attempt multiple options. $item['title'] = trim($result['title']); - if($item['title'] === "") + if($item['title'] === '') $item['title'] = trim($result['rich_summary']['display_name']); - if($item['title'] === "") + if($item['title'] === '') $item['title'] = trim($result['grid_description']); $item['timestamp'] = strtotime($result['created_at']); diff --git a/bridges/PixivBridge.php b/bridges/PixivBridge.php index 2f15b4b4..3a4cc930 100644 --- a/bridges/PixivBridge.php +++ b/bridges/PixivBridge.php @@ -33,40 +33,40 @@ class PixivBridge extends BridgeAbstract { $count++; $item = array(); - $item["id"] = $result["illustId"]; - $item["uri"] = "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=" . $result["illustId"]; - $item["title"] = $result["illustTitle"]; - $item["author"] = $result["userName"]; + $item['id'] = $result['illustId']; + $item['uri'] = 'https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' . $result['illustId']; + $item['title'] = $result['illustTitle']; + $item['author'] = $result['userName']; - preg_match_all($timeRegex, $result["url"], $dt, PREG_SET_ORDER, 0); - $elementDate = DateTime::createFromFormat("YmdHis", + preg_match_all($timeRegex, $result['url'], $dt, PREG_SET_ORDER, 0); + $elementDate = DateTime::createFromFormat('YmdHis', $dt[0][1] . $dt[0][2] . $dt[0][3] . $dt[0][4] . $dt[0][5] . $dt[0][6]); - $item["timestamp"] = $elementDate->getTimestamp(); + $item['timestamp'] = $elementDate->getTimestamp(); - $item["content"] = ""; + $item['content'] = ""; $this->items[] = $item; } } public function cacheImage($url, $illustId) { - $url = str_replace("_master1200", "", $url); - $url = str_replace("c/240x240/img-master/", "img-original/", $url); + $url = str_replace('_master1200', '', $url); + $url = str_replace('c/240x240/img-master/', 'img-original/', $url); $path = CACHE_DIR . '/pixiv_img'; if(!is_dir($path)) mkdir($path, 0755, true); if(!is_file($path . '/' . $illustId . '.jpeg')) { - $headers = array("Referer: https://www.pixiv.net/member_illust.php?mode=medium&illust_id=" . $illustId); + $headers = array('Referer: https://www.pixiv.net/member_illust.php?mode=medium&illust_id=' . $illustId); $illust = getContents($url, $headers); - if(strpos($illust, "404 Not Found") !== false) { - $illust = getContents(str_replace("jpg", "png", $url), $headers); + if(strpos($illust, '404 Not Found') !== false) { + $illust = getContents(str_replace('jpg', 'png', $url), $headers); } file_put_contents($path . '/' . $illustId . '.jpeg', $illust); } - return 'cache/pixiv_img/' . $illustId . ".jpeg"; + return 'cache/pixiv_img/' . $illustId . '.jpeg'; } diff --git a/bridges/RainbowSixSiegeBridge.php b/bridges/RainbowSixSiegeBridge.php index 302bb896..d362bbda 100644 --- a/bridges/RainbowSixSiegeBridge.php +++ b/bridges/RainbowSixSiegeBridge.php @@ -8,9 +8,9 @@ class RainbowSixSiegeBridge extends BridgeAbstract { const DESCRIPTION = 'Latest articles from the Rainbow Six Siege blog'; public function collectData(){ - $dlUrl = "https://prod-tridionservice.ubisoft.com/live/v1/News/Latest?templateId=tcm%3A152-7677"; - $dlUrl .= "8-32&pageIndex=0&pageSize=10&language=en-US&detailPageId=tcm%3A152-194572-64"; - $dlUrl .= "&keywordList=175426&siteId=undefined&useSeoFriendlyUrl=true"; + $dlUrl = 'https://prod-tridionservice.ubisoft.com/live/v1/News/Latest?templateId=tcm%3A152-7677'; + $dlUrl .= '8-32&pageIndex=0&pageSize=10&language=en-US&detailPageId=tcm%3A152-194572-64'; + $dlUrl .= '&keywordList=175426&siteId=undefined&useSeoFriendlyUrl=true'; $jsonString = getContents($dlUrl) or returnServerError('Error while downloading the website content'); $json = json_decode($jsonString, true); diff --git a/bridges/ReadComicsBridge.php b/bridges/ReadComicsBridge.php index 33c8ed9e..739e6ccb 100644 --- a/bridges/ReadComicsBridge.php +++ b/bridges/ReadComicsBridge.php @@ -25,7 +25,7 @@ class ReadComicsBridge extends BridgeAbstract { return $timestamp; } - $keywordsList = explode(";", $this->getInput('q')); + $keywordsList = explode(';', $this->getInput('q')); foreach($keywordsList as $keywords) { $html = $this->getSimpleHTMLDOM(self::URI . 'comic/' . rawurlencode($keywords)) or $this->returnServerError('Could not request readcomics.tv.'); diff --git a/bridges/ReporterreBridge.php b/bridges/ReporterreBridge.php index db1104c1..438c55be 100644 --- a/bridges/ReporterreBridge.php +++ b/bridges/ReporterreBridge.php @@ -19,7 +19,7 @@ class ReporterreBridge extends BridgeAbstract { // Replace all relative urls with absolute ones $text = preg_replace( '/(href|src)(\=[\"\'])(?!http)([^"\']+)/ims', - "$1$2" . self::URI . "$3", + '$1$2' . self::URI . '$3', $text ); diff --git a/bridges/Rue89Bridge.php b/bridges/Rue89Bridge.php index 65991225..72f01eb9 100644 --- a/bridges/Rue89Bridge.php +++ b/bridges/Rue89Bridge.php @@ -9,9 +9,9 @@ class Rue89Bridge extends FeedExpander { protected function parseItem($item){ $item = parent::parseItem($item); - $url = "http://api.rue89.nouvelobs.com/export/mobile2/node/" - . str_replace(" ", "", substr($item['uri'], -8)) - . "/full"; + $url = 'http://api.rue89.nouvelobs.com/export/mobile2/node/' + . str_replace(' ', '', substr($item['uri'], -8)) + . '/full'; $datas = json_decode(getContents($url), true); $item['content'] = $datas['node']['body']; diff --git a/bridges/SexactuBridge.php b/bridges/SexactuBridge.php index 5bc552ab..b0a71745 100644 --- a/bridges/SexactuBridge.php +++ b/bridges/SexactuBridge.php @@ -32,7 +32,7 @@ class SexactuBridge extends BridgeAbstract { $item = array(); $item['author'] = self::AUTHOR; $item['title'] = $title->plaintext; - $urlAttribute = "data-href"; + $urlAttribute = 'data-href'; $uri = $title->$urlAttribute; if($uri === false) continue; diff --git a/bridges/ShanaprojectBridge.php b/bridges/ShanaprojectBridge.php index e86f7729..6eadcb12 100644 --- a/bridges/ShanaprojectBridge.php +++ b/bridges/ShanaprojectBridge.php @@ -73,7 +73,7 @@ class ShanaprojectBridge extends BridgeAbstract { // Getting the picture is a little bit tricky as it is part of the style. // Luckily the style is part of the parent div :) - if(preg_match("/url\(\/\/([^\)]+)\)/i", $anime->parent->style, $matches)) + if(preg_match('/url\(\/\/([^\)]+)\)/i', $anime->parent->style, $matches)) return $matches[1]; returnServerError('Could not extract background image!'); diff --git a/bridges/Shimmie2Bridge.php b/bridges/Shimmie2Bridge.php index efbcd9b7..bdbc504a 100644 --- a/bridges/Shimmie2Bridge.php +++ b/bridges/Shimmie2Bridge.php @@ -21,7 +21,7 @@ class Shimmie2Bridge extends DanbooruBridge { protected function getItemFromElement($element){ $item = array(); $item['uri'] = $this->getURI() . $element->href; - $item['id'] = (int)preg_replace("/[^0-9]/", '', $element->getAttribute(static::IDATTRIBUTE)); + $item['id'] = (int)preg_replace('/[^0-9]/', '', $element->getAttribute(static::IDATTRIBUTE)); $item['timestamp'] = time(); $thumbnailUri = $this->getURI() . $element->find('img', 0)->src; $item['tags'] = $element->getAttribute('data-tags'); diff --git a/bridges/SuperSmashBlogBridge.php b/bridges/SuperSmashBlogBridge.php index 06c58fca..9216ef6e 100644 --- a/bridges/SuperSmashBlogBridge.php +++ b/bridges/SuperSmashBlogBridge.php @@ -8,7 +8,7 @@ class SuperSmashBlogBridge extends BridgeAbstract { const DESCRIPTION = 'Latest articles from the Super Smash Blog blog'; public function collectData(){ - $dlUrl = "https://www.smashbros.com/data/bs/en_US/json/en_US.json"; + $dlUrl = 'https://www.smashbros.com/data/bs/en_US/json/en_US.json'; $jsonString = getContents($dlUrl) or returnServerError('Error while downloading the website content'); $json = json_decode($jsonString, true); diff --git a/bridges/VkBridge.php b/bridges/VkBridge.php index 0110754d..70c0db41 100644 --- a/bridges/VkBridge.php +++ b/bridges/VkBridge.php @@ -66,7 +66,7 @@ class VkBridge extends BridgeAbstract $post->find('a.wall_post_more', 0)->outertext = ''; } - $content_suffix = ""; + $content_suffix = ''; // looking for external links $external_link_selectors = array( @@ -81,8 +81,8 @@ class VkBridge extends BridgeAbstract $innertext = $a->innertext; $parsed_url = parse_url($a->getAttribute('href')); if (strpos($parsed_url['path'], '/away.php') !== 0) continue; - parse_str($parsed_url["query"], $parsed_query); - $content_suffix .= "
External link: $innertext"; + parse_str($parsed_url['query'], $parsed_query); + $content_suffix .= "
External link: $innertext"; } } @@ -100,17 +100,17 @@ class VkBridge extends BridgeAbstract } // looking for article - $article = $post->find("a.article_snippet", 0); + $article = $post->find('a.article_snippet', 0); if (is_object($article)) { - if (strpos($article->getAttribute('class'), "article_snippet_mini") !== false) { - $article_title_selector = "div.article_snippet_mini_title"; - $article_author_selector = "div.article_snippet_mini_info > .mem_link, - div.article_snippet_mini_info > .group_link"; - $article_thumb_selector = "div.article_snippet_mini_thumb"; + if (strpos($article->getAttribute('class'), 'article_snippet_mini') !== false) { + $article_title_selector = 'div.article_snippet_mini_title'; + $article_author_selector = 'div.article_snippet_mini_info > .mem_link, + div.article_snippet_mini_info > .group_link'; + $article_thumb_selector = 'div.article_snippet_mini_thumb'; } else { - $article_title_selector = "div.article_snippet__title"; - $article_author_selector = "div.article_snippet__author"; - $article_thumb_selector = "div.article_snippet__image"; + $article_title_selector = 'div.article_snippet__title'; + $article_author_selector = 'div.article_snippet__author'; + $article_thumb_selector = 'div.article_snippet__image'; } $article_title = $article->find($article_title_selector, 0)->innertext; $article_author = $article->find($article_author_selector, 0)->innertext; @@ -136,7 +136,7 @@ class VkBridge extends BridgeAbstract // get all other videos foreach($post->find('a.page_post_thumb_video') as $a) { $video_title = $a->getAttribute('aria-label'); - $temp = explode(" ", $video_title, 2); + $temp = explode(' ', $video_title, 2); if (count($temp) > 1) $video_title = $temp[1]; $video_link = self::URI . ltrim( $a->getAttribute('href'), '/' ); $content_suffix .= "
Video: $video_title"; @@ -163,8 +163,8 @@ class VkBridge extends BridgeAbstract // get photo documents foreach($post->find('a.page_doc_photo_href') as $a) { $doc_link = self::URI . ltrim($a->getAttribute('href'), '/'); - $doc_gif_label_element = $a->find(".page_gif_label", 0); - $doc_title_element = $a->find(".doc_label", 0); + $doc_gif_label_element = $a->find('.page_gif_label', 0); + $doc_title_element = $a->find('.doc_label', 0); if (is_object($doc_gif_label_element)) { $gif_preview_img = backgroundToImg($a->find('.page_doc_photo', 0)); @@ -184,7 +184,7 @@ class VkBridge extends BridgeAbstract // get other documents foreach($post->find('div.page_doc_row') as $div) { - $doc_title_element = $div->find("a.page_doc_title", 0); + $doc_title_element = $div->find('a.page_doc_title', 0); if (is_object($doc_title_element)) { $doc_title = $doc_title_element->innertext; @@ -204,7 +204,7 @@ class VkBridge extends BridgeAbstract $poll_title = $div->find('.page_media_poll_title', 0)->innertext; $content_suffix .= "
Poll: $poll_title"; foreach($div->find('div.page_poll_text') as $poll_stat_title) { - $content_suffix .= "
- " . $poll_stat_title->innertext; + $content_suffix .= '
- ' . $poll_stat_title->innertext; } $div->outertext = ''; } @@ -231,10 +231,10 @@ class VkBridge extends BridgeAbstract // get post link $post_link = $post->find('a.post_link', 0)->getAttribute('href'); - preg_match("/wall-?\d+_(\d+)/", $post_link, $preg_match_result); + preg_match('/wall-?\d+_(\d+)/', $post_link, $preg_match_result); $item['post_id'] = intval($preg_match_result[1]); if (substr(self::URI, -1) == '/') { - $post_link = self::URI . ltrim($post_link, "/"); + $post_link = self::URI . ltrim($post_link, '/'); } else { $post_link = self::URI . $post_link; } @@ -273,17 +273,17 @@ class VkBridge extends BridgeAbstract $data = json_decode($arg, true); if ($data == null) return; - $thumb = $data['temp']['base'] . $data['temp']['x_'][0] . ".jpg"; + $thumb = $data['temp']['base'] . $data['temp']['x_'][0] . '.jpg'; $original = ''; foreach(array('y_', 'z_', 'w_') as $key) { if (!isset($data['temp'][$key])) continue; if (!isset($data['temp'][$key][0])) continue; - if (substr($data['temp'][$key][0], 0, 4) == "http") { - $base = ""; + if (substr($data['temp'][$key][0], 0, 4) == 'http') { + $base = ''; } else { $base = $data['temp']['base']; } - $original = $base . $data['temp'][$key][0] . ".jpg"; + $original = $base . $data['temp'][$key][0] . '.jpg'; } if ($original) { @@ -296,7 +296,7 @@ class VkBridge extends BridgeAbstract private function getTitle($content) { preg_match('/^["\w\ \p{Cyrillic}\(\)\?#«»-]+/mu', htmlspecialchars_decode($content), $result); - if (count($result) == 0) return "untitled"; + if (count($result) == 0) return 'untitled'; return $result[0]; } diff --git a/bridges/WhydBridge.php b/bridges/WhydBridge.php index accdb759..347db6ea 100644 --- a/bridges/WhydBridge.php +++ b/bridges/WhydBridge.php @@ -18,10 +18,10 @@ class WhydBridge extends BridgeAbstract { public function collectData(){ $html = ''; - if(strlen(preg_replace("/[^0-9a-f]/", '', $this->getInput('u'))) == 24) { + if(strlen(preg_replace('/[^0-9a-f]/', '', $this->getInput('u'))) == 24) { // is input the userid ? $html = getSimpleHTMLDOM( - self::URI . 'u/' . preg_replace("/[^0-9a-f]/", '', $this->getInput('u')) + self::URI . 'u/' . preg_replace('/[^0-9a-f]/', '', $this->getInput('u')) ) or returnServerError('No results for this query.'); } else { // input may be the username $html = getSimpleHTMLDOM( diff --git a/bridges/YGGTorrentBridge.php b/bridges/YGGTorrentBridge.php index c6d38a57..bc434d34 100644 --- a/bridges/YGGTorrentBridge.php +++ b/bridges/YGGTorrentBridge.php @@ -12,72 +12,72 @@ class YGGTorrentBridge extends BridgeAbstract { const PARAMETERS = array( array( - "cat" => array( - "name" => "category", - "type" => "list", - "values" => array( - "Toute les catégories" => "all.all", - "Film/Vidéo - Toutes les sous-catégories" => "2145.all", - "Film/Vidéo - Animation" => "2145.2178", - "Film/Vidéo - Animation Série" => "2145.2179", - "Film/Vidéo - Concert" => "2145.2180", - "Film/Vidéo - Documentaire" => "2145.2181", - "Film/Vidéo - Émission TV" => "2145.2182", - "Film/Vidéo - Film" => "2145.2183", - "Film/Vidéo - Série TV" => "2145.2184", - "Film/Vidéo - Spectacle" => "2145.2185", - "Film/Vidéo - Sport" => "2145.2186", - "Film/Vidéo - Vidéo-clips" => "2145.2186", - "Audio - Toutes les sous-catégories" => "2139.all", - "Audio - Karaoké" => "2139.2147", - "Audio - Musique" => "2139.2148", - "Audio - Podcast Radio" => "2139.2150", - "Audio - Samples" => "2139.2149", - "Jeu vidéo - Toutes les sous-catégories" => "2142.all", - "Jeu vidéo - Autre" => "2142.2167", - "Jeu vidéo - Linux" => "2142.2159", - "Jeu vidéo - MacOS" => "2142.2160", - "Jeu vidéo - Microsoft" => "2142.2162", - "Jeu vidéo - Nintendo" => "2142.2163", - "Jeu vidéo - Smartphone" => "2142.2165", - "Jeu vidéo - Sony" => "2142.2164", - "Jeu vidéo - Tablette" => "2142.2166", - "Jeu vidéo - Windows" => "2142.2161", - "eBook - Toutes les sous-catégories" => "2140.all", - "eBook - Audio" => "2140.2151", - "eBook - Bds" => "2140.2152", - "eBook - Comics" => "2140.2153", - "eBook - Livres" => "2140.2154", - "eBook - Mangas" => "2140.2155", - "eBook - Presse" => "2140.2156", - "Emulation - Toutes les sous-catégories" => "2141.all", - "Emulation - Emulateurs" => "2141.2157", - "Emulation - Roms" => "2141.2158", - "GPS - Toutes les sous-catégories" => "2141.all", - "GPS - Applications" => "2141.2168", - "GPS - Cartes" => "2141.2169", - "GPS - Divers" => "2141.2170" + 'cat' => array( + 'name' => 'category', + 'type' => 'list', + 'values' => array( + 'Toute les catégories' => 'all.all', + 'Film/Vidéo - Toutes les sous-catégories' => '2145.all', + 'Film/Vidéo - Animation' => '2145.2178', + 'Film/Vidéo - Animation Série' => '2145.2179', + 'Film/Vidéo - Concert' => '2145.2180', + 'Film/Vidéo - Documentaire' => '2145.2181', + 'Film/Vidéo - Émission TV' => '2145.2182', + 'Film/Vidéo - Film' => '2145.2183', + 'Film/Vidéo - Série TV' => '2145.2184', + 'Film/Vidéo - Spectacle' => '2145.2185', + 'Film/Vidéo - Sport' => '2145.2186', + 'Film/Vidéo - Vidéo-clips' => '2145.2186', + 'Audio - Toutes les sous-catégories' => '2139.all', + 'Audio - Karaoké' => '2139.2147', + 'Audio - Musique' => '2139.2148', + 'Audio - Podcast Radio' => '2139.2150', + 'Audio - Samples' => '2139.2149', + 'Jeu vidéo - Toutes les sous-catégories' => '2142.all', + 'Jeu vidéo - Autre' => '2142.2167', + 'Jeu vidéo - Linux' => '2142.2159', + 'Jeu vidéo - MacOS' => '2142.2160', + 'Jeu vidéo - Microsoft' => '2142.2162', + 'Jeu vidéo - Nintendo' => '2142.2163', + 'Jeu vidéo - Smartphone' => '2142.2165', + 'Jeu vidéo - Sony' => '2142.2164', + 'Jeu vidéo - Tablette' => '2142.2166', + 'Jeu vidéo - Windows' => '2142.2161', + 'eBook - Toutes les sous-catégories' => '2140.all', + 'eBook - Audio' => '2140.2151', + 'eBook - Bds' => '2140.2152', + 'eBook - Comics' => '2140.2153', + 'eBook - Livres' => '2140.2154', + 'eBook - Mangas' => '2140.2155', + 'eBook - Presse' => '2140.2156', + 'Emulation - Toutes les sous-catégories' => '2141.all', + 'Emulation - Emulateurs' => '2141.2157', + 'Emulation - Roms' => '2141.2158', + 'GPS - Toutes les sous-catégories' => '2141.all', + 'GPS - Applications' => '2141.2168', + 'GPS - Cartes' => '2141.2169', + 'GPS - Divers' => '2141.2170' ) ), - "nom" => array( - "name" => "Nom", - "description" => "Nom du torrent", - "type" => "text" + 'nom' => array( + 'name' => 'Nom', + 'description' => 'Nom du torrent', + 'type' => 'text' ), - "description" => array( - "name" => "Description", - "description" => "Description du torrent", - "type" => "text" + 'description' => array( + 'name' => 'Description', + 'description' => 'Description du torrent', + 'type' => 'text' ), - "fichier" => array( - "name" => "Fichier", - "description" => "Fichier du torrent", - "type" => "text" + 'fichier' => array( + 'name' => 'Fichier', + 'description' => 'Fichier du torrent', + 'type' => 'text' ), - "uploader" => array( - "name" => "Uploader", - "description" => "Uploader du torrent", - "type" => "text" + 'uploader' => array( + 'name' => 'Uploader', + 'description' => 'Uploader du torrent', + 'type' => 'text' ), ) @@ -85,42 +85,42 @@ class YGGTorrentBridge extends BridgeAbstract { public function collectData() { - $catInfo = explode(".", $this->getInput("cat")); + $catInfo = explode('.', $this->getInput('cat')); $category = $catInfo[0]; $subcategory = $catInfo[1]; - $html = getSimpleHTMLDOM(self::URI . "/engine/search?name=" - . $this->getInput("nom") - . "&description=" - . $this->getInput("description") - . "&fichier=" - . $this->getInput("fichier") - . "&file=" - . $this->getInput("uploader") - . "&category=" + $html = getSimpleHTMLDOM(self::URI . '/engine/search?name=' + . $this->getInput('nom') + . '&description=' + . $this->getInput('description') + . '&fichier=' + . $this->getInput('fichier') + . '&file=' + . $this->getInput('uploader') + . '&category=' . $category - . "&sub_category=" + . '&sub_category=' . $subcategory - . "&do=search") - or returnServerError("Unable to query Yggtorrent !"); + . '&do=search') + or returnServerError('Unable to query Yggtorrent !'); $count = 0; - $results = $html->find(".results", 0); + $results = $html->find('.results', 0); if(!$results) return; - foreach($results->find("tr") as $row) { + foreach($results->find('tr') as $row) { $count++; if($count == 1) continue; if($count == 12) break; $item = array(); - $item["timestamp"] = $row->find(".hidden", 1)->plaintext; - $item["title"] = $row->find("a", 1)->plaintext; - $torrentData = $this->collectTorrentData($row->find("a", 1)->href); - $item["author"] = $torrentData["author"]; - $item["content"] = $torrentData["content"]; - $item["seeders"] = $row->find("td", 7)->plaintext; - $item["leechers"] = $row->find("td", 8)->plaintext; - $item["size"] = $row->find("td", 5)->plaintext; + $item['timestamp'] = $row->find('.hidden', 1)->plaintext; + $item['title'] = $row->find('a', 1)->plaintext; + $torrentData = $this->collectTorrentData($row->find('a', 1)->href); + $item['author'] = $torrentData['author']; + $item['content'] = $torrentData['content']; + $item['seeders'] = $row->find('td', 7)->plaintext; + $item['leechers'] = $row->find('td', 8)->plaintext; + $item['size'] = $row->find('td', 5)->plaintext; $this->items[] = $item; } @@ -130,14 +130,14 @@ class YGGTorrentBridge extends BridgeAbstract { public function collectTorrentData($url) { //For weird reason, the link we get can be invalid, we fix it. - $url_full = explode("/", $url); + $url_full = explode('/', $url); $url_full[4] = urlencode($url_full[4]); $url_full[5] = urlencode($url_full[5]); $url_full[6] = urlencode($url_full[6]); - $url = implode("/", $url_full); - $page = getSimpleHTMLDOM($url) or returnServerError("Unable to query Yggtorrent page !"); - $author = $page->find(".informations", 0)->find("a", 4)->plaintext; - $content = $page->find(".default", 1); - return array("author" => $author, "content" => $content); + $url = implode('/', $url_full); + $page = getSimpleHTMLDOM($url) or returnServerError('Unable to query Yggtorrent page !'); + $author = $page->find('.informations', 0)->find('a', 4)->plaintext; + $content = $page->find('.default', 1); + return array('author' => $author, 'content' => $content); } } diff --git a/bridges/YoutubeBridge.php b/bridges/YoutubeBridge.php index 043d965e..e597fe3a 100644 --- a/bridges/YoutubeBridge.php +++ b/bridges/YoutubeBridge.php @@ -25,14 +25,14 @@ class YoutubeBridge extends BridgeAbstract { 'By channel id' => array( 'c' => array( 'name' => 'channel id', - 'exampleValue' => "15", + 'exampleValue' => '15', 'required' => true ) ), 'By playlist Id' => array( 'p' => array( 'name' => 'playlist id', - 'exampleValue' => "15" + 'exampleValue' => '15' ) ), 'Search result' => array( @@ -195,7 +195,7 @@ class YoutubeBridge extends BridgeAbstract { $this->request = $this->getInput('s'); $page = 1; if($this->getInput('pa')) - $page = (int)preg_replace("/[^0-9]/", '', $this->getInput('pa')); + $page = (int)preg_replace('/[^0-9]/', '', $this->getInput('pa')); $url_listing = self::URI . 'results?search_query=' diff --git a/caches/FileCache.php b/caches/FileCache.php index 0ca36d22..de17d527 100644 --- a/caches/FileCache.php +++ b/caches/FileCache.php @@ -19,7 +19,7 @@ class FileCache implements CacheInterface { $writeStream = file_put_contents($this->getCacheFile(), serialize($datas)); if($writeStream === false) { - throw new \Exception("Cannot write the cache... Do you have the right permissions ?"); + throw new \Exception('Cannot write the cache... Do you have the right permissions ?'); } return $this; diff --git a/lib/Configuration.php b/lib/Configuration.php index d491fc4a..02a908c9 100644 --- a/lib/Configuration.php +++ b/lib/Configuration.php @@ -26,7 +26,7 @@ class Configuration { die('"curl" extension not loaded. Please check "php.ini"'); // configuration checks - if(ini_get('allow_url_fopen') !== "1") + if(ini_get('allow_url_fopen') !== '1') die('"allow_url_fopen" is not set to "1". Please check "php.ini'); // Check cache folder permissions (write permissions required) diff --git a/lib/FeedExpander.php b/lib/FeedExpander.php index 9702ce32..6e1f16ff 100644 --- a/lib/FeedExpander.php +++ b/lib/FeedExpander.php @@ -24,15 +24,15 @@ abstract class FeedExpander extends BridgeAbstract { switch(true) { case isset($rssContent->item[0]): debugMessage('Detected RSS 1.0 format'); - $this->feedType = "RSS_1_0"; + $this->feedType = 'RSS_1_0'; break; case isset($rssContent->channel[0]): debugMessage('Detected RSS 0.9x or 2.0 format'); - $this->feedType = "RSS_2_0"; + $this->feedType = 'RSS_2_0'; break; case isset($rssContent->entry[0]): debugMessage('Detected ATOM format'); - $this->feedType = "ATOM_1_0"; + $this->feedType = 'ATOM_1_0'; break; default: debugMessage('Unknown feed format/version'); diff --git a/lib/html.php b/lib/html.php index eec47ae0..297ab801 100644 --- a/lib/html.php +++ b/lib/html.php @@ -26,7 +26,7 @@ EOD; $bridge = Bridge::create($bridgeName); if($bridge == false) - return ""; + return ''; $HTTPSWarning = ''; if(strpos($bridge->getURI(), 'https') !== 0) { diff --git a/phpcs.xml b/phpcs.xml index c88b0f50..a67262ce 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -70,4 +70,8 @@ + + + + From 71c29d41920870b4669eb714b022e56be0845a68 Mon Sep 17 00:00:00 2001 From: teromene Date: Fri, 29 Jun 2018 23:15:22 +0100 Subject: [PATCH 014/146] Fix phpcs for master. --- bridges/ContainerLinuxReleasesBridge.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bridges/ContainerLinuxReleasesBridge.php b/bridges/ContainerLinuxReleasesBridge.php index bcb421d2..ce3235ff 100644 --- a/bridges/ContainerLinuxReleasesBridge.php +++ b/bridges/ContainerLinuxReleasesBridge.php @@ -66,7 +66,7 @@ EOT; $regex = '/\n\s*[\*|\-](.*)/'; $item['content'] = preg_replace_callback ($regex, function($regs) { $item = $regs[1]; - return sprintf ("
  • %s
", trim ($item)); + return sprintf ('
  • %s
', trim ($item)); }, $item['content']); $this->items[] = $item; From da6b98851caa490043893869738f96dd7db35a18 Mon Sep 17 00:00:00 2001 From: Teromene Date: Sat, 30 Jun 2018 09:24:22 +0100 Subject: [PATCH 015/146] Add recuperation of the current version from git if available (#731) * Add recuperation of the current version from git if available * Include version when auto-reporting an error --- index.php | 3 ++- lib/Configuration.php | 19 +++++++++++++++++++ lib/Exceptions.php | 5 ++++- static/style.css | 5 +++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 8cb8908e..4a1e2aa2 100644 --- a/index.php +++ b/index.php @@ -253,7 +253,8 @@ EOD; echo $inactiveBridges; ?> EOD; diff --git a/formats/MrssFormat.php b/formats/MrssFormat.php index 8f54ef0b..6d079288 100644 --- a/formats/MrssFormat.php +++ b/formats/MrssFormat.php @@ -51,6 +51,16 @@ Some media files might not be shown to you. Consider using the ATOM format inste } } + $entryCategories = ''; + if(isset($item['categories'])) { + + foreach($item['categories'] as $category) { + $entryCategories .= '' + . $category . '' + . PHP_EOL; + } + } + $items .= << @@ -61,6 +71,7 @@ Some media files might not be shown to you. Consider using the ATOM format inste {$itemContent}{$entryEnclosuresWarning} {$itemAuthor} {$entryEnclosures} + {$entryCategories} EOD; diff --git a/static/HtmlFormat.css b/static/HtmlFormat.css index 9e0ee13e..195a9b0d 100644 --- a/static/HtmlFormat.css +++ b/static/HtmlFormat.css @@ -69,12 +69,14 @@ a.backlink, a.backlink:link, a.backlink:visited, a.itemtitle, a.itemtitle:link, } +section > div.content, section > div.categories, section > div.content, section > div.attachments { padding: 10px; } +section > div.categories > li.category, section > div.attachments > li.enclosure { list-style-type: circle; @@ -114,4 +116,4 @@ img { max-width: 100%; -} \ No newline at end of file +} From fbf874cb295d3adcd79ea8ff7ad72e4da9246964 Mon Sep 17 00:00:00 2001 From: Teromene Date: Mon, 16 Jul 2018 12:37:09 +0200 Subject: [PATCH 025/146] Update README.md Remove allow_url_fopen requirement. This should no longer be necessary. Added requirement for curl. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45bbc6d9..3ca495c4 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Requirements * PHP 5.6, e.g. `AddHandler application/x-httpd-php56 .php` in `.htaccess` * `openssl` extension enabled in PHP config (`php.ini`) - * `allow_url_fopen=1` in `php.ini` + * `curl` extension enabled in PHP config (`php.ini`) Enabling/Disabling bridges === From c7b0c9fd31aa5ce88dbf4d4a0fb7ca71bf8b7f46 Mon Sep 17 00:00:00 2001 From: Nemo Date: Mon, 16 Jul 2018 18:24:52 +0530 Subject: [PATCH 026/146] Amazon Price Tracker Bridge (#741) * [amazonprice] Adds AmazonPriceTracker bridge --- bridges/AmazonPriceTrackerBridge.php | 149 +++++++++++++++++++++++ bridges/ContainerLinuxReleasesBridge.php | 2 +- 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 bridges/AmazonPriceTrackerBridge.php diff --git a/bridges/AmazonPriceTrackerBridge.php b/bridges/AmazonPriceTrackerBridge.php new file mode 100644 index 00000000..dd352af1 --- /dev/null +++ b/bridges/AmazonPriceTrackerBridge.php @@ -0,0 +1,149 @@ + array( + 'name' => 'ASIN', + 'required' => true, + 'exampleValue' => 'B071GB1VMQ', + // https://stackoverflow.com/a/12827734 + 'pattern' => 'B[\dA-Z]{9}|\d{9}(X|\d)', + ), + 'tld' => array( + 'name' => 'Country', + 'type' => 'list', + 'required' => true, + 'values' => array( + 'Australia' => 'com.au', + 'Brazil' => 'com.br', + 'Canada' => 'ca', + 'China' => 'cn', + 'France' => 'fr', + 'Germany' => 'de', + 'India' => 'in', + 'Italy' => 'it', + 'Japan' => 'co.jp', + 'Mexico' => 'com.mx', + 'Netherlands' => 'nl', + 'Spain' => 'es', + 'United Kingdom' => 'co.uk', + 'United States' => 'com', + ), + 'defaultValue' => 'com', + ), + )); + + protected $title; + + /** + * Generates domain name given a amazon TLD + */ + private function getDomainName() { + return 'https://www.amazon.' . $this->getInput('tld'); + } + + /** + * Generates URI for a Amazon product page + */ + public function getURI() { + if (!is_null($this->getInput('asin'))) { + return $this->getDomainName() . '/dp/' . $this->getInput('asin') . '/'; + } + return parent::getURI(); + } + + /** + * Scrapes the product title from the html page + * returns the default title if scraping fails + */ + private function getTitle($html) { + $titleTag = $html->find('#productTitle', 0); + + if (!$titleTag) { + return $this->getDefaultTitle(); + } else { + return trim(html_entity_decode($titleTag->innertext, ENT_QUOTES)); + } + } + + /** + * Title used by the feed if none could be found + */ + private function getDefaultTitle() { + return 'Amazon.' . $this->getInput('tld') . ': ' . $this->getInput('asin'); + } + + /** + * Returns name for the feed + * Uses title (already scraped) if it has one + */ + public function getName() { + if (isset($this->title)) { + return $this->title; + } else { + return parent::getName(); + } + } + + /** + * Returns a generated image tag for the product + */ + private function getImage($html) { + $imageSrc = $html->find('#main-image-container img', 0); + + if ($imageSrc) { + $imageSrc = $imageSrc ? $imageSrc->getAttribute('data-old-hires') : ''; + return << +EOT; + } + } + + /** + * Return \simple_html_dom object + * for the entire html of the product page + */ + private function getHtml() { + $uri = $this->getURI(); + + return getSimpleHTMLDOM($uri) ?: returnServerError('Could not request Amazon.'); + } + + /** + * Scrape method for Amazon product page + * @return [type] [description] + */ + public function collectData() { + $html = $this->getHtml(); + $this->title = $this->getTitle($html); + $imageTag = $this->getImage($html); + + $asinData = $html->find('#cerberus-data-metrics', 0); + + //