Merge branch 'master' of github.com:RSS-Bridge/rss-bridge
This commit is contained in:
commit
e9424f6a08
10 changed files with 604 additions and 46 deletions
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
class Arte7Bridge extends BridgeAbstract {
|
class Arte7Bridge extends BridgeAbstract {
|
||||||
|
|
||||||
const MAINTAINER = 'mitsukarenai';
|
// const MAINTAINER = 'mitsukarenai';
|
||||||
const NAME = 'Arte +7';
|
const NAME = 'Arte +7';
|
||||||
const URI = 'https://www.arte.tv/';
|
const URI = 'https://www.arte.tv/';
|
||||||
const CACHE_TIMEOUT = 1800; // 30min
|
const CACHE_TIMEOUT = 1800; // 30min
|
||||||
|
|
219
bridges/BukowskisBridge.php
Executable file
219
bridges/BukowskisBridge.php
Executable file
|
@ -0,0 +1,219 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class BukowskisBridge extends BridgeAbstract
|
||||||
|
{
|
||||||
|
const NAME = 'Bukowskis';
|
||||||
|
const URI = 'https://www.bukowskis.com';
|
||||||
|
const DESCRIPTION = 'Fetches info about auction objects from Bukowskis auction house';
|
||||||
|
const MAINTAINER = 'Qluxzz';
|
||||||
|
const PARAMETERS = array(array(
|
||||||
|
'category' => array(
|
||||||
|
'name' => 'Category',
|
||||||
|
'type' => 'list',
|
||||||
|
'values' => array(
|
||||||
|
'All categories' => '',
|
||||||
|
'Art' => array(
|
||||||
|
'All' => 'art',
|
||||||
|
'Classic Art' => 'art.classic-art',
|
||||||
|
'Classic Finnish Art' => 'art.classic-finnish-art',
|
||||||
|
'Classic Swedish Art' => 'art.classic-swedish-art',
|
||||||
|
'Contemporary' => 'art.contemporary',
|
||||||
|
'Modern Finnish Art' => 'art.modern-finnish-art',
|
||||||
|
'Modern International Art' => 'art.modern-international-art',
|
||||||
|
'Modern Swedish Art' => 'art.modern-swedish-art',
|
||||||
|
'Old Masters' => 'art.old-masters',
|
||||||
|
'Other' => 'art.other',
|
||||||
|
'Photographs' => 'art.photographs',
|
||||||
|
'Prints' => 'art.prints',
|
||||||
|
'Sculpture' => 'art.sculpture',
|
||||||
|
'Swedish Old Masters' => 'art.swedish-old-masters',
|
||||||
|
),
|
||||||
|
'Asian Ceramics & Works of Art' => array(
|
||||||
|
'All' => 'asian-ceramics-works-of-art',
|
||||||
|
'Other' => 'asian-ceramics-works-of-art.other',
|
||||||
|
'Porcelain' => 'asian-ceramics-works-of-art.porcelain',
|
||||||
|
),
|
||||||
|
'Books & Manuscripts' => array(
|
||||||
|
'All' => 'books-manuscripts',
|
||||||
|
'Books' => 'books-manuscripts.books',
|
||||||
|
),
|
||||||
|
'Carpets, rugs & textiles' => array(
|
||||||
|
'All' => 'carpets-rugs-textiles',
|
||||||
|
'European' => 'carpets-rugs-textiles.european',
|
||||||
|
'Oriental' => 'carpets-rugs-textiles.oriental',
|
||||||
|
'Rest of the world' => 'carpets-rugs-textiles.rest-of-the-world',
|
||||||
|
'Scandinavian' => 'carpets-rugs-textiles.scandinavian',
|
||||||
|
),
|
||||||
|
'Ceramics & porcelain' => array(
|
||||||
|
'All' => 'ceramics-porcelain',
|
||||||
|
'Ceramic ware' => 'ceramics-porcelain.ceramic-ware',
|
||||||
|
'European' => 'ceramics-porcelain.european',
|
||||||
|
'Rest of the world' => 'ceramics-porcelain.rest-of-the-world',
|
||||||
|
'Scandinavian' => 'ceramics-porcelain.scandinavian',
|
||||||
|
),
|
||||||
|
'Collectibles' => array(
|
||||||
|
'All' => 'collectibles',
|
||||||
|
'Advertising & Retail' => 'collectibles.advertising-retail',
|
||||||
|
'Memorabilia' => 'collectibles.memorabilia',
|
||||||
|
'Movies & music' => 'collectibles.movies-music',
|
||||||
|
'Other' => 'collectibles.other',
|
||||||
|
'Retro & Popular Culture' => 'collectibles.retro-popular-culture',
|
||||||
|
'Technica & Nautica' => 'collectibles.technica-nautica',
|
||||||
|
'Toys' => 'collectibles.toys',
|
||||||
|
),
|
||||||
|
'Design' => array(
|
||||||
|
'All' => 'design',
|
||||||
|
'Art glass' => 'design.art-glass',
|
||||||
|
'Furniture' => 'design.furniture',
|
||||||
|
'Other' => 'design.other',
|
||||||
|
),
|
||||||
|
'Folk art' => array(
|
||||||
|
'All' => 'folk-art',
|
||||||
|
'All categories' => 'lots',
|
||||||
|
),
|
||||||
|
'Furniture' => array(
|
||||||
|
'All' => 'furniture',
|
||||||
|
'Armchairs & Sofas' => 'furniture.armchairs-sofas',
|
||||||
|
'Cabinets & Bureaus' => 'furniture.cabinets-bureaus',
|
||||||
|
'Chairs' => 'furniture.chairs',
|
||||||
|
'Garden furniture' => 'furniture.garden-furniture',
|
||||||
|
'Mirrors' => 'furniture.mirrors',
|
||||||
|
'Other' => 'furniture.other',
|
||||||
|
'Shelves & Book cases' => 'furniture.shelves-book-cases',
|
||||||
|
'Tables' => 'furniture.tables',
|
||||||
|
),
|
||||||
|
'Glassware' => array(
|
||||||
|
'All' => 'glassware',
|
||||||
|
'Glassware' => 'glassware.glassware',
|
||||||
|
'Other' => 'glassware.other',
|
||||||
|
),
|
||||||
|
'Jewellery' => array(
|
||||||
|
'All' => 'jewellery',
|
||||||
|
'Bracelets' => 'jewellery.bracelets',
|
||||||
|
'Brooches' => 'jewellery.brooches',
|
||||||
|
'Earrings' => 'jewellery.earrings',
|
||||||
|
'Necklaces & Pendants' => 'jewellery.necklaces-pendants',
|
||||||
|
'Other' => 'jewellery.other',
|
||||||
|
'Rings' => 'jewellery.rings',
|
||||||
|
),
|
||||||
|
'Lighting' => array(
|
||||||
|
'All' => 'lighting',
|
||||||
|
'Candle sticks & Candelabras' => 'lighting.candle-sticks-candelabras',
|
||||||
|
'Ceiling lights' => 'lighting.ceiling-lights',
|
||||||
|
'Chandeliers' => 'lighting.chandeliers',
|
||||||
|
'Floor lights' => 'lighting.floor-lights',
|
||||||
|
'Other' => 'lighting.other',
|
||||||
|
'Table lights' => 'lighting.table-lights',
|
||||||
|
'Wall lights' => 'lighting.wall-lights',
|
||||||
|
),
|
||||||
|
'Militaria' => array(
|
||||||
|
'All' => 'militaria',
|
||||||
|
'Honors & Medals' => 'militaria.honors-medals',
|
||||||
|
'Other militaria' => 'militaria.other-militaria',
|
||||||
|
'Weaponry' => 'militaria.weaponry',
|
||||||
|
),
|
||||||
|
'Miscellaneous' => array(
|
||||||
|
'All' => 'miscellaneous',
|
||||||
|
'Brass, Copper & Pewter' => 'miscellaneous.brass-copper-pewter',
|
||||||
|
'Nickel silver' => 'miscellaneous.nickel-silver',
|
||||||
|
'Oriental' => 'miscellaneous.oriental',
|
||||||
|
'Other' => 'miscellaneous.other',
|
||||||
|
),
|
||||||
|
'Silver' => array(
|
||||||
|
'All' => 'silver',
|
||||||
|
'Candle sticks' => 'silver.candle-sticks',
|
||||||
|
'Cups & Bowls' => 'silver.cups-bowls',
|
||||||
|
'Cutlery' => 'silver.cutlery',
|
||||||
|
'Other' => 'silver.other',
|
||||||
|
),
|
||||||
|
'Timepieces' => array(
|
||||||
|
'All' => 'timepieces',
|
||||||
|
'Other' => 'timepieces.other',
|
||||||
|
'Pocket watches' => 'timepieces.pocket-watches',
|
||||||
|
'Table clocks' => 'timepieces.table-clocks',
|
||||||
|
'Wrist watches' => 'timepieces.wrist-watches',
|
||||||
|
),
|
||||||
|
'Vintage & Fashion' => array(
|
||||||
|
'All' => 'vintage-fashion',
|
||||||
|
'Accessories' => 'vintage-fashion.accessories',
|
||||||
|
'Bags & Trunks' => 'vintage-fashion.bags-trunks',
|
||||||
|
'Clothes' => 'vintage-fashion.clothes',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'sort_order' => array(
|
||||||
|
'name' => 'Sort order',
|
||||||
|
'type' => 'list',
|
||||||
|
'values' => array(
|
||||||
|
'Ending soon' => 'ending',
|
||||||
|
'Most recent' => 'recent',
|
||||||
|
'Most bids' => 'most',
|
||||||
|
'Fewest bids' => 'fewest',
|
||||||
|
'Lowest price' => 'lowest',
|
||||||
|
'Highest price' => 'highest',
|
||||||
|
'Lowest estimate' => 'low',
|
||||||
|
'Highest estimate' => 'high',
|
||||||
|
'Alphabetical' => 'alphabetical',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'language' => array(
|
||||||
|
'name' => 'Language',
|
||||||
|
'type' => 'list',
|
||||||
|
'values' => array(
|
||||||
|
'English' => 'en',
|
||||||
|
'Swedish' => 'sv',
|
||||||
|
'Finnish' => 'fi'
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||||
|
|
||||||
|
private $title;
|
||||||
|
|
||||||
|
public function collectData()
|
||||||
|
{
|
||||||
|
$baseUrl = 'https://www.bukowskis.com';
|
||||||
|
$category = $this->getInput('category');
|
||||||
|
$language = $this->getInput('language');
|
||||||
|
$sort_order = $this->getInput('sort_order');
|
||||||
|
|
||||||
|
$url = $baseUrl . '/' . $language . '/lots';
|
||||||
|
|
||||||
|
if ($category)
|
||||||
|
$url = $url . '/category/' . $category;
|
||||||
|
|
||||||
|
if ($sort_order)
|
||||||
|
$url = $url . '/sort/' . $sort_order;
|
||||||
|
|
||||||
|
$html = getSimpleHTMLDOM($url)
|
||||||
|
or returnServerError('Could not request: ' . $url);
|
||||||
|
|
||||||
|
$this->title = htmlspecialchars_decode($html->find('title', 0)->innertext);
|
||||||
|
|
||||||
|
foreach ($html->find('div.c-lot-index-lot') as $lot) {
|
||||||
|
$title = $lot->find('a.c-lot-index-lot__title', 0)->plaintext;
|
||||||
|
$relative_url = $lot->find('a.c-lot-index-lot__link', 0)->href;
|
||||||
|
$images = json_decode(
|
||||||
|
htmlspecialchars_decode(
|
||||||
|
$lot
|
||||||
|
->find('img.o-aspect-ratio__image', 0)
|
||||||
|
->getAttribute('data-thumbnails')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->items[] = array(
|
||||||
|
'title' => $title,
|
||||||
|
'uri' => $baseUrl . $relative_url,
|
||||||
|
'uid' => $lot->getAttribute('data-lot-id'),
|
||||||
|
'content' => count($images) > 0 ? "<img src='$images[0]'/><br/>$title" : $title,
|
||||||
|
'enclosures' => array_slice($images, 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->title ?: parent::getName();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +0,0 @@
|
||||||
<?php
|
|
||||||
class ChristianDailyReporterBridge extends BridgeAbstract {
|
|
||||||
|
|
||||||
const MAINTAINER = 'rogerdc';
|
|
||||||
const NAME = 'Christian Daily Reporter Unofficial RSS';
|
|
||||||
const URI = 'https://www.christiandailyreporter.com/';
|
|
||||||
const DESCRIPTION = 'The Unofficial Christian Daily Reporter RSS';
|
|
||||||
// const CACHE_TIMEOUT = 86400; // 1 day
|
|
||||||
|
|
||||||
public function getIcon() {
|
|
||||||
return self::URI . 'images/cdrfavicon.png';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function collectData() {
|
|
||||||
$uri = 'https://www.christiandailyreporter.com/';
|
|
||||||
|
|
||||||
$html = getSimpleHTMLDOM($uri)
|
|
||||||
or returnServerError('Could not request Christian Daily Reporter.');
|
|
||||||
foreach($html->find('div.top p a,div.column p a') as $element) {
|
|
||||||
$item = array();
|
|
||||||
// Title
|
|
||||||
$item['title'] = $element->innertext;
|
|
||||||
// URL
|
|
||||||
$item['uri'] = $element->href;
|
|
||||||
$this->items[] = $item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -86,7 +86,7 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
||||||
|
|
||||||
private function getImageTag($preview_path, $title){
|
private function getImageTag($preview_path, $title){
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<br /> <a href="%s"><img src="%s" alt="%s" /></a>',
|
'<br /> <a href="%s"><img srcset="%s" alt="%s" /></a>',
|
||||||
$this->getFullSizeImagePath($preview_path),
|
$this->getFullSizeImagePath($preview_path),
|
||||||
$preview_path,
|
$preview_path,
|
||||||
$title
|
$title
|
||||||
|
@ -94,6 +94,11 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFullSizeImagePath($preview_path){
|
private function getFullSizeImagePath($preview_path){
|
||||||
return explode('?compress=1', $preview_path)[0];
|
// Get last image from srcset
|
||||||
|
$src_set_urls = explode(',', $preview_path);
|
||||||
|
$url = end($src_set_urls);
|
||||||
|
$url = explode(' ', $url)[1];
|
||||||
|
|
||||||
|
return htmlspecialchars_decode($url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
class ExtremeDownloadBridge extends BridgeAbstract {
|
class ExtremeDownloadBridge extends BridgeAbstract {
|
||||||
const NAME = 'Extreme Download';
|
const NAME = 'Extreme Download';
|
||||||
const URI = 'https://www.extreme-down.ninja/';
|
const URI = 'https://www.extreme-down.tv/';
|
||||||
const DESCRIPTION = 'Suivi de série sur Extreme Download';
|
const DESCRIPTION = 'Suivi de série sur Extreme Download';
|
||||||
const MAINTAINER = 'sysadminstory';
|
const MAINTAINER = 'sysadminstory';
|
||||||
const PARAMETERS = array(
|
const PARAMETERS = array(
|
||||||
|
|
115
bridges/FSecureBlogBridge.php
Normal file
115
bridges/FSecureBlogBridge.php
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class FSecureBlogBridge extends BridgeAbstract {
|
||||||
|
const NAME = 'F-Secure Blog';
|
||||||
|
const URI = 'https://blog.f-secure.com';
|
||||||
|
const DESCRIPTION = 'F-Secure Blog';
|
||||||
|
const MAINTAINER = 'simon816';
|
||||||
|
const PARAMETERS = array(
|
||||||
|
'' => array(
|
||||||
|
'categories' => array(
|
||||||
|
'name' => 'Blog categories',
|
||||||
|
'exampleValue' => 'home-security',
|
||||||
|
),
|
||||||
|
'language' => array(
|
||||||
|
'name' => 'Language',
|
||||||
|
'defaultValue' => 'en',
|
||||||
|
),
|
||||||
|
'oldest_date' => array(
|
||||||
|
'name' => 'Oldest article date',
|
||||||
|
'exampleValue' => '-2 months',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
public function getURI() {
|
||||||
|
$lang = $this->getInput('language') or 'en';
|
||||||
|
if ($lang === 'en') {
|
||||||
|
return self::URI;
|
||||||
|
}
|
||||||
|
return self::URI . "/$lang";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collectData() {
|
||||||
|
$this->items = array();
|
||||||
|
$this->seen = array();
|
||||||
|
|
||||||
|
$this->oldest = strtotime($this->getInput('oldest_date')) ?: 0;
|
||||||
|
|
||||||
|
$categories = $this->getInput('categories');
|
||||||
|
if (!empty($categories)) {
|
||||||
|
foreach (explode(',', $categories) as $cat) {
|
||||||
|
if (!empty($cat)) {
|
||||||
|
$this->collectCategory($cat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = getSimpleHTMLDOMCached($this->getURI() . '/');
|
||||||
|
|
||||||
|
foreach ($html->find('ul.c-header-menu-desktop__list li a') as $link) {
|
||||||
|
$url = parse_url($link->href);
|
||||||
|
if (($pos = strpos($url['path'], '/category/')) !== false) {
|
||||||
|
$cat = substr($url['path'], $pos + strlen('/category/'), -1);
|
||||||
|
$this->collectCategory($cat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function collectCategory($category) {
|
||||||
|
$url = $this->getURI() . "/category/$category/";
|
||||||
|
while ($url) {
|
||||||
|
$url = $this->collectListing($url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// n.b. this relies on articles to be ordered by date so the cutoff works
|
||||||
|
private function collectListing($url) {
|
||||||
|
$html = getSimpleHTMLDOMCached($url, 60 * 60);
|
||||||
|
$items = $html->find('section.b-blog .l-blog__content__listing div.c-listing-item');
|
||||||
|
|
||||||
|
$catName = trim($html->find('section.b-blog .c-blog-header__title', 0)->plaintext);
|
||||||
|
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$url = $item->getAttribute('data-url');
|
||||||
|
if (!$this->collectArticle($url)) {
|
||||||
|
return null; // Too old, stop collecting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Point's to 404 for non-english blog
|
||||||
|
// $next = $html->find('link[rel=next]', 0);
|
||||||
|
$next = $html->find('ul.page-numbers a.next', 0);
|
||||||
|
return $next ? $next->href : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a boolean whether to continue collecting articles
|
||||||
|
// i.e. date is after oldest cutoff
|
||||||
|
private function collectArticle($url) {
|
||||||
|
if (array_key_exists($url, $this->seen)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
$html = getSimpleHTMLDOMCached($url);
|
||||||
|
|
||||||
|
$rssItem = array( 'uri' => $url, 'uid' => $url );
|
||||||
|
$rssItem['title'] = $html->find('meta[property=og:title]', 0)->content;
|
||||||
|
$dt = $html->find('meta[property=article:published_time]', 0)->content;
|
||||||
|
// Exit if too old
|
||||||
|
if (strtotime($dt) < $this->oldest) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$rssItem['timestamp'] = $dt;
|
||||||
|
$img = $html->find('meta[property=og:image]', 0);
|
||||||
|
$rssItem['enclosures'] = $img ? array($img->content) : array();
|
||||||
|
$rssItem['author'] = trim($html->find('.c-blog-author__text a', 0)->plaintext);
|
||||||
|
$rssItem['categories'] = array_map(function ($link) {
|
||||||
|
return trim($link->plaintext);
|
||||||
|
}, $html->find('.b-single-header__categories .c-category-list a'));
|
||||||
|
$rssItem['content'] = trim($html->find('article', 0)->innertext);
|
||||||
|
|
||||||
|
$this->items[] = $rssItem;
|
||||||
|
$this->seen[$url] = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -109,8 +109,7 @@ class GithubIssueBridge extends BridgeAbstract {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function extractIssueComment($issueNbr, $title, $comment){
|
private function extractIssueComment($issueNbr, $title, $comment){
|
||||||
|
$uri = $this->buildGitHubIssueCommentUri($issueNbr, $comment->id);
|
||||||
$uri = $this->buildGitHubIssueCommentUri($issueNbr, $comment->parent->id);
|
|
||||||
|
|
||||||
$author = $comment->find('.author', 0)->plaintext;
|
$author = $comment->find('.author', 0)->plaintext;
|
||||||
|
|
||||||
|
@ -171,9 +170,9 @@ class GithubIssueBridge extends BridgeAbstract {
|
||||||
case 'Project Issues':
|
case 'Project Issues':
|
||||||
foreach($html->find('.js-active-navigation-container .js-navigation-item') as $issue) {
|
foreach($html->find('.js-active-navigation-container .js-navigation-item') as $issue) {
|
||||||
$info = $issue->find('.opened-by', 0);
|
$info = $issue->find('.opened-by', 0);
|
||||||
$issueNbr = substr(
|
|
||||||
trim($info->plaintext), 1, strpos(trim($info->plaintext), ' ')
|
preg_match('/\/([0-9]+)$/', $issue->find('a', 0)->href, $match);
|
||||||
);
|
$issueNbr = $match[1];
|
||||||
|
|
||||||
$item = array();
|
$item = array();
|
||||||
$item['content'] = '';
|
$item['content'] = '';
|
||||||
|
|
246
bridges/ReutersBridge.php
Normal file
246
bridges/ReutersBridge.php
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
<?php
|
||||||
|
class ReutersBridge extends BridgeAbstract
|
||||||
|
{
|
||||||
|
const MAINTAINER = 'hollowleviathan, spraynard, csisoap';
|
||||||
|
const NAME = 'Reuters Bridge';
|
||||||
|
const URI = 'https://reuters.com/';
|
||||||
|
const CACHE_TIMEOUT = 1800; // 30min
|
||||||
|
const DESCRIPTION = 'Returns news from Reuters';
|
||||||
|
|
||||||
|
private $feedName = self::NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wireitem types allowed in the final story output
|
||||||
|
*/
|
||||||
|
const ALLOWED_WIREITEM_TYPES = array(
|
||||||
|
'story',
|
||||||
|
'headlines'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wireitem template types allowed in the final story output
|
||||||
|
*/
|
||||||
|
const ALLOWED_TEMPLATE_TYPES = array(
|
||||||
|
'story'
|
||||||
|
);
|
||||||
|
|
||||||
|
const PARAMETERS = array(
|
||||||
|
array(
|
||||||
|
'feed' => array(
|
||||||
|
'name' => 'News Feed',
|
||||||
|
'type' => 'list',
|
||||||
|
'title' => 'Feeds from Reuters U.S/International edition',
|
||||||
|
'values' => array(
|
||||||
|
'Aerospace and Defense' => 'aerospace',
|
||||||
|
'Business' => 'business',
|
||||||
|
'China' => 'china',
|
||||||
|
'Energy' => 'energy',
|
||||||
|
'Entertainment' => 'chan:8ym8q8dl',
|
||||||
|
'Environment' => 'chan:6u4f0jgs',
|
||||||
|
'Health' => 'chan:8hw7807a',
|
||||||
|
'Lifestyle' => 'life',
|
||||||
|
'Markets' => 'markets',
|
||||||
|
'Politics' => 'politics',
|
||||||
|
'Science' => 'science',
|
||||||
|
'Special Reports' => 'special-reports',
|
||||||
|
'Sports' => 'sports',
|
||||||
|
'Tech' => 'tech',
|
||||||
|
'Top News' => 'home/topnews',
|
||||||
|
'UK' => 'chan:61leiu7j',
|
||||||
|
'USA News' => 'us',
|
||||||
|
'Wire' => 'wire',
|
||||||
|
'World' => 'world',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs an HTTP request to the Reuters API and returns decoded JSON
|
||||||
|
* in the form of an associative array
|
||||||
|
* @param string $feed_uri Parameter string to the Reuters API
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getJson($feed_uri)
|
||||||
|
{
|
||||||
|
$uri = "https://wireapi.reuters.com/v8$feed_uri";
|
||||||
|
$returned_data = getContents($uri);
|
||||||
|
return json_decode($returned_data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes in data from Reuters Wire API and
|
||||||
|
* creates structured data in the form of a list
|
||||||
|
* of story information.
|
||||||
|
* @param array $data JSON collected from the Reuters Wire API
|
||||||
|
*/
|
||||||
|
private function processData($data)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Gets a list of wire items which are groups of templates
|
||||||
|
*/
|
||||||
|
$reuters_allowed_wireitems = array_filter(
|
||||||
|
$data, function ($wireitem) {
|
||||||
|
return in_array(
|
||||||
|
$wireitem['wireitem_type'],
|
||||||
|
self::ALLOWED_WIREITEM_TYPES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gets a list of "Templates", which is data containing a story
|
||||||
|
*/
|
||||||
|
$reuters_wireitem_templates = array_reduce(
|
||||||
|
$reuters_allowed_wireitems,
|
||||||
|
function (array $carry, array $wireitem) {
|
||||||
|
$wireitem_templates = $wireitem['templates'];
|
||||||
|
return array_merge(
|
||||||
|
$carry,
|
||||||
|
array_filter(
|
||||||
|
$wireitem_templates, function (
|
||||||
|
array $template_data
|
||||||
|
) {
|
||||||
|
return in_array(
|
||||||
|
$template_data['type'],
|
||||||
|
self::ALLOWED_TEMPLATE_TYPES
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
array()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $reuters_wireitem_templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getArticle($feed_uri)
|
||||||
|
{
|
||||||
|
// This will make another request to API to get full detail of article and author's name.
|
||||||
|
$rawData = $this->getJson($feed_uri);
|
||||||
|
$reuters_wireitems = $rawData['wireitems'];
|
||||||
|
$processedData = $this->processData($reuters_wireitems);
|
||||||
|
|
||||||
|
$first = reset($processedData);
|
||||||
|
$article_content = $first['story']['body_items'];
|
||||||
|
$authorlist = $first['story']['authors'];
|
||||||
|
$category = $first['story']['channel']['name'];
|
||||||
|
$image_list = $first['story']['images'];
|
||||||
|
$img_placeholder = '';
|
||||||
|
|
||||||
|
foreach($image_list as $image) { // Add more image to article.
|
||||||
|
$image_url = $image['url'];
|
||||||
|
$image_caption = $image['caption'];
|
||||||
|
$img = "<img src=\"$image_url\">";
|
||||||
|
$img_caption = "<figcaption style=\"text-align: center;\"><i>$image_caption</i></figcaption>";
|
||||||
|
$figure = "<figure>$img \t $img_caption</figure>";
|
||||||
|
$img_placeholder = $img_placeholder . $figure;
|
||||||
|
}
|
||||||
|
|
||||||
|
$author = '';
|
||||||
|
$counter = 0;
|
||||||
|
foreach ($authorlist as $data) {
|
||||||
|
//Formatting author's name.
|
||||||
|
$counter++;
|
||||||
|
$name = $data['name'];
|
||||||
|
if ($counter == count($authorlist)) {
|
||||||
|
$author = $author . $name;
|
||||||
|
} else {
|
||||||
|
$author = $author . "$name, ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$description = '';
|
||||||
|
foreach ($article_content as $content) {
|
||||||
|
$data;
|
||||||
|
if(isset($content['content'])) {
|
||||||
|
$data = $content['content'];
|
||||||
|
}
|
||||||
|
switch($content['type']) {
|
||||||
|
case 'paragraph':
|
||||||
|
$description = $description . "<p>$data</p>";
|
||||||
|
break;
|
||||||
|
case 'heading':
|
||||||
|
$description = $description . "<h3>$data</h3>";
|
||||||
|
break;
|
||||||
|
case 'infographics':
|
||||||
|
$description = $description . "<img src=\"$data\">";
|
||||||
|
break;
|
||||||
|
case 'inline_items':
|
||||||
|
$item_list = $content['items'];
|
||||||
|
$description = $description . '<p>';
|
||||||
|
foreach ($item_list as $item) {
|
||||||
|
if($item['type'] == 'text') {
|
||||||
|
$description = $description . $item['content'];
|
||||||
|
} else {
|
||||||
|
$description = $description . $item['symbol'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$description = $description . '</p>';
|
||||||
|
break;
|
||||||
|
case 'p_table':
|
||||||
|
$description = $description . $content['content'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content_detail = array(
|
||||||
|
'content' => $description,
|
||||||
|
'author' => $author,
|
||||||
|
'category' => $category,
|
||||||
|
'images' => $img_placeholder,
|
||||||
|
);
|
||||||
|
return $content_detail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return $this->feedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collectData()
|
||||||
|
{
|
||||||
|
$reuters_feed_name = $this->getInput('feed');
|
||||||
|
|
||||||
|
if(strpos($reuters_feed_name, 'chan:') !== false) {
|
||||||
|
// Now checking whether that feed has unique ID or not.
|
||||||
|
$feed_uri = "/feed/rapp/us/wirefeed/$reuters_feed_name";
|
||||||
|
} else {
|
||||||
|
$feed_uri = "/feed/rapp/us/tabbar/feeds/$reuters_feed_name";
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = $this->getJson($feed_uri);
|
||||||
|
|
||||||
|
$reuters_wireitems = $data['wireitems'];
|
||||||
|
$this->feedName = $data['wire_name'] . ' | Reuters';
|
||||||
|
$processedData = $this->processData($reuters_wireitems);
|
||||||
|
|
||||||
|
// Merge all articles from Editor's Highlight section into existing array of templates.
|
||||||
|
$top_section = reset($reuters_wireitems);
|
||||||
|
if ($top_section['wireitem_type'] == 'headlines') {
|
||||||
|
$top_articles = $top_section['templates'][1]['headlines'];
|
||||||
|
$processedData = array_merge($top_articles, $processedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($processedData as $story) {
|
||||||
|
$item['uid'] = $story['story']['usn'];
|
||||||
|
$article_uri = $story['template_action']['api_path'];
|
||||||
|
$content_detail = $this->getArticle($article_uri);
|
||||||
|
$description = $content_detail['content'];
|
||||||
|
$author = $content_detail['author'];
|
||||||
|
$images = $content_detail['images'];
|
||||||
|
$item['categories'] = array($content_detail['category']);
|
||||||
|
$item['author'] = $author;
|
||||||
|
if (!(bool) $description) {
|
||||||
|
$description = $story['story']['lede']; // Just in case the content doesn't have anything.
|
||||||
|
} else {
|
||||||
|
$item['content'] = "$description $images";
|
||||||
|
}
|
||||||
|
|
||||||
|
$item['title'] = $story['story']['hed'];
|
||||||
|
$item['timestamp'] = $story['story']['updated_at'];
|
||||||
|
$item['uri'] = $story['template_action']['url'];
|
||||||
|
$this->items[] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ class ZoneTelechargementBridge extends BridgeAbstract {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const NAME = 'Zone Telechargement';
|
const NAME = 'Zone Telechargement';
|
||||||
const URI = 'https://www.zt-za.com/';
|
const URI = 'https://www.zt-za.net/';
|
||||||
const DESCRIPTION = 'Suivi de série sur Zone Telechargement';
|
const DESCRIPTION = 'Suivi de série sur Zone Telechargement';
|
||||||
const MAINTAINER = 'sysadminstory';
|
const MAINTAINER = 'sysadminstory';
|
||||||
const PARAMETERS = array(
|
const PARAMETERS = array(
|
||||||
|
@ -34,17 +34,17 @@ class ZoneTelechargementBridge extends BridgeAbstract {
|
||||||
);
|
);
|
||||||
|
|
||||||
// This is an URL that is not protected by robot protection for Direct Download
|
// This is an URL that is not protected by robot protection for Direct Download
|
||||||
const UNPROTECED_URI = 'https://www.zone-annuaire.com/';
|
const UNPROTECTED_URI = 'https://www.zone-telechargement.net/';
|
||||||
|
|
||||||
// This is an URL that is not protected by robot protection for Streaming Links
|
// This is an URL that is not protected by robot protection for Streaming Links
|
||||||
const UNPROTECED_URI_STREAMING = 'https://zone-telechargement.stream/';
|
const UNPROTECTED_URI_STREAMING = 'https://zone-telechargement.stream/';
|
||||||
|
|
||||||
public function getIcon() {
|
public function getIcon() {
|
||||||
return self::UNPROTECED_URI . '/templates/Default/images/favicon.ico';
|
return self::UNPROTECTED_URI . '/templates/Default/images/favicon.ico';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function collectData(){
|
public function collectData(){
|
||||||
$html = getSimpleHTMLDOM(self::UNPROTECED_URI . $this->getInput('url'))
|
$html = getSimpleHTMLDOM(self::UNPROTECTED_URI . $this->getInput('url'))
|
||||||
or returnServerError('Could not request Zone Telechargement.');
|
or returnServerError('Could not request Zone Telechargement.');
|
||||||
|
|
||||||
$filter = $this->getInput('filter');
|
$filter = $this->getInput('filter');
|
||||||
|
@ -79,7 +79,7 @@ class ZoneTelechargementBridge extends BridgeAbstract {
|
||||||
// Handle the Streaming links
|
// Handle the Streaming links
|
||||||
if($filter == 'both' || $filter == 'streaming') {
|
if($filter == 'both' || $filter == 'streaming') {
|
||||||
// Get the post content, on the dedicated streaming website
|
// Get the post content, on the dedicated streaming website
|
||||||
$htmlstreaming = getSimpleHTMLDOM(self::UNPROTECED_URI_STREAMING . $this->getInput('url'))
|
$htmlstreaming = getSimpleHTMLDOM(self::UNPROTECTED_URI_STREAMING . $this->getInput('url'))
|
||||||
or returnServerError('Could not request Zone Telechargement.');
|
or returnServerError('Could not request Zone Telechargement.');
|
||||||
// Get the HTML element containing all the links
|
// Get the HTML element containing all the links
|
||||||
$streaminglinkshtml = $htmlstreaming->find('p[style=background-color: #FECC00;]', 1)->parent()->next_sibling();
|
$streaminglinkshtml = $htmlstreaming->find('p[style=background-color: #FECC00;]', 1)->parent()->next_sibling();
|
||||||
|
|
|
@ -347,11 +347,13 @@ This bridge is not fetching its content through a secure connection</div>';
|
||||||
CARD;
|
CARD;
|
||||||
|
|
||||||
// If we don't have any parameter for the bridge, we print a generic form to load it.
|
// If we don't have any parameter for the bridge, we print a generic form to load it.
|
||||||
if(count($parameters) === 0
|
if (count($parameters) === 0) {
|
||||||
|| count($parameters) === 1 && array_key_exists('global', $parameters)) {
|
|
||||||
|
|
||||||
$card .= self::getForm($bridgeName, $formats, $isActive, $isHttps);
|
$card .= self::getForm($bridgeName, $formats, $isActive, $isHttps);
|
||||||
|
|
||||||
|
// Display form with cache timeout and/or noproxy options (if enabled) when bridge has no parameters
|
||||||
|
} else if (count($parameters) === 1 && array_key_exists('global', $parameters)) {
|
||||||
|
$card .= self::getForm($bridgeName, $formats, $isActive, $isHttps, '', $parameters['global']);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
foreach($parameters as $parameterName => $parameter) {
|
foreach($parameters as $parameterName => $parameter) {
|
||||||
|
|
Loading…
Reference in a new issue