mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-08-25 17:31:25 +02:00
Compare commits
18 Commits
2018-04-20
...
2018-06-10
Author | SHA1 | Date | |
---|---|---|---|
|
4c5013bc82 | ||
|
7dc09db9ca | ||
|
d92da8f0f7 | ||
|
064ba456e8 | ||
|
8ac8e08abf | ||
|
c4f32c31a8 | ||
|
4369e077c2 | ||
|
1045850043 | ||
|
2d8f4dc3c5 | ||
|
779b638fb4 | ||
|
3ca59392c2 | ||
|
9b34b68180 | ||
|
79ebdc4b39 | ||
|
8770c87389 | ||
|
c1e3352218 | ||
|
00570ce1b4 | ||
|
df33dcff4e | ||
|
e60b5ab193 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -227,6 +227,7 @@ pip-log.txt
|
||||
/cache
|
||||
/whitelist.txt
|
||||
DEBUG
|
||||
config.ini.php
|
||||
|
||||
######################
|
||||
## VisualStudioCode ##
|
||||
|
25
bridges/ChristianDailyReporterBridge.php
Normal file
25
bridges/ChristianDailyReporterBridge.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -148,7 +148,6 @@ class DealabsBridge extends BridgeAbstract {
|
||||
'cept-thread-image-link',
|
||||
'imgFrame',
|
||||
'imgFrame--noBorder',
|
||||
'box--all-i',
|
||||
'thread-listImgCell',
|
||||
)
|
||||
);
|
||||
@@ -179,6 +178,7 @@ class DealabsBridge extends BridgeAbstract {
|
||||
' ', /* Notice this is a space! */
|
||||
array(
|
||||
'cept-description-container',
|
||||
'userHtml',
|
||||
'overflow--wrap-break',
|
||||
'size--all-s',
|
||||
'size--fromW3-m',
|
||||
@@ -302,12 +302,18 @@ class DealabsBridge extends BridgeAbstract {
|
||||
private function getReduction($deal)
|
||||
{
|
||||
if($deal->find('span[class*=mute--text text--lineThrough]', 0) != null) {
|
||||
$discountHtml = $deal->find('span[class=space--ml-1 size--all-l size--fromW3-xl]', 0);
|
||||
if($discountHtml != null) {
|
||||
$discount = $discountHtml->plaintext;
|
||||
} else {
|
||||
$discount = '';
|
||||
}
|
||||
return '<div>Réduction : <span style="text-decoration: line-through;">'
|
||||
. $deal->find(
|
||||
'span[class*=mute--text text--lineThrough]', 0
|
||||
)->plaintext
|
||||
. '</span> '
|
||||
. $deal->find('span[class=space--ml-1 size--all-l size--fromW3-xl]', 0)->plaintext
|
||||
. $discount
|
||||
. '</div>';
|
||||
} else {
|
||||
return '';
|
||||
@@ -412,6 +418,7 @@ class DealabsBridge extends BridgeAbstract {
|
||||
'November',
|
||||
'December'
|
||||
);
|
||||
$string = str_replace('Actualisé ', '', $string);
|
||||
$date_str = trim(str_replace($month_fr, $month_en, $string));
|
||||
|
||||
if(!preg_match('/[0-9]{4}/', $string)) {
|
||||
|
142
bridges/ETTVBridge.php
Normal file
142
bridges/ETTVBridge.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
class ETTVBridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = "GregThib";
|
||||
const NAME = 'ETTV';
|
||||
const URI = 'https://www.ettv.tv/';
|
||||
const DESCRIPTION = 'Returns list of 20 latest torrents for a specific search.';
|
||||
const CACHE_TIMEOUT = 14400; // 4 hours
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'query' => array(
|
||||
'name' => 'Keywords',
|
||||
'required' => true
|
||||
),
|
||||
'cat' => array(
|
||||
'type' => 'list',
|
||||
'name' => 'Category',
|
||||
'values' => array(
|
||||
'(ALL TYPES)' => '0',
|
||||
'Anime: Movies' => '73',
|
||||
'Anime: Dubbed/Subbed' => '74',
|
||||
'Anime: Others' => '75',
|
||||
'Books: Ebooks' => '53',
|
||||
'Books: Magazines' => '54',
|
||||
'Books: Comics' => '55',
|
||||
'Books: Audio' => '56',
|
||||
'Books: Others' => '68',
|
||||
'Games: Windows' => '57',
|
||||
'Games: Android' => '58',
|
||||
'Games: Others' => '71',
|
||||
'Movies: HD 1080p' => '1',
|
||||
'Movies: HD 720p' => '2',
|
||||
'Movies: UltraHD/4K' => '3',
|
||||
'Movies: XviD' => '42',
|
||||
'Movies: X264/H264' => '47',
|
||||
'Movies: 3D' => '49',
|
||||
'Movies: Dubs/Dual Audio' => '51',
|
||||
'Movies: CAM/TS' => '65',
|
||||
'Movies: BluRay Disc/Remux' => '66',
|
||||
'Movies: DVDR' => '67',
|
||||
'Movies: HEVC/x265' => '76',
|
||||
'Music: MP3' => '59',
|
||||
'Music: FLAC' => '60',
|
||||
'Music: Music Videos' => '61',
|
||||
'Music: Others' => '69',
|
||||
'Software: Windows' => '62',
|
||||
'Software: Android' => '63',
|
||||
'Software: Mac' => '64',
|
||||
'Software: Others' => '70',
|
||||
'TV: HD/X264/H264' => '41',
|
||||
'TV: SD/X264/H264' => '5',
|
||||
'TV: TV Packs' => '7',
|
||||
'TV: SD/XVID' => '50',
|
||||
'TV: Sport' => '72',
|
||||
'TV: HEVC/x265' => '77',
|
||||
'Unsorted: Unsorted' => '78'
|
||||
),
|
||||
'defaultValue' => '(ALL TYPES)'
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'list',
|
||||
'name' => 'Status',
|
||||
'values' => array(
|
||||
'Active Transfers' => '0',
|
||||
'Included Dead' => '1',
|
||||
'Only Dead' => '2'
|
||||
),
|
||||
'defaultValue' => 'Included Dead'
|
||||
),
|
||||
'lang' => array(
|
||||
'type' => 'list',
|
||||
'name' => 'Lang',
|
||||
'values' => array(
|
||||
'(ALL)' => '0',
|
||||
'Arabic' => '17',
|
||||
'Chinese ' => '10',
|
||||
'Danish' => '13',
|
||||
'Dutch' => '11',
|
||||
'English' => '1',
|
||||
'Finnish' => '18',
|
||||
'French' => '2',
|
||||
'German' => '3',
|
||||
'Greek' => '15',
|
||||
'Hindi' => '8',
|
||||
'Italian' => '4',
|
||||
'Japanese' => '5',
|
||||
'Korean' => '9',
|
||||
'Polish' => '14',
|
||||
'Russian' => '7',
|
||||
'Spanish' => '6',
|
||||
'Turkish' => '16'
|
||||
),
|
||||
'defaultValue' => '(ALL)'
|
||||
)
|
||||
));
|
||||
|
||||
public function collectData(){
|
||||
// No control on inputs, because all have defaultValue set
|
||||
$query_str = 'torrents-search.php';
|
||||
$query_str .= '?search=' . urlencode('+'.str_replace(' ', ' +', $this->getInput('query')));
|
||||
$query_str .= '&cat=' . $this->getInput('cat');
|
||||
$query_str .= 'incldead&=' . $this->getInput('status');
|
||||
$query_str .= '&lang=' . $this->getInput('lang');
|
||||
$query_str .= '&sort=id&order=desc';
|
||||
|
||||
// Get results page
|
||||
$html = getSimpleHTMLDOM(self::URI . $query_str)
|
||||
or returnServerError('Could not request ' . $this->getName());
|
||||
|
||||
// Loop on each entry
|
||||
foreach($html->find('table.table tr') as $element) {
|
||||
if($element->parent->tag == 'thead') continue;
|
||||
$entry = $element->find('td', 1)->find('a', 0);
|
||||
|
||||
// retrieve result page to get more details
|
||||
$link = rtrim(self::URI, "/") . $entry->href;
|
||||
$page = getSimpleHTMLDOM($link)
|
||||
or returnServerError('Could not request page ' . $link);
|
||||
|
||||
// get details & download links
|
||||
$details = $page->find('fieldset.download table', 0); // WHAT?? It should be the second one…
|
||||
$dllinks = $page->find('div#downloadbox table', 0);
|
||||
|
||||
// fill item
|
||||
$item = array();
|
||||
$item['author'] = $details->children(6)->children(1)->plaintext;
|
||||
$item['title'] = $entry->title;
|
||||
$item['uri'] = $dllinks->children(0)->children(0)->children(0)->href;
|
||||
$item['timestamp'] = strtotime($details->children(7)->children(1)->plaintext);
|
||||
$item['content'] = '';
|
||||
$item['content'] .= '<br/><b>Name: </b>' . $details->children(0)->children(1)->innertext;
|
||||
$item['content'] .= '<br/><b>Lang: </b>' . $details->children(3)->children(1)->innertext;
|
||||
$item['content'] .= '<br/><b>Size: </b>' . $details->children(4)->children(1)->innertext;
|
||||
$item['content'] .= '<br/><b>Hash: </b>' . $details->children(5)->children(1)->innertext;
|
||||
foreach($dllinks->children(0)->children(1)->find('a') as $dl) {
|
||||
$item['content'] .= '<br/>' . $dl->outertext;
|
||||
}
|
||||
$item['content'] .= '<br/><br/>' . $details->children(1)->children(0)->innertext;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
146
bridges/ElloBridge.php
Normal file
146
bridges/ElloBridge.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
class ElloBridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = 'teromene';
|
||||
const NAME = 'Ello Bridge';
|
||||
const URI = 'https://ello.co/';
|
||||
const CACHE_TIMEOUT = 4800; //2hours
|
||||
const DESCRIPTION = 'Returns the newest posts for Ello';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'By User' => array(
|
||||
'u' => array(
|
||||
'name' => 'Username',
|
||||
'required' => true,
|
||||
'title' => 'Username'
|
||||
)
|
||||
),
|
||||
'Search' => array(
|
||||
's' => array(
|
||||
'name' => 'Search',
|
||||
'required' => true,
|
||||
'title' => 'Search'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function collectData() {
|
||||
|
||||
$header = array(
|
||||
'Authorization: Bearer ' . $this->getAPIKey()
|
||||
);
|
||||
|
||||
if(!empty($this->getInput('u'))) {
|
||||
$postData = getContents(self::URI . 'api/v2/users/~' . urlencode($this->getInput('u')) . '/posts', $header) or
|
||||
returnServerError('Unable to query Ello API.');
|
||||
} else {
|
||||
$postData = getContents(self::URI . 'api/v2/posts?terms=' . urlencode($this->getInput('s')), $header) or
|
||||
returnServerError('Unable to query Ello API.');
|
||||
}
|
||||
|
||||
$postData = json_decode($postData);
|
||||
$count = 0;
|
||||
foreach($postData->posts as $post) {
|
||||
|
||||
$item = array();
|
||||
$item['author'] = $this->getUsername($post, $postData);
|
||||
$item['timestamp'] = strtotime($post->created_at);
|
||||
$item['title'] = $this->findText($post->summary);
|
||||
$item['content'] = $this->getPostContent($post->body);
|
||||
$item['enclosures'] = $this->getEnclosures($post, $postData);
|
||||
$content = $post->body;
|
||||
|
||||
$this->items[] = $item;
|
||||
$count += 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function findText($path) {
|
||||
|
||||
foreach($path as $summaryElement) {
|
||||
|
||||
if($summaryElement->kind == 'text') {
|
||||
return $summaryElement->data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
public function getPostContent($path) {
|
||||
|
||||
$content = '';
|
||||
foreach($path as $summaryElement) {
|
||||
|
||||
if($summaryElement->kind == 'text') {
|
||||
$content .= $summaryElement->data;
|
||||
} elseif ($summaryElement->kind == 'image') {
|
||||
$alt = '';
|
||||
if(property_exists($summaryElement->data, 'alt')) {
|
||||
$alt = $summaryElement->data->alt;
|
||||
}
|
||||
$content .= '<img src="' . $summaryElement->data->url . '" alt="' . $alt . '" />';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
public function getEnclosures($post, $postData) {
|
||||
|
||||
$assets = [];
|
||||
foreach($post->links->assets as $asset) {
|
||||
foreach($postData->linked->assets as $assetLink) {
|
||||
if($asset == $assetLink->id) {
|
||||
$assets[] = $assetLink->attachment->original->url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $assets;
|
||||
|
||||
}
|
||||
|
||||
public function getUsername($post, $postData) {
|
||||
|
||||
foreach($postData->linked->users as $user) {
|
||||
if($user->id == $post->links->author->id) {
|
||||
return $user->username;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getAPIKey() {
|
||||
$cache = Cache::create('FileCache');
|
||||
$cache->setPath(CACHE_DIR);
|
||||
$cache->setParameters(['key']);
|
||||
$key = $cache->loadData();
|
||||
|
||||
if($key == null) {
|
||||
$keyInfo = getContents(self::URI . 'api/webapp-token') or
|
||||
returnServerError('Unable to get token.');
|
||||
$key = json_decode($keyInfo)->token->access_token;
|
||||
$cache->saveData($key);
|
||||
}
|
||||
|
||||
return $key;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
return $this->getInput('u') . ' - Ello Bridge';
|
||||
}
|
||||
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
}
|
@@ -164,6 +164,12 @@ EOD;
|
||||
}
|
||||
|
||||
//No captcha? We can carry on retrieving page contents :)
|
||||
//First, we check wether the page is public or not
|
||||
$loginForm = $html->find('._585r', 0);
|
||||
if($loginForm != null) {
|
||||
returnServerError('You must be logged in to view this page. This is not supported by RSS-Bridge.');
|
||||
}
|
||||
|
||||
$element = $html
|
||||
->find('#pagelet_timeline_main_column')[0]
|
||||
->children(0)
|
||||
|
@@ -11,60 +11,38 @@ class InstagramBridge extends BridgeAbstract {
|
||||
'u' => array(
|
||||
'name' => 'username',
|
||||
'required' => true
|
||||
),
|
||||
'media_type' => array(
|
||||
'name' => 'Media type',
|
||||
'type' => 'list',
|
||||
'required' => false,
|
||||
'values' => array(
|
||||
'Both' => 'all',
|
||||
'Video' => 'video',
|
||||
'Picture' => 'picture'
|
||||
),
|
||||
'defaultValue' => 'all'
|
||||
)
|
||||
),
|
||||
array(
|
||||
'h' => array(
|
||||
'name' => 'hashtag',
|
||||
'required' => true
|
||||
),
|
||||
)
|
||||
),
|
||||
'global' => array(
|
||||
'media_type' => array(
|
||||
'name' => 'Media type',
|
||||
'type' => 'list',
|
||||
'required' => false,
|
||||
'values' => array(
|
||||
'Both' => 'all',
|
||||
'All' => 'all',
|
||||
'Story' => 'story',
|
||||
'Video' => 'video',
|
||||
'Picture' => 'picture'
|
||||
'Picture' => 'picture',
|
||||
),
|
||||
'defaultValue' => 'all'
|
||||
)
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
public function collectData(){
|
||||
$html = getSimpleHTMLDOM($this->getURI())
|
||||
or returnServerError('Could not request Instagram.');
|
||||
|
||||
$innertext = null;
|
||||
|
||||
foreach($html->find('script') as $script) {
|
||||
if('' === $script->innertext) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pos = strpos(trim($script->innertext), 'window._sharedData');
|
||||
if(0 !== $pos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$innertext = $script->innertext;
|
||||
break;
|
||||
if(!is_null($this->getInput('h')) && $this->getInput('media_type') == 'story') {
|
||||
returnClientError('Stories are not supported for hashtags!');
|
||||
}
|
||||
|
||||
$json = trim(substr($innertext, $pos + 18), ' =;');
|
||||
$data = json_decode($json);
|
||||
$data = $this->getInstagramJSON($this->getURI());
|
||||
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
$userMedia = $data->entry_data->ProfilePage[0]->graphql->user->edge_owner_to_timeline_media->edges;
|
||||
@@ -74,32 +52,83 @@ class InstagramBridge extends BridgeAbstract {
|
||||
|
||||
foreach($userMedia as $media) {
|
||||
$media = $media->node;
|
||||
// Check media type
|
||||
switch($this->getInput('media_type')) {
|
||||
case 'all': break;
|
||||
case 'video':
|
||||
if($media->is_video === false) continue 2;
|
||||
break;
|
||||
case 'picture':
|
||||
if($media->is_video === true) continue 2;
|
||||
break;
|
||||
default: break;
|
||||
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
switch($this->getInput('media_type')) {
|
||||
case 'all': break;
|
||||
case 'video':
|
||||
if($media->__typename != 'GraphVideo') continue 2;
|
||||
break;
|
||||
case 'picture':
|
||||
if($media->__typename != 'GraphImage') continue 2;
|
||||
break;
|
||||
case 'story':
|
||||
if($media->__typename != 'GraphSidecar') continue 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
} else {
|
||||
if($this->getInput('media_type') == 'video' && !$media->is_video) continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item['uri'] = self::URI . 'p/' . $media->shortcode . '/';
|
||||
$item['content'] = '<img src="' . htmlentities($media->display_url) . '" />';
|
||||
|
||||
if (isset($media->edge_media_to_caption->edges[0]->node->text)) {
|
||||
$item['title'] = $media->edge_media_to_caption->edges[0]->node->text;
|
||||
} else {
|
||||
$item['title'] = basename($media->display_url);
|
||||
}
|
||||
|
||||
if(!is_null($this->getInput('u')) && $media->__typename == 'GraphSidecar') {
|
||||
$data = $this->getInstagramStory($item['uri']);
|
||||
$item['content'] = $data[0];
|
||||
$item['enclosures'] = $data[1];
|
||||
} else {
|
||||
$item['content'] = '<img src="' . htmlentities($media->display_url) . '" alt="'. $item["title"] . '" />';
|
||||
$item['enclosures'] = array($media->display_url);
|
||||
}
|
||||
|
||||
$item['timestamp'] = $media->taken_at_timestamp;
|
||||
$item['enclosures'] = array($media->display_url);
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getInstagramStory($uri) {
|
||||
|
||||
$data = $this->getInstagramJSON($uri);
|
||||
$mediaInfo = $data->entry_data->PostPage[0]->graphql->shortcode_media;
|
||||
|
||||
//Process the first element, that isn't in the node graph
|
||||
$caption = $mediaInfo->edge_media_to_caption->edges[0]->node->text;
|
||||
|
||||
$enclosures = [$mediaInfo->display_url];
|
||||
$content = '<img src="' . htmlentities($mediaInfo->display_url) . '" alt="'. $caption . '" />';
|
||||
|
||||
foreach($mediaInfo->edge_sidecar_to_children->edges as $media) {
|
||||
|
||||
$content .= '<img src="' . htmlentities($media->node->display_url) . '" alt="'. $caption . '" />';
|
||||
$enclosures[] = $media->node->display_url;
|
||||
|
||||
}
|
||||
|
||||
return [$content, $enclosures];
|
||||
|
||||
}
|
||||
|
||||
protected function getInstagramJSON($uri) {
|
||||
|
||||
$html = getContents($uri)
|
||||
or returnServerError('Could not request Instagram.');
|
||||
$scriptRegex = '/window\._sharedData = (.*);<\/script>/';
|
||||
|
||||
preg_match($scriptRegex, $html, $matches, PREG_OFFSET_CAPTURE, 0);
|
||||
|
||||
return json_decode($matches[1][0]);
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
return $this->getInput('u') . ' - Instagram Bridge';
|
||||
|
@@ -102,10 +102,20 @@ class VkBridge extends BridgeAbstract
|
||||
// looking for article
|
||||
$article = $post->find("a.article_snippet", 0);
|
||||
if (is_object($article)) {
|
||||
$article_title = $article->find("div.article_snippet__title", 0)->innertext;
|
||||
$article_author = $article->find("div.article_snippet__author", 0)->innertext;
|
||||
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 = $article->find($article_title_selector, 0)->innertext;
|
||||
$article_author = $article->find($article_author_selector, 0)->innertext;
|
||||
$article_link = self::URI . ltrim($article->getAttribute('href'), '/');
|
||||
$article_img_element_style = $article->find("div.article_snippet__image", 0)->getAttribute('style');
|
||||
$article_img_element_style = $article->find($article_thumb_selector, 0)->getAttribute('style');
|
||||
preg_match('/background-image: url\((.*)\)/', $article_img_element_style, $matches);
|
||||
if (count($matches) > 0) {
|
||||
$content_suffix .= "<br><img src='" . $matches[1] . "'>";
|
||||
@@ -123,6 +133,16 @@ class VkBridge extends BridgeAbstract
|
||||
$video->outertext = '';
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (count($temp) > 1) $video_title = $temp[1];
|
||||
$video_link = self::URI . ltrim( $a->getAttribute('href'), '/' );
|
||||
$content_suffix .= "<br>Video: <a href='$video_link'>$video_title</a>";
|
||||
$a->outertext = '';
|
||||
}
|
||||
|
||||
// get all photos
|
||||
foreach($post->find('div.wall_text > a.page_post_thumb_wrap') as $a) {
|
||||
$result = $this->getPhoto($a);
|
||||
@@ -179,6 +199,16 @@ class VkBridge extends BridgeAbstract
|
||||
$div->outertext = '';
|
||||
}
|
||||
|
||||
// get polls
|
||||
foreach($post->find('div.page_media_poll_wrap') as $div) {
|
||||
$poll_title = $div->find('.page_media_poll_title', 0)->innertext;
|
||||
$content_suffix .= "<br>Poll: $poll_title";
|
||||
foreach($div->find('div.page_poll_text') as $poll_stat_title) {
|
||||
$content_suffix .= "<br>- " . $poll_stat_title->innertext;
|
||||
}
|
||||
$div->outertext = '';
|
||||
}
|
||||
|
||||
// get sign
|
||||
$post_author = $pageName;
|
||||
foreach($post->find('a.wall_signed_by') as $a) {
|
||||
@@ -247,7 +277,13 @@ class VkBridge extends BridgeAbstract
|
||||
$original = '';
|
||||
foreach(array('y_', 'z_', 'w_') as $key) {
|
||||
if (!isset($data['temp'][$key])) continue;
|
||||
$original = $data['temp']['base'] . $data['temp'][$key][0] . ".jpg";
|
||||
if (!isset($data['temp'][$key][0])) continue;
|
||||
if (substr($data['temp'][$key][0], 0, 4) == "http") {
|
||||
$base = "";
|
||||
} else {
|
||||
$base = $data['temp']['base'];
|
||||
}
|
||||
$original = $base . $data['temp'][$key][0] . ".jpg";
|
||||
}
|
||||
|
||||
if ($original) {
|
||||
|
@@ -1,16 +1,12 @@
|
||||
<?php
|
||||
class WorldOfTanksBridge extends BridgeAbstract {
|
||||
class WorldOfTanksBridge extends FeedExpander {
|
||||
|
||||
const MAINTAINER = 'mitsukarenai';
|
||||
const MAINTAINER = 'Riduidel';
|
||||
const NAME = 'World of Tanks';
|
||||
const URI = 'http://worldoftanks.eu/';
|
||||
const DESCRIPTION = 'News about the tank slaughter game.';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'category' => array(
|
||||
// TODO: should be a list
|
||||
'name' => 'nom de la catégorie'
|
||||
),
|
||||
'lang' => array(
|
||||
'name' => 'Langue',
|
||||
'type' => 'list',
|
||||
@@ -26,47 +22,31 @@ class WorldOfTanksBridge extends BridgeAbstract {
|
||||
)
|
||||
));
|
||||
|
||||
private $title = '';
|
||||
public function collectData() {
|
||||
$this->collectExpandableDatas(sprintf('https://worldoftanks.eu/%s/rss/news/', $this->getInput('lang')));
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('lang'))) {
|
||||
$lang = $this->getInput('lang');
|
||||
$uri = self::URI . $lang . '/news/';
|
||||
if(!empty($this->getInput('category'))) {
|
||||
$uri .= 'pc-browser/' . $this->getInput('category') . '/';
|
||||
}
|
||||
return $uri;
|
||||
protected function parseItem($newsItem){
|
||||
$item = parent::parseItem($newsItem);
|
||||
$item['content'] = $this->loadFullArticle($item['uri']);
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the full article and returns the contents
|
||||
* @param $uri The article URI
|
||||
* @return The article content
|
||||
*/
|
||||
private function loadFullArticle($uri){
|
||||
$html = getSimpleHTMLDOMCached($uri);
|
||||
|
||||
$content = $html->find('article', 0);
|
||||
|
||||
// Remove the scripts, please
|
||||
foreach($content->find('script') as $script) {
|
||||
$script->outertext = '';
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return $this->title ?: parent::getName();
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
$html = getSimpleHTMLDOM($this->getURI())
|
||||
or returnServerError('Could not request ' . $this->getURI());
|
||||
debugMessage("loaded HTML from " . $this->getURI());
|
||||
// customize name
|
||||
$this->title = $html->find('title', 0)->innertext;
|
||||
foreach($html->find('.b-imgblock_ico') as $infoLink) {
|
||||
$this->parseLine($infoLink);
|
||||
}
|
||||
}
|
||||
|
||||
private function parseLine($infoLink){
|
||||
$item = array();
|
||||
$item['uri'] = self::URI . $infoLink->href;
|
||||
// now load that uri from cache
|
||||
debugMessage('loading page ' . $item['uri']);
|
||||
$articlePage = getSimpleHTMLDOMCached($item['uri']);
|
||||
$content = $articlePage->find('.l-content', 0);
|
||||
defaultLinkTo($content, self::URI);
|
||||
$item['title'] = $content->find('h1', 0)->innertext;
|
||||
$item['content'] = $content->find('.b-content', 0)->innertext;
|
||||
$item['timestamp'] = $content->find('.b-statistic_time', 0)->getAttribute("data-timestamp");
|
||||
$this->items[] = $item;
|
||||
return $content->innertext;
|
||||
}
|
||||
}
|
||||
|
@@ -105,7 +105,10 @@ class YGGTorrentBridge extends BridgeAbstract {
|
||||
or returnServerError("Unable to query Yggtorrent !");
|
||||
|
||||
$count = 0;
|
||||
foreach($html->find(".results", 0)->find("tr") as $row) {
|
||||
$results = $html->find(".results", 0);
|
||||
if(!$results) return;
|
||||
|
||||
foreach($results->find("tr") as $row) {
|
||||
$count++;
|
||||
if($count == 1) continue;
|
||||
if($count == 12) break;
|
||||
@@ -118,6 +121,7 @@ class YGGTorrentBridge extends BridgeAbstract {
|
||||
$item["seeders"] = $row->find("td", 7)->plaintext;
|
||||
$item["leechers"] = $row->find("td", 8)->plaintext;
|
||||
$item["size"] = $row->find("td", 5)->plaintext;
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
@@ -127,9 +131,10 @@ class YGGTorrentBridge extends BridgeAbstract {
|
||||
|
||||
//For weird reason, the link we get can be invalid, we fix it.
|
||||
$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);
|
||||
|
@@ -8,7 +8,9 @@ class FileCache implements CacheInterface {
|
||||
protected $param;
|
||||
|
||||
public function loadData(){
|
||||
return unserialize(file_get_contents($this->getCacheFile()));
|
||||
if(file_exists($this->getCacheFile())) {
|
||||
return unserialize(file_get_contents($this->getCacheFile()));
|
||||
}
|
||||
}
|
||||
|
||||
public function saveData($datas){
|
||||
|
27
config.default.ini.php
Normal file
27
config.default.ini.php
Normal file
@@ -0,0 +1,27 @@
|
||||
; <?php exit; ?> DO NOT REMOVE THIS LINE
|
||||
|
||||
; This file contains the default settings for RSS-Bridge. Do not change this
|
||||
; file, it will be replaced on the next update of RSS-Bridge! You can specify
|
||||
; your own configuration in 'config.ini.php' (copy this file).
|
||||
|
||||
[cache]
|
||||
|
||||
; Allow users to specify custom timeout for specific requests.
|
||||
; true = enabled
|
||||
; false = disabled (default)
|
||||
custom_timeout = false
|
||||
|
||||
[proxy]
|
||||
|
||||
; Sets the proxy url (i.e. "tcp://192.168.0.0:32")
|
||||
; "" = Proxy disabled (default)
|
||||
url = ""
|
||||
|
||||
; Sets the proxy name that is shown on the bridge instead of the proxy url.
|
||||
; "" = Show proxy url
|
||||
name = "Hidden proxy name"
|
||||
|
||||
; Allow users to disable proxy usage for specific requests.
|
||||
; true = enabled
|
||||
; false = disabled (default)
|
||||
by_bridge = false
|
@@ -15,8 +15,8 @@ class AtomFormat extends FormatAbstract{
|
||||
|
||||
$extraInfos = $this->getExtraInfos();
|
||||
$title = $this->xml_encode($extraInfos['name']);
|
||||
$uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/sebsauvage/rss-bridge';
|
||||
$icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
|
||||
$uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/RSS-Bridge/rss-bridge';
|
||||
$icon = $this->xml_encode($uri .'/favicon.ico');
|
||||
$uri = $this->xml_encode($uri);
|
||||
|
||||
$entries = '';
|
||||
|
@@ -18,10 +18,10 @@ class MrssFormat extends FormatAbstract {
|
||||
if(!empty($extraInfos['uri'])) {
|
||||
$uri = $this->xml_encode($extraInfos['uri']);
|
||||
} else {
|
||||
$uri = 'https://github.com/sebsauvage/rss-bridge';
|
||||
$uri = 'https://github.com/RSS-Bridge/rss-bridge';
|
||||
}
|
||||
|
||||
$icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
|
||||
$icon = $this->xml_encode($uri .'/favicon.ico');
|
||||
|
||||
$items = '';
|
||||
foreach($this->getItems() as $item) {
|
||||
|
50
index.php
50
index.php
@@ -10,19 +10,47 @@ TODO :
|
||||
- implement header('X-Cached-Version: '.date(DATE_ATOM, filemtime($cachefile)));
|
||||
*/
|
||||
|
||||
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(file_exists('config.ini.php')) {
|
||||
// Replace default configuration with custom settings
|
||||
foreach(parse_ini_file('config.ini.php', true, INI_SCANNER_TYPED) as $header => $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');
|
||||
|
||||
//define('PROXY_URL', 'tcp://192.168.0.0:28');
|
||||
// Set to true if you allow users to disable proxy usage for specific bridges
|
||||
define('PROXY_BYBRIDGE', false);
|
||||
// Comment this line or keep PROXY_NAME empty to display PROXY_URL instead
|
||||
define('PROXY_NAME', 'Hidden Proxy Name');
|
||||
|
||||
// Allows the operator to specify custom cache timeouts via '&_cache_timeout=3600'
|
||||
// true: enabled, false: disabled (default)
|
||||
define('CUSTOM_CACHE_TIMEOUT', false);
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
error_reporting(0);
|
||||
|
||||
@@ -303,7 +331,7 @@ EOD;
|
||||
echo $inactiveBridges;
|
||||
?>
|
||||
<section class="footer">
|
||||
<a href="https://github.com/RSS-Bridge/rss-bridge">RSS-Bridge 2018-04-20 ~ Public Domain</a><br />
|
||||
<a href="https://github.com/RSS-Bridge/rss-bridge">RSS-Bridge 2018-06-10 ~ Public Domain</a><br />
|
||||
<?= $activeFoundBridgeCount; ?>/<?= count($bridgeList) ?> active bridges. <br />
|
||||
<?php
|
||||
if($activeFoundBridgeCount !== count($bridgeList)) {
|
||||
|
@@ -22,10 +22,12 @@ function getContents($url, $header = array(), $opts = array()){
|
||||
}
|
||||
|
||||
$content = curl_exec($ch);
|
||||
$curlError = curl_error($ch);
|
||||
$curlErrno = curl_errno($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if($content === false)
|
||||
debugMessage('Cant\'t download ' . $url);
|
||||
debugMessage('Cant\'t download ' . $url . ' cUrl error: ' . $curlError . ' (' . $curlErrno . ')');
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
Reference in New Issue
Block a user