mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-02-17 15:49:57 +03:00
Reformat codebase v4 (#2872)
Reformat code base to PSR12 Co-authored-by: rssbridge <noreply@github.com>
This commit is contained in:
parent
66568e3a39
commit
4f75591060
398 changed files with 58607 additions and 56442 deletions
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
|
||||
* Atom feeds for websites that don't have one.
|
||||
|
@ -25,13 +26,13 @@ class ConnectivityAction implements ActionInterface
|
|||
{
|
||||
public $userData = [];
|
||||
|
||||
public function execute() {
|
||||
|
||||
if(!Debug::isEnabled()) {
|
||||
public function execute()
|
||||
{
|
||||
if (!Debug::isEnabled()) {
|
||||
returnError('This action is only available in debug mode!', 400);
|
||||
}
|
||||
|
||||
if(!isset($this->userData['bridge'])) {
|
||||
if (!isset($this->userData['bridge'])) {
|
||||
$this->returnEntryPage();
|
||||
return;
|
||||
}
|
||||
|
@ -39,7 +40,6 @@ class ConnectivityAction implements ActionInterface
|
|||
$bridgeName = $this->userData['bridge'];
|
||||
|
||||
$this->reportBridgeConnectivity($bridgeName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,52 +55,52 @@ class ConnectivityAction implements ActionInterface
|
|||
* @param string $bridgeName Name of the bridge to generate the report for
|
||||
* @return void
|
||||
*/
|
||||
private function reportBridgeConnectivity($bridgeName) {
|
||||
|
||||
private function reportBridgeConnectivity($bridgeName)
|
||||
{
|
||||
$bridgeFac = new \BridgeFactory();
|
||||
|
||||
if(!$bridgeFac->isWhitelisted($bridgeName)) {
|
||||
if (!$bridgeFac->isWhitelisted($bridgeName)) {
|
||||
header('Content-Type: text/html');
|
||||
returnServerError('Bridge is not whitelisted!');
|
||||
}
|
||||
|
||||
header('Content-Type: text/json');
|
||||
|
||||
$retVal = array(
|
||||
$retVal = [
|
||||
'bridge' => $bridgeName,
|
||||
'successful' => false,
|
||||
'http_code' => 200,
|
||||
);
|
||||
];
|
||||
|
||||
$bridge = $bridgeFac->create($bridgeName);
|
||||
|
||||
if($bridge === false) {
|
||||
if ($bridge === false) {
|
||||
echo json_encode($retVal);
|
||||
return;
|
||||
}
|
||||
|
||||
$curl_opts = array(
|
||||
$curl_opts = [
|
||||
CURLOPT_CONNECTTIMEOUT => 5
|
||||
);
|
||||
];
|
||||
|
||||
try {
|
||||
$reply = getContents($bridge::URI, array(), $curl_opts, true);
|
||||
$reply = getContents($bridge::URI, [], $curl_opts, true);
|
||||
|
||||
if($reply['code'] === 200) {
|
||||
if ($reply['code'] === 200) {
|
||||
$retVal['successful'] = true;
|
||||
if (strpos(implode('', $reply['status_lines']), '301 Moved Permanently')) {
|
||||
$retVal['http_code'] = 301;
|
||||
}
|
||||
}
|
||||
} catch(Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
$retVal['successful'] = false;
|
||||
}
|
||||
|
||||
echo json_encode($retVal);
|
||||
|
||||
}
|
||||
|
||||
private function returnEntryPage() {
|
||||
private function returnEntryPage()
|
||||
{
|
||||
echo <<<EOD
|
||||
<!DOCTYPE html>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
|
||||
* Atom feeds for websites that don't have one.
|
||||
|
@ -15,7 +16,8 @@ class DetectAction implements ActionInterface
|
|||
{
|
||||
public $userData = [];
|
||||
|
||||
public function execute() {
|
||||
public function execute()
|
||||
{
|
||||
$targetURL = $this->userData['url']
|
||||
or returnClientError('You must specify a url!');
|
||||
|
||||
|
@ -24,21 +26,20 @@ class DetectAction implements ActionInterface
|
|||
|
||||
$bridgeFac = new \BridgeFactory();
|
||||
|
||||
foreach($bridgeFac->getBridgeNames() as $bridgeName) {
|
||||
|
||||
if(!$bridgeFac->isWhitelisted($bridgeName)) {
|
||||
foreach ($bridgeFac->getBridgeNames() as $bridgeName) {
|
||||
if (!$bridgeFac->isWhitelisted($bridgeName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bridge = $bridgeFac->create($bridgeName);
|
||||
|
||||
if($bridge === false) {
|
||||
if ($bridge === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$bridgeParams = $bridge->detectParameters($targetURL);
|
||||
|
||||
if(is_null($bridgeParams)) {
|
||||
if (is_null($bridgeParams)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -47,7 +48,6 @@ class DetectAction implements ActionInterface
|
|||
|
||||
header('Location: ?action=display&' . http_build_query($bridgeParams), true, 301);
|
||||
die();
|
||||
|
||||
}
|
||||
|
||||
returnClientError('No bridge found for given URL: ' . $targetURL);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
|
||||
* Atom feeds for websites that don't have one.
|
||||
|
@ -15,7 +16,8 @@ class DisplayAction implements ActionInterface
|
|||
{
|
||||
public $userData = [];
|
||||
|
||||
private function getReturnCode($error) {
|
||||
private function getReturnCode($error)
|
||||
{
|
||||
$returnCode = $error->getCode();
|
||||
if ($returnCode === 301 || $returnCode === 302) {
|
||||
# Don't pass redirect codes to the exterior
|
||||
|
@ -24,7 +26,8 @@ class DisplayAction implements ActionInterface
|
|||
return $returnCode;
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
public function execute()
|
||||
{
|
||||
$bridge = array_key_exists('bridge', $this->userData) ? $this->userData['bridge'] : null;
|
||||
|
||||
$format = $this->userData['format']
|
||||
|
@ -33,7 +36,7 @@ class DisplayAction implements ActionInterface
|
|||
$bridgeFac = new \BridgeFactory();
|
||||
|
||||
// whitelist control
|
||||
if(!$bridgeFac->isWhitelisted($bridge)) {
|
||||
if (!$bridgeFac->isWhitelisted($bridge)) {
|
||||
throw new \Exception('This bridge is not whitelisted', 401);
|
||||
die;
|
||||
}
|
||||
|
@ -45,15 +48,14 @@ class DisplayAction implements ActionInterface
|
|||
$noproxy = array_key_exists('_noproxy', $this->userData)
|
||||
&& filter_var($this->userData['_noproxy'], FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if(defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy) {
|
||||
if (defined('PROXY_URL') && PROXY_BYBRIDGE && $noproxy) {
|
||||
define('NOPROXY', true);
|
||||
}
|
||||
|
||||
// Cache timeout
|
||||
$cache_timeout = -1;
|
||||
if(array_key_exists('_cache_timeout', $this->userData)) {
|
||||
|
||||
if(!CUSTOM_CACHE_TIMEOUT) {
|
||||
if (array_key_exists('_cache_timeout', $this->userData)) {
|
||||
if (!CUSTOM_CACHE_TIMEOUT) {
|
||||
unset($this->userData['_cache_timeout']);
|
||||
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) . '?' . http_build_query($this->userData);
|
||||
header('Location: ' . $uri, true, 301);
|
||||
|
@ -61,7 +63,6 @@ class DisplayAction implements ActionInterface
|
|||
}
|
||||
|
||||
$cache_timeout = filter_var($this->userData['_cache_timeout'], FILTER_VALIDATE_INT);
|
||||
|
||||
} else {
|
||||
$cache_timeout = $bridge->getCacheTimeout();
|
||||
}
|
||||
|
@ -70,27 +71,31 @@ class DisplayAction implements ActionInterface
|
|||
$bridge_params = array_diff_key(
|
||||
$this->userData,
|
||||
array_fill_keys(
|
||||
array(
|
||||
[
|
||||
'action',
|
||||
'bridge',
|
||||
'format',
|
||||
'_noproxy',
|
||||
'_cache_timeout',
|
||||
'_error_time'
|
||||
), '')
|
||||
],
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
// Remove parameters that don't concern caches
|
||||
$cache_params = array_diff_key(
|
||||
$this->userData,
|
||||
array_fill_keys(
|
||||
array(
|
||||
[
|
||||
'action',
|
||||
'format',
|
||||
'_noproxy',
|
||||
'_cache_timeout',
|
||||
'_error_time'
|
||||
), '')
|
||||
],
|
||||
''
|
||||
)
|
||||
);
|
||||
|
||||
// Initialize cache
|
||||
|
@ -101,20 +106,21 @@ class DisplayAction implements ActionInterface
|
|||
$cache->purgeCache(86400); // 24 hours
|
||||
$cache->setKey($cache_params);
|
||||
|
||||
$items = array();
|
||||
$infos = array();
|
||||
$items = [];
|
||||
$infos = [];
|
||||
$mtime = $cache->getTime();
|
||||
|
||||
if($mtime !== false
|
||||
if (
|
||||
$mtime !== false
|
||||
&& (time() - $cache_timeout < $mtime)
|
||||
&& !Debug::isEnabled()) { // Load cached data
|
||||
|
||||
&& !Debug::isEnabled()
|
||||
) { // Load cached data
|
||||
// Send "Not Modified" response if client supports it
|
||||
// Implementation based on https://stackoverflow.com/a/10847262
|
||||
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
$stime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
||||
|
||||
if($mtime <= $stime) { // Cached data is older or same
|
||||
if ($mtime <= $stime) { // Cached data is older or same
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s ', $mtime) . 'GMT', true, 304);
|
||||
die();
|
||||
}
|
||||
|
@ -122,16 +128,14 @@ class DisplayAction implements ActionInterface
|
|||
|
||||
$cached = $cache->loadData();
|
||||
|
||||
if(isset($cached['items']) && isset($cached['extraInfos'])) {
|
||||
foreach($cached['items'] as $item) {
|
||||
if (isset($cached['items']) && isset($cached['extraInfos'])) {
|
||||
foreach ($cached['items'] as $item) {
|
||||
$items[] = new \FeedItem($item);
|
||||
}
|
||||
|
||||
$infos = $cached['extraInfos'];
|
||||
}
|
||||
|
||||
} else { // Collect new data
|
||||
|
||||
try {
|
||||
$bridge->setDatas($bridge_params);
|
||||
$bridge->collectData();
|
||||
|
@ -140,27 +144,27 @@ class DisplayAction implements ActionInterface
|
|||
|
||||
// Transform "legacy" items to FeedItems if necessary.
|
||||
// Remove this code when support for "legacy" items ends!
|
||||
if(isset($items[0]) && is_array($items[0])) {
|
||||
$feedItems = array();
|
||||
if (isset($items[0]) && is_array($items[0])) {
|
||||
$feedItems = [];
|
||||
|
||||
foreach($items as $item) {
|
||||
foreach ($items as $item) {
|
||||
$feedItems[] = new \FeedItem($item);
|
||||
}
|
||||
|
||||
$items = $feedItems;
|
||||
}
|
||||
|
||||
$infos = array(
|
||||
$infos = [
|
||||
'name' => $bridge->getName(),
|
||||
'uri' => $bridge->getURI(),
|
||||
'donationUri' => $bridge->getDonationURI(),
|
||||
'icon' => $bridge->getIcon()
|
||||
);
|
||||
} catch(\Throwable $e) {
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
error_log($e);
|
||||
|
||||
if(logBridgeError($bridge::NAME, $e->getCode()) >= Configuration::getConfig('error', 'report_limit')) {
|
||||
if(Configuration::getConfig('error', 'output') === 'feed') {
|
||||
if (logBridgeError($bridge::NAME, $e->getCode()) >= Configuration::getConfig('error', 'report_limit')) {
|
||||
if (Configuration::getConfig('error', 'output') === 'feed') {
|
||||
$item = new \FeedItem();
|
||||
|
||||
// Create "new" error message every 24 hours
|
||||
|
@ -183,7 +187,7 @@ class DisplayAction implements ActionInterface
|
|||
$item->setContent(buildBridgeException($e, $bridge));
|
||||
|
||||
$items[] = $item;
|
||||
} elseif(Configuration::getConfig('error', 'output') === 'http') {
|
||||
} elseif (Configuration::getConfig('error', 'output') === 'http') {
|
||||
header('Content-Type: text/html', true, $this->getReturnCode($e));
|
||||
die(buildTransformException($e, $bridge));
|
||||
}
|
||||
|
@ -191,11 +195,12 @@ class DisplayAction implements ActionInterface
|
|||
}
|
||||
|
||||
// Store data in cache
|
||||
$cache->saveData(array(
|
||||
'items' => array_map(function($i){ return $i->toArray(); }, $items),
|
||||
$cache->saveData([
|
||||
'items' => array_map(function ($i) {
|
||||
return $i->toArray();
|
||||
}, $items),
|
||||
'extraInfos' => $infos
|
||||
));
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
// Data transformation
|
||||
|
@ -212,7 +217,7 @@ class DisplayAction implements ActionInterface
|
|||
header('Content-Type: ' . $format->getMimeType() . '; charset=' . $format->getCharset());
|
||||
|
||||
echo $format->stringify();
|
||||
} catch(\Throwable $e) {
|
||||
} catch (\Throwable $e) {
|
||||
error_log($e);
|
||||
header('Content-Type: text/html', true, $e->getCode());
|
||||
die(buildTransformException($e, $bridge));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of RSS-Bridge, a PHP project capable of generating RSS and
|
||||
* Atom feeds for websites that don't have one.
|
||||
|
@ -13,30 +14,28 @@
|
|||
|
||||
class ListAction implements ActionInterface
|
||||
{
|
||||
public function execute() {
|
||||
public function execute()
|
||||
{
|
||||
$list = new StdClass();
|
||||
$list->bridges = array();
|
||||
$list->bridges = [];
|
||||
$list->total = 0;
|
||||
|
||||
$bridgeFac = new \BridgeFactory();
|
||||
|
||||
foreach($bridgeFac->getBridgeNames() as $bridgeName) {
|
||||
|
||||
foreach ($bridgeFac->getBridgeNames() as $bridgeName) {
|
||||
$bridge = $bridgeFac->create($bridgeName);
|
||||
|
||||
if($bridge === false) { // Broken bridge, show as inactive
|
||||
|
||||
$list->bridges[$bridgeName] = array(
|
||||
if ($bridge === false) { // Broken bridge, show as inactive
|
||||
$list->bridges[$bridgeName] = [
|
||||
'status' => 'inactive'
|
||||
);
|
||||
];
|
||||
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
$status = $bridgeFac->isWhitelisted($bridgeName) ? 'active' : 'inactive';
|
||||
|
||||
$list->bridges[$bridgeName] = array(
|
||||
$list->bridges[$bridgeName] = [
|
||||
'status' => $status,
|
||||
'uri' => $bridge->getURI(),
|
||||
'donationUri' => $bridge->getDonationURI(),
|
||||
|
@ -45,8 +44,7 @@ class ListAction implements ActionInterface
|
|||
'parameters' => $bridge->getParameters(),
|
||||
'maintainer' => $bridge->getMaintainer(),
|
||||
'description' => $bridge->getDescription()
|
||||
);
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
$list->total = count($list->bridges);
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
<?php
|
||||
class ABCNewsBridge extends BridgeAbstract {
|
||||
|
||||
class ABCNewsBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'ABC News Bridge';
|
||||
const URI = 'https://www.abc.net.au';
|
||||
const DESCRIPTION = 'Topics of the Australian Broadcasting Corporation';
|
||||
const MAINTAINER = 'yue-dongchen';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'topic' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'topic' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Region',
|
||||
'title' => 'Choose state',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'ACT' => 'act',
|
||||
'NSW' => 'nsw',
|
||||
'NT' => 'nt',
|
||||
|
@ -20,18 +22,19 @@ class ABCNewsBridge extends BridgeAbstract {
|
|||
'TAS' => 'tas',
|
||||
'VIC' => 'vic',
|
||||
'WA' => 'wa'
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$url = 'https://www.abc.net.au/news/' . $this->getInput('topic');
|
||||
$html = getSimpleHTMLDOM($url)->find('.YAJzu._2FvRw.ZWhbj._3BZxh', 0);
|
||||
$html = defaultLinkTo($html, $this->getURI());
|
||||
|
||||
foreach($html->find('._2H7Su') as $article) {
|
||||
$item = array();
|
||||
foreach ($html->find('._2H7Su') as $article) {
|
||||
$item = [];
|
||||
|
||||
$title = $article->find('._3T9Id.fmhNa.nsZdE._2c2Zy._1tOey._3EOTW', 0);
|
||||
$item['title'] = $title->plaintext;
|
||||
|
|
|
@ -1,49 +1,53 @@
|
|||
<?php
|
||||
|
||||
class AO3Bridge extends BridgeAbstract {
|
||||
class AO3Bridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'AO3';
|
||||
const URI = 'https://archiveofourown.org/';
|
||||
const CACHE_TIMEOUT = 1800;
|
||||
const DESCRIPTION = 'Returns works or chapters from Archive of Our Own';
|
||||
const MAINTAINER = 'Obsidienne';
|
||||
const PARAMETERS = array(
|
||||
'List' => array(
|
||||
'url' => array(
|
||||
const PARAMETERS = [
|
||||
'List' => [
|
||||
'url' => [
|
||||
'name' => 'url',
|
||||
'required' => true,
|
||||
// Example: F/F tag, complete works only
|
||||
'exampleValue' => 'https://archiveofourown.org/works?work_search[complete]=T&tag_id=F*s*F',
|
||||
),
|
||||
),
|
||||
'Bookmarks' => array(
|
||||
'user' => array(
|
||||
],
|
||||
],
|
||||
'Bookmarks' => [
|
||||
'user' => [
|
||||
'name' => 'user',
|
||||
'required' => true,
|
||||
// Example: Nyaaru's bookmarks
|
||||
'exampleValue' => 'Nyaaru',
|
||||
),
|
||||
),
|
||||
'Work' => array(
|
||||
'id' => array(
|
||||
],
|
||||
],
|
||||
'Work' => [
|
||||
'id' => [
|
||||
'name' => 'id',
|
||||
'required' => true,
|
||||
// Example: latest chapters from A Better Past by LysSerris
|
||||
'exampleValue' => '18181853',
|
||||
),
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Feed for lists of works (e.g. recent works, search results, filtered tags,
|
||||
// bookmarks, series, collections).
|
||||
private function collectList($url) {
|
||||
private function collectList($url)
|
||||
{
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
|
||||
foreach($html->find('.index.group > li') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('.index.group > li') as $element) {
|
||||
$item = [];
|
||||
|
||||
$title = $element->find('div h4 a', 0);
|
||||
if (!isset($title)) continue; // discard deleted works
|
||||
if (!isset($title)) {
|
||||
continue; // discard deleted works
|
||||
}
|
||||
$item['title'] = $title->plaintext;
|
||||
$item['content'] = $element;
|
||||
$item['uri'] = $title->href;
|
||||
|
@ -61,15 +65,16 @@ class AO3Bridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Feed for recent chapters of a specific work.
|
||||
private function collectWork($id) {
|
||||
private function collectWork($id)
|
||||
{
|
||||
$url = self::URI . "/works/$id/navigate";
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
|
||||
$this->title = $html->find('h2 a', 0)->plaintext;
|
||||
|
||||
foreach($html->find('ol.index.group > li') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('ol.index.group > li') as $element) {
|
||||
$item = [];
|
||||
|
||||
$item['title'] = $element->find('a', 0)->plaintext;
|
||||
$item['content'] = $element;
|
||||
|
@ -88,8 +93,9 @@ class AO3Bridge extends BridgeAbstract {
|
|||
$this->items = array_reverse($this->items);
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
switch($this->queriedContext) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Bookmarks':
|
||||
$user = $this->getInput('user');
|
||||
$this->title = $user;
|
||||
|
@ -97,22 +103,28 @@ class AO3Bridge extends BridgeAbstract {
|
|||
. '/users/' . $user
|
||||
. '/bookmarks?bookmark_search[sort_column]=bookmarkable_date';
|
||||
return $this->collectList($url);
|
||||
case 'List': return $this->collectList(
|
||||
case 'List':
|
||||
return $this->collectList(
|
||||
$this->getInput('url')
|
||||
);
|
||||
case 'Work': return $this->collectWork(
|
||||
case 'Work':
|
||||
return $this->collectWork(
|
||||
$this->getInput('id')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
$name = parent::getName() . " $this->queriedContext";
|
||||
if (isset($this->title)) $name .= " - $this->title";
|
||||
if (isset($this->title)) {
|
||||
$name .= " - $this->title";
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . '/favicon.ico';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
class ARDMediathekBridge extends BridgeAbstract {
|
||||
|
||||
class ARDMediathekBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'ARD-Mediathek Bridge';
|
||||
const URI = 'https://www.ardmediathek.de';
|
||||
const DESCRIPTION = 'Feed of any series in the ARD-Mediathek, specified by its path';
|
||||
|
@ -39,18 +41,19 @@ class ARDMediathekBridge extends BridgeAbstract {
|
|||
*/
|
||||
const IMAGEWIDTHPLACEHOLDER = '{width}';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'path' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'path' => [
|
||||
'name' => 'Show Link or ID',
|
||||
'required' => true,
|
||||
'title' => 'Link to the show page or just its alphanumeric suffix',
|
||||
'defaultValue' => 'https://www.ardmediathek.de/sendung/45-min/Y3JpZDovL25kci5kZS8xMzkx/'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$oldTz = date_default_timezone_get();
|
||||
|
||||
date_default_timezone_set('Europe/Berlin');
|
||||
|
@ -69,20 +72,20 @@ class ARDMediathekBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
$url = SELF::APIENDPOINT . $showID . '/?pageSize=' . SELF::PAGESIZE;
|
||||
$url = self::APIENDPOINT . $showID . '/?pageSize=' . self::PAGESIZE;
|
||||
$rawJSON = getContents($url);
|
||||
$processedJSON = json_decode($rawJSON);
|
||||
|
||||
foreach($processedJSON->teasers as $video) {
|
||||
$item = array();
|
||||
foreach ($processedJSON->teasers as $video) {
|
||||
$item = [];
|
||||
// there is also ->links->self->id, ->links->self->urlId, ->links->target->id, ->links->target->urlId
|
||||
$item['uri'] = SELF::VIDEOLINKPREFIX . $video->id . '/';
|
||||
$item['uri'] = self::VIDEOLINKPREFIX . $video->id . '/';
|
||||
// there is also ->mediumTitle and ->shortTitle
|
||||
$item['title'] = $video->longTitle;
|
||||
// in the test, aspect16x9 was the only child of images, not sure whether that is always true
|
||||
$item['enclosures'] = array(
|
||||
str_replace(SELF::IMAGEWIDTHPLACEHOLDER, SELF::IMAGEWIDTH, $video->images->aspect16x9->src)
|
||||
);
|
||||
$item['enclosures'] = [
|
||||
str_replace(self::IMAGEWIDTHPLACEHOLDER, self::IMAGEWIDTH, $video->images->aspect16x9->src)
|
||||
];
|
||||
$item['content'] = '<img src="' . $item['enclosures'][0] . '" /><p>';
|
||||
$item['timestamp'] = $video->broadcastedOn;
|
||||
$item['uid'] = $video->id;
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
<?php
|
||||
class ASRockNewsBridge extends BridgeAbstract {
|
||||
|
||||
class ASRockNewsBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'ASRock News Bridge';
|
||||
const URI = 'https://www.asrock.com';
|
||||
const DESCRIPTION = 'Returns latest news articles';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array();
|
||||
const PARAMETERS = [];
|
||||
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI . '/news/index.asp');
|
||||
|
||||
$html = defaultLinkTo($html, self::URI . '/news/');
|
||||
|
||||
foreach($html->find('div.inner > a') as $index => $a) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.inner > a') as $index => $a) {
|
||||
$item = [];
|
||||
|
||||
$articlePath = $a->href;
|
||||
|
||||
|
@ -41,7 +43,8 @@ class ASRockNewsBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function extractDate($text) {
|
||||
private function extractDate($text)
|
||||
{
|
||||
$dateRegex = '/^([0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2})/';
|
||||
|
||||
$text = trim($text);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class AcrimedBridge extends FeedExpander {
|
||||
|
||||
class AcrimedBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'qwertygc';
|
||||
const NAME = 'Acrimed Bridge';
|
||||
const URI = 'https://www.acrimed.org/';
|
||||
|
@ -17,14 +18,16 @@ class AcrimedBridge extends FeedExpander {
|
|||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$this->collectExpandableDatas(
|
||||
static::URI . 'spip.php?page=backend',
|
||||
$this->getInput('limit')
|
||||
);
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
$item = parent::parseItem($newsItem);
|
||||
|
||||
$articlePage = getSimpleHTMLDOM($newsItem->link);
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
<?php
|
||||
class AirBreizhBridge extends BridgeAbstract {
|
||||
|
||||
class AirBreizhBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'fanch317';
|
||||
const NAME = 'Air Breizh';
|
||||
const URI = 'https://www.airbreizh.asso.fr/';
|
||||
const DESCRIPTION = 'Returns newests publications on Air Breizh';
|
||||
const PARAMETERS = array(
|
||||
'Publications' => array(
|
||||
'theme' => array(
|
||||
const PARAMETERS = [
|
||||
'Publications' => [
|
||||
'theme' => [
|
||||
'name' => 'Thematique',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Tout' => '',
|
||||
'Rapport d\'activite' => 'rapport-dactivite',
|
||||
'Etude' => 'etudes',
|
||||
|
@ -18,22 +19,24 @@ class AirBreizhBridge extends BridgeAbstract {
|
|||
'Autres documents' => 'autres-documents',
|
||||
'Plan Régional de Surveillance de la qualité de l’air' => 'prsqa',
|
||||
'Transport' => 'transport'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.airbreizh.asso.fr/voy_content/uploads/2017/11/favicon.png';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = '';
|
||||
$html = getSimpleHTMLDOM(static::URI . 'publications/?fwp_publications_thematiques=' . $this->getInput('theme'))
|
||||
or returnClientError('No results for this query.');
|
||||
|
||||
foreach ($html->find('article') as $article) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
// Title
|
||||
$item['title'] = $article->find('h2', 0)->plaintext;
|
||||
// Author
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
<?php
|
||||
class AlbionOnlineBridge extends BridgeAbstract {
|
||||
|
||||
class AlbionOnlineBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Albion Online Changelog';
|
||||
const MAINTAINER = 'otakuf';
|
||||
const URI = 'https://albiononline.com';
|
||||
const DESCRIPTION = 'Returns the changes made to the Albion Online';
|
||||
const CACHE_TIMEOUT = 3600; // 60min
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'postcount' => array(
|
||||
const PARAMETERS = [ [
|
||||
'postcount' => [
|
||||
'name' => 'Limit',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'title' => 'Maximum number of items to return',
|
||||
'defaultValue' => 5,
|
||||
),
|
||||
'language' => array(
|
||||
],
|
||||
'language' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'English' => 'en',
|
||||
'Deutsch' => 'de',
|
||||
'Polski' => 'pl',
|
||||
|
@ -26,19 +27,20 @@ class AlbionOnlineBridge extends BridgeAbstract {
|
|||
'Русский' => 'ru',
|
||||
'Português' => 'pt',
|
||||
'Español' => 'es',
|
||||
),
|
||||
],
|
||||
'title' => 'Language of changelog posts',
|
||||
'defaultValue' => 'en',
|
||||
),
|
||||
'full' => array(
|
||||
],
|
||||
'full' => [
|
||||
'name' => 'Full changelog',
|
||||
'type' => 'checkbox',
|
||||
'required' => false,
|
||||
'title' => 'Enable to receive the full changelog post for each item'
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$api = 'https://albiononline.com/';
|
||||
// Example: https://albiononline.com/en/changelog/1/5
|
||||
$url = $api . $this->getInput('language') . '/changelog/1/' . $this->getInput('postcount');
|
||||
|
@ -46,14 +48,14 @@ class AlbionOnlineBridge extends BridgeAbstract {
|
|||
$html = getSimpleHTMLDOM($url);
|
||||
|
||||
foreach ($html->find('li') as $data) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = self::URI . $data->find('a', 0)->getAttribute('href');
|
||||
$item['title'] = trim(explode('|', $data->find('span', 0)->plaintext)[0]);
|
||||
// Time below work only with en lang. Need to think about solution. May be separate request like getFullChangelog, but to english list for all language
|
||||
//print_r( date_parse_from_format( 'M j, Y' , 'Sep 9, 2020') );
|
||||
//$item['timestamp'] = $this->extractDate($a->plaintext);
|
||||
$item['author'] = 'albiononline.com';
|
||||
if($this->getInput('full')) {
|
||||
if ($this->getInput('full')) {
|
||||
$item['content'] = $this->getFullChangelog($item['uri']);
|
||||
} else {
|
||||
//$item['content'] = trim(preg_replace('/\s+/', ' ', $data->find('span', 0)->plaintext));
|
||||
|
@ -65,7 +67,8 @@ class AlbionOnlineBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function getFullChangelog($url) {
|
||||
private function getFullChangelog($url)
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached($url);
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
return $html->find('div.small-12.columns', 1)->innertext;
|
||||
|
|
|
@ -1,46 +1,48 @@
|
|||
<?php
|
||||
class AlfaBankByBridge extends BridgeAbstract {
|
||||
|
||||
class AlfaBankByBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'lassana';
|
||||
const NAME = 'AlfaBank.by Новости';
|
||||
const URI = 'https://www.alfabank.by';
|
||||
const DESCRIPTION = 'Уведомления Alfa-Now — новости от Альфа-Банка';
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
const PARAMETERS = array(
|
||||
'News' => array(
|
||||
'business' => array(
|
||||
const PARAMETERS = [
|
||||
'News' => [
|
||||
'business' => [
|
||||
'name' => 'Альфа Бизнес',
|
||||
'type' => 'list',
|
||||
'title' => 'В зависимости от выбора, возращает уведомления для" .
|
||||
" клиентов физ. лиц либо для клиентов-юридических лиц и ИП',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Новости' => 'news',
|
||||
'Новости бизнеса' => 'newsBusiness'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'news'
|
||||
),
|
||||
'fullContent' => array(
|
||||
],
|
||||
'fullContent' => [
|
||||
'name' => 'Включать содержимое',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Если выбрано, содержимое уведомлений вставляется в поток (работает медленно)'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$business = $this->getInput('business') == 'newsBusiness';
|
||||
$fullContent = $this->getInput('fullContent') == 'on';
|
||||
|
||||
$mainPageUrl = self::URI . '/about/articles/uvedomleniya/';
|
||||
if($business) {
|
||||
if ($business) {
|
||||
$mainPageUrl .= '?business=true';
|
||||
}
|
||||
$html = getSimpleHTMLDOM($mainPageUrl);
|
||||
$limit = 0;
|
||||
|
||||
foreach($html->find('a.notifications__item') as $element) {
|
||||
if($limit < 10) {
|
||||
$item = array();
|
||||
foreach ($html->find('a.notifications__item') as $element) {
|
||||
if ($limit < 10) {
|
||||
$item = [];
|
||||
$item['uid'] = 'urn:sha1:' . hash('sha1', $element->getAttribute('data-notification-id'));
|
||||
$item['title'] = $element->find('div.item-title', 0)->innertext;
|
||||
$item['timestamp'] = DateTime::createFromFormat(
|
||||
|
@ -49,14 +51,14 @@ class AlfaBankByBridge extends BridgeAbstract {
|
|||
)->getTimestamp();
|
||||
|
||||
$itemUrl = self::URI . $element->href;
|
||||
if($business) {
|
||||
if ($business) {
|
||||
$itemUrl = str_replace('?business=true', '', $itemUrl);
|
||||
}
|
||||
$item['uri'] = $itemUrl;
|
||||
|
||||
if($fullContent) {
|
||||
if ($fullContent) {
|
||||
$itemHtml = getSimpleHTMLDOM($itemUrl);
|
||||
if($itemHtml) {
|
||||
if ($itemHtml) {
|
||||
$item['content'] = $itemHtml->find('div.now-p__content-text', 0)->innertext;
|
||||
}
|
||||
}
|
||||
|
@ -67,17 +69,19 @@ class AlfaBankByBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return static::URI . '/local/images/favicon.ico';
|
||||
}
|
||||
|
||||
private function ruMonthsToEn($date) {
|
||||
$ruMonths = array(
|
||||
private function ruMonthsToEn($date)
|
||||
{
|
||||
$ruMonths = [
|
||||
'Января', 'Февраля', 'Марта', 'Апреля', 'Мая', 'Июня',
|
||||
'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря' );
|
||||
$enMonths = array(
|
||||
'Июля', 'Августа', 'Сентября', 'Октября', 'Ноября', 'Декабря' ];
|
||||
$enMonths = [
|
||||
'January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December' );
|
||||
'July', 'August', 'September', 'October', 'November', 'December' ];
|
||||
return str_replace($ruMonths, $enMonths, $date);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
class AllocineFRBridge extends BridgeAbstract {
|
||||
|
||||
class AllocineFRBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'superbaillot.net';
|
||||
const NAME = 'Allo Cine Bridge';
|
||||
const CACHE_TIMEOUT = 25200; // 7h
|
||||
const URI = 'https://www.allocine.fr';
|
||||
const DESCRIPTION = 'Bridge for allocine.fr';
|
||||
const PARAMETERS = array( array(
|
||||
'category' => array(
|
||||
const PARAMETERS = [ [
|
||||
'category' => [
|
||||
'name' => 'Emission',
|
||||
'type' => 'list',
|
||||
'title' => 'Sélectionner l\'emission',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Faux Raccord' => 'faux-raccord',
|
||||
'Fanzone' => 'fanzone',
|
||||
'Game In Ciné' => 'game-in-cine',
|
||||
|
@ -27,14 +28,14 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
'Complètement...' => 'completement',
|
||||
'#Fun Facts' => 'fun-facts',
|
||||
'Origin Story' => 'origin-story',
|
||||
)
|
||||
)
|
||||
));
|
||||
]
|
||||
]
|
||||
]];
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('category'))) {
|
||||
|
||||
$categories = array(
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('category'))) {
|
||||
$categories = [
|
||||
'faux-raccord' => '/video/programme-12284/',
|
||||
'fanzone' => '/video/programme-12298/',
|
||||
'game-in-cine' => '/video/programme-12288/',
|
||||
|
@ -50,10 +51,10 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
'completement' => '/video/programme-23859/',
|
||||
'fun-facts' => '/video/programme-23040/',
|
||||
'origin-story' => '/video/programme-25667/'
|
||||
);
|
||||
];
|
||||
|
||||
$category = $this->getInput('category');
|
||||
if(array_key_exists($category, $categories)) {
|
||||
if (array_key_exists($category, $categories)) {
|
||||
return static::URI . $this->getLastSeasonURI($categories[$category]);
|
||||
} else {
|
||||
returnClientError('Emission inconnue');
|
||||
|
@ -71,8 +72,9 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
return $URI;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('category'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('category'))) {
|
||||
return self::NAME . ' : '
|
||||
. array_search(
|
||||
$this->getInput('category'),
|
||||
|
@ -83,16 +85,16 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
$category = array_search(
|
||||
$this->getInput('category'),
|
||||
self::PARAMETERS[$this->queriedContext]['category']['values']
|
||||
);
|
||||
foreach($html->find('div[class=gd-col-left]', 0)->find('div[class*=video-card]') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div[class=gd-col-left]', 0)->find('div[class*=video-card]') as $element) {
|
||||
$item = [];
|
||||
|
||||
$title = $element->find('a[class*=meta-title-link]', 0);
|
||||
$content = trim(defaultLinkTo($element->outertext, static::URI));
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
<?php
|
||||
|
||||
class AmazonBridge extends BridgeAbstract {
|
||||
|
||||
class AmazonBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Alexis CHEMEL';
|
||||
const NAME = 'Amazon';
|
||||
const URI = 'https://www.amazon.com/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'Returns products from Amazon search';
|
||||
|
||||
const PARAMETERS = array(array(
|
||||
'q' => array(
|
||||
const PARAMETERS = [[
|
||||
'q' => [
|
||||
'name' => 'Keyword',
|
||||
'required' => true,
|
||||
'exampleValue' => 'watch',
|
||||
),
|
||||
'sort' => array(
|
||||
],
|
||||
'sort' => [
|
||||
'name' => 'Sort by',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Relevance' => 'relevanceblender',
|
||||
'Price: Low to High' => 'price-asc-rank',
|
||||
'Price: High to Low' => 'price-desc-rank',
|
||||
'Average Customer Review' => 'review-rank',
|
||||
'Newest Arrivals' => 'date-desc-rank',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'relevanceblender',
|
||||
),
|
||||
'tld' => array(
|
||||
],
|
||||
'tld' => [
|
||||
'name' => 'Country',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Australia' => 'com.au',
|
||||
'Brazil' => 'com.br',
|
||||
'Canada' => 'ca',
|
||||
|
@ -46,13 +46,13 @@ class AmazonBridge extends BridgeAbstract {
|
|||
'Turkey' => 'com.tr',
|
||||
'United Kingdom' => 'co.uk',
|
||||
'United States' => 'com',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'com',
|
||||
),
|
||||
));
|
||||
|
||||
public function collectData() {
|
||||
],
|
||||
]];
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$baseUrl = sprintf('https://www.amazon.%s', $this->getInput('tld'));
|
||||
|
||||
$url = sprintf(
|
||||
|
@ -66,7 +66,7 @@ class AmazonBridge extends BridgeAbstract {
|
|||
|
||||
$elements = $dom->find('div.s-result-item');
|
||||
|
||||
foreach($elements as $element) {
|
||||
foreach ($elements as $element) {
|
||||
$item = [];
|
||||
|
||||
$title = $element->find('h2', 0);
|
||||
|
@ -93,8 +93,9 @@ class AmazonBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('tld')) && !is_null($this->getInput('q'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('tld')) && !is_null($this->getInput('q'))) {
|
||||
return 'Amazon.' . $this->getInput('tld') . ': ' . $this->getInput('q');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
<?php
|
||||
|
||||
class AmazonPriceTrackerBridge extends BridgeAbstract {
|
||||
class AmazonPriceTrackerBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'captn3m0, sal0max';
|
||||
const NAME = 'Amazon Price Tracker';
|
||||
const URI = 'https://www.amazon.com/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'Tracks price for a single product on Amazon';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'asin' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'asin' => [
|
||||
'name' => 'ASIN',
|
||||
'required' => true,
|
||||
'exampleValue' => 'B071GB1VMQ',
|
||||
// https://stackoverflow.com/a/12827734
|
||||
'pattern' => 'B[\dA-Z]{9}|\d{9}(X|\d)',
|
||||
),
|
||||
'tld' => array(
|
||||
],
|
||||
'tld' => [
|
||||
'name' => 'Country',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Australia' => 'com.au',
|
||||
'Brazil' => 'com.br',
|
||||
'Canada' => 'ca',
|
||||
|
@ -36,19 +37,19 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
'Turkey' => 'com.tr',
|
||||
'United Kingdom' => 'co.uk',
|
||||
'United States' => 'com',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'com',
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
const PRICE_SELECTORS = array(
|
||||
const PRICE_SELECTORS = [
|
||||
'#priceblock_ourprice',
|
||||
'.priceBlockBuyingPriceString',
|
||||
'#newBuyBoxPrice',
|
||||
'#tp_price_block_total_price_ww',
|
||||
'span.offer-price',
|
||||
'.a-color-price',
|
||||
);
|
||||
];
|
||||
|
||||
const WHITESPACE = " \t\n\r\0\x0B\xC2\xA0";
|
||||
|
||||
|
@ -57,14 +58,16 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Generates domain name given a amazon TLD
|
||||
*/
|
||||
private function getDomainName() {
|
||||
private function getDomainName()
|
||||
{
|
||||
return 'https://www.amazon.' . $this->getInput('tld');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates URI for a Amazon product page
|
||||
*/
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('asin'))) {
|
||||
return $this->getDomainName() . '/dp/' . $this->getInput('asin');
|
||||
}
|
||||
|
@ -75,7 +78,8 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
* Scrapes the product title from the html page
|
||||
* returns the default title if scraping fails
|
||||
*/
|
||||
private function getTitle($html) {
|
||||
private function getTitle($html)
|
||||
{
|
||||
$titleTag = $html->find('#productTitle', 0);
|
||||
|
||||
if (!$titleTag) {
|
||||
|
@ -88,7 +92,8 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Title used by the feed if none could be found
|
||||
*/
|
||||
private function getDefaultTitle() {
|
||||
private function getDefaultTitle()
|
||||
{
|
||||
return 'Amazon.' . $this->getInput('tld') . ': ' . $this->getInput('asin');
|
||||
}
|
||||
|
||||
|
@ -96,7 +101,8 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
* Returns name for the feed
|
||||
* Uses title (already scraped) if it has one
|
||||
*/
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if (isset($this->title)) {
|
||||
return $this->title;
|
||||
} else {
|
||||
|
@ -104,7 +110,8 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function parseDynamicImage($attribute) {
|
||||
private function parseDynamicImage($attribute)
|
||||
{
|
||||
$json = json_decode(html_entity_decode($attribute), true);
|
||||
|
||||
if ($json and count($json) > 0) {
|
||||
|
@ -115,7 +122,8 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Returns a generated image tag for the product
|
||||
*/
|
||||
private function getImage($html) {
|
||||
private function getImage($html)
|
||||
{
|
||||
$imageSrc = $html->find('#main-image-container img', 0);
|
||||
|
||||
if ($imageSrc) {
|
||||
|
@ -134,49 +142,53 @@ EOT;
|
|||
* Return \simple_html_dom object
|
||||
* for the entire html of the product page
|
||||
*/
|
||||
private function getHtml() {
|
||||
private function getHtml()
|
||||
{
|
||||
$uri = $this->getURI();
|
||||
|
||||
return getSimpleHTMLDOM($uri) ?: returnServerError('Could not request Amazon.');
|
||||
}
|
||||
|
||||
private function scrapePriceFromMetrics($html) {
|
||||
private function scrapePriceFromMetrics($html)
|
||||
{
|
||||
$asinData = $html->find('#cerberus-data-metrics', 0);
|
||||
|
||||
// <div id="cerberus-data-metrics" style="display: none;"
|
||||
// data-asin="B00WTHJ5SU" data-asin-price="14.99" data-asin-shipping="0"
|
||||
// data-asin-currency-code="USD" data-substitute-count="-1" ... />
|
||||
if ($asinData) {
|
||||
return array(
|
||||
return [
|
||||
'price' => $asinData->getAttribute('data-asin-price'),
|
||||
'currency' => $asinData->getAttribute('data-asin-currency-code'),
|
||||
'shipping' => $asinData->getAttribute('data-asin-shipping')
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function scrapePriceTwister($html) {
|
||||
private function scrapePriceTwister($html)
|
||||
{
|
||||
$str = $html->find('.twister-plus-buying-options-price-data', 0);
|
||||
|
||||
$data = json_decode($str->innertext, true);
|
||||
if(count($data) === 1) {
|
||||
if (count($data) === 1) {
|
||||
$data = $data[0];
|
||||
return array(
|
||||
return [
|
||||
'displayPrice' => $data['displayPrice'],
|
||||
'currency' => $data['currency'],
|
||||
'shipping' => '0',
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function scrapePriceGeneric($html) {
|
||||
private function scrapePriceGeneric($html)
|
||||
{
|
||||
$priceDiv = null;
|
||||
|
||||
foreach(self::PRICE_SELECTORS as $sel) {
|
||||
foreach (self::PRICE_SELECTORS as $sel) {
|
||||
$priceDiv = $html->find($sel, 0);
|
||||
if ($priceDiv) {
|
||||
break;
|
||||
|
@ -194,17 +206,18 @@ EOT;
|
|||
$currency = str_replace($price, '', $priceString);
|
||||
|
||||
if ($price != null && $currency != null) {
|
||||
return array(
|
||||
return [
|
||||
'price' => $price,
|
||||
'currency' => $currency,
|
||||
'shipping' => '0'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function renderContent($image, $data) {
|
||||
private function renderContent($image, $data)
|
||||
{
|
||||
$price = $data['displayPrice'];
|
||||
if (!$price) {
|
||||
$price = "{$data['price']} {$data['currency']}";
|
||||
|
@ -223,20 +236,21 @@ EOT;
|
|||
* Scrape method for Amazon product page
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = $this->getHtml();
|
||||
$this->title = $this->getTitle($html);
|
||||
$imageTag = $this->getImage($html);
|
||||
|
||||
$data = $this->scrapePriceGeneric($html);
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'title' => $this->title,
|
||||
'uri' => $this->getURI(),
|
||||
'content' => $this->renderContent($imageTag, $data),
|
||||
// This is to ensure that feed readers notice the price change
|
||||
'uid' => md5($data['price'])
|
||||
);
|
||||
];
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
<?php
|
||||
class AnidexBridge extends BridgeAbstract {
|
||||
|
||||
class AnidexBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'Anidex';
|
||||
const URI = 'http://anidex.info/'; // anidex.info has ddos-guard so we need to use anidex.moe
|
||||
const ALTERNATE_URI = 'https://anidex.moe/'; // anidex.moe returns 301 unless Host is set to anidex.info
|
||||
const ALTERNATE_HOST = 'anidex.info'; // Correct host for requesting anidex.moe without 301 redirect
|
||||
const DESCRIPTION = 'Returns the newest torrents, with optional search criteria.';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'id' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'id' => [
|
||||
'name' => 'Category',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All categories' => '0',
|
||||
'Anime' => '1,2,3',
|
||||
'Anime - Sub' => '1',
|
||||
|
@ -34,12 +35,12 @@ class AnidexBridge extends BridgeAbstract {
|
|||
'Pictures' => '14',
|
||||
'Adult Video' => '15',
|
||||
'Other' => '16'
|
||||
)
|
||||
),
|
||||
'lang_id' => array(
|
||||
]
|
||||
],
|
||||
'lang_id' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All languages' => '0',
|
||||
'English' => '1',
|
||||
'Japanese' => '2',
|
||||
|
@ -72,52 +73,52 @@ class AnidexBridge extends BridgeAbstract {
|
|||
'Spanish (LATAM)' => '29',
|
||||
'Persian' => '30',
|
||||
'Malaysian' => '31'
|
||||
)
|
||||
),
|
||||
'group_id' => array(
|
||||
]
|
||||
],
|
||||
'group_id' => [
|
||||
'name' => 'Group ID',
|
||||
'type' => 'number'
|
||||
),
|
||||
'r' => array(
|
||||
],
|
||||
'r' => [
|
||||
'name' => 'Hide Remakes',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'b' => array(
|
||||
],
|
||||
'b' => [
|
||||
'name' => 'Only Batches',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'a' => array(
|
||||
],
|
||||
'a' => [
|
||||
'name' => 'Only Authorized',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'q' => array(
|
||||
],
|
||||
'q' => [
|
||||
'name' => 'Keyword',
|
||||
'description' => 'Keyword(s)',
|
||||
'type' => 'text'
|
||||
),
|
||||
'h' => array(
|
||||
],
|
||||
'h' => [
|
||||
'name' => 'Adult content',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'No filter' => '0',
|
||||
'Hide +18' => '1',
|
||||
'Only +18' => '2'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function collectData() {
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
// Build Search URL from user-provided parameters
|
||||
$search_url = self::ALTERNATE_URI . '?s=upload_timestamp&o=desc';
|
||||
foreach (array('id', 'lang_id', 'group_id') as $param_name) {
|
||||
foreach (['id', 'lang_id', 'group_id'] as $param_name) {
|
||||
$param = $this->getInput($param_name);
|
||||
if (!empty($param) && intval($param) != 0 && ctype_digit(str_replace(',', '', $param))) {
|
||||
$search_url .= '&' . $param_name . '=' . $param;
|
||||
}
|
||||
}
|
||||
foreach (array('r', 'b', 'a') as $param_name) {
|
||||
foreach (['r', 'b', 'a'] as $param_name) {
|
||||
$param = $this->getInput($param_name);
|
||||
if (!empty($param) && boolval($param)) {
|
||||
$search_url .= '&' . $param_name . '=1';
|
||||
|
@ -127,14 +128,14 @@ class AnidexBridge extends BridgeAbstract {
|
|||
if (!empty($query)) {
|
||||
$search_url .= '&q=' . urlencode($query);
|
||||
}
|
||||
$opt = array();
|
||||
$opt = [];
|
||||
$h = $this->getInput('h');
|
||||
if (!empty($h) && intval($h) != 0 && ctype_digit($h)) {
|
||||
$opt[CURLOPT_COOKIE] = 'anidex_h_toggle=' . $h;
|
||||
}
|
||||
|
||||
// We need to use a different Host HTTP header to reach the correct page on ALTERNATE_URI
|
||||
$headers = array('Host: ' . self::ALTERNATE_HOST);
|
||||
$headers = ['Host: ' . self::ALTERNATE_HOST];
|
||||
|
||||
// The HTTPS certificate presented by anidex.moe is for anidex.info. We need to ignore this.
|
||||
// As a consequence, the bridge is intentionally marked as insecure by setting self::URI to http://
|
||||
|
@ -144,18 +145,20 @@ class AnidexBridge extends BridgeAbstract {
|
|||
// Retrieve torrent listing from search results, which does not contain torrent description
|
||||
$html = getSimpleHTMLDOM($search_url, $headers, $opt);
|
||||
$links = $html->find('a');
|
||||
$results = array();
|
||||
foreach ($links as $link)
|
||||
if (strpos($link->href, '/torrent/') === 0 && !in_array($link->href, $results))
|
||||
$results = [];
|
||||
foreach ($links as $link) {
|
||||
if (strpos($link->href, '/torrent/') === 0 && !in_array($link->href, $results)) {
|
||||
$results[] = $link->href;
|
||||
if (empty($results) && empty($this->getInput('q')))
|
||||
}
|
||||
}
|
||||
if (empty($results) && empty($this->getInput('q'))) {
|
||||
returnServerError('No results from Anidex: ' . $search_url);
|
||||
}
|
||||
|
||||
//Process each item individually
|
||||
foreach ($results as $element) {
|
||||
|
||||
//Limit total amount of requests
|
||||
if(count($this->items) >= 20) {
|
||||
if (count($this->items) >= 20) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -163,14 +166,12 @@ class AnidexBridge extends BridgeAbstract {
|
|||
|
||||
//Ignore entries without valid torrent ID
|
||||
if ($torrent_id != 0 && ctype_digit($torrent_id)) {
|
||||
|
||||
//Retrieve data for this torrent ID
|
||||
$item_browse_uri = self::URI . 'torrent/' . $torrent_id;
|
||||
$item_fetch_uri = self::ALTERNATE_URI . 'torrent/' . $torrent_id;
|
||||
|
||||
//Retrieve full description from torrent page (cached for 24 hours: 86400 seconds)
|
||||
if ($item_html = getSimpleHTMLDOMCached($item_fetch_uri, 86400, $headers, $opt)) {
|
||||
|
||||
//Retrieve data from page contents
|
||||
$item_title = str_replace(' (Torrent) - AniDex ', '', $item_html->find('title', 0)->plaintext);
|
||||
$item_desc = $item_html->find('div.panel-body', 0);
|
||||
|
@ -200,12 +201,12 @@ class AnidexBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
//Build and add final item
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $item_browse_uri;
|
||||
$item['title'] = $item_title;
|
||||
$item['author'] = $item_author;
|
||||
$item['timestamp'] = $item_date;
|
||||
$item['enclosures'] = array($item_image);
|
||||
$item['enclosures'] = [$item_image];
|
||||
$item['content'] = $item_desc;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
|
|
@ -1,28 +1,29 @@
|
|||
<?php
|
||||
class AnimeUltimeBridge extends BridgeAbstract {
|
||||
|
||||
class AnimeUltimeBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'Anime-Ultime';
|
||||
const URI = 'http://www.anime-ultime.net/';
|
||||
const CACHE_TIMEOUT = 10800; // 3h
|
||||
const DESCRIPTION = 'Returns the newest releases posted on Anime-Ultime.';
|
||||
const PARAMETERS = array( array(
|
||||
'type' => array(
|
||||
const PARAMETERS = [ [
|
||||
'type' => [
|
||||
'name' => 'Type',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Everything' => '',
|
||||
'Anime' => 'A',
|
||||
'Drama' => 'D',
|
||||
'Tokusatsu' => 'T'
|
||||
)
|
||||
)
|
||||
));
|
||||
]
|
||||
]
|
||||
]];
|
||||
|
||||
private $filter = 'Releases';
|
||||
|
||||
public function collectData(){
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
//Add type filter if provided
|
||||
$typeFilter = array_search(
|
||||
$this->getInput('type'),
|
||||
|
@ -35,8 +36,7 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
|
||||
//Process each HTML page until having 10 releases
|
||||
$processedOK = 0;
|
||||
foreach (array($thismonth, $lastmonth) as $requestFilter) {
|
||||
|
||||
foreach ([$thismonth, $lastmonth] as $requestFilter) {
|
||||
$url = self::URI . 'history-0-1/' . $requestFilter;
|
||||
$html = getContents($url);
|
||||
// Convert html from iso-8859-1 => utf8
|
||||
|
@ -44,8 +44,7 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$html = str_get_html($html);
|
||||
|
||||
//Relases are sorted by day : process each day individually
|
||||
foreach($html->find('div.history', 0)->find('h3') as $daySection) {
|
||||
|
||||
foreach ($html->find('div.history', 0)->find('h3') as $daySection) {
|
||||
//Retrieve day and build date information
|
||||
$dateString = $daySection->plaintext;
|
||||
$day = intval(substr($dateString, strpos($dateString, ' ') + 1, 2));
|
||||
|
@ -59,9 +58,8 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$release = $daySection->next_sibling()->next_sibling()->first_child();
|
||||
|
||||
//Process each release of that day, ignoring first table row: contains table headers
|
||||
while(!is_null($release = $release->next_sibling())) {
|
||||
if(count($release->find('td')) > 0) {
|
||||
|
||||
while (!is_null($release = $release->next_sibling())) {
|
||||
if (count($release->find('td')) > 0) {
|
||||
//Retrieve metadata from table columns
|
||||
$item_link_element = $release->find('td', 0)->find('a', 0);
|
||||
$item_uri = self::URI . $item_link_element->href;
|
||||
|
@ -85,8 +83,7 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$item_fansub = $release->find('td', 2)->plaintext;
|
||||
$item_type = $release->find('td', 4)->plaintext;
|
||||
|
||||
if(!empty($item_uri)) {
|
||||
|
||||
if (!empty($item_uri)) {
|
||||
// Retrieve description from description page
|
||||
$html_item = getContents($item_uri);
|
||||
// Convert html from iso-8859-1 => utf8
|
||||
|
@ -95,7 +92,8 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$html_item,
|
||||
strpos($html_item, 'class="principal_contain" align="center">') + 41
|
||||
);
|
||||
$item_description = substr($item_description,
|
||||
$item_description = substr(
|
||||
$item_description,
|
||||
0,
|
||||
strpos($item_description, '<div id="table">')
|
||||
);
|
||||
|
@ -106,18 +104,18 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$item_description = str_replace("\n", '', $item_description);
|
||||
|
||||
//Build and add final item
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $item_uri;
|
||||
$item['title'] = $item_name . ' ' . $item_type . ' ' . $item_episode;
|
||||
$item['author'] = $item_fansub;
|
||||
$item['timestamp'] = $item_date;
|
||||
$item['enclosures'] = array($item_image);
|
||||
$item['enclosures'] = [$item_image];
|
||||
$item['content'] = $item_description;
|
||||
$this->items[] = $item;
|
||||
$processedOK++;
|
||||
|
||||
//Stop processing once limit is reached
|
||||
if ($processedOK >= 10)
|
||||
if ($processedOK >= 10) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -125,9 +123,11 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
if(!is_null($this->getInput('type'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('type'))) {
|
||||
$typeFilter = array_search(
|
||||
$this->getInput('type'),
|
||||
self::PARAMETERS[$this->queriedContext]['type']['values']
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
<?php
|
||||
|
||||
class AppleAppStoreBridge extends BridgeAbstract {
|
||||
|
||||
class AppleAppStoreBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'captn3m0';
|
||||
const NAME = 'Apple App Store';
|
||||
const URI = 'https://apps.apple.com/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'Returns version updates for a specific application';
|
||||
|
||||
const PARAMETERS = array(array(
|
||||
'id' => array(
|
||||
const PARAMETERS = [[
|
||||
'id' => [
|
||||
'name' => 'Application ID',
|
||||
'required' => true,
|
||||
'exampleValue' => '310633997'
|
||||
),
|
||||
'p' => array(
|
||||
],
|
||||
'p' => [
|
||||
'name' => 'Platform',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'iPad' => 'ipad',
|
||||
'iPhone' => 'iphone',
|
||||
'Mac' => 'mac',
|
||||
|
@ -26,36 +26,39 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
// but not yet tested
|
||||
'Web' => 'web',
|
||||
'Apple TV' => 'appletv',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'iphone',
|
||||
),
|
||||
'country' => array(
|
||||
],
|
||||
'country' => [
|
||||
'name' => 'Store Country',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'US' => 'US',
|
||||
'India' => 'IN',
|
||||
'Canada' => 'CA',
|
||||
'Germany' => 'DE',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'US',
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
const PLATFORM_MAPPING = array(
|
||||
const PLATFORM_MAPPING = [
|
||||
'iphone' => 'ios',
|
||||
'ipad' => 'ios',
|
||||
);
|
||||
];
|
||||
|
||||
private function makeHtmlUrl($id, $country){
|
||||
private function makeHtmlUrl($id, $country)
|
||||
{
|
||||
return 'https://apps.apple.com/' . $country . '/app/id' . $id;
|
||||
}
|
||||
|
||||
private function makeJsonUrl($id, $platform, $country){
|
||||
private function makeJsonUrl($id, $platform, $country)
|
||||
{
|
||||
return "https://amp-api.apps.apple.com/v1/catalog/$country/apps/$id?platform=$platform&extend=versionHistory";
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
public function getName()
|
||||
{
|
||||
if (isset($this->name)) {
|
||||
return $this->name . ' - AppStore Updates';
|
||||
}
|
||||
|
@ -66,7 +69,8 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
/**
|
||||
* In case of some platforms, the data is present in the initial response
|
||||
*/
|
||||
private function getDataFromShoebox($id, $platform, $country){
|
||||
private function getDataFromShoebox($id, $platform, $country)
|
||||
{
|
||||
$uri = $this->makeHtmlUrl($id, $country);
|
||||
$html = getSimpleHTMLDOMCached($uri, 3600);
|
||||
$script = $html->find('script[id="shoebox-ember-data-store"]', 0);
|
||||
|
@ -75,7 +79,8 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
return $json['data'];
|
||||
}
|
||||
|
||||
private function getJWTToken($id, $platform, $country){
|
||||
private function getJWTToken($id, $platform, $country)
|
||||
{
|
||||
$uri = $this->makeHtmlUrl($id, $country);
|
||||
|
||||
$html = getSimpleHTMLDOMCached($uri, 3600);
|
||||
|
@ -89,13 +94,14 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
return $json->MEDIA_API->token;
|
||||
}
|
||||
|
||||
private function getAppData($id, $platform, $country, $token){
|
||||
private function getAppData($id, $platform, $country, $token)
|
||||
{
|
||||
$uri = $this->makeJsonUrl($id, $platform, $country);
|
||||
|
||||
$headers = array(
|
||||
$headers = [
|
||||
"Authorization: Bearer $token",
|
||||
'Origin: https://apps.apple.com',
|
||||
);
|
||||
];
|
||||
|
||||
$json = json_decode(getContents($uri, $headers), true);
|
||||
|
||||
|
@ -106,8 +112,9 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
* Parses the version history from the data received
|
||||
* @return array list of versions with details on each element
|
||||
*/
|
||||
private function getVersionHistory($data, $platform){
|
||||
switch($platform) {
|
||||
private function getVersionHistory($data, $platform)
|
||||
{
|
||||
switch ($platform) {
|
||||
case 'mac':
|
||||
return $data['relationships']['platforms']['data'][0]['attributes']['versionHistory'];
|
||||
default:
|
||||
|
@ -116,7 +123,8 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$id = $this->getInput('id');
|
||||
$country = $this->getInput('country');
|
||||
$platform = $this->getInput('p');
|
||||
|
@ -136,7 +144,7 @@ class AppleAppStoreBridge extends BridgeAbstract {
|
|||
$author = $data['attributes']['artistName'];
|
||||
|
||||
foreach ($versionHistory as $row) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$item['content'] = nl2br($row['releaseNotes']);
|
||||
$item['title'] = $name . ' - ' . $row['versionDisplay'];
|
||||
|
|
|
@ -1,25 +1,27 @@
|
|||
<?php
|
||||
|
||||
class AppleMusicBridge extends BridgeAbstract {
|
||||
class AppleMusicBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Apple Music';
|
||||
const URI = 'https://www.apple.com';
|
||||
const DESCRIPTION = 'Fetches the latest releases from an artist';
|
||||
const MAINTAINER = 'bockiii';
|
||||
const PARAMETERS = array(array(
|
||||
'artist' => array(
|
||||
const PARAMETERS = [[
|
||||
'artist' => [
|
||||
'name' => 'Artist ID',
|
||||
'exampleValue' => '909253',
|
||||
'required' => true,
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'Latest X Releases (max 50)',
|
||||
'defaultValue' => '10',
|
||||
'required' => true,
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
const CACHE_TIMEOUT = 21600; // 6 hours
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
# Limit the amount of releases to 50
|
||||
if ($this->getInput('limit') > 50) {
|
||||
$limit = 50;
|
||||
|
@ -38,7 +40,7 @@ class AppleMusicBridge extends BridgeAbstract {
|
|||
|
||||
foreach ($json->results as $obj) {
|
||||
if ($obj->wrapperType === 'collection') {
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'title' => $obj->artistName . ' - ' . $obj->collectionName,
|
||||
'uri' => $obj->collectionViewUrl,
|
||||
'timestamp' => $obj->releaseDate,
|
||||
|
@ -48,7 +50,7 @@ class AppleMusicBridge extends BridgeAbstract {
|
|||
. $obj->artistName . ' - ' . $obj->collectionName
|
||||
. '<br>'
|
||||
. $obj->copyright,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,65 +1,72 @@
|
|||
<?php
|
||||
class ArtStationBridge extends BridgeAbstract {
|
||||
|
||||
class ArtStationBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'ArtStation';
|
||||
const URI = 'https://www.artstation.com';
|
||||
const DESCRIPTION = 'Fetches the latest ten artworks from a search query on ArtStation.';
|
||||
const MAINTAINER = 'thefranke';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
|
||||
const PARAMETERS = array(
|
||||
'Search Query' => array(
|
||||
'q' => array(
|
||||
const PARAMETERS = [
|
||||
'Search Query' => [
|
||||
'q' => [
|
||||
'name' => 'Search term',
|
||||
'required' => true,
|
||||
'exampleValue' => 'bird'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.artstation.com/assets/favicon-58653022bc38c1905ac7aa1b10bffa6b.ico';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return self::NAME . ': ' . $this->getInput('q');
|
||||
}
|
||||
|
||||
private function fetchSearch($searchQuery) {
|
||||
private function fetchSearch($searchQuery)
|
||||
{
|
||||
$data = '{"query":"' . $searchQuery . '","page":1,"per_page":50,"sorting":"date",';
|
||||
$data .= '"pro_first":"1","filters":[],"additional_fields":[]}';
|
||||
|
||||
$header = array(
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
'Accept: application/json'
|
||||
);
|
||||
];
|
||||
|
||||
$opts = array(
|
||||
$opts = [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $data,
|
||||
CURLOPT_RETURNTRANSFER => true
|
||||
);
|
||||
];
|
||||
|
||||
$jsonSearchURL = self::URI . '/api/v2/search/projects.json';
|
||||
$jsonSearchStr = getContents($jsonSearchURL, $header, $opts);
|
||||
return json_decode($jsonSearchStr);
|
||||
}
|
||||
|
||||
private function fetchProject($hashID) {
|
||||
private function fetchProject($hashID)
|
||||
{
|
||||
$jsonProjectURL = self::URI . '/projects/' . $hashID . '.json';
|
||||
$jsonProjectStr = getContents($jsonProjectURL);
|
||||
return json_decode($jsonProjectStr);
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$searchTerm = $this->getInput('q');
|
||||
$jsonQuery = $this->fetchSearch($searchTerm);
|
||||
|
||||
foreach($jsonQuery->data as $media) {
|
||||
foreach ($jsonQuery->data as $media) {
|
||||
// get detailed info about media item
|
||||
$jsonProject = $this->fetchProject($media->hash_id);
|
||||
|
||||
// create item
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $media->title;
|
||||
$item['uri'] = $media->url;
|
||||
$item['timestamp'] = strtotime($jsonProject->published_at);
|
||||
|
@ -76,17 +83,19 @@ class ArtStationBridge extends BridgeAbstract {
|
|||
|
||||
$numAssets = count($jsonProject->assets);
|
||||
|
||||
if ($numAssets > 1)
|
||||
if ($numAssets > 1) {
|
||||
$item['content'] .= '<p><a href="'
|
||||
. $media->url
|
||||
. '">Project contains '
|
||||
. ($numAssets - 1)
|
||||
. ' more item(s).</a></p>';
|
||||
}
|
||||
|
||||
$this->items[] = $item;
|
||||
|
||||
if (count($this->items) >= 10)
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class Arte7Bridge extends BridgeAbstract {
|
||||
|
||||
class Arte7Bridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Arte +7';
|
||||
const URI = 'https://www.arte.tv/';
|
||||
const MAINTAINER = 'imagoiq';
|
||||
|
@ -9,14 +10,14 @@ class Arte7Bridge extends BridgeAbstract {
|
|||
|
||||
const API_TOKEN = 'Nzc1Yjc1ZjJkYjk1NWFhN2I2MWEwMmRlMzAzNjI5NmU3NWU3ODg4ODJjOWMxNTMxYzEzZGRjYjg2ZGE4MmIwOA';
|
||||
|
||||
const PARAMETERS = array(
|
||||
const PARAMETERS = [
|
||||
'global' => [
|
||||
'sort_by' => array(
|
||||
'sort_by' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Sort by',
|
||||
'required' => false,
|
||||
'defaultValue' => null,
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Default' => null,
|
||||
'Video rights start date' => 'videoRightsBegin',
|
||||
'Video rights end date' => 'videoRightsEnd',
|
||||
|
@ -27,18 +28,18 @@ class Arte7Bridge extends BridgeAbstract {
|
|||
'Number of views per period' => 'viewsPeriod',
|
||||
'Available screens' => 'availableScreens',
|
||||
'Episode' => 'episode'
|
||||
),
|
||||
),
|
||||
'sort_direction' => array(
|
||||
],
|
||||
],
|
||||
'sort_direction' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Sort direction',
|
||||
'required' => false,
|
||||
'defaultValue' => 'DESC',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Ascending' => 'ASC',
|
||||
'Descending' => 'DESC'
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
'exclude_trailers' => [
|
||||
'name' => 'Exclude trailers',
|
||||
'type' => 'checkbox',
|
||||
|
@ -46,23 +47,23 @@ class Arte7Bridge extends BridgeAbstract {
|
|||
'defaultValue' => false
|
||||
],
|
||||
],
|
||||
'Category' => array(
|
||||
'lang' => array(
|
||||
'Category' => [
|
||||
'lang' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Language',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Français' => 'fr',
|
||||
'Deutsch' => 'de',
|
||||
'English' => 'en',
|
||||
'Español' => 'es',
|
||||
'Polski' => 'pl',
|
||||
'Italiano' => 'it'
|
||||
),
|
||||
),
|
||||
'cat' => array(
|
||||
],
|
||||
],
|
||||
'cat' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Category',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All videos' => null,
|
||||
'News & society' => 'ACT',
|
||||
'Series & fiction' => 'SER',
|
||||
|
@ -73,33 +74,34 @@ class Arte7Bridge extends BridgeAbstract {
|
|||
'History' => 'HIST',
|
||||
'Science' => 'SCI',
|
||||
'Other' => 'AUT'
|
||||
)
|
||||
),
|
||||
),
|
||||
'Collection' => array(
|
||||
'lang' => array(
|
||||
]
|
||||
],
|
||||
],
|
||||
'Collection' => [
|
||||
'lang' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Language',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Français' => 'fr',
|
||||
'Deutsch' => 'de',
|
||||
'English' => 'en',
|
||||
'Español' => 'es',
|
||||
'Polski' => 'pl',
|
||||
'Italiano' => 'it'
|
||||
)
|
||||
),
|
||||
'col' => array(
|
||||
]
|
||||
],
|
||||
'col' => [
|
||||
'name' => 'Collection id',
|
||||
'required' => true,
|
||||
'title' => 'ex. RC-014095 pour https://www.arte.tv/de/videos/RC-014095/blow-up/',
|
||||
'exampleValue' => 'RC-014095'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
switch($this->queriedContext) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Category':
|
||||
$category = $this->getInput('cat');
|
||||
$collectionId = null;
|
||||
|
@ -120,29 +122,30 @@ class Arte7Bridge extends BridgeAbstract {
|
|||
. ($category != null ? '&category.code=' . $category : '')
|
||||
. ($collectionId != null ? '&collections.collectionId=' . $collectionId : '');
|
||||
|
||||
$header = array(
|
||||
$header = [
|
||||
'Authorization: Bearer ' . self::API_TOKEN
|
||||
);
|
||||
];
|
||||
|
||||
$input = getContents($url, $header);
|
||||
$input_json = json_decode($input, true);
|
||||
|
||||
foreach($input_json['videos'] as $element) {
|
||||
if($this->getInput('exclude_trailers') && $element['platform'] == 'EXTRAIT') {
|
||||
foreach ($input_json['videos'] as $element) {
|
||||
if ($this->getInput('exclude_trailers') && $element['platform'] == 'EXTRAIT') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$durationSeconds = $element['durationSeconds'];
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $element['url'];
|
||||
$item['id'] = $element['id'];
|
||||
|
||||
$item['timestamp'] = strtotime($element['videoRightsBegin']);
|
||||
$item['title'] = $element['title'];
|
||||
|
||||
if(!empty($element['subtitle']))
|
||||
if (!empty($element['subtitle'])) {
|
||||
$item['title'] = $element['title'] . ' | ' . $element['subtitle'];
|
||||
}
|
||||
|
||||
$durationMinutes = round((int)$durationSeconds / 60);
|
||||
$item['content'] = $element['teaserText']
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
class AsahiShimbunAJWBridge extends BridgeAbstract {
|
||||
|
||||
class AsahiShimbunAJWBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Asahi Shimbun AJW';
|
||||
const BASE_URI = 'http://www.asahi.com';
|
||||
const URI = self::BASE_URI . '/ajw/';
|
||||
const DESCRIPTION = 'Asahi Shimbun - Asia & Japan Watch';
|
||||
const MAINTAINER = 'somini';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'section' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'section' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Section',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Japan » Social Affairs' => 'japan/social',
|
||||
'Japan » People' => 'japan/people',
|
||||
'Japan » 3/11 Disaster' => 'japan/0311disaster',
|
||||
|
@ -26,25 +28,27 @@ class AsahiShimbunAJWBridge extends BridgeAbstract {
|
|||
'Asia » World' => 'asia_world/world',
|
||||
'Opinion » Editorial' => 'opinion/editorial',
|
||||
'Opinion » Vox Populi' => 'opinion/vox',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'politics',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private function getSectionURI($section) {
|
||||
private function getSectionURI($section)
|
||||
{
|
||||
return self::getURI() . $section . '/';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getSectionURI($this->getInput('section')));
|
||||
|
||||
foreach($html->find('#MainInner li a') as $element) {
|
||||
foreach ($html->find('#MainInner li a') as $element) {
|
||||
if ($element->parent()->class == 'HeadlineTopImage-S') {
|
||||
Debug::log('Skip Headline, it is repeated below');
|
||||
continue;
|
||||
}
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = self::BASE_URI . $element->href;
|
||||
$e_lead = $element->find('span.Lead', 0);
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
<?php
|
||||
class AskfmBridge extends BridgeAbstract {
|
||||
|
||||
class AskfmBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'az5he6ch, logmanoriginal';
|
||||
const NAME = 'Ask.fm Answers';
|
||||
const URI = 'https://ask.fm/';
|
||||
const CACHE_TIMEOUT = 300; //5 min
|
||||
const DESCRIPTION = 'Returns answers from an Ask.fm user';
|
||||
const PARAMETERS = array(
|
||||
'Ask.fm username' => array(
|
||||
'u' => array(
|
||||
const PARAMETERS = [
|
||||
'Ask.fm username' => [
|
||||
'u' => [
|
||||
'name' => 'Username',
|
||||
'required' => true,
|
||||
'exampleValue' => 'ApprovedAndReal'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
|
||||
foreach($html->find('article.streamItem-answer') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('article.streamItem-answer') as $element) {
|
||||
$item = [];
|
||||
$item['uri'] = $element->find('a.streamItem_meta', 0)->href;
|
||||
$question = trim($element->find('header.streamItem_header', 0)->innertext);
|
||||
|
||||
$item['title'] = trim(
|
||||
htmlspecialchars_decode($element->find('header.streamItem_header', 0)->plaintext,
|
||||
htmlspecialchars_decode(
|
||||
$element->find('header.streamItem_header', 0)->plaintext,
|
||||
ENT_QUOTES
|
||||
)
|
||||
);
|
||||
|
@ -37,13 +40,13 @@ class AskfmBridge extends BridgeAbstract {
|
|||
$answer = trim($element->find('div.streamItem_content', 0)->innertext);
|
||||
|
||||
// This probably should be cleaned up, especially for YouTube embeds
|
||||
if($visual = $element->find('div.streamItem_visual', 0)) {
|
||||
if ($visual = $element->find('div.streamItem_visual', 0)) {
|
||||
$visual = $visual->innertext;
|
||||
}
|
||||
|
||||
// Fix tracking links, also doesn't work
|
||||
foreach($element->find('a') as $link) {
|
||||
if(strpos($link->href, 'l.ask.fm') !== false) {
|
||||
foreach ($element->find('a') as $link) {
|
||||
if (strpos($link->href, 'l.ask.fm') !== false) {
|
||||
$link->href = $link->plaintext;
|
||||
}
|
||||
}
|
||||
|
@ -56,16 +59,18 @@ class AskfmBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('u'))) {
|
||||
return self::NAME . ' : ' . $this->getInput('u');
|
||||
}
|
||||
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('u'))) {
|
||||
return self::URI . urlencode($this->getInput('u'));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
<?php
|
||||
class AssociatedPressNewsBridge extends BridgeAbstract {
|
||||
|
||||
class AssociatedPressNewsBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Associated Press News Bridge';
|
||||
const URI = 'https://apnews.com/';
|
||||
const DESCRIPTION = 'Returns newest articles by topic';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(
|
||||
'Standard Topics' => array(
|
||||
'topic' => array(
|
||||
const PARAMETERS = [
|
||||
'Standard Topics' => [
|
||||
'topic' => [
|
||||
'name' => 'Topic',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'AP Top News' => 'apf-topnews',
|
||||
'Sports' => 'apf-sports',
|
||||
'Entertainment' => 'apf-entertainment',
|
||||
|
@ -27,19 +29,19 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
'Photo Galleries' => 'PhotoGalleries',
|
||||
'Fact Checks' => 'APFactCheck',
|
||||
'Videos' => 'apf-videos',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'apf-topnews',
|
||||
),
|
||||
),
|
||||
'Custom Topic' => array(
|
||||
'topic' => array(
|
||||
],
|
||||
],
|
||||
'Custom Topic' => [
|
||||
'topic' => [
|
||||
'name' => 'Topic',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'europe'
|
||||
),
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
const CACHE_TIMEOUT = 900; // 15 mins
|
||||
|
||||
|
@ -47,10 +49,11 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
private $tagEndpoint = 'https://afs-prod.appspot.com/api/v2/feed/tag?tags=';
|
||||
private $feedName = '';
|
||||
|
||||
public function detectParameters($url) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
if(preg_match($this->detectParamRegex, $url, $matches) > 0) {
|
||||
if (preg_match($this->detectParamRegex, $url, $matches) > 0) {
|
||||
$params['topic'] = $matches[1];
|
||||
$params['context'] = 'Custom Topic';
|
||||
return $params;
|
||||
|
@ -59,8 +62,9 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
switch($this->getInput('topic')) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->getInput('topic')) {
|
||||
case 'Podcasts':
|
||||
returnClientError('Podcasts topic feed is not supported');
|
||||
break;
|
||||
|
@ -72,7 +76,8 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('topic'))) {
|
||||
return self::URI . $this->getInput('topic');
|
||||
}
|
||||
|
@ -80,7 +85,8 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if (!empty($this->feedName)) {
|
||||
return $this->feedName . ' - Associated Press';
|
||||
}
|
||||
|
@ -88,7 +94,8 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
private function getTagURI() {
|
||||
private function getTagURI()
|
||||
{
|
||||
if (!is_null($this->getInput('topic'))) {
|
||||
return $this->tagEndpoint . $this->getInput('topic');
|
||||
}
|
||||
|
@ -96,7 +103,8 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
private function collectCardData() {
|
||||
private function collectCardData()
|
||||
{
|
||||
$json = getContents($this->getTagURI())
|
||||
or returnServerError('Could not request: ' . $this->getTagURI());
|
||||
|
||||
|
@ -109,7 +117,7 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
$this->feedName = $tagContents['tagObjs'][0]['name'];
|
||||
|
||||
foreach ($tagContents['cards'] as $card) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
// skip hub peeks & Notifications
|
||||
if ($card['cardType'] == 'Hub Peek' || $card['cardType'] == 'Notification') {
|
||||
|
@ -118,7 +126,7 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
|
||||
$storyContent = $card['contents'][0];
|
||||
|
||||
switch($storyContent['contentType']) {
|
||||
switch ($storyContent['contentType']) {
|
||||
case 'web': // Skip link only content
|
||||
continue 2;
|
||||
|
||||
|
@ -178,8 +186,8 @@ class AssociatedPressNewsBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function processMediaPlaceholders($html, $id) {
|
||||
|
||||
private function processMediaPlaceholders($html, $id)
|
||||
{
|
||||
if ($html->find('div.media-placeholder', 0)) {
|
||||
// Fetch page content
|
||||
$json = getContents('https://afs-prod.appspot.com/api/v2/content/' . $id);
|
||||
|
@ -216,11 +224,10 @@ EOD;
|
|||
/*
|
||||
Create full coverage links (HubLinks)
|
||||
*/
|
||||
private function processHubLinks($html, $storyContent) {
|
||||
|
||||
private function processHubLinks($html, $storyContent)
|
||||
{
|
||||
if (!empty($storyContent['richEmbeds'])) {
|
||||
foreach ($storyContent['richEmbeds'] as $embed) {
|
||||
|
||||
if ($embed['type'] === 'Hub Link') {
|
||||
$url = self::URI . $embed['tag']['id'];
|
||||
$div = $html->find('div[id=' . $embed['id'] . ']', 0);
|
||||
|
@ -235,7 +242,8 @@ EOD;
|
|||
}
|
||||
}
|
||||
|
||||
private function processVideo($storyContent) {
|
||||
private function processVideo($storyContent)
|
||||
{
|
||||
$video = $storyContent['media'][0];
|
||||
|
||||
if ($video['type'] === 'YouTube') {
|
||||
|
@ -255,8 +263,8 @@ EOD;
|
|||
}
|
||||
|
||||
// Remove datawrapper.dwcdn.net iframes and related javaScript
|
||||
private function processIframes($html) {
|
||||
|
||||
private function processIframes($html)
|
||||
{
|
||||
foreach ($html->find('iframe') as $index => $iframe) {
|
||||
if (preg_match('/datawrapper\.dwcdn\.net/', $iframe->src)) {
|
||||
$iframe->outertext = '';
|
||||
|
|
|
@ -1,42 +1,47 @@
|
|||
<?php
|
||||
class AstrophysicsDataSystemBridge extends BridgeAbstract {
|
||||
|
||||
class AstrophysicsDataSystemBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'SAO/NASA Astrophysics Data System';
|
||||
const DESCRIPTION = 'Returns the latest publications from a query';
|
||||
const URI = 'https://ui.adsabs.harvard.edu';
|
||||
const PARAMETERS = array(
|
||||
'Publications' => array(
|
||||
'query' => array(
|
||||
const PARAMETERS = [
|
||||
'Publications' => [
|
||||
'query' => [
|
||||
'name' => 'query',
|
||||
'title' => 'Same format as the search bar on the website',
|
||||
'exampleValue' => 'author:"huchra, john"',
|
||||
'required' => true
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
private $feedTitle;
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if ($this->queriedContext === 'Publications') {
|
||||
return $this->feedTitle;
|
||||
}
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
if ($this->queriedContext === 'Publications') {
|
||||
return self::URI . '/search/?q=' . urlencode($this->getInput('query'));
|
||||
}
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
$headers = array (
|
||||
public function collectData()
|
||||
{
|
||||
$headers = [
|
||||
'Cookie: core=always;'
|
||||
);
|
||||
];
|
||||
$html = str_get_html(defaultLinkTo(getContents($this->getURI(), $headers), self::URI));
|
||||
$this->feedTitle = html_entity_decode($html->find('title', 0)->plaintext);
|
||||
foreach($html->find('div.row > ul > li') as $pub) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.row > ul > li') as $pub) {
|
||||
$item = [];
|
||||
$item['title'] = $pub->find('h3.s-results-title', 0)->plaintext;
|
||||
$item['content'] = $pub->find('div.s-results-links', 0);
|
||||
$item['uri'] = $pub->find('a.abs-redirect-link', 0)->href;
|
||||
|
|
|
@ -1,22 +1,24 @@
|
|||
<?php
|
||||
class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
||||
|
||||
class AtmoNouvelleAquitaineBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Atmo Nouvelle Aquitaine';
|
||||
const URI = 'https://www.atmo-nouvelleaquitaine.org';
|
||||
const DESCRIPTION = 'Fetches the latest air polution of cities in Nouvelle Aquitaine from Atmo';
|
||||
const MAINTAINER = 'floviolleau';
|
||||
const PARAMETERS = array(array(
|
||||
'cities' => array(
|
||||
const PARAMETERS = [[
|
||||
'cities' => [
|
||||
'name' => 'Choisir une ville',
|
||||
'type' => 'list',
|
||||
'values' => self::CITIES
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
const CACHE_TIMEOUT = 7200;
|
||||
|
||||
private $dom;
|
||||
|
||||
private function getClosest($search, $arr) {
|
||||
private function getClosest($search, $arr)
|
||||
{
|
||||
$closest = null;
|
||||
foreach ($arr as $key => $value) {
|
||||
if ($closest === null || abs((int)$search - $closest) > abs((int)$key - (int)$search)) {
|
||||
|
@ -26,7 +28,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $arr[$closest];
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$uri = self::URI . '/monair/commune/' . $this->getInput('cities');
|
||||
|
||||
$html = getSimpleHTMLDOM($uri);
|
||||
|
@ -47,7 +50,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
private function getIndex() {
|
||||
private function getIndex()
|
||||
{
|
||||
$index = $this->dom->find('.indice', 0)->innertext;
|
||||
|
||||
if ($index == 'XX') {
|
||||
|
@ -57,12 +61,14 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $index;
|
||||
}
|
||||
|
||||
private function getMaxIndexText() {
|
||||
private function getMaxIndexText()
|
||||
{
|
||||
// will return '/100'
|
||||
return $this->dom->find('.pourcent', 0)->innertext;
|
||||
}
|
||||
|
||||
private function getQualityText($index, $indexes) {
|
||||
private function getQualityText($index, $indexes)
|
||||
{
|
||||
if ($index == -1) {
|
||||
if (array_key_exists('no-available', $indexes)) {
|
||||
return $indexes['no-available'];
|
||||
|
@ -74,9 +80,10 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $this->getClosest($index, $indexes);
|
||||
}
|
||||
|
||||
private function getLegendIndexes() {
|
||||
private function getLegendIndexes()
|
||||
{
|
||||
$rawIndexes = $this->dom->find('.prevision-legend .prevision-legend-label');
|
||||
$indexes = array();
|
||||
$indexes = [];
|
||||
for ($i = 0; $i < count($rawIndexes); $i++) {
|
||||
if ($rawIndexes[$i]->hasAttribute('data-color')) {
|
||||
$indexes[$rawIndexes[$i]->getAttribute('data-color')] = $rawIndexes[$i]->innertext;
|
||||
|
@ -86,7 +93,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $indexes;
|
||||
}
|
||||
|
||||
private function getTomorrowTrendIndex() {
|
||||
private function getTomorrowTrendIndex()
|
||||
{
|
||||
$tomorrowTrendDomNode = $this->dom
|
||||
->find('.day-controls.raster-controls .list-raster-controls .raster-control', 2);
|
||||
$tomorrowTrendIndexNode = null;
|
||||
|
@ -104,7 +112,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $tomorrowTrendIndex;
|
||||
}
|
||||
|
||||
private function getTomorrowTrendQualityText($trendIndex, $indexes) {
|
||||
private function getTomorrowTrendQualityText($trendIndex, $indexes)
|
||||
{
|
||||
if ($trendIndex == -1) {
|
||||
if (array_key_exists('no-available', $indexes)) {
|
||||
return $indexes['no-available'];
|
||||
|
@ -116,7 +125,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return $this->getClosest($trendIndex, $indexes);
|
||||
}
|
||||
|
||||
private function getIndexMessage() {
|
||||
private function getIndexMessage()
|
||||
{
|
||||
$index = $this->getIndex();
|
||||
$maxIndexText = $this->getMaxIndexText();
|
||||
|
||||
|
@ -127,7 +137,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return "L'indice d'aujourd'hui est $index$maxIndexText.";
|
||||
}
|
||||
|
||||
private function getQualityMessage() {
|
||||
private function getQualityMessage()
|
||||
{
|
||||
$index = $index = $this->getIndex();
|
||||
$indexes = $this->getLegendIndexes();
|
||||
$quality = $this->getQualityText($index, $indexes);
|
||||
|
@ -139,7 +150,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return "La qualité de l'air est $quality.";
|
||||
}
|
||||
|
||||
private function getTomorrowTrendIndexMessage() {
|
||||
private function getTomorrowTrendIndexMessage()
|
||||
{
|
||||
$trendIndex = $this->getTomorrowTrendIndex();
|
||||
$maxIndexText = $this->getMaxIndexText();
|
||||
|
||||
|
@ -150,7 +162,8 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return "L'indice prévu pour demain est $trendIndex$maxIndexText.";
|
||||
}
|
||||
|
||||
private function getTomorrowTrendQualityMessage() {
|
||||
private function getTomorrowTrendQualityMessage()
|
||||
{
|
||||
$trendIndex = $this->getTomorrowTrendIndex();
|
||||
$indexes = $this->getLegendIndexes();
|
||||
$trendQuality = $this->getTomorrowTrendQualityText($trendIndex, $indexes);
|
||||
|
@ -161,7 +174,7 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
return "La qualite de l'air pour demain sera $trendQuality.";
|
||||
}
|
||||
|
||||
const CITIES = array(
|
||||
const CITIES = [
|
||||
'Aast (64460)' => '64001',
|
||||
'Abère (64160)' => '64002',
|
||||
'Abidos (64150)' => '64003',
|
||||
|
@ -4633,5 +4646,5 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
'Yvrac (33370)' => '33554',
|
||||
'Yvrac-et-Malleyrand (16110)' => '16425',
|
||||
'Yzosse (40180)' => '40334'
|
||||
);
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
<?php
|
||||
class AtmoOccitanieBridge extends BridgeAbstract {
|
||||
|
||||
class AtmoOccitanieBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Atmo Occitanie';
|
||||
const URI = 'https://www.atmo-occitanie.org/';
|
||||
const DESCRIPTION = 'Fetches the latest air polution of cities in Occitanie from Atmo';
|
||||
const MAINTAINER = 'floviolleau';
|
||||
const PARAMETERS = array(array(
|
||||
'city' => array(
|
||||
const PARAMETERS = [[
|
||||
'city' => [
|
||||
'name' => 'Ville',
|
||||
'required' => true,
|
||||
'exampleValue' => 'cahors'
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
const CACHE_TIMEOUT = 7200;
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$uri = self::URI . $this->getInput('city');
|
||||
|
||||
$html = getSimpleHTMLDOM($uri);
|
||||
|
|
|
@ -1,48 +1,49 @@
|
|||
<?php
|
||||
|
||||
class AutoJMBridge extends BridgeAbstract {
|
||||
|
||||
class AutoJMBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'AutoJM';
|
||||
const URI = 'https://www.autojm.fr/';
|
||||
const DESCRIPTION = 'Suivre les offres de véhicules proposés par AutoJM en fonction des critères de filtrages';
|
||||
const MAINTAINER = 'sysadminstory';
|
||||
const PARAMETERS = array(
|
||||
'Afficher les offres de véhicules disponible sur la recheche AutoJM' => array(
|
||||
'url' => array(
|
||||
const PARAMETERS = [
|
||||
'Afficher les offres de véhicules disponible sur la recheche AutoJM' => [
|
||||
'url' => [
|
||||
'name' => 'URL de la page de recherche',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'URL d\'une recherche avec filtre de véhicules sans le http://www.autojm.fr/',
|
||||
'exampleValue' => 'recherche?brands[]=peugeot&ranges[]=peugeot-nouvelle-308-2021-5p'
|
||||
),
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
];
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . 'favicon.ico';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Afficher les offres de véhicules disponible sur la recheche AutoJM':
|
||||
return 'AutoJM | Recherche de véhicules';
|
||||
break;
|
||||
default:
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
// Get the number of result for this search
|
||||
$search_url = self::URI . $this->getInput('url') . '&open=energy&onlyFilters=false';
|
||||
|
||||
// Set the header 'X-Requested-With' like the website does it
|
||||
$header = array(
|
||||
$header = [
|
||||
'X-Requested-With: XMLHttpRequest'
|
||||
);
|
||||
];
|
||||
|
||||
// Get the JSON content of the form
|
||||
$json = getContents($search_url, $header);
|
||||
|
@ -54,14 +55,13 @@ class AutoJMBridge extends BridgeAbstract {
|
|||
$total_pages = ceil($nb_results / 15);
|
||||
|
||||
// Limit the number of page to analyse to 10
|
||||
for($page = 1; $page <= $total_pages && $page <= 10; $page++) {
|
||||
for ($page = 1; $page <= $total_pages && $page <= 10; $page++) {
|
||||
// Get the result the next page
|
||||
$html = $this->getResults($page);
|
||||
|
||||
// Go through every car of the search
|
||||
$list = $html->find('div[class*=card-car card-car--listing]');
|
||||
foreach ($list as $car) {
|
||||
|
||||
// Get the info about the car offer
|
||||
$image = $car->find('div[class=card-car__header__img]', 0)->find('img', 0)->src;
|
||||
// Decode HTML attribute JSON data
|
||||
|
@ -89,7 +89,7 @@ class AutoJMBridge extends BridgeAbstract {
|
|||
$transmission = $car->find('span[data-cfg=vehicle__transmission]', 0)->plaintext;
|
||||
$loa_html = $car->find('span[data-cfg=vehicle__loa]', 0);
|
||||
// Check if any LOA price is displayed
|
||||
if($loa_html != null) {
|
||||
if ($loa_html != null) {
|
||||
$loa_value = $car->find('span[data-cfg=vehicle__loa]', 0)->plaintext;
|
||||
$loa = '<li>LOA : à partir de ' . $loa_value . ' / mois </li>';
|
||||
} else {
|
||||
|
@ -97,7 +97,7 @@ class AutoJMBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Construct the new item
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $car_model;
|
||||
$item['content'] = '<p><img style="vertical-align:middle ; padding: 10px" src="' . $image . '" />'
|
||||
. $car_model . '</p>';
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
class AwwwardsBridge extends BridgeAbstract {
|
||||
|
||||
class AwwwardsBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Awwwards';
|
||||
const URI = 'https://www.awwwards.com/';
|
||||
const DESCRIPTION = 'Fetches the latest ten sites of the day from Awwwards';
|
||||
|
@ -10,31 +12,37 @@ class AwwwardsBridge extends BridgeAbstract {
|
|||
const SITEURI = 'https://www.awwwards.com/sites/';
|
||||
const ASSETSURI = 'https://assets.awwwards.com/awards/media/cache/thumb_417_299/';
|
||||
|
||||
private $sites = array();
|
||||
private $sites = [];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.awwwards.com/favicon.ico';
|
||||
}
|
||||
|
||||
private function fetchSites() {
|
||||
private function fetchSites()
|
||||
{
|
||||
Debug::log('Fetching all sites');
|
||||
$sites = getSimpleHTMLDOM(self::SITESURI);
|
||||
|
||||
Debug::log('Parsing all JSON data');
|
||||
foreach($sites->find('li[data-model]') as $site) {
|
||||
$decode = html_entity_decode($site->attr['data-model'],
|
||||
ENT_QUOTES, 'utf-8');
|
||||
foreach ($sites->find('li[data-model]') as $site) {
|
||||
$decode = html_entity_decode(
|
||||
$site->attr['data-model'],
|
||||
ENT_QUOTES,
|
||||
'utf-8'
|
||||
);
|
||||
$decode = json_decode($decode, true);
|
||||
$this->sites[] = $decode;
|
||||
}
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$this->fetchSites();
|
||||
|
||||
Debug::log('Building RSS feed');
|
||||
foreach($this->sites as $site) {
|
||||
$item = array();
|
||||
foreach ($this->sites as $site) {
|
||||
$item = [];
|
||||
$item['title'] = $site['title'];
|
||||
$item['timestamp'] = $site['createdAt'];
|
||||
$item['categories'] = $site['tags'];
|
||||
|
@ -47,8 +55,9 @@ class AwwwardsBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
|
||||
if(count($this->items) >= 10)
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,33 @@
|
|||
<?php
|
||||
class BAEBridge extends BridgeAbstract {
|
||||
|
||||
class BAEBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'couraudt';
|
||||
const NAME = 'Bourse Aux Equipiers Bridge';
|
||||
const URI = 'https://www.bourse-aux-equipiers.com';
|
||||
const DESCRIPTION = 'Returns the newest sailing offers.';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'keyword' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'keyword' => [
|
||||
'name' => 'Filtrer par mots clés',
|
||||
'title' => 'Entrez le mot clé à filtrer ici'
|
||||
),
|
||||
'type' => array(
|
||||
],
|
||||
'type' => [
|
||||
'name' => 'Type de recherche',
|
||||
'title' => 'Afficher seuleument un certain type d\'annonce',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Toutes les annonces' => false,
|
||||
'Les embarquements' => 'boat',
|
||||
'Les skippers' => 'skipper',
|
||||
'Les équipiers' => 'crew'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$url = $this->getURI();
|
||||
$html = getSimpleHTMLDOM($url) or returnClientError('No results for this query.');
|
||||
|
||||
|
@ -33,10 +36,11 @@ class BAEBridge extends BridgeAbstract {
|
|||
$detail = $annonce->find('footer a', 0);
|
||||
|
||||
$htmlDetail = getSimpleHTMLDOMCached(parent::getURI() . $detail->href);
|
||||
if (!$htmlDetail)
|
||||
if (!$htmlDetail) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$item['title'] = $annonce->find('header h2', 0)->plaintext;
|
||||
$item['uri'] = parent::getURI() . $detail->href;
|
||||
|
@ -58,13 +62,14 @@ class BAEBridge extends BridgeAbstract {
|
|||
$item['content'] = defaultLinkTo($content, parent::getURI());
|
||||
$image = $htmlDetail->find('#zoom', 0);
|
||||
if ($image) {
|
||||
$item['enclosures'] = array(parent::getURI() . $image->getAttribute('src'));
|
||||
$item['enclosures'] = [parent::getURI() . $image->getAttribute('src')];
|
||||
}
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
$uri = parent::getURI();
|
||||
if (!empty($this->getInput('type'))) {
|
||||
if ($this->getInput('type') == 'boat') {
|
||||
|
@ -79,8 +84,9 @@ class BAEBridge extends BridgeAbstract {
|
|||
return $uri;
|
||||
}
|
||||
|
||||
private function removeAccents($string) {
|
||||
$chars = array(
|
||||
private function removeAccents($string)
|
||||
{
|
||||
$chars = [
|
||||
// Decompositions for Latin-1 Supplement
|
||||
'ª' => 'a', 'º' => 'o',
|
||||
'À' => 'A', 'Á' => 'A',
|
||||
|
@ -254,7 +260,7 @@ class BAEBridge extends BridgeAbstract {
|
|||
'Ǚ' => 'U', 'ǚ' => 'u',
|
||||
// grave accent
|
||||
'Ǜ' => 'U', 'ǜ' => 'u',
|
||||
);
|
||||
];
|
||||
|
||||
$string = strtr($string, $chars);
|
||||
|
||||
|
|
|
@ -1,55 +1,57 @@
|
|||
<?php
|
||||
class BadDragonBridge extends BridgeAbstract {
|
||||
|
||||
class BadDragonBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Bad Dragon Bridge';
|
||||
const URI = 'https://bad-dragon.com/';
|
||||
const CACHE_TIMEOUT = 300; // 5min
|
||||
const DESCRIPTION = 'Returns sales or new clearance items';
|
||||
const MAINTAINER = 'Roliga';
|
||||
const PARAMETERS = array(
|
||||
'Sales' => array(
|
||||
),
|
||||
'Clearance' => array(
|
||||
'ready_made' => array(
|
||||
const PARAMETERS = [
|
||||
'Sales' => [
|
||||
],
|
||||
'Clearance' => [
|
||||
'ready_made' => [
|
||||
'name' => 'Ready Made',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'flop' => array(
|
||||
],
|
||||
'flop' => [
|
||||
'name' => 'Flops',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'skus' => array(
|
||||
],
|
||||
'skus' => [
|
||||
'name' => 'Products',
|
||||
'exampleValue' => 'chanceflared, crackers',
|
||||
'title' => 'Comma separated list of product SKUs'
|
||||
),
|
||||
'onesize' => array(
|
||||
],
|
||||
'onesize' => [
|
||||
'name' => 'One-Size',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'mini' => array(
|
||||
],
|
||||
'mini' => [
|
||||
'name' => 'Mini',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'small' => array(
|
||||
],
|
||||
'small' => [
|
||||
'name' => 'Small',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'medium' => array(
|
||||
],
|
||||
'medium' => [
|
||||
'name' => 'Medium',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'large' => array(
|
||||
],
|
||||
'large' => [
|
||||
'name' => 'Large',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'extralarge' => array(
|
||||
],
|
||||
'extralarge' => [
|
||||
'name' => 'Extra Large',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'category' => array(
|
||||
],
|
||||
'category' => [
|
||||
'name' => 'Category',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All' => 'all',
|
||||
'Accessories' => 'accessories',
|
||||
'Merchandise' => 'merchandise',
|
||||
|
@ -59,50 +61,50 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
'Lil\' Squirts' => 'shooter',
|
||||
'Lil\' Vibes' => 'vibrator',
|
||||
'Wearables' => 'wearable'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'all',
|
||||
),
|
||||
'soft' => array(
|
||||
],
|
||||
'soft' => [
|
||||
'name' => 'Soft Firmness',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'med_firm' => array(
|
||||
],
|
||||
'med_firm' => [
|
||||
'name' => 'Medium Firmness',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'firm' => array(
|
||||
],
|
||||
'firm' => [
|
||||
'name' => 'Firm',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'split' => array(
|
||||
],
|
||||
'split' => [
|
||||
'name' => 'Split Firmness',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'maxprice' => array(
|
||||
],
|
||||
'maxprice' => [
|
||||
'name' => 'Max Price',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'defaultValue' => 300
|
||||
),
|
||||
'minprice' => array(
|
||||
],
|
||||
'minprice' => [
|
||||
'name' => 'Min Price',
|
||||
'type' => 'number',
|
||||
'defaultValue' => 0
|
||||
),
|
||||
'cumtube' => array(
|
||||
],
|
||||
'cumtube' => [
|
||||
'name' => 'Cumtube',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'suctionCup' => array(
|
||||
],
|
||||
'suctionCup' => [
|
||||
'name' => 'Suction Cup',
|
||||
'type' => 'checkbox'
|
||||
),
|
||||
'noAccessories' => array(
|
||||
],
|
||||
'noAccessories' => [
|
||||
'name' => 'No Accessories',
|
||||
'type' => 'checkbox'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/*
|
||||
* This sets index $strFrom (or $strTo if set) in $outArr to 'on' if
|
||||
|
@ -122,32 +124,34 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
* [flop] => on
|
||||
* )
|
||||
* */
|
||||
private function setParam($inArr, &$outArr, $param, $strFrom, $strTo = null) {
|
||||
if(isset($inArr[$param]) && in_array($strFrom, $inArr[$param])) {
|
||||
private function setParam($inArr, &$outArr, $param, $strFrom, $strTo = null)
|
||||
{
|
||||
if (isset($inArr[$param]) && in_array($strFrom, $inArr[$param])) {
|
||||
$outArr[($strTo ?: $strFrom)] = 'on';
|
||||
}
|
||||
}
|
||||
|
||||
public function detectParameters($url) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// Sale
|
||||
$regex = '/^(https?:\/\/)?bad-dragon\.com\/sales/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
return $params;
|
||||
}
|
||||
|
||||
// Clearance
|
||||
$regex = '/^(https?:\/\/)?bad-dragon\.com\/shop\/clearance/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
parse_str(parse_url($url, PHP_URL_QUERY), $urlParams);
|
||||
|
||||
$this->setParam($urlParams, $params, 'type', 'ready_made');
|
||||
$this->setParam($urlParams, $params, 'type', 'flop');
|
||||
|
||||
if(isset($urlParams['skus'])) {
|
||||
$skus = array();
|
||||
foreach($urlParams['skus'] as $sku) {
|
||||
if (isset($urlParams['skus'])) {
|
||||
$skus = [];
|
||||
foreach ($urlParams['skus'] as $sku) {
|
||||
is_string($sku) && $skus[] = $sku;
|
||||
is_array($sku) && $skus[] = $sku[0];
|
||||
}
|
||||
|
@ -161,9 +165,9 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$this->setParam($urlParams, $params, 'sizes', 'large');
|
||||
$this->setParam($urlParams, $params, 'sizes', 'extralarge');
|
||||
|
||||
if(isset($urlParams['category'])) {
|
||||
if (isset($urlParams['category'])) {
|
||||
$params['category'] = strtolower($urlParams['category']);
|
||||
} else{
|
||||
} else {
|
||||
$params['category'] = 'all';
|
||||
}
|
||||
|
||||
|
@ -172,7 +176,7 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$this->setParam($urlParams, $params, 'firmnessValues', 'firm');
|
||||
$this->setParam($urlParams, $params, 'firmnessValues', 'split');
|
||||
|
||||
if(isset($urlParams['price'])) {
|
||||
if (isset($urlParams['price'])) {
|
||||
isset($urlParams['price']['max'])
|
||||
&& $params['maxprice'] = $urlParams['price']['max'];
|
||||
isset($urlParams['price']['min'])
|
||||
|
@ -195,8 +199,9 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Sales':
|
||||
return 'Bad Dragon Sales';
|
||||
case 'Clearance':
|
||||
|
@ -206,8 +211,9 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Sales':
|
||||
return self::URI . 'sales';
|
||||
case 'Clearance':
|
||||
|
@ -217,13 +223,14 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
switch($this->queriedContext) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Sales':
|
||||
$sales = json_decode(getContents(self::URI . 'api/sales'));
|
||||
|
||||
foreach($sales as $sale) {
|
||||
$item = array();
|
||||
foreach ($sales as $sale) {
|
||||
$item = [];
|
||||
|
||||
$item['title'] = $sale->title;
|
||||
$item['timestamp'] = strtotime($sale->startDate);
|
||||
|
@ -231,7 +238,7 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$item['uri'] = $this->getURI() . '/' . $sale->slug;
|
||||
|
||||
$contentHTML = '<p><img src="' . $sale->image->url . '"></p>';
|
||||
if(isset($sale->endDate)) {
|
||||
if (isset($sale->endDate)) {
|
||||
$contentHTML .= '<p><b>This promotion ends on '
|
||||
. gmdate('M j, Y \a\t g:i A T', strtotime($sale->endDate))
|
||||
. '</b></p>';
|
||||
|
@ -240,8 +247,8 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
}
|
||||
$ul = false;
|
||||
$content = json_decode($sale->content);
|
||||
foreach($content->blocks as $block) {
|
||||
switch($block->type) {
|
||||
foreach ($content->blocks as $block) {
|
||||
switch ($block->type) {
|
||||
case 'header-one':
|
||||
$contentHTML .= '<h1>' . $block->text . '</h1>';
|
||||
break;
|
||||
|
@ -252,14 +259,14 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$contentHTML .= '<h3>' . $block->text . '</h3>';
|
||||
break;
|
||||
case 'unordered-list-item':
|
||||
if(!$ul) {
|
||||
if (!$ul) {
|
||||
$contentHTML .= '<ul>';
|
||||
$ul = true;
|
||||
}
|
||||
$contentHTML .= '<li>' . $block->text . '</li>';
|
||||
break;
|
||||
default:
|
||||
if($ul) {
|
||||
if ($ul) {
|
||||
$contentHTML .= '</ul>';
|
||||
$ul = false;
|
||||
}
|
||||
|
@ -278,16 +285,16 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$productList = json_decode(getContents(self::URI
|
||||
. 'api/inventory-toy/product-list'));
|
||||
|
||||
foreach($toyData->toys as $toy) {
|
||||
$item = array();
|
||||
foreach ($toyData->toys as $toy) {
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $this->getURI()
|
||||
. '#'
|
||||
. $toy->id;
|
||||
$item['timestamp'] = strtotime($toy->created);
|
||||
|
||||
foreach($productList as $product) {
|
||||
if($product->sku == $toy->sku) {
|
||||
foreach ($productList as $product) {
|
||||
if ($product->sku == $toy->sku) {
|
||||
$item['title'] = $product->name;
|
||||
break;
|
||||
}
|
||||
|
@ -295,7 +302,7 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
|
||||
// images
|
||||
$content = '<p>';
|
||||
foreach($toy->images as $image) {
|
||||
foreach ($toy->images as $image) {
|
||||
$content .= '<a href="'
|
||||
. $image->fullFilename
|
||||
. '"><img src="'
|
||||
|
@ -318,44 +325,44 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
. ($toy->cumtube ? 'Cumtube' : '')
|
||||
. ($toy->suction_cup || $toy->cumtube ? '' : 'None');
|
||||
// firmness
|
||||
$firmnessTexts = array(
|
||||
$firmnessTexts = [
|
||||
'2' => 'Extra soft',
|
||||
'3' => 'Soft',
|
||||
'5' => 'Medium',
|
||||
'8' => 'Firm'
|
||||
);
|
||||
];
|
||||
$firmnesses = explode('/', $toy->firmness);
|
||||
if(count($firmnesses) === 2) {
|
||||
if (count($firmnesses) === 2) {
|
||||
$content .= '<br /><b>Firmness:</b> '
|
||||
. $firmnessTexts[$firmnesses[0]]
|
||||
. ', '
|
||||
. $firmnessTexts[$firmnesses[1]];
|
||||
} else{
|
||||
} else {
|
||||
$content .= '<br /><b>Firmness:</b> '
|
||||
. $firmnessTexts[$firmnesses[0]];
|
||||
}
|
||||
// flop
|
||||
if($toy->type === 'flop') {
|
||||
if ($toy->type === 'flop') {
|
||||
$content .= '<br /><b>Flop reason:</b> '
|
||||
. $toy->flop_reason;
|
||||
}
|
||||
$content .= '</p>';
|
||||
$item['content'] = $content;
|
||||
|
||||
$enclosures = array();
|
||||
foreach($toy->images as $image) {
|
||||
$enclosures = [];
|
||||
foreach ($toy->images as $image) {
|
||||
$enclosures[] = $image->fullFilename;
|
||||
}
|
||||
$item['enclosures'] = $enclosures;
|
||||
|
||||
$categories = array();
|
||||
$categories = [];
|
||||
$categories[] = $toy->sku;
|
||||
$categories[] = $toy->type;
|
||||
$categories[] = $toy->size;
|
||||
if($toy->cumtube) {
|
||||
if ($toy->cumtube) {
|
||||
$categories[] = 'cumtube';
|
||||
}
|
||||
if($toy->suction_cup) {
|
||||
if ($toy->suction_cup) {
|
||||
$categories[] = 'suction_cup';
|
||||
}
|
||||
$item['categories'] = $categories;
|
||||
|
@ -366,7 +373,8 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function inputToURL($api = false) {
|
||||
private function inputToURL($api = false)
|
||||
{
|
||||
$url = self::URI;
|
||||
$url .= ($api ? 'api/inventory-toys?' : 'shop/clearance?');
|
||||
|
||||
|
@ -381,7 +389,7 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
$url .= ($this->getInput('flop') ? '&type[]=flop' : '');
|
||||
|
||||
// Product names
|
||||
foreach(array_filter(explode(',', $this->getInput('skus'))) as $sku) {
|
||||
foreach (array_filter(explode(',', $this->getInput('skus'))) as $sku) {
|
||||
$url .= '&skus[]=' . urlencode(trim($sku));
|
||||
}
|
||||
|
||||
|
@ -398,18 +406,18 @@ class BadDragonBridge extends BridgeAbstract {
|
|||
. urlencode($this->getInput('category')) : '');
|
||||
|
||||
// Firmness
|
||||
if($api) {
|
||||
if ($api) {
|
||||
$url .= ($this->getInput('soft') ? '&firmnessValues[]=3' : '');
|
||||
$url .= ($this->getInput('med_firm') ? '&firmnessValues[]=5' : '');
|
||||
$url .= ($this->getInput('firm') ? '&firmnessValues[]=8' : '');
|
||||
if($this->getInput('split')) {
|
||||
if ($this->getInput('split')) {
|
||||
$url .= '&firmnessValues[]=3/5';
|
||||
$url .= '&firmnessValues[]=3/8';
|
||||
$url .= '&firmnessValues[]=8/3';
|
||||
$url .= '&firmnessValues[]=5/8';
|
||||
$url .= '&firmnessValues[]=8/5';
|
||||
}
|
||||
} else{
|
||||
} else {
|
||||
$url .= ($this->getInput('soft') ? '&firmnessValues[]=soft' : '');
|
||||
$url .= ($this->getInput('med_firm') ? '&firmnessValues[]=medium' : '');
|
||||
$url .= ($this->getInput('firm') ? '&firmnessValues[]=firm' : '');
|
||||
|
|
|
@ -1,107 +1,126 @@
|
|||
<?php
|
||||
class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
||||
|
||||
class BakaUpdatesMangaReleasesBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Baka Updates Manga Releases';
|
||||
const URI = 'https://www.mangaupdates.com/';
|
||||
const DESCRIPTION = 'Get the latest series releases';
|
||||
const MAINTAINER = 'fulmeek, KamaleiZestri';
|
||||
const PARAMETERS = array(
|
||||
'By series' => array(
|
||||
'series_id' => array(
|
||||
const PARAMETERS = [
|
||||
'By series' => [
|
||||
'series_id' => [
|
||||
'name' => 'Series ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => '188066'
|
||||
)
|
||||
),
|
||||
'By list' => array(
|
||||
'list_id' => array(
|
||||
]
|
||||
],
|
||||
'By list' => [
|
||||
'list_id' => [
|
||||
'name' => 'List ID and Type',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => '4395&list=read'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
const LIMIT_COLS = 5;
|
||||
const LIMIT_ITEMS = 10;
|
||||
const RELEASES_URL = 'https://www.mangaupdates.com/releases.html';
|
||||
|
||||
private $feedName = '';
|
||||
|
||||
public function collectData() {
|
||||
if($this -> queriedContext == 'By series')
|
||||
public function collectData()
|
||||
{
|
||||
if ($this -> queriedContext == 'By series') {
|
||||
$this -> collectDataBySeries();
|
||||
else //queriedContext == 'By list'
|
||||
} else { //queriedContext == 'By list'
|
||||
$this -> collectDataByList();
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if($this -> queriedContext == 'By series') {
|
||||
public function getURI()
|
||||
{
|
||||
if ($this -> queriedContext == 'By series') {
|
||||
$series_id = $this->getInput('series_id');
|
||||
if (!empty($series_id)) {
|
||||
return self::URI . 'releases.html?search=' . $series_id . '&stype=series';
|
||||
}
|
||||
} else //queriedContext == 'By list'
|
||||
} else { //queriedContext == 'By list'
|
||||
return self::RELEASES_URL;
|
||||
}
|
||||
|
||||
return self::URI;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!empty($this->feedName)) {
|
||||
public function getName()
|
||||
{
|
||||
if (!empty($this->feedName)) {
|
||||
return $this->feedName . ' - ' . self::NAME;
|
||||
}
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
private function getSanitizedHash($string) {
|
||||
private function getSanitizedHash($string)
|
||||
{
|
||||
return hash('sha1', preg_replace('/[^a-zA-Z0-9\-\.]/', '', ucwords(strtolower($string))));
|
||||
}
|
||||
|
||||
private function filterText($text) {
|
||||
private function filterText($text)
|
||||
{
|
||||
return rtrim($text, '* ');
|
||||
}
|
||||
|
||||
private function filterHTML($text) {
|
||||
private function filterHTML($text)
|
||||
{
|
||||
return $this->filterText(html_entity_decode($text));
|
||||
}
|
||||
|
||||
private function findID($manga) {
|
||||
private function findID($manga)
|
||||
{
|
||||
// sometimes new series are on the release list that have no ID. just drop them.
|
||||
if(@$this -> filterHTML($manga -> find('a', 0) -> href) != null) {
|
||||
if (@$this -> filterHTML($manga -> find('a', 0) -> href) != null) {
|
||||
preg_match('/id=([0-9]*)/', $this -> filterHTML($manga -> find('a', 0) -> href), $match);
|
||||
return $match[1];
|
||||
} else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private function collectDataBySeries() {
|
||||
private function collectDataBySeries()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
// content is an unstructured pile of divs, ugly to parse
|
||||
$cols = $html->find('div#main_content div.row > div.text');
|
||||
if (!$cols)
|
||||
if (!$cols) {
|
||||
returnServerError('No releases');
|
||||
}
|
||||
|
||||
$rows = array_slice(
|
||||
array_chunk($cols, self::LIMIT_COLS), 0, self::LIMIT_ITEMS
|
||||
array_chunk($cols, self::LIMIT_COLS),
|
||||
0,
|
||||
self::LIMIT_ITEMS
|
||||
);
|
||||
|
||||
if (isset($rows[0][1])) {
|
||||
$this->feedName = $this->filterHTML($rows[0][1]->plaintext);
|
||||
}
|
||||
|
||||
foreach($rows as $cols) {
|
||||
if (count($cols) < self::LIMIT_COLS) continue;
|
||||
foreach ($rows as $cols) {
|
||||
if (count($cols) < self::LIMIT_COLS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$title = array();
|
||||
$item = [];
|
||||
$title = [];
|
||||
|
||||
$item['content'] = '';
|
||||
|
||||
$objDate = $cols[0];
|
||||
if ($objDate)
|
||||
if ($objDate) {
|
||||
$item['timestamp'] = strtotime($objDate->plaintext);
|
||||
}
|
||||
|
||||
$objTitle = $cols[1];
|
||||
if ($objTitle) {
|
||||
|
@ -110,12 +129,14 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
$objVolume = $cols[2];
|
||||
if ($objVolume && !empty($objVolume->plaintext))
|
||||
if ($objVolume && !empty($objVolume->plaintext)) {
|
||||
$title[] = 'Vol.' . $objVolume->plaintext;
|
||||
}
|
||||
|
||||
$objChapter = $cols[3];
|
||||
if ($objChapter && !empty($objChapter->plaintext))
|
||||
if ($objChapter && !empty($objChapter->plaintext)) {
|
||||
$title[] = 'Chp.' . $objChapter->plaintext;
|
||||
}
|
||||
|
||||
$objAuthor = $cols[4];
|
||||
if ($objAuthor && !empty($objAuthor->plaintext)) {
|
||||
|
@ -131,9 +152,10 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function collectDataByList() {
|
||||
private function collectDataByList()
|
||||
{
|
||||
$this -> feedName = 'Releases';
|
||||
$list = array();
|
||||
$list = [];
|
||||
|
||||
$releasesHTML = getSimpleHTMLDOM(self::RELEASES_URL);
|
||||
|
||||
|
@ -142,7 +164,7 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
|||
|
||||
//get ids of the manga that the user follows,
|
||||
$parts = $listHTML -> find('table#ptable tr > td.pl');
|
||||
foreach($parts as $part) {
|
||||
foreach ($parts as $part) {
|
||||
$list[] = $this -> findID($part);
|
||||
}
|
||||
|
||||
|
@ -150,13 +172,15 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
|||
$cols = $releasesHTML -> find('div#main_content div.row > div.pbreak');
|
||||
$rows = array_slice(array_chunk($cols, 3), 0);
|
||||
|
||||
foreach($rows as $cols) {
|
||||
foreach ($rows as $cols) {
|
||||
//check if current manga is in user's list.
|
||||
$id = $this -> findId($cols[0]);
|
||||
if(!array_search($id, $list)) continue;
|
||||
if (!array_search($id, $list)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$title = array();
|
||||
$item = [];
|
||||
$title = [];
|
||||
|
||||
$item['content'] = '';
|
||||
|
||||
|
@ -167,8 +191,9 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
$objVolChap = $cols[1];
|
||||
if ($objVolChap && !empty($objVolChap->plaintext))
|
||||
if ($objVolChap && !empty($objVolChap->plaintext)) {
|
||||
$title[] = $this -> filterHTML($objVolChap -> innertext);
|
||||
}
|
||||
|
||||
$objAuthor = $cols[2];
|
||||
if ($objAuthor && !empty($objAuthor->plaintext)) {
|
||||
|
|
|
@ -1,120 +1,123 @@
|
|||
<?php
|
||||
class BandcampBridge extends BridgeAbstract {
|
||||
|
||||
class BandcampBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'sebsauvage, Roliga';
|
||||
const NAME = 'Bandcamp Bridge';
|
||||
const URI = 'https://bandcamp.com/';
|
||||
const CACHE_TIMEOUT = 600; // 10min
|
||||
const DESCRIPTION = 'New bandcamp releases by tag, band or album';
|
||||
const PARAMETERS = array(
|
||||
'By tag' => array(
|
||||
'tag' => array(
|
||||
const PARAMETERS = [
|
||||
'By tag' => [
|
||||
'tag' => [
|
||||
'name' => 'tag',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'hip-hop-rap'
|
||||
)
|
||||
),
|
||||
'By band' => array(
|
||||
'band' => array(
|
||||
]
|
||||
],
|
||||
'By band' => [
|
||||
'band' => [
|
||||
'name' => 'band',
|
||||
'type' => 'text',
|
||||
'title' => 'Band name as seen in the band page URL',
|
||||
'required' => true,
|
||||
'exampleValue' => 'aesoprock'
|
||||
),
|
||||
'type' => array(
|
||||
],
|
||||
'type' => [
|
||||
'name' => 'Articles are',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Releases' => 'releases',
|
||||
'Releases, new one when track list changes' => 'changes',
|
||||
'Individual tracks' => 'tracks'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'changes'
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'limit',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'title' => 'Number of releases to return',
|
||||
'defaultValue' => 5
|
||||
)
|
||||
),
|
||||
'By label' => array(
|
||||
'label' => array(
|
||||
]
|
||||
],
|
||||
'By label' => [
|
||||
'label' => [
|
||||
'name' => 'label',
|
||||
'type' => 'text',
|
||||
'title' => 'label name as seen in the label page URL',
|
||||
'required' => true
|
||||
),
|
||||
'type' => array(
|
||||
],
|
||||
'type' => [
|
||||
'name' => 'Articles are',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Releases' => 'releases',
|
||||
'Releases, new one when track list changes' => 'changes',
|
||||
'Individual tracks' => 'tracks'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'changes'
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'limit',
|
||||
'type' => 'number',
|
||||
'title' => 'Number of releases to return',
|
||||
'defaultValue' => 5
|
||||
)
|
||||
),
|
||||
'By album' => array(
|
||||
'band' => array(
|
||||
]
|
||||
],
|
||||
'By album' => [
|
||||
'band' => [
|
||||
'name' => 'band',
|
||||
'type' => 'text',
|
||||
'title' => 'Band name as seen in the album page URL',
|
||||
'required' => true,
|
||||
'exampleValue' => 'aesoprock'
|
||||
),
|
||||
'album' => array(
|
||||
],
|
||||
'album' => [
|
||||
'name' => 'album',
|
||||
'type' => 'text',
|
||||
'title' => 'Album name as seen in the album page URL',
|
||||
'required' => true,
|
||||
'exampleValue' => 'appleseed'
|
||||
),
|
||||
'type' => array(
|
||||
],
|
||||
'type' => [
|
||||
'name' => 'Articles are',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Releases' => 'releases',
|
||||
'Releases, new one when track list changes' => 'changes',
|
||||
'Individual tracks' => 'tracks'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'tracks'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
const IMGURI = 'https://f4.bcbits.com/';
|
||||
const IMGSIZE_300PX = 23;
|
||||
const IMGSIZE_700PX = 16;
|
||||
|
||||
private $feedName;
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://s4.bcbits.com/img/bc_favicon.ico';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
switch($this->queriedContext) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'By tag':
|
||||
$url = self::URI . 'api/hub/1/dig_deeper';
|
||||
$data = $this->buildRequestJson();
|
||||
$header = array(
|
||||
$header = [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . strlen($data)
|
||||
);
|
||||
$opts = array(
|
||||
];
|
||||
$opts = [
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => $data
|
||||
);
|
||||
];
|
||||
$content = getContents($url, $header, $opts);
|
||||
|
||||
$json = json_decode($content);
|
||||
|
@ -139,13 +142,13 @@ class BandcampBridge extends BridgeAbstract {
|
|||
$small_img = $this->getImageUrl($entry->art_id, self::IMGSIZE_300PX);
|
||||
$img = $this->getImageUrl($entry->art_id, self::IMGSIZE_700PX);
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'uri' => $url,
|
||||
'author' => $full_artist,
|
||||
'title' => $full_title
|
||||
);
|
||||
];
|
||||
$item['content'] = "<img src='$small_img' /><br/>$full_title";
|
||||
$item['enclosures'] = array($img);
|
||||
$item['enclosures'] = [$img];
|
||||
$this->items[] = $item;
|
||||
}
|
||||
break;
|
||||
|
@ -161,45 +164,47 @@ class BandcampBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
$regex = '/band_id=(\d+)/';
|
||||
if(preg_match($regex, $html, $matches) == false)
|
||||
if (preg_match($regex, $html, $matches) == false) {
|
||||
returnServerError('Unable to find band ID on: ' . $this->getURI());
|
||||
}
|
||||
$band_id = $matches[1];
|
||||
|
||||
$tralbums = array();
|
||||
switch($this->queriedContext) {
|
||||
$tralbums = [];
|
||||
switch ($this->queriedContext) {
|
||||
case 'By band':
|
||||
case 'By label':
|
||||
$query_data = array(
|
||||
$query_data = [
|
||||
'band_id' => $band_id
|
||||
);
|
||||
];
|
||||
$band_data = $this->apiGet('mobile/22/band_details', $query_data);
|
||||
|
||||
$num_albums = min(count($band_data->discography), $this->getInput('limit'));
|
||||
for($i = 0; $i < $num_albums; $i++) {
|
||||
for ($i = 0; $i < $num_albums; $i++) {
|
||||
$album_basic_data = $band_data->discography[$i];
|
||||
|
||||
// 'a' or 't' for albums and individual tracks respectively
|
||||
$tralbum_type = substr($album_basic_data->item_type, 0, 1);
|
||||
|
||||
$query_data = array(
|
||||
$query_data = [
|
||||
'band_id' => $band_id,
|
||||
'tralbum_type' => $tralbum_type,
|
||||
'tralbum_id' => $album_basic_data->item_id
|
||||
);
|
||||
];
|
||||
$tralbums[] = $this->apiGet('mobile/22/tralbum_details', $query_data);
|
||||
}
|
||||
break;
|
||||
case 'By album':
|
||||
$regex = '/album=(\d+)/';
|
||||
if(preg_match($regex, $html, $matches) == false)
|
||||
if (preg_match($regex, $html, $matches) == false) {
|
||||
returnServerError('Unable to find album ID on: ' . $this->getURI());
|
||||
}
|
||||
$album_id = $matches[1];
|
||||
|
||||
$query_data = array(
|
||||
$query_data = [
|
||||
'band_id' => $band_id,
|
||||
'tralbum_type' => 'a',
|
||||
'tralbum_id' => $album_id
|
||||
);
|
||||
];
|
||||
$tralbums[] = $this->apiGet('mobile/22/tralbum_details', $query_data);
|
||||
|
||||
break;
|
||||
|
@ -208,11 +213,11 @@ class BandcampBridge extends BridgeAbstract {
|
|||
foreach ($tralbums as $tralbum_data) {
|
||||
if ($tralbum_data->type === 'a' && $this->getInput('type') === 'tracks') {
|
||||
foreach ($tralbum_data->tracks as $track) {
|
||||
$query_data = array(
|
||||
$query_data = [
|
||||
'band_id' => $band_id,
|
||||
'tralbum_type' => 't',
|
||||
'tralbum_id' => $track->track_id
|
||||
);
|
||||
];
|
||||
$track_data = $this->apiGet('mobile/22/tralbum_details', $query_data);
|
||||
|
||||
$this->items[] = $this->buildTralbumItem($track_data);
|
||||
|
@ -225,7 +230,8 @@ class BandcampBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function buildTralbumItem($tralbum_data){
|
||||
private function buildTralbumItem($tralbum_data)
|
||||
{
|
||||
$band_data = $tralbum_data->band;
|
||||
|
||||
// Format title like: ARTIST - ALBUM/TRACK (OPTIONAL RELEASER)
|
||||
|
@ -250,15 +256,15 @@ class BandcampBridge extends BridgeAbstract {
|
|||
$small_img = $this->getImageUrl($tralbum_data->art_id, self::IMGSIZE_300PX);
|
||||
$img = $this->getImageUrl($tralbum_data->art_id, self::IMGSIZE_700PX);
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'uri' => $tralbum_data->bandcamp_url,
|
||||
'author' => $full_artist,
|
||||
'title' => $full_title,
|
||||
'enclosures' => array($img),
|
||||
'enclosures' => [$img],
|
||||
'timestamp' => $tralbum_data->release_date
|
||||
);
|
||||
];
|
||||
|
||||
$item['categories'] = array();
|
||||
$item['categories'] = [];
|
||||
foreach ($tralbum_data->tags as $tag) {
|
||||
$item['categories'][] = $tag->norm_name;
|
||||
}
|
||||
|
@ -289,29 +295,33 @@ class BandcampBridge extends BridgeAbstract {
|
|||
return $item;
|
||||
}
|
||||
|
||||
private function buildRequestJson(){
|
||||
$requestJson = array(
|
||||
private function buildRequestJson()
|
||||
{
|
||||
$requestJson = [
|
||||
'tag' => $this->getInput('tag'),
|
||||
'page' => 1,
|
||||
'sort' => 'date'
|
||||
);
|
||||
];
|
||||
return json_encode($requestJson);
|
||||
}
|
||||
|
||||
private function getImageUrl($id, $size){
|
||||
private function getImageUrl($id, $size)
|
||||
{
|
||||
return self::IMGURI . 'img/a' . $id . '_' . $size . '.jpg';
|
||||
}
|
||||
|
||||
private function apiGet($endpoint, $query_data) {
|
||||
private function apiGet($endpoint, $query_data)
|
||||
{
|
||||
$url = self::URI . 'api/' . $endpoint . '?' . http_build_query($query_data);
|
||||
$data = json_decode(getContents($url));
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'By tag':
|
||||
if(!is_null($this->getInput('tag'))) {
|
||||
if (!is_null($this->getInput('tag'))) {
|
||||
return self::URI
|
||||
. 'tag/'
|
||||
. urlencode($this->getInput('tag'))
|
||||
|
@ -319,21 +329,21 @@ class BandcampBridge extends BridgeAbstract {
|
|||
}
|
||||
break;
|
||||
case 'By label':
|
||||
if(!is_null($this->getInput('label'))) {
|
||||
if (!is_null($this->getInput('label'))) {
|
||||
return 'https://'
|
||||
. $this->getInput('label')
|
||||
. '.bandcamp.com/music';
|
||||
}
|
||||
break;
|
||||
case 'By band':
|
||||
if(!is_null($this->getInput('band'))) {
|
||||
if (!is_null($this->getInput('band'))) {
|
||||
return 'https://'
|
||||
. $this->getInput('band')
|
||||
. '.bandcamp.com/music';
|
||||
}
|
||||
break;
|
||||
case 'By album':
|
||||
if(!is_null($this->getInput('band')) && !is_null($this->getInput('album'))) {
|
||||
if (!is_null($this->getInput('band')) && !is_null($this->getInput('album'))) {
|
||||
return 'https://'
|
||||
. $this->getInput('band')
|
||||
. '.bandcamp.com/album/'
|
||||
|
@ -345,31 +355,32 @@ class BandcampBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'By tag':
|
||||
if(!is_null($this->getInput('tag'))) {
|
||||
if (!is_null($this->getInput('tag'))) {
|
||||
return $this->getInput('tag') . ' - Bandcamp Tag';
|
||||
}
|
||||
break;
|
||||
case 'By band':
|
||||
if(isset($this->feedName)) {
|
||||
if (isset($this->feedName)) {
|
||||
return $this->feedName . ' - Bandcamp Band';
|
||||
} elseif(!is_null($this->getInput('band'))) {
|
||||
} elseif (!is_null($this->getInput('band'))) {
|
||||
return $this->getInput('band') . ' - Bandcamp Band';
|
||||
}
|
||||
break;
|
||||
case 'By label':
|
||||
if(isset($this->feedName)) {
|
||||
if (isset($this->feedName)) {
|
||||
return $this->feedName . ' - Bandcamp Label';
|
||||
} elseif(!is_null($this->getInput('label'))) {
|
||||
} elseif (!is_null($this->getInput('label'))) {
|
||||
return $this->getInput('label') . ' - Bandcamp Label';
|
||||
}
|
||||
break;
|
||||
case 'By album':
|
||||
if(isset($this->feedName)) {
|
||||
if (isset($this->feedName)) {
|
||||
return $this->feedName . ' - Bandcamp Album';
|
||||
} elseif(!is_null($this->getInput('album'))) {
|
||||
} elseif (!is_null($this->getInput('album'))) {
|
||||
return $this->getInput('album') . ' - Bandcamp Album';
|
||||
}
|
||||
break;
|
||||
|
@ -378,26 +389,27 @@ class BandcampBridge extends BridgeAbstract {
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
public function detectParameters($url) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// By tag
|
||||
$regex = '/^(https?:\/\/)?bandcamp\.com\/tag\/([^\/.&?\n]+)/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
$params['tag'] = urldecode($matches[2]);
|
||||
return $params;
|
||||
}
|
||||
|
||||
// By band
|
||||
$regex = '/^(https?:\/\/)?([^\/.&?\n]+?)\.bandcamp\.com/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
$params['band'] = urldecode($matches[2]);
|
||||
return $params;
|
||||
}
|
||||
|
||||
// By album
|
||||
$regex = '/^(https?:\/\/)?([^\/.&?\n]+?)\.bandcamp\.com\/album\/([^\/.&?\n]+)/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
$params['band'] = urldecode($matches[2]);
|
||||
$params['album'] = urldecode($matches[3]);
|
||||
return $params;
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
class BandcampDailyBridge extends BridgeAbstract {
|
||||
|
||||
class BandcampDailyBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Bandcamp Daily Bridge';
|
||||
const URI = 'https://daily.bandcamp.com';
|
||||
const DESCRIPTION = 'Returns newest articles';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(
|
||||
'Latest articles' => array(),
|
||||
'Best of' => array(
|
||||
'best-content' => array(
|
||||
const PARAMETERS = [
|
||||
'Latest articles' => [],
|
||||
'Best of' => [
|
||||
'best-content' => [
|
||||
'name' => 'content',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Best Ambient' => 'best-ambient',
|
||||
'Best Beat Tapes' => 'best-beat-tapes',
|
||||
'Best Dance 12\'s' => 'best-dance-12s',
|
||||
|
@ -23,15 +25,15 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
'Best Punk' => 'best-punk',
|
||||
'Best Reissues' => 'best-reissues',
|
||||
'Best Soul' => 'best-soul',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'best-ambient',
|
||||
),
|
||||
),
|
||||
'Genres' => array(
|
||||
'genres-content' => array(
|
||||
],
|
||||
],
|
||||
'Genres' => [
|
||||
'genres-content' => [
|
||||
'name' => 'content',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Acoustic' => 'genres/acoustic',
|
||||
'Alternative' => 'genres/alternative',
|
||||
'Ambient' => 'genres/ambient',
|
||||
|
@ -57,15 +59,15 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
'Soundtrack' => 'genres/soundtrack',
|
||||
'Spoken Word' => 'genres/spoken-word',
|
||||
'World' => 'genres/world',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'genres/acoustic',
|
||||
),
|
||||
),
|
||||
'Franchises' => array(
|
||||
'franchises-content' => array(
|
||||
],
|
||||
],
|
||||
'Franchises' => [
|
||||
'franchises-content' => [
|
||||
'name' => 'content',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Lists' => 'lists',
|
||||
'Features' => 'features',
|
||||
'Album of the Day' => 'album-of-the-day',
|
||||
|
@ -81,15 +83,16 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
'Scene Report' => 'scene-report',
|
||||
'Seven Essential Releases' => 'seven-essential-releases',
|
||||
'The Merch Table' => 'the-merch-table',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'lists',
|
||||
),
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI())
|
||||
or returnServerError('Could not request: ' . $this->getURI());
|
||||
|
||||
|
@ -97,8 +100,8 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
|
||||
$articles = $html->find('articles-list', 0);
|
||||
|
||||
foreach($articles->find('div.list-article') as $index => $article) {
|
||||
$item = array();
|
||||
foreach ($articles->find('div.list-article') as $index => $article) {
|
||||
$item = [];
|
||||
|
||||
$articlePath = $article->find('a.title', 0)->href;
|
||||
|
||||
|
@ -126,8 +129,9 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Latest articles':
|
||||
return self::URI . '/latest';
|
||||
case 'Best of':
|
||||
|
@ -141,8 +145,9 @@ class BandcampDailyBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Latest articles':
|
||||
return $this->queriedContext . ' - Bandcamp Daily';
|
||||
case 'Best of':
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
<?php
|
||||
class BastaBridge extends BridgeAbstract {
|
||||
|
||||
class BastaBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'qwertygc';
|
||||
const NAME = 'Bastamag Bridge';
|
||||
const URI = 'https://www.bastamag.net/';
|
||||
const CACHE_TIMEOUT = 7200; // 2h
|
||||
const DESCRIPTION = 'Returns the newest articles.';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI . 'spip.php?page=backend');
|
||||
|
||||
$limit = 0;
|
||||
|
||||
foreach($html->find('item') as $element) {
|
||||
if($limit < 10) {
|
||||
$item = array();
|
||||
foreach ($html->find('item') as $element) {
|
||||
if ($limit < 10) {
|
||||
$item = [];
|
||||
$item['title'] = $element->find('title', 0)->innertext;
|
||||
$item['uri'] = $element->find('guid', 0)->plaintext;
|
||||
$item['timestamp'] = strtotime($element->find('dc:date', 0)->plaintext);
|
||||
|
|
|
@ -1,31 +1,34 @@
|
|||
<?php
|
||||
class BinanceBridge extends BridgeAbstract {
|
||||
|
||||
class BinanceBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Binance Blog';
|
||||
const URI = 'https://www.binance.com/en/blog';
|
||||
const DESCRIPTION = 'Subscribe to the Binance blog.';
|
||||
const MAINTAINER = 'thefranke';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://bin.bnbstatic.com/static/images/common/favicon.ico';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI)
|
||||
or returnServerError('Could not fetch Binance blog data.');
|
||||
|
||||
$appData = $html->find('script[id="__APP_DATA"]');
|
||||
$appDataJson = json_decode($appData[0]->innertext);
|
||||
|
||||
foreach($appDataJson->pageData->redux->blogList->blogList as $element) {
|
||||
|
||||
foreach ($appDataJson->pageData->redux->blogList->blogList as $element) {
|
||||
$date = $element->postTime;
|
||||
$abstract = $element->brief;
|
||||
$uri = self::URI . '/' . $element->lang . '/blog/' . $element->idStr;
|
||||
$title = $element->title;
|
||||
$content = $element->content;
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $title;
|
||||
$item['uri'] = $uri;
|
||||
$item['timestamp'] = substr($date, 0, -3);
|
||||
|
@ -34,8 +37,9 @@ class BinanceBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
|
||||
if (count($this->items) >= 10)
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
<?php
|
||||
class BlaguesDeMerdeBridge extends BridgeAbstract {
|
||||
|
||||
class BlaguesDeMerdeBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'superbaillot.net, logmanoriginal';
|
||||
const NAME = 'Blagues De Merde';
|
||||
const URI = 'http://www.blaguesdemerde.fr/';
|
||||
const CACHE_TIMEOUT = 7200; // 2h
|
||||
const DESCRIPTION = 'Blagues De Merde';
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . 'assets/img/favicon.ico';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
foreach($html->find('div.blague') as $element) {
|
||||
|
||||
$item = array();
|
||||
foreach ($html->find('div.blague') as $element) {
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = static::URI . '#' . $element->id;
|
||||
$item['author'] = $element->find('div[class="blague-footer"] p strong', 0)->plaintext;
|
||||
|
@ -38,8 +39,6 @@ class BlaguesDeMerdeBridge extends BridgeAbstract {
|
|||
$item['timestamp'] = strtotime($matches[1]);
|
||||
|
||||
$this->items[] = $item;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
class BleepingComputerBridge extends FeedExpander {
|
||||
|
||||
class BleepingComputerBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'csisoap';
|
||||
const NAME = 'Bleeping Computer';
|
||||
const URI = 'https://www.bleepingcomputer.com/';
|
||||
const DESCRIPTION = 'Returns the newest articles.';
|
||||
|
||||
protected function parseItem($item){
|
||||
protected function parseItem($item)
|
||||
{
|
||||
$item = parent::parseItem($item);
|
||||
|
||||
$article_html = getSimpleHTMLDOMCached($item['uri']);
|
||||
if(!$article_html) {
|
||||
if (!$article_html) {
|
||||
$item['content'] .= '<p><em>Could not request ' . $this->getName() . ': ' . $item['uri'] . '</em></p>';
|
||||
return $item;
|
||||
}
|
||||
|
@ -22,7 +24,8 @@ class BleepingComputerBridge extends FeedExpander {
|
|||
return $item;
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$feed = static::URI . 'feed/';
|
||||
$this->collectExpandableDatas($feed);
|
||||
}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
<?php
|
||||
|
||||
class BlizzardNewsBridge extends XPathAbstract {
|
||||
|
||||
class BlizzardNewsBridge extends XPathAbstract
|
||||
{
|
||||
const NAME = 'Blizzard News';
|
||||
const URI = 'https://news.blizzard.com';
|
||||
const DESCRIPTION = 'Blizzard (game company) newsfeed';
|
||||
const MAINTAINER = 'Niehztog';
|
||||
const PARAMETERS = array(
|
||||
'' => array(
|
||||
'locale' => array(
|
||||
const PARAMETERS = [
|
||||
'' => [
|
||||
'locale' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Deutsch' => 'de-de',
|
||||
'English (EU)' => 'en-gb',
|
||||
'English (US)' => 'en-us',
|
||||
|
@ -27,12 +27,12 @@ class BlizzardNewsBridge extends XPathAbstract {
|
|||
'ภาษาไทย' => 'th-th',
|
||||
'简体中文' => 'zh-cn',
|
||||
'繁體中文' => 'zh-tw'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'en-us',
|
||||
'title' => 'Select your language'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
|
||||
const XPATH_EXPRESSION_ITEM = '/html/body/div/div[4]/div[2]/div[2]/div/div/section/ol/li/article';
|
||||
|
@ -49,10 +49,10 @@ class BlizzardNewsBridge extends XPathAbstract {
|
|||
* Source Web page URL (should provide either HTML or XML content)
|
||||
* @return string
|
||||
*/
|
||||
protected function getSourceUrl(){
|
||||
|
||||
protected function getSourceUrl()
|
||||
{
|
||||
$locale = $this->getInput('locale');
|
||||
if('zh-cn' === $locale) {
|
||||
if ('zh-cn' === $locale) {
|
||||
return 'https://cn.news.blizzard.com';
|
||||
}
|
||||
return 'https://news.blizzard.com/' . $locale;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class BookMyShowBridge extends BridgeAbstract {
|
||||
|
||||
class BookMyShowBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'captn3m0';
|
||||
const NAME = 'BookMyShow Bridge';
|
||||
const URI = 'https://in.bookmyshow.com';
|
||||
|
@ -1091,7 +1092,8 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
// The city information is passed via a cookie
|
||||
const URL_PREFIX = 'https://in.bookmyshow.com/serv/getData?cmd=QUICKBOOK&type=';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$city = $this->getInput('city');
|
||||
$category = $this->getInput('category');
|
||||
|
||||
|
@ -1113,18 +1115,20 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
usort($this->items, function($a, $b) {
|
||||
usort($this->items, function ($a, $b) {
|
||||
return $b['timestamp'] - $a['timestamp'];
|
||||
});
|
||||
|
||||
$this->items = array_slice($this->items, 0, 15);
|
||||
}
|
||||
|
||||
private function makeUrl($category){
|
||||
private function makeUrl($category)
|
||||
{
|
||||
return self::URL_PREFIX . $category;
|
||||
}
|
||||
|
||||
private function getDatesHtml($dates){
|
||||
private function getDatesHtml($dates)
|
||||
{
|
||||
$tz = new DateTimeZone(self::TIMEZONE);
|
||||
$firstDate = DateTime::createFromFormat('Ymd', $dates[0]['ShowDateCode'], $tz)
|
||||
->format('D, d M Y');
|
||||
|
@ -1142,7 +1146,8 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
* @param array $event
|
||||
* @see https://gist.github.com/captn3m0/6dbd539ca67579d22d6f90fab710ccd2 Sample JSON data for various events
|
||||
*/
|
||||
private function generateEventHtml($event, $category){
|
||||
private function generateEventHtml($event, $category)
|
||||
{
|
||||
$html = $this->getDatesHtml($event['arrDates']);
|
||||
switch ($category) {
|
||||
case self::MOVIES:
|
||||
|
@ -1160,7 +1165,8 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
* Generates a simple Venue HTML, even for multiple venues
|
||||
* spread across multiple dates as a description list.
|
||||
*/
|
||||
private function generateVenueHtml($venues){
|
||||
private function generateVenueHtml($venues)
|
||||
{
|
||||
$html = '<h3>Venues</h3><table><thead><tr><th>Venue</th><th>Directions</th></tr></thead><tbody>';
|
||||
|
||||
foreach ($venues as $i => $venueData) {
|
||||
|
@ -1180,7 +1186,8 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
* Generates a simple Table with event Data
|
||||
* @todo Add support for jsonGenre as a tags row
|
||||
*/
|
||||
private function generateEventDetailsTable($event, $headers = self::TABLE_HEADERS){
|
||||
private function generateEventDetailsTable($event, $headers = self::TABLE_HEADERS)
|
||||
{
|
||||
$table = '';
|
||||
foreach ($headers as $key => $header) {
|
||||
if ($header == 'Language') {
|
||||
|
@ -1189,7 +1196,7 @@ class BookMyShowBridge extends BridgeAbstract {
|
|||
|
||||
if ($event[$key] == 'Y') {
|
||||
$value = 'Yes';
|
||||
} else if ($event[$key] == 'N') {
|
||||
} elseif ($event[$key] == 'N') {
|
||||
$value = 'No';
|
||||
} else {
|
||||
$value = $event[$key];
|
||||
|
@ -1206,7 +1213,8 @@ EOT;
|
|||
return "<table>$table</table>";
|
||||
}
|
||||
|
||||
private function generateStandardHtml($event){
|
||||
private function generateStandardHtml($event)
|
||||
{
|
||||
$table = $this->generateEventDetailsTable($event);
|
||||
|
||||
$imgsrc = $event['BannerURL'];
|
||||
|
@ -1224,7 +1232,8 @@ EOT;
|
|||
* Converts some movie details from child entries, such as language
|
||||
* into a single row item, either as a list, or as a Y/N
|
||||
*/
|
||||
private function generateInnerMovieDetails($data){
|
||||
private function generateInnerMovieDetails($data)
|
||||
{
|
||||
// Show list of languages and list of formats
|
||||
$headers = ['EventLanguage', 'EventDimension'];
|
||||
// if any of these has a Y for any of the screenings, mark it as YES
|
||||
|
@ -1262,7 +1271,7 @@ EOT;
|
|||
|
||||
// Put a yes for the boolean entries
|
||||
foreach ($booleanHeaders as $header) {
|
||||
if(in_array('Y', $items[$header])) {
|
||||
if (in_array('Y', $items[$header])) {
|
||||
$html .= self::INNER_MOVIE_HEADERS[$header] . ': Yes<br>';
|
||||
}
|
||||
}
|
||||
|
@ -1270,7 +1279,8 @@ EOT;
|
|||
return $html;
|
||||
}
|
||||
|
||||
private function generateMovieHtml($eventGroup){
|
||||
private function generateMovieHtml($eventGroup)
|
||||
{
|
||||
$data = $eventGroup['ChildEvents'][0];
|
||||
$table = $this->generateEventDetailsTable($data, self::MOVIE_TABLE_HEADERS);
|
||||
|
||||
|
@ -1290,17 +1300,18 @@ EOT;
|
|||
More Details are available on the <a href="$url">BookMyShow website</a> and a trailer is available
|
||||
<a href="${data['EventTrailerURL']}" title="Trailer URL">here</a>
|
||||
EOT;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a canonical movie URL
|
||||
*/
|
||||
private function generateMovieUrl($eventGroup){
|
||||
private function generateMovieUrl($eventGroup)
|
||||
{
|
||||
return self::URI . '/movies/' . $eventGroup['EventURLTitle'] . '/' . $eventGroup['EventCode'];
|
||||
}
|
||||
|
||||
private function generateMoviesData($eventGroup){
|
||||
private function generateMoviesData($eventGroup)
|
||||
{
|
||||
// Additional data picked up from the first Child Event
|
||||
$data = $eventGroup['ChildEvents'][0];
|
||||
$date = new DateTime($data['EventDate']);
|
||||
|
@ -1323,8 +1334,9 @@ EOT;
|
|||
];
|
||||
}
|
||||
|
||||
private function generateEventData($event, $category){
|
||||
if($category == self::MOVIES) {
|
||||
private function generateEventData($event, $category)
|
||||
{
|
||||
if ($category == self::MOVIES) {
|
||||
return $this->generateMoviesData($event);
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1346,8 @@ EOT;
|
|||
/**
|
||||
* Takes an event data as array and returns data for RSS Post
|
||||
*/
|
||||
private function generateGenericEventData($event, $category){
|
||||
private function generateGenericEventData($event, $category)
|
||||
{
|
||||
$datetime = $event['Event_dtmCreated'];
|
||||
if (empty($datetime)) {
|
||||
return null;
|
||||
|
@ -1362,7 +1375,8 @@ EOT;
|
|||
* Check if this is an online event. We can't rely on
|
||||
* EventIsWebView, since that is set to Y for everything
|
||||
*/
|
||||
private function isEventOnline($event){
|
||||
private function isEventOnline($event)
|
||||
{
|
||||
if (isset($event['arrVenues']) && count($event['arrVenues']) === 1) {
|
||||
if (preg_match('/(Online|Zoom)/i', $event['arrVenues'][0]['VenueName'])) {
|
||||
return true;
|
||||
|
@ -1372,7 +1386,8 @@ EOT;
|
|||
return false;
|
||||
}
|
||||
|
||||
private function matchesLanguage(){
|
||||
private function matchesLanguage()
|
||||
{
|
||||
if ($this->getInput('language') !== 'all') {
|
||||
$language = $this->getInput('language');
|
||||
return in_array($language, $this->languages);
|
||||
|
@ -1380,7 +1395,8 @@ EOT;
|
|||
return true;
|
||||
}
|
||||
|
||||
private function matchesOnline($event){
|
||||
private function matchesOnline($event)
|
||||
{
|
||||
if ($this->getInput('include_online')) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1390,17 +1406,19 @@ EOT;
|
|||
/**
|
||||
* Currently only checks if the language filter matches
|
||||
*/
|
||||
private function matchesFilters($category, $event){
|
||||
private function matchesFilters($category, $event)
|
||||
{
|
||||
return $this->matchesLanguage() and $this->matchesOnline($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the RSS Feed title
|
||||
*/
|
||||
public function getName(){
|
||||
public function getName()
|
||||
{
|
||||
$city = $this->getInput('city');
|
||||
$category = $this->getInput('category');
|
||||
if(!is_null($city) and !is_null($category)) {
|
||||
if (!is_null($city) and !is_null($category)) {
|
||||
$categoryName = self::CATEGORIES[$category];
|
||||
$cityNames = array_flip(self::CITIES);
|
||||
$cityName = $cityNames[$city];
|
||||
|
@ -1420,7 +1438,8 @@ EOT;
|
|||
* @param string $city City Code
|
||||
* @return array list of headers
|
||||
*/
|
||||
private function makeHeaders($city){
|
||||
private function makeHeaders($city)
|
||||
{
|
||||
$uniqid = uniqid();
|
||||
$rgn = urlencode("|Code=$city|");
|
||||
return [
|
||||
|
@ -1432,7 +1451,8 @@ EOT;
|
|||
* Generates various URLs as per https://tools.ietf.org/html/rfc5870
|
||||
* and other standards
|
||||
*/
|
||||
private function generateDirectionsHtml($lat, $long, $address = ''){
|
||||
private function generateDirectionsHtml($lat, $long, $address = '')
|
||||
{
|
||||
$address = urlencode($address);
|
||||
|
||||
$links = [
|
||||
|
|
|
@ -1,68 +1,74 @@
|
|||
<?php
|
||||
|
||||
class BooruprojectBridge extends DanbooruBridge {
|
||||
|
||||
class BooruprojectBridge extends DanbooruBridge
|
||||
{
|
||||
const MAINTAINER = 'mitsukarenai';
|
||||
const NAME = 'Booruproject';
|
||||
const URI = 'https://booru.org/';
|
||||
const DESCRIPTION = 'Returns images from given page of booruproject';
|
||||
const PARAMETERS = array(
|
||||
'global' => array(
|
||||
'p' => array(
|
||||
const PARAMETERS = [
|
||||
'global' => [
|
||||
'p' => [
|
||||
'name' => 'page',
|
||||
'defaultValue' => 0,
|
||||
'type' => 'number'
|
||||
),
|
||||
't' => array(
|
||||
],
|
||||
't' => [
|
||||
'name' => 'tags',
|
||||
'required' => true,
|
||||
'exampleValue' => 'tagme',
|
||||
'title' => 'Use "all" to get all posts'
|
||||
)
|
||||
),
|
||||
'Booru subdomain (subdomain.booru.org)' => array(
|
||||
'i' => array(
|
||||
]
|
||||
],
|
||||
'Booru subdomain (subdomain.booru.org)' => [
|
||||
'i' => [
|
||||
'name' => 'Subdomain',
|
||||
'required' => true,
|
||||
'exampleValue' => 'rm'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
const PATHTODATA = '.thumb';
|
||||
const IDATTRIBUTE = 'id';
|
||||
const TAGATTRIBUTE = 'title';
|
||||
const PIDBYPAGE = 20;
|
||||
|
||||
protected function getFullURI(){
|
||||
protected function getFullURI()
|
||||
{
|
||||
return $this->getURI()
|
||||
. 'index.php?page=post&s=list&pid='
|
||||
. ($this->getInput('p') ? ($this->getInput('p') - 1) * static::PIDBYPAGE : '')
|
||||
. '&tags=' . urlencode($this->getInput('t'));
|
||||
}
|
||||
|
||||
protected function getTags($element){
|
||||
protected function getTags($element)
|
||||
{
|
||||
$tags = parent::getTags($element);
|
||||
$tags = explode(' ', $tags);
|
||||
|
||||
// Remove statistics from the tags list (identified by colon)
|
||||
foreach($tags as $key => $tag) {
|
||||
if(strpos($tag, ':') !== false) unset($tags[$key]);
|
||||
foreach ($tags as $key => $tag) {
|
||||
if (strpos($tag, ':') !== false) {
|
||||
unset($tags[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return implode(' ', $tags);
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('i'))) {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('i'))) {
|
||||
return 'https://' . $this->getInput('i') . '.booru.org/';
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('i'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('i'))) {
|
||||
return static::NAME . ' ' . $this->getInput('i');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<?php
|
||||
class BrutBridge extends BridgeAbstract {
|
||||
|
||||
class BrutBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Brut Bridge';
|
||||
const URI = 'https://www.brut.media';
|
||||
const DESCRIPTION = 'Returns 10 newest videos by category and edition';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(array(
|
||||
'category' => array(
|
||||
const PARAMETERS = [[
|
||||
'category' => [
|
||||
'name' => 'Category',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'News' => 'news',
|
||||
'International' => 'international',
|
||||
'Economy' => 'economy',
|
||||
|
@ -17,37 +19,37 @@ class BrutBridge extends BridgeAbstract {
|
|||
'Sports' => 'sport',
|
||||
'Nature' => 'nature',
|
||||
'Health' => 'health',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'news',
|
||||
),
|
||||
'edition' => array(
|
||||
],
|
||||
'edition' => [
|
||||
'name' => ' Edition',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'United States' => 'us',
|
||||
'United Kingdom' => 'uk',
|
||||
'France' => 'fr',
|
||||
'Spain' => 'es',
|
||||
'India' => 'in',
|
||||
'Mexico' => 'mx',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'us',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
const CACHE_TIMEOUT = 1800; // 30 mins
|
||||
|
||||
private $jsonRegex = '/window\.__PRELOADED_STATE__ = ((?:.*)});/';
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
$results = $html->find('div.results', 0);
|
||||
|
||||
foreach($results->find('li.col-6.col-sm-4.col-md-3.col-lg-2.px-2.pb-4') as $li) {
|
||||
$item = array();
|
||||
foreach ($results->find('li.col-6.col-sm-4.col-md-3.col-lg-2.px-2.pb-4') as $li) {
|
||||
$item = [];
|
||||
|
||||
$videoPath = self::URI . $li->children(0)->href;
|
||||
$videoPageHtml = getSimpleHTMLDOMCached($videoPath, 3600);
|
||||
|
@ -83,8 +85,8 @@ EOD;
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('edition')) && !is_null($this->getInput('category'))) {
|
||||
return self::URI . '/' . $this->getInput('edition') . '/' . $this->getInput('category');
|
||||
}
|
||||
|
@ -92,8 +94,8 @@ EOD;
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('edition')) && !is_null($this->getInput('category'))) {
|
||||
$parameters = $this->getParameters();
|
||||
|
||||
|
@ -110,8 +112,8 @@ EOD;
|
|||
/**
|
||||
* Extract JSON from page
|
||||
*/
|
||||
private function extractJson($html) {
|
||||
|
||||
private function extractJson($html)
|
||||
{
|
||||
if (!preg_match($this->jsonRegex, $html, $parts)) {
|
||||
returnServerError('Failed to extract data from page');
|
||||
}
|
||||
|
|
|
@ -1,65 +1,69 @@
|
|||
<?php
|
||||
|
||||
class BugzillaBridge extends BridgeAbstract {
|
||||
class BugzillaBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Bugzilla Bridge';
|
||||
const URI = 'https://www.bugzilla.org/';
|
||||
const DESCRIPTION = 'Bridge for any Bugzilla instance';
|
||||
const MAINTAINER = 'Yaman Qalieh';
|
||||
const PARAMETERS = array(
|
||||
'global' => array(
|
||||
'instance' => array(
|
||||
const PARAMETERS = [
|
||||
'global' => [
|
||||
'instance' => [
|
||||
'name' => 'Instance URL',
|
||||
'required' => true,
|
||||
'exampleValue' => 'https://bugzilla.mozilla.org'
|
||||
)
|
||||
),
|
||||
'Bug comments' => array(
|
||||
'id' => array(
|
||||
]
|
||||
],
|
||||
'Bug comments' => [
|
||||
'id' => [
|
||||
'name' => 'Bug tracking ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'title' => 'Insert bug tracking ID',
|
||||
'exampleValue' => 121241
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'Number of comments to return',
|
||||
'type' => 'number',
|
||||
'required' => false,
|
||||
'title' => 'Specify number of comments to return',
|
||||
'defaultValue' => -1
|
||||
),
|
||||
'skiptags' => array(
|
||||
],
|
||||
'skiptags' => [
|
||||
'name' => 'Skip offtopic comments',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Excludes comments tagged as advocacy, metoo, or offtopic from the feed'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
const SKIPPED_ACTIVITY = array(
|
||||
const SKIPPED_ACTIVITY = [
|
||||
'cc' => true,
|
||||
'comment_tag' => true
|
||||
);
|
||||
];
|
||||
|
||||
const SKIPPED_TAGS = array('advocacy', 'metoo', 'offtopic');
|
||||
const SKIPPED_TAGS = ['advocacy', 'metoo', 'offtopic'];
|
||||
|
||||
private $instance;
|
||||
private $bugid;
|
||||
private $buguri;
|
||||
private $title;
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->title)) {
|
||||
return $this->title;
|
||||
}
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
return $this->buguri ?? parent::getURI();
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$this->instance = rtrim($this->getInput('instance'), '/');
|
||||
$this->bugid = $this->getInput('id');
|
||||
$this->buguri = $this->instance . '/show_bug.cgi?id=' . $this->bugid;
|
||||
|
@ -69,7 +73,7 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
$this->collectComments($url . '/comment');
|
||||
$this->collectUpdates($url . '/history');
|
||||
|
||||
usort($this->items, function($a, $b) {
|
||||
usort($this->items, function ($a, $b) {
|
||||
return $b['timestamp'] <=> $a['timestamp'];
|
||||
});
|
||||
|
||||
|
@ -78,7 +82,8 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
protected function getTitle($url) {
|
||||
protected function getTitle($url)
|
||||
{
|
||||
// Only request the summary for a faster request
|
||||
$json = json_decode(getContents($url . '?include_fields=summary'), true);
|
||||
$this->title = 'Bug ' . $this->bugid . ' - ' .
|
||||
|
@ -87,7 +92,8 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
substr($this->instance, 8);
|
||||
}
|
||||
|
||||
protected function collectComments($url) {
|
||||
protected function collectComments($url)
|
||||
{
|
||||
$json = json_decode(getContents($url), true);
|
||||
|
||||
// Array of comments is here
|
||||
|
@ -95,10 +101,12 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
returnClientError('Cannot find REST endpoint');
|
||||
}
|
||||
|
||||
foreach($json['bugs'][$this->bugid]['comments'] as $comment) {
|
||||
$item = array();
|
||||
if ($this->getInput('skiptags') and
|
||||
array_intersect(self::SKIPPED_TAGS, $comment['tags'])) {
|
||||
foreach ($json['bugs'][$this->bugid]['comments'] as $comment) {
|
||||
$item = [];
|
||||
if (
|
||||
$this->getInput('skiptags') and
|
||||
array_intersect(self::SKIPPED_TAGS, $comment['tags'])
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
$item['categories'] = $comment['tags'];
|
||||
|
@ -111,13 +119,14 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
$item['content'] = markdownToHtml($item['content']);
|
||||
}
|
||||
if (!is_null($comment['attachment_id'])) {
|
||||
$item['enclosures'] = array($this->instance . '/attachment.cgi?id=' . $comment['attachment_id']);
|
||||
$item['enclosures'] = [$this->instance . '/attachment.cgi?id=' . $comment['attachment_id']];
|
||||
}
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
protected function collectUpdates($url) {
|
||||
protected function collectUpdates($url)
|
||||
{
|
||||
$json = json_decode(getContents($url), true);
|
||||
|
||||
// Array of changesets which contain an array of changes
|
||||
|
@ -125,16 +134,16 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
returnClientError('Cannot find REST endpoint');
|
||||
}
|
||||
|
||||
foreach($json['bugs']['0']['history'] as $changeset) {
|
||||
foreach ($json['bugs']['0']['history'] as $changeset) {
|
||||
$author = $this->getUser($changeset['who']);
|
||||
$timestamp = $changeset['when'];
|
||||
foreach($changeset['changes'] as $change) {
|
||||
foreach ($changeset['changes'] as $change) {
|
||||
// Skip updates to the cc list and comment tagging
|
||||
if (isset(self::SKIPPED_ACTIVITY[$change['field_name']])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $this->buguri;
|
||||
$item['title'] = 'Updated';
|
||||
$item['timestamp'] = $timestamp;
|
||||
|
@ -147,7 +156,8 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
protected function getUser($user) {
|
||||
protected function getUser($user)
|
||||
{
|
||||
// Check if the user endpoint is available
|
||||
if ($this->loadCacheValue($this->instance . 'userEndpointClosed')) {
|
||||
return $user;
|
||||
|
@ -162,7 +172,7 @@ class BugzillaBridge extends BridgeAbstract {
|
|||
try {
|
||||
$json = json_decode(getContents($url), true);
|
||||
if (isset($json['error']) and $json['error']) {
|
||||
throw new Exception;
|
||||
throw new Exception();
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->saveCacheValue($this->instance . 'userEndpointClosed', true);
|
||||
|
|
|
@ -6,13 +6,13 @@ class BukowskisBridge extends BridgeAbstract
|
|||
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(
|
||||
const PARAMETERS = [[
|
||||
'category' => [
|
||||
'name' => 'Category',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All categories' => '',
|
||||
'Art' => array(
|
||||
'Art' => [
|
||||
'All' => 'art',
|
||||
'Classic Art' => 'art.classic-art',
|
||||
'Classic Finnish Art' => 'art.classic-finnish-art',
|
||||
|
@ -27,31 +27,31 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Prints' => 'art.prints',
|
||||
'Sculpture' => 'art.sculpture',
|
||||
'Swedish Old Masters' => 'art.swedish-old-masters',
|
||||
),
|
||||
'Asian Ceramics & Works of Art' => array(
|
||||
],
|
||||
'Asian Ceramics & Works of Art' => [
|
||||
'All' => 'asian-ceramics-works-of-art',
|
||||
'Other' => 'asian-ceramics-works-of-art.other',
|
||||
'Porcelain' => 'asian-ceramics-works-of-art.porcelain',
|
||||
),
|
||||
'Books & Manuscripts' => array(
|
||||
],
|
||||
'Books & Manuscripts' => [
|
||||
'All' => 'books-manuscripts',
|
||||
'Books' => 'books-manuscripts.books',
|
||||
),
|
||||
'Carpets, rugs & textiles' => array(
|
||||
],
|
||||
'Carpets, rugs & textiles' => [
|
||||
'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(
|
||||
],
|
||||
'Ceramics & porcelain' => [
|
||||
'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(
|
||||
],
|
||||
'Collectibles' => [
|
||||
'All' => 'collectibles',
|
||||
'Advertising & Retail' => 'collectibles.advertising-retail',
|
||||
'Memorabilia' => 'collectibles.memorabilia',
|
||||
|
@ -60,18 +60,18 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Retro & Popular Culture' => 'collectibles.retro-popular-culture',
|
||||
'Technica & Nautica' => 'collectibles.technica-nautica',
|
||||
'Toys' => 'collectibles.toys',
|
||||
),
|
||||
'Design' => array(
|
||||
],
|
||||
'Design' => [
|
||||
'All' => 'design',
|
||||
'Art glass' => 'design.art-glass',
|
||||
'Furniture' => 'design.furniture',
|
||||
'Other' => 'design.other',
|
||||
),
|
||||
'Folk art' => array(
|
||||
],
|
||||
'Folk art' => [
|
||||
'All' => 'folk-art',
|
||||
'All categories' => 'lots',
|
||||
),
|
||||
'Furniture' => array(
|
||||
],
|
||||
'Furniture' => [
|
||||
'All' => 'furniture',
|
||||
'Armchairs & Sofas' => 'furniture.armchairs-sofas',
|
||||
'Cabinets & Bureaus' => 'furniture.cabinets-bureaus',
|
||||
|
@ -81,13 +81,13 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Other' => 'furniture.other',
|
||||
'Shelves & Book cases' => 'furniture.shelves-book-cases',
|
||||
'Tables' => 'furniture.tables',
|
||||
),
|
||||
'Glassware' => array(
|
||||
],
|
||||
'Glassware' => [
|
||||
'All' => 'glassware',
|
||||
'Glassware' => 'glassware.glassware',
|
||||
'Other' => 'glassware.other',
|
||||
),
|
||||
'Jewellery' => array(
|
||||
],
|
||||
'Jewellery' => [
|
||||
'All' => 'jewellery',
|
||||
'Bracelets' => 'jewellery.bracelets',
|
||||
'Brooches' => 'jewellery.brooches',
|
||||
|
@ -95,8 +95,8 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Necklaces & Pendants' => 'jewellery.necklaces-pendants',
|
||||
'Other' => 'jewellery.other',
|
||||
'Rings' => 'jewellery.rings',
|
||||
),
|
||||
'Lighting' => array(
|
||||
],
|
||||
'Lighting' => [
|
||||
'All' => 'lighting',
|
||||
'Candle sticks & Candelabras' => 'lighting.candle-sticks-candelabras',
|
||||
'Ceiling lights' => 'lighting.ceiling-lights',
|
||||
|
@ -105,46 +105,46 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Other' => 'lighting.other',
|
||||
'Table lights' => 'lighting.table-lights',
|
||||
'Wall lights' => 'lighting.wall-lights',
|
||||
),
|
||||
'Militaria' => array(
|
||||
],
|
||||
'Militaria' => [
|
||||
'All' => 'militaria',
|
||||
'Honors & Medals' => 'militaria.honors-medals',
|
||||
'Other militaria' => 'militaria.other-militaria',
|
||||
'Weaponry' => 'militaria.weaponry',
|
||||
),
|
||||
'Miscellaneous' => array(
|
||||
],
|
||||
'Miscellaneous' => [
|
||||
'All' => 'miscellaneous',
|
||||
'Brass, Copper & Pewter' => 'miscellaneous.brass-copper-pewter',
|
||||
'Nickel silver' => 'miscellaneous.nickel-silver',
|
||||
'Oriental' => 'miscellaneous.oriental',
|
||||
'Other' => 'miscellaneous.other',
|
||||
),
|
||||
'Silver' => array(
|
||||
],
|
||||
'Silver' => [
|
||||
'All' => 'silver',
|
||||
'Candle sticks' => 'silver.candle-sticks',
|
||||
'Cups & Bowls' => 'silver.cups-bowls',
|
||||
'Cutlery' => 'silver.cutlery',
|
||||
'Other' => 'silver.other',
|
||||
),
|
||||
'Timepieces' => array(
|
||||
],
|
||||
'Timepieces' => [
|
||||
'All' => 'timepieces',
|
||||
'Other' => 'timepieces.other',
|
||||
'Pocket watches' => 'timepieces.pocket-watches',
|
||||
'Table clocks' => 'timepieces.table-clocks',
|
||||
'Wrist watches' => 'timepieces.wrist-watches',
|
||||
),
|
||||
'Vintage & Fashion' => array(
|
||||
],
|
||||
'Vintage & Fashion' => [
|
||||
'All' => 'vintage-fashion',
|
||||
'Accessories' => 'vintage-fashion.accessories',
|
||||
'Bags & Trunks' => 'vintage-fashion.bags-trunks',
|
||||
'Clothes' => 'vintage-fashion.clothes',
|
||||
),
|
||||
)
|
||||
),
|
||||
'sort_order' => array(
|
||||
],
|
||||
]
|
||||
],
|
||||
'sort_order' => [
|
||||
'name' => 'Sort order',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Ending soon' => 'ending',
|
||||
'Most recent' => 'recent',
|
||||
'Most bids' => 'most',
|
||||
|
@ -154,18 +154,18 @@ class BukowskisBridge extends BridgeAbstract
|
|||
'Lowest estimate' => 'low',
|
||||
'Highest estimate' => 'high',
|
||||
'Alphabetical' => 'alphabetical',
|
||||
),
|
||||
),
|
||||
'language' => array(
|
||||
],
|
||||
],
|
||||
'language' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'English' => 'en',
|
||||
'Swedish' => 'sv',
|
||||
'Finnish' => 'fi'
|
||||
),
|
||||
),
|
||||
));
|
||||
],
|
||||
],
|
||||
]];
|
||||
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
|
||||
|
@ -180,11 +180,13 @@ class BukowskisBridge extends BridgeAbstract
|
|||
|
||||
$url = $baseUrl . '/' . $language . '/lots';
|
||||
|
||||
if ($category)
|
||||
if ($category) {
|
||||
$url = $url . '/category/' . $category;
|
||||
}
|
||||
|
||||
if ($sort_order)
|
||||
if ($sort_order) {
|
||||
$url = $url . '/sort/' . $sort_order;
|
||||
}
|
||||
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
|
||||
|
@ -201,13 +203,13 @@ class BukowskisBridge extends BridgeAbstract
|
|||
)
|
||||
);
|
||||
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'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),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class BundesbankBridge extends BridgeAbstract {
|
||||
|
||||
class BundesbankBridge extends BridgeAbstract
|
||||
{
|
||||
const PARAM_LANG = 'lang';
|
||||
|
||||
const LANG_EN = 'en';
|
||||
|
@ -12,48 +13,52 @@ class BundesbankBridge extends BridgeAbstract {
|
|||
const MAINTAINER = 'logmanoriginal';
|
||||
const CACHE_TIMEOUT = 86400; // 24 hours
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
self::PARAM_LANG => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
self::PARAM_LANG => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'defaultValue' => self::LANG_DE,
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'English' => self::LANG_EN,
|
||||
'Deutsch' => self::LANG_DE
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . 'resource/crblob/1890/a7f48ee0ae35348748121770ba3ca009/mL/favicon-ico-data.ico';
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
switch($this->getInput(self::PARAM_LANG)) {
|
||||
case self::LANG_EN: return self::URI . 'en/publications/reports/studies';
|
||||
case self::LANG_DE: return self::URI . 'de/publikationen/berichte/studien';
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->getInput(self::PARAM_LANG)) {
|
||||
case self::LANG_EN:
|
||||
return self::URI . 'en/publications/reports/studies';
|
||||
case self::LANG_DE:
|
||||
return self::URI . 'de/publikationen/berichte/studien';
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
$html = defaultLinkTo($html, $this->getURI());
|
||||
|
||||
foreach($html->find('ul.resultlist li') as $study) {
|
||||
$item = array();
|
||||
foreach ($html->find('ul.resultlist li') as $study) {
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $study->find('.teasable__link', 0)->href;
|
||||
|
||||
// Get title without child elements (i.e. subtitle)
|
||||
$title = $study->find('.teasable__title div.h2', 0);
|
||||
|
||||
foreach($title->children as &$child) {
|
||||
foreach ($title->children as &$child) {
|
||||
$child->outertext = '';
|
||||
}
|
||||
|
||||
|
@ -62,7 +67,7 @@ class BundesbankBridge extends BridgeAbstract {
|
|||
// Add subtitle to the content if it exists
|
||||
$item['content'] = '';
|
||||
|
||||
if($subtitle = $study->find('.teasable__subtitle', 0)) {
|
||||
if ($subtitle = $study->find('.teasable__subtitle', 0)) {
|
||||
$item['content'] .= '<strong>' . $study->find('.teasable__subtitle', 0)->plaintext . '</strong>';
|
||||
}
|
||||
|
||||
|
@ -71,14 +76,13 @@ class BundesbankBridge extends BridgeAbstract {
|
|||
$item['timestamp'] = strtotime($study->find('.teasable__date', 0)->plaintext);
|
||||
|
||||
// Downloads and older studies don't have images
|
||||
if($study->find('.teasable__image', 0)) {
|
||||
$item['enclosures'] = array(
|
||||
if ($study->find('.teasable__image', 0)) {
|
||||
$item['enclosures'] = [
|
||||
$study->find('.teasable__image img', 0)->src
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
class BundestagParteispendenBridge extends BridgeAbstract {
|
||||
|
||||
class BundestagParteispendenBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'mibe';
|
||||
const NAME = 'Deutscher Bundestag - Parteispenden';
|
||||
const URI = 'https://www.bundestag.de/parlament/praesidium/parteienfinanzierung/fundstellen50000';
|
||||
|
@ -40,7 +42,7 @@ URI;
|
|||
$rows = $html->find('table.table > tbody > tr')
|
||||
or returnServerError('Could not find the proper HTML elements.');
|
||||
|
||||
foreach($rows as $row) {
|
||||
foreach ($rows as $row) {
|
||||
$item = $this->generateItemFromRow($row);
|
||||
if (is_array($item)) {
|
||||
$item['uri'] = $url;
|
||||
|
@ -52,10 +54,11 @@ URI;
|
|||
private function generateItemFromRow(simple_html_dom_node $row)
|
||||
{
|
||||
// The row must have 5 columns. There are monthly header rows, which are ignored here.
|
||||
if(count($row->children) != 5)
|
||||
if (count($row->children) != 5) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
// | column | paragraph inside column
|
||||
$party = $row->children[0]->children[0]->innertext;
|
||||
|
@ -69,20 +72,22 @@ URI;
|
|||
|
||||
$content = sprintf(self::CONTENT_TEMPLATE, $party, $amount, $donor, $date);
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'title' => $party . ': ' . $amount,
|
||||
'content' => $content,
|
||||
'uid' => sha1($content),
|
||||
);
|
||||
];
|
||||
|
||||
// Try to get the link to the official document
|
||||
if ($dip != null)
|
||||
$item['enclosures'] = array($dip->href);
|
||||
if ($dip != null) {
|
||||
$item['enclosures'] = [$dip->href];
|
||||
}
|
||||
|
||||
// Try to parse the date
|
||||
$dateTime = DateTime::createFromFormat('d.m.Y', $date);
|
||||
if ($dateTime !== false)
|
||||
if ($dateTime !== false) {
|
||||
$item['timestamp'] = $dateTime->getTimestamp();
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
class CBCEditorsBlogBridge extends BridgeAbstract {
|
||||
|
||||
class CBCEditorsBlogBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'quickwick';
|
||||
const NAME = 'CBC Editors Blog';
|
||||
const URI = 'https://www.cbc.ca/news/editorsblog';
|
||||
const DESCRIPTION = 'Recent CBC Editor\'s Blog posts';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
// Loop on each blog post entry
|
||||
foreach($html->find('div.contentListCards', 0)->find('a[data-test=type-story]') as $element) {
|
||||
foreach ($html->find('div.contentListCards', 0)->find('a[data-test=type-story]') as $element) {
|
||||
$headline = ($element->find('.headline', 0))->innertext;
|
||||
$timestamp = ($element->find('time', 0))->datetime;
|
||||
$articleUri = 'https://www.cbc.ca' . $element->href;
|
||||
|
@ -19,7 +21,7 @@ class CBCEditorsBlogBridge extends BridgeAbstract {
|
|||
$thumbnailUri = rtrim(explode(',', $thumbnailUris)[0], ' 300w');
|
||||
|
||||
// Fill item
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $articleUri;
|
||||
$item['id'] = $item['uri'];
|
||||
$item['timestamp'] = $timestamp;
|
||||
|
@ -28,7 +30,7 @@ class CBCEditorsBlogBridge extends BridgeAbstract {
|
|||
. $thumbnailUri . '" /><br>' . $summary;
|
||||
$item['author'] = 'Editor\'s Blog';
|
||||
|
||||
if(isset($item['title'])) {
|
||||
if (isset($item['title'])) {
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
class CNETBridge extends BridgeAbstract {
|
||||
|
||||
class CNETBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'CNET News';
|
||||
const URI = 'https://www.cnet.com/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'Returns the newest articles.';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'topic' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'topic' => [
|
||||
'name' => 'Topic',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All articles' => '',
|
||||
'Apple' => 'apple',
|
||||
'Google' => 'google',
|
||||
|
@ -22,12 +23,13 @@ class CNETBridge extends BridgeAbstract {
|
|||
'Security' => 'topics-security',
|
||||
'Internet' => 'topics-internet',
|
||||
'Tech Industry' => 'topics-tech-industry'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private function cleanArticle($article_html) {
|
||||
private function cleanArticle($article_html)
|
||||
{
|
||||
$offset_p = strpos($article_html, '<p>');
|
||||
$offset_figure = strpos($article_html, '<figure');
|
||||
$offset = ($offset_figure < $offset_p ? $offset_figure : $offset_p);
|
||||
|
@ -44,21 +46,21 @@ class CNETBridge extends BridgeAbstract {
|
|||
return $article_html;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
// Retrieve and check user input
|
||||
$topic = str_replace('-', '/', $this->getInput('topic'));
|
||||
if (!empty($topic) && (substr_count($topic, '/') > 1 || !ctype_alpha(str_replace('/', '', $topic))))
|
||||
if (!empty($topic) && (substr_count($topic, '/') > 1 || !ctype_alpha(str_replace('/', '', $topic)))) {
|
||||
returnClientError('Invalid topic: ' . $topic);
|
||||
}
|
||||
|
||||
// Retrieve webpage
|
||||
$pageUrl = self::URI . (empty($topic) ? 'news/' : $topic . '/');
|
||||
$html = getSimpleHTMLDOM($pageUrl);
|
||||
|
||||
// Process articles
|
||||
foreach($html->find('div.assetBody, div.riverPost') as $element) {
|
||||
|
||||
if(count($this->items) >= 10) {
|
||||
foreach ($html->find('div.assetBody, div.riverPost') as $element) {
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -69,37 +71,41 @@ class CNETBridge extends BridgeAbstract {
|
|||
$article_author = trim($element->find('a[rel=author], a.name', 0)->plaintext);
|
||||
$article_content = '<p><b>' . trim($element->find('p.dek', 0)->plaintext) . '</b></p>';
|
||||
|
||||
if (is_null($article_thumbnail))
|
||||
if (is_null($article_thumbnail)) {
|
||||
$article_thumbnail = extractFromDelimiters($element->innertext, '<img src="', '"');
|
||||
}
|
||||
|
||||
if (!empty($article_title) && !empty($article_uri) && strpos($article_uri, self::URI . 'news/') !== false) {
|
||||
|
||||
$article_html = getSimpleHTMLDOMCached($article_uri) or $article_html = null;
|
||||
|
||||
if (!is_null($article_html)) {
|
||||
|
||||
if (empty($article_thumbnail))
|
||||
if (empty($article_thumbnail)) {
|
||||
$article_thumbnail = $article_html->find('div.originalImage', 0);
|
||||
if (empty($article_thumbnail))
|
||||
}
|
||||
if (empty($article_thumbnail)) {
|
||||
$article_thumbnail = $article_html->find('span.imageContainer', 0);
|
||||
if (is_object($article_thumbnail))
|
||||
}
|
||||
if (is_object($article_thumbnail)) {
|
||||
$article_thumbnail = $article_thumbnail->find('img', 0)->src;
|
||||
}
|
||||
|
||||
$article_content .= trim(
|
||||
$this->cleanArticle(
|
||||
extractFromDelimiters(
|
||||
$article_html, '<article', '<footer'
|
||||
$article_html,
|
||||
'<article',
|
||||
'<footer'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $article_uri;
|
||||
$item['title'] = $article_title;
|
||||
$item['author'] = $article_author;
|
||||
$item['timestamp'] = $article_timestamp;
|
||||
$item['enclosures'] = array($article_thumbnail);
|
||||
$item['enclosures'] = [$article_thumbnail];
|
||||
$item['content'] = $article_content;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
class CNETFranceBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'leomaradan';
|
||||
|
@ -6,25 +7,25 @@ class CNETFranceBridge extends FeedExpander
|
|||
const URI = 'https://www.cnetfrance.fr/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'CNET France RSS with filters';
|
||||
const PARAMETERS = array(
|
||||
'filters' => array(
|
||||
'title' => array(
|
||||
const PARAMETERS = [
|
||||
'filters' => [
|
||||
'title' => [
|
||||
'name' => 'Exclude by title',
|
||||
'required' => false,
|
||||
'title' => 'Title term, separated by semicolon (;)',
|
||||
'exampleValue' => 'bon plan;bons plans;au meilleur prix;des meilleures offres;Amazon Prime Day;RED by SFR ou B&You'
|
||||
),
|
||||
'url' => array(
|
||||
],
|
||||
'url' => [
|
||||
'name' => 'Exclude by url',
|
||||
'required' => false,
|
||||
'title' => 'URL term, separated by semicolon (;)',
|
||||
'exampleValue' => 'bon-plan;bons-plans'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private $bannedTitle = array();
|
||||
private $bannedURL = array();
|
||||
private $bannedTitle = [];
|
||||
private $bannedURL = [];
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
|
|
|
@ -7,29 +7,30 @@
|
|||
// it is not reliable and contain no useful information. This bridge create a
|
||||
// sane feed with additional information like tags and a link to the CWE
|
||||
// a description of the vulnerability.
|
||||
class CVEDetailsBridge extends BridgeAbstract {
|
||||
class CVEDetailsBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Aaron Fischer';
|
||||
const NAME = 'CVE Details';
|
||||
const CACHE_TIMEOUT = 60 * 60 * 6; // 6 hours
|
||||
const DESCRIPTION = 'Report new CVE vulnerabilities for a given vendor (and product)';
|
||||
const URI = 'https://www.cvedetails.com';
|
||||
|
||||
const PARAMETERS = array(array(
|
||||
const PARAMETERS = [[
|
||||
// The Vendor ID can be taken from the URL
|
||||
'vendor_id' => array(
|
||||
'vendor_id' => [
|
||||
'name' => 'Vendor ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => 74, // PHP
|
||||
),
|
||||
],
|
||||
// The optional Product ID can be taken from the URL as well
|
||||
'product_id' => array(
|
||||
'product_id' => [
|
||||
'name' => 'Product ID',
|
||||
'type' => 'number',
|
||||
'required' => false,
|
||||
'exampleValue' => 128, // PHP
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
private $html = null;
|
||||
private $vendor = '';
|
||||
|
@ -39,7 +40,8 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
// Because of the optional product ID, we need to attach it if it is
|
||||
// set. The search result page has the exact same structure (with and
|
||||
// without the product ID).
|
||||
private function buildUrl() {
|
||||
private function buildUrl()
|
||||
{
|
||||
$url = self::URI . '/vulnerability-list/vendor_id-' . $this->getInput('vendor_id');
|
||||
if ($this->getInput('product_id') !== '') {
|
||||
$url .= '/product_id-' . $this->getInput('product_id');
|
||||
|
@ -54,7 +56,8 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
|
||||
// Make the actual request to cvedetails.com and stores the response
|
||||
// (HTML) for later use and extract vendor and product from it.
|
||||
private function fetchContent() {
|
||||
private function fetchContent()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->buildUrl());
|
||||
$this->html = defaultLinkTo($html, self::URI);
|
||||
|
||||
|
@ -74,7 +77,8 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Build the name of the feed.
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if ($this->getInput('vendor_id') == '') {
|
||||
return self::NAME;
|
||||
}
|
||||
|
@ -92,7 +96,8 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Pull the data from the HTML response and fill the items..
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
if ($this->html == null) {
|
||||
$this->fetchContent();
|
||||
}
|
||||
|
@ -101,8 +106,8 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
// There are some optional vulnerability types, which will be
|
||||
// added to the categories as well as the CWE number -- which is
|
||||
// always given.
|
||||
$categories = array($this->vendor);
|
||||
$enclosures = array();
|
||||
$categories = [$this->vendor];
|
||||
$enclosures = [];
|
||||
|
||||
$cwe = $tr->find('td', 2)->find('a', 0);
|
||||
if ($cwe != null) {
|
||||
|
@ -121,7 +126,7 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
// The CVE number itself
|
||||
$title = $tr->find('td', 1)->find('a', 0)->innertext;
|
||||
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'uri' => $tr->find('td', 1)->find('a', 0)->href,
|
||||
'title' => $title,
|
||||
'timestamp' => $tr->find('td', 5)->innertext,
|
||||
|
@ -129,7 +134,7 @@ class CVEDetailsBridge extends BridgeAbstract {
|
|||
'categories' => $categories,
|
||||
'enclosures' => $enclosures,
|
||||
'uid' => $tr->find('td', 1)->find('a', 0)->innertext,
|
||||
);
|
||||
];
|
||||
|
||||
// We only want to fetch the latest 10 CVEs
|
||||
if (count($this->items) >= 10) {
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
<?php
|
||||
|
||||
class CachetBridge extends BridgeAbstract {
|
||||
class CachetBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Cachet Bridge';
|
||||
const URI = 'https://cachethq.io/';
|
||||
const DESCRIPTION = 'Returns status updates from any Cachet installation';
|
||||
const MAINTAINER = 'klimplant';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'host' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'host' => [
|
||||
'name' => 'Cachet installation',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'The URL of the Cachet installation',
|
||||
'exampleValue' => 'https://demo.cachethq.io/',
|
||||
), 'additional_info' => array(
|
||||
], 'additional_info' => [
|
||||
'name' => 'Additional Timestamps',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Whether to include the given timestamps'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
const CACHE_TIMEOUT = 300;
|
||||
|
||||
private $componentCache = array();
|
||||
private $componentCache = [];
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
return $this->getInput('host') === null ? 'https://cachethq.io/' : $this->getInput('host');
|
||||
}
|
||||
|
||||
|
@ -34,7 +36,8 @@ class CachetBridge extends BridgeAbstract {
|
|||
* @param string $ping
|
||||
* @return boolean
|
||||
*/
|
||||
private function validatePing($ping) {
|
||||
private function validatePing($ping)
|
||||
{
|
||||
$ping = json_decode($ping);
|
||||
if ($ping === null) {
|
||||
return false;
|
||||
|
@ -48,7 +51,8 @@ class CachetBridge extends BridgeAbstract {
|
|||
* @param integer $id
|
||||
* @return string
|
||||
*/
|
||||
private function getComponentName($id) {
|
||||
private function getComponentName($id)
|
||||
{
|
||||
if ($id === 0) {
|
||||
return '';
|
||||
}
|
||||
|
@ -64,7 +68,8 @@ class CachetBridge extends BridgeAbstract {
|
|||
return $component->data->name;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$ping = getContents(urljoin($this->getURI(), '/api/v1/ping'));
|
||||
if (!$this->validatePing($ping)) {
|
||||
returnClientError('Provided URI is invalid!');
|
||||
|
@ -84,7 +89,6 @@ class CachetBridge extends BridgeAbstract {
|
|||
});
|
||||
|
||||
foreach ($incidents->data as $incident) {
|
||||
|
||||
if (isset($incident->permalink)) {
|
||||
$permalink = $incident->permalink;
|
||||
} else {
|
||||
|
@ -114,13 +118,13 @@ class CachetBridge extends BridgeAbstract {
|
|||
$uidOrig = $permalink . $incident->created_at;
|
||||
$uid = hash('sha512', $uidOrig);
|
||||
$timestamp = strtotime($incident->created_at);
|
||||
$categories = array();
|
||||
$categories = [];
|
||||
$categories[] = $incident->human_status;
|
||||
if ($componentName !== '') {
|
||||
$categories[] = $componentName;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $permalink;
|
||||
$item['title'] = $title;
|
||||
$item['timestamp'] = $timestamp;
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
<?php
|
||||
class CarThrottleBridge extends FeedExpander {
|
||||
|
||||
class CarThrottleBridge extends FeedExpander
|
||||
{
|
||||
const NAME = 'Car Throttle ';
|
||||
const URI = 'https://www.carthrottle.com';
|
||||
const DESCRIPTION = 'Get the latest car-related news from Car Throttle.';
|
||||
const MAINTAINER = 't0stiman';
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$this->collectExpandableDatas('https://www.carthrottle.com/rss', 10);
|
||||
}
|
||||
|
||||
protected function parseItem($feedItem) {
|
||||
protected function parseItem($feedItem)
|
||||
{
|
||||
$item = parent::parseItem($feedItem);
|
||||
|
||||
//fetch page
|
||||
|
@ -22,8 +26,7 @@ class CarThrottleBridge extends FeedExpander {
|
|||
$item['content'] = str_get_html($subtitle . $article);
|
||||
|
||||
//convert <iframe>s to <a>s. meant for embedded videos.
|
||||
foreach($item['content']->find('iframe') as $found) {
|
||||
|
||||
foreach ($item['content']->find('iframe') as $found) {
|
||||
$iframeUrl = $found->getAttribute('src');
|
||||
|
||||
if ($iframeUrl) {
|
||||
|
|
|
@ -1,63 +1,71 @@
|
|||
<?php
|
||||
class CastorusBridge extends BridgeAbstract {
|
||||
|
||||
class CastorusBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'logmanoriginal';
|
||||
const NAME = 'Castorus Bridge';
|
||||
const URI = 'https://www.castorus.com';
|
||||
const CACHE_TIMEOUT = 600; // 10min
|
||||
const DESCRIPTION = 'Returns the latest changes';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'Get latest changes' => array(),
|
||||
'Get latest changes via ZIP code' => array(
|
||||
'zip' => array(
|
||||
const PARAMETERS = [
|
||||
'Get latest changes' => [],
|
||||
'Get latest changes via ZIP code' => [
|
||||
'zip' => [
|
||||
'name' => 'ZIP code',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => '7',
|
||||
'title' => 'Insert ZIP code (complete or partial). e.g: 78125 OR 781 OR 7'
|
||||
)
|
||||
),
|
||||
'Get latest changes via city name' => array(
|
||||
'city' => array(
|
||||
]
|
||||
],
|
||||
'Get latest changes via city name' => [
|
||||
'city' => [
|
||||
'name' => 'City name',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'Paris',
|
||||
'title' => 'Insert city name (complete or partial). e.g: Paris OR Par OR P'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// Extracts the title from an actitiy
|
||||
private function extractActivityTitle($activity){
|
||||
private function extractActivityTitle($activity)
|
||||
{
|
||||
$title = $activity->find('a', 0);
|
||||
|
||||
if(!$title)
|
||||
if (!$title) {
|
||||
returnServerError('Cannot find title!');
|
||||
}
|
||||
|
||||
return trim($title->plaintext);
|
||||
}
|
||||
|
||||
// Extracts the url from an actitiy
|
||||
private function extractActivityUrl($activity){
|
||||
private function extractActivityUrl($activity)
|
||||
{
|
||||
$url = $activity->find('a', 0);
|
||||
|
||||
if(!$url)
|
||||
if (!$url) {
|
||||
returnServerError('Cannot find url!');
|
||||
}
|
||||
|
||||
return self::URI . $url->href;
|
||||
}
|
||||
|
||||
// Extracts the time from an activity
|
||||
private function extractActivityTime($activity){
|
||||
private function extractActivityTime($activity)
|
||||
{
|
||||
// Unfortunately the time is part of the parent node,
|
||||
// so we have to clear all child nodes first
|
||||
$nodes = $activity->find('*');
|
||||
|
||||
if(!$nodes)
|
||||
if (!$nodes) {
|
||||
returnServerError('Cannot find nodes!');
|
||||
}
|
||||
|
||||
foreach($nodes as $node) {
|
||||
foreach ($nodes as $node) {
|
||||
$node->outertext = '';
|
||||
}
|
||||
|
||||
|
@ -65,31 +73,36 @@ class CastorusBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Extracts the price change
|
||||
private function extractActivityPrice($activity){
|
||||
private function extractActivityPrice($activity)
|
||||
{
|
||||
$price = $activity->find('span', 1);
|
||||
|
||||
if(!$price)
|
||||
if (!$price) {
|
||||
returnServerError('Cannot find price!');
|
||||
}
|
||||
|
||||
return $price->innertext;
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$zip_filter = trim($this->getInput('zip'));
|
||||
$city_filter = trim($this->getInput('city'));
|
||||
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
if(!$html)
|
||||
if (!$html) {
|
||||
returnServerError('Could not load data from ' . self::URI . '!');
|
||||
}
|
||||
|
||||
$activities = $html->find('div#activite > li');
|
||||
|
||||
if(!$activities)
|
||||
if (!$activities) {
|
||||
returnServerError('Failed to find activities!');
|
||||
}
|
||||
|
||||
foreach($activities as $activity) {
|
||||
$item = array();
|
||||
foreach ($activities as $activity) {
|
||||
$item = [];
|
||||
|
||||
$item['title'] = $this->extractActivityTitle($activity);
|
||||
$item['uri'] = $this->extractActivityUrl($activity);
|
||||
|
@ -102,13 +115,17 @@ class CastorusBridge extends BridgeAbstract {
|
|||
. $this->extractActivityPrice($activity)
|
||||
. '</p>';
|
||||
|
||||
if(isset($zip_filter)
|
||||
&& !(substr($item['title'], 0, strlen($zip_filter)) === $zip_filter)) {
|
||||
if (
|
||||
isset($zip_filter)
|
||||
&& !(substr($item['title'], 0, strlen($zip_filter)) === $zip_filter)
|
||||
) {
|
||||
continue; // Skip this item
|
||||
}
|
||||
|
||||
if(isset($city_filter)
|
||||
&& !(substr($item['title'], strpos($item['title'], ' ') + 1, strlen($city_filter)) === $city_filter)) {
|
||||
if (
|
||||
isset($city_filter)
|
||||
&& !(substr($item['title'], strpos($item['title'], ' ') + 1, strlen($city_filter)) === $city_filter)
|
||||
) {
|
||||
continue; // Skip this item
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,42 @@
|
|||
<?php
|
||||
|
||||
class CdactionBridge extends BridgeAbstract {
|
||||
class CdactionBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'CD-ACTION bridge';
|
||||
const URI = 'https://cdaction.pl';
|
||||
const DESCRIPTION = 'Fetches the latest posts from given category.';
|
||||
const MAINTAINER = 'tomaszkane';
|
||||
const PARAMETERS = array( array(
|
||||
'category' => array(
|
||||
const PARAMETERS = [ [
|
||||
'category' => [
|
||||
'name' => 'Kategoria',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Najnowsze (wszystkie)' => 'najnowsze',
|
||||
'Newsy' => 'newsy',
|
||||
'Recenzje' => 'recenzje',
|
||||
'Teksty' => array(
|
||||
'Teksty' => [
|
||||
'Publicystyka' => 'publicystyka',
|
||||
'Zapowiedzi' => 'zapowiedzi',
|
||||
'Już graliśmy' => 'juz-gralismy',
|
||||
'Poradniki' => 'poradniki',
|
||||
),
|
||||
],
|
||||
'Kultura' => 'kultura',
|
||||
'Wideo' => 'wideo',
|
||||
'Czasopismo' => 'czasopismo',
|
||||
'Technologie' => array(
|
||||
'Technologie' => [
|
||||
'Artykuły' => 'artykuly',
|
||||
'Testy' => 'testy',
|
||||
),
|
||||
'Na luzie' => array(
|
||||
],
|
||||
'Na luzie' => [
|
||||
'Konkursy' => 'konkursy',
|
||||
'Nadgodziny' => 'nadgodziny',
|
||||
)
|
||||
)
|
||||
))
|
||||
);
|
||||
]
|
||||
]
|
||||
]]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI() . '/' . $this->getInput('category'));
|
||||
|
||||
$newsJson = $html->find('script#__NEXT_DATA__', 0)->innertext;
|
||||
|
@ -44,7 +46,7 @@ class CdactionBridge extends BridgeAbstract {
|
|||
|
||||
$queriesIndex = $this->getInput('category') === 'najnowsze' ? 0 : 1;
|
||||
foreach ($newsJson->props->pageProps->dehydratedState->queries[$queriesIndex]->state->data->results as $news) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $this->getURI() . '/' . $news->category->slug . '/' . $news->slug;
|
||||
$item['title'] = $news->title;
|
||||
$item['timestamp'] = $news->publishedAt;
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
<?php
|
||||
|
||||
class CeskaTelevizeBridge extends BridgeAbstract {
|
||||
|
||||
class CeskaTelevizeBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Česká televize Bridge';
|
||||
const URI = 'https://www.ceskatelevize.cz';
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
const DESCRIPTION = 'Return newest videos';
|
||||
const MAINTAINER = 'kolarcz';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'url' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'url' => [
|
||||
'name' => 'url to the show',
|
||||
'required' => true,
|
||||
'exampleValue' => 'https://www.ceskatelevize.cz/porady/1097181328-udalosti/'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private function fixChars($text) {
|
||||
private function fixChars($text)
|
||||
{
|
||||
return html_entity_decode($text, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
private function getUploadTimeFromString($string) {
|
||||
private function getUploadTimeFromString($string)
|
||||
{
|
||||
if (strpos($string, 'dnes') !== false) {
|
||||
return strtotime('today');
|
||||
} elseif (strpos($string, 'včera') !== false) {
|
||||
|
@ -35,7 +37,8 @@ class CeskaTelevizeBridge extends BridgeAbstract {
|
|||
return strtotime($date);
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$url = $this->getInput('url');
|
||||
|
||||
$validUrl = '/^(https:\/\/www\.ceskatelevize\.cz\/porady\/\d+-[a-z0-9-]+\/)(bonus\/)?$/';
|
||||
|
@ -61,23 +64,25 @@ class CeskaTelevizeBridge extends BridgeAbstract {
|
|||
$itemThumbnail = $element->find('img', 0);
|
||||
$itemUri = self::URI . $element->getAttribute('href');
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'title' => $this->fixChars($itemTitle->plaintext),
|
||||
'uri' => $itemUri,
|
||||
'content' => '<img src="' . $itemThumbnail->getAttribute('src') . '" /><br />'
|
||||
. $this->fixChars($itemContent->plaintext),
|
||||
'timestamp' => $this->getUploadTimeFromString($itemDate->plaintext)
|
||||
);
|
||||
];
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
return isset($this->feedUri) ? $this->feedUri : parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return isset($this->feedName) ? $this->feedName : parent::getName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,69 +1,71 @@
|
|||
<?php
|
||||
class CodebergBridge extends BridgeAbstract {
|
||||
|
||||
class CodebergBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Codeberg Bridge';
|
||||
const URI = 'https://codeberg.org/';
|
||||
const DESCRIPTION = 'Returns commits, issues, pull requests or releases for a repository.';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(
|
||||
'Commits' => array(
|
||||
'branch' => array(
|
||||
const PARAMETERS = [
|
||||
'Commits' => [
|
||||
'branch' => [
|
||||
'name' => 'branch',
|
||||
'type' => 'text',
|
||||
'exampleValue' => 'main',
|
||||
'required' => false,
|
||||
'title' => 'Optional, main branch is used by default.',
|
||||
),
|
||||
),
|
||||
'Issues' => array(),
|
||||
'Issue Comments' => array(
|
||||
'issueId' => array(
|
||||
],
|
||||
],
|
||||
'Issues' => [],
|
||||
'Issue Comments' => [
|
||||
'issueId' => [
|
||||
'name' => 'Issue ID',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => '513',
|
||||
)
|
||||
),
|
||||
'Pull Requests' => array(),
|
||||
'Releases' => array(),
|
||||
'global' => array(
|
||||
'username' => array(
|
||||
]
|
||||
],
|
||||
'Pull Requests' => [],
|
||||
'Releases' => [],
|
||||
'global' => [
|
||||
'username' => [
|
||||
'name' => 'Username',
|
||||
'type' => 'text',
|
||||
'exampleValue' => 'Codeberg',
|
||||
'title' => 'Username of account that the repository belongs to.',
|
||||
'required' => true,
|
||||
),
|
||||
'repo' => array(
|
||||
],
|
||||
'repo' => [
|
||||
'name' => 'Repository',
|
||||
'type' => 'text',
|
||||
'exampleValue' => 'Community',
|
||||
'required' => true,
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
const CACHE_TIMEOUT = 1800;
|
||||
|
||||
const TEST_DETECT_PARAMETERS = array(
|
||||
'https://codeberg.org/Codeberg/Community/issues/507' => array(
|
||||
const TEST_DETECT_PARAMETERS = [
|
||||
'https://codeberg.org/Codeberg/Community/issues/507' => [
|
||||
'context' => 'Issue Comments', 'username' => 'Codeberg', 'repo' => 'Community', 'issueId' => '507'
|
||||
),
|
||||
'https://codeberg.org/Codeberg/Community/issues' => array(
|
||||
],
|
||||
'https://codeberg.org/Codeberg/Community/issues' => [
|
||||
'context' => 'Issues', 'username' => 'Codeberg', 'repo' => 'Community'
|
||||
),
|
||||
'https://codeberg.org/Codeberg/Community/pulls' => array(
|
||||
],
|
||||
'https://codeberg.org/Codeberg/Community/pulls' => [
|
||||
'context' => 'Pull Requests', 'username' => 'Codeberg', 'repo' => 'Community'
|
||||
),
|
||||
'https://codeberg.org/Codeberg/Community/releases' => array(
|
||||
],
|
||||
'https://codeberg.org/Codeberg/Community/releases' => [
|
||||
'context' => 'Releases', 'username' => 'Codeberg', 'repo' => 'Community'
|
||||
),
|
||||
'https://codeberg.org/Codeberg/Community/commits/branch/master' => array(
|
||||
],
|
||||
'https://codeberg.org/Codeberg/Community/commits/branch/master' => [
|
||||
'context' => 'Commits', 'username' => 'Codeberg', 'repo' => 'Community', 'branch' => 'master'
|
||||
),
|
||||
'https://codeberg.org/Codeberg/Community/commits' => array(
|
||||
],
|
||||
'https://codeberg.org/Codeberg/Community/commits' => [
|
||||
'context' => 'Commits', 'username' => 'Codeberg', 'repo' => 'Community'
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
|
||||
private $defaultBranch = 'main';
|
||||
private $issueTitle = '';
|
||||
|
@ -74,11 +76,12 @@ class CodebergBridge extends BridgeAbstract {
|
|||
private $releasesUrlRegex = '/codeberg\.org\/([\w]+)\/([\w]+)\/releases/';
|
||||
private $issueCommentsUrlRegex = '/codeberg\.org\/([\w]+)\/([\w]+)\/issues\/([0-9]+)/';
|
||||
|
||||
public function detectParameters($url) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// Issue Comments
|
||||
if(preg_match($this->issueCommentsUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->issueCommentsUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Issue Comments';
|
||||
$params['username'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -88,7 +91,7 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Issues
|
||||
if(preg_match($this->issuesUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->issuesUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Issues';
|
||||
$params['username'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -97,7 +100,7 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Pull Requests
|
||||
if(preg_match($this->pullsUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->pullsUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Pull Requests';
|
||||
$params['username'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -106,7 +109,7 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Releases
|
||||
if(preg_match($this->releasesUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->releasesUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Releases';
|
||||
$params['username'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -115,7 +118,7 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// Commits
|
||||
if(preg_match($this->urlRegex, $url, $matches)) {
|
||||
if (preg_match($this->urlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Commits';
|
||||
$params['username'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -130,12 +133,13 @@ class CodebergBridge extends BridgeAbstract {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
$html = defaultLinkTo($html, $this->getURI());
|
||||
|
||||
switch($this->queriedContext) {
|
||||
switch ($this->queriedContext) {
|
||||
case 'Commits':
|
||||
$this->extractCommits($html);
|
||||
break;
|
||||
|
@ -156,8 +160,9 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Commits':
|
||||
if ($this->getBranch() === $this->defaultBranch) {
|
||||
return $this->getRepo() . ' Commits';
|
||||
|
@ -177,8 +182,9 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Commits':
|
||||
return self::URI . $this->getRepo() . '/commits/branch/' . $this->getBranch();
|
||||
case 'Issues':
|
||||
|
@ -194,7 +200,8 @@ class CodebergBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
private function getBranch() {
|
||||
private function getBranch()
|
||||
{
|
||||
if ($this->getInput('branch')) {
|
||||
return $this->getInput('branch');
|
||||
}
|
||||
|
@ -202,19 +209,21 @@ class CodebergBridge extends BridgeAbstract {
|
|||
return $this->defaultBranch;
|
||||
}
|
||||
|
||||
private function getRepo() {
|
||||
private function getRepo()
|
||||
{
|
||||
return $this->getInput('username') . '/' . $this->getInput('repo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract commits
|
||||
*/
|
||||
private function extractCommits($html) {
|
||||
private function extractCommits($html)
|
||||
{
|
||||
$table = $html->find('table#commits-table', 0);
|
||||
$tbody = $table->find('tbody.commit-list', 0);
|
||||
|
||||
foreach ($tbody->find('tr') as $tr) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$message = $tr->find('td.message', 0);
|
||||
|
||||
|
@ -238,11 +247,12 @@ class CodebergBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Extract issues
|
||||
*/
|
||||
private function extractIssues($html) {
|
||||
private function extractIssues($html)
|
||||
{
|
||||
$div = $html->find('div.issue.list', 0);
|
||||
|
||||
foreach ($div->find('li.item') as $li) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$number = trim($li->find('a.index,ml-0.mr-2', 0)->plaintext);
|
||||
|
||||
|
@ -268,12 +278,13 @@ class CodebergBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Extract issue comments
|
||||
*/
|
||||
private function extractIssueComments($html) {
|
||||
private function extractIssueComments($html)
|
||||
{
|
||||
$this->issueTitle = $html->find('span#issue-title', 0)->plaintext
|
||||
. ' (' . $html->find('span.index', 0)->plaintext . ')';
|
||||
|
||||
foreach ($html->find('div.timeline-item.comment') as $div) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
if ($div->class === 'timeline-item comment merge box') {
|
||||
continue;
|
||||
|
@ -297,11 +308,12 @@ class CodebergBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Extract pulls
|
||||
*/
|
||||
private function extractPulls($html) {
|
||||
private function extractPulls($html)
|
||||
{
|
||||
$div = $html->find('div.issue.list', 0);
|
||||
|
||||
foreach ($div->find('li.item') as $li) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$number = trim($li->find('a.index,ml-0.mr-2', 0)->plaintext);
|
||||
|
||||
|
@ -327,11 +339,12 @@ class CodebergBridge extends BridgeAbstract {
|
|||
/**
|
||||
* Extract releases
|
||||
*/
|
||||
private function extractReleases($html) {
|
||||
private function extractReleases($html)
|
||||
{
|
||||
$ul = $html->find('ul#release-list', 0);
|
||||
|
||||
foreach ($ul->find('li.ui.grid') as $li) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $li->find('h4', 0)->plaintext;
|
||||
$item['uri'] = $li->find('h4', 0)->find('a', 0)->href;
|
||||
|
||||
|
@ -358,7 +371,8 @@ HTML;
|
|||
/**
|
||||
* Extract downloads for a releases
|
||||
*/
|
||||
private function extractDownloads($html, $skipFirst = false) {
|
||||
private function extractDownloads($html, $skipFirst = false)
|
||||
{
|
||||
$downloads = '';
|
||||
|
||||
foreach ($html->find('a') as $index => $a) {
|
||||
|
@ -380,7 +394,8 @@ EOD;
|
|||
/**
|
||||
* Ellipsis title to first 100 characters
|
||||
*/
|
||||
private function ellipsisTitle($text) {
|
||||
private function ellipsisTitle($text)
|
||||
{
|
||||
$length = 100;
|
||||
|
||||
if (strlen($text) > $length) {
|
||||
|
@ -393,7 +408,8 @@ EOD;
|
|||
/**
|
||||
* Strip SVG tag
|
||||
*/
|
||||
private function stripSvg($html) {
|
||||
private function stripSvg($html)
|
||||
{
|
||||
if ($html->find('svg', 0)) {
|
||||
$html->find('svg', 0)->outertext = '';
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<?php
|
||||
class CollegeDeFranceBridge extends BridgeAbstract {
|
||||
|
||||
class CollegeDeFranceBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'pit-fgfjiudghdf';
|
||||
const NAME = 'CollegeDeFrance';
|
||||
const URI = 'https://www.college-de-france.fr/';
|
||||
const CACHE_TIMEOUT = 10800; // 3h
|
||||
const DESCRIPTION = 'Returns the latest audio and video from CollegeDeFrance';
|
||||
|
||||
public function collectData(){
|
||||
$months = array(
|
||||
public function collectData()
|
||||
{
|
||||
$months = [
|
||||
'01' => 'janv.',
|
||||
'02' => 'févr.',
|
||||
'03' => 'mars',
|
||||
|
@ -21,7 +23,7 @@ class CollegeDeFranceBridge extends BridgeAbstract {
|
|||
'10' => 'oct.',
|
||||
'11' => 'nov.',
|
||||
'12' => 'déc.'
|
||||
);
|
||||
];
|
||||
|
||||
// The "API" used by the site returns a list of partial HTML in this form
|
||||
/* <li>
|
||||
|
@ -36,8 +38,8 @@ class CollegeDeFranceBridge extends BridgeAbstract {
|
|||
$html = getSimpleHTMLDOM(self::URI
|
||||
. 'components/search-audiovideo.jsp?fulltext=&siteid=1156951719600&lang=FR&type=all');
|
||||
|
||||
foreach($html->find('a[data-target]') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('a[data-target]') as $element) {
|
||||
$item = [];
|
||||
$item['title'] = $element->find('.title', 0)->plaintext;
|
||||
|
||||
// Most relative URLs contains an hour in addition to the date, so let's use it
|
||||
|
@ -59,7 +61,7 @@ class CollegeDeFranceBridge extends BridgeAbstract {
|
|||
$timezone
|
||||
);
|
||||
|
||||
if(!$d) {
|
||||
if (!$d) {
|
||||
$d = DateTime::createFromFormat(
|
||||
'!d m Y',
|
||||
trim(str_replace(
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
<?php
|
||||
class ComboiosDePortugalBridge extends BridgeAbstract {
|
||||
|
||||
class ComboiosDePortugalBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'CP | Avisos';
|
||||
const BASE_URI = 'https://www.cp.pt';
|
||||
const URI = self::BASE_URI . '/passageiros/pt';
|
||||
const DESCRIPTION = 'Comboios de Portugal | Avisos';
|
||||
const MAINTAINER = 'somini';
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
# Do not verify SSL certificate (the server doesn't send the intermediate)
|
||||
# https://github.com/RSS-Bridge/rss-bridge/issues/2397
|
||||
$html = getSimpleHTMLDOM($this->getURI() . '/consultar-horarios/avisos', array(), array(
|
||||
$html = getSimpleHTMLDOM($this->getURI() . '/consultar-horarios/avisos', [], [
|
||||
CURLOPT_SSL_VERIFYPEER => 0,
|
||||
));
|
||||
]);
|
||||
|
||||
foreach($html->find('.warnings-table a') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('.warnings-table a') as $element) {
|
||||
$item = [];
|
||||
|
||||
$item['title'] = $element->innertext;
|
||||
$item['uri'] = self::BASE_URI . implode('/', array_map('urlencode', explode('/', $element->href)));
|
||||
|
|
|
@ -1,31 +1,34 @@
|
|||
<?php
|
||||
class ComicsKingdomBridge extends BridgeAbstract {
|
||||
|
||||
class ComicsKingdomBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'stjohnjohnson';
|
||||
const NAME = 'Comics Kingdom Unofficial RSS';
|
||||
const URI = 'https://comicskingdom.com/';
|
||||
const CACHE_TIMEOUT = 21600; // 6h
|
||||
const DESCRIPTION = 'Comics Kingdom Unofficial RSS';
|
||||
const PARAMETERS = array( array(
|
||||
'comicname' => array(
|
||||
const PARAMETERS = [ [
|
||||
'comicname' => [
|
||||
'name' => 'comicname',
|
||||
'type' => 'text',
|
||||
'exampleValue' => 'mutts',
|
||||
'title' => 'The name of the comic in the URL after https://comicskingdom.com/',
|
||||
'required' => true
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
public function collectData(){
|
||||
$html = getSimpleHTMLDOM($this->getURI(), array(), array(), true, false);
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getURI(), [], [], true, false);
|
||||
|
||||
// Get author from first page
|
||||
$author = $html->find('div.author p', 0);;
|
||||
$author = $html->find('div.author p', 0);
|
||||
;
|
||||
|
||||
// Get current date/link
|
||||
$link = $html->find('meta[property=og:url]', -1)->content;
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
$item = array();
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$item = [];
|
||||
|
||||
$page = getSimpleHTMLDOM($link);
|
||||
|
||||
|
@ -42,20 +45,24 @@ class ComicsKingdomBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
$link = $page->find('div.comic-viewer-inline a', 0)->href;
|
||||
if (empty($link)) break; // allow bridge to continue if there's less than 3 comics
|
||||
if (empty($link)) {
|
||||
break; // allow bridge to continue if there's less than 3 comics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('comicname'))) {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('comicname'))) {
|
||||
return self::URI . urlencode($this->getInput('comicname'));
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('comicname'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('comicname'))) {
|
||||
return $this->getInput('comicname') . ' - Comics Kingdom';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
<?php
|
||||
class CommonDreamsBridge extends FeedExpander {
|
||||
|
||||
class CommonDreamsBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'nyutag';
|
||||
const NAME = 'CommonDreams Bridge';
|
||||
const URI = 'https://www.commondreams.org/';
|
||||
const DESCRIPTION = 'Returns the newest articles.';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$this->collectExpandableDatas('http://www.commondreams.org/rss.xml', 10);
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
$item = parent::parseItem($newsItem);
|
||||
$item['content'] = $this->extractContent($item['uri']);
|
||||
return $item;
|
||||
}
|
||||
|
||||
private function extractContent($url){
|
||||
private function extractContent($url)
|
||||
{
|
||||
$html3 = getSimpleHTMLDOMCached($url);
|
||||
$text = $html3->find('div[class=field--type-text-with-summary]', 0)->innertext;
|
||||
$html3->clear();
|
||||
unset ($html3);
|
||||
unset($html3);
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
<?php
|
||||
class CopieDoubleBridge extends BridgeAbstract {
|
||||
|
||||
class CopieDoubleBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'superbaillot.net';
|
||||
const NAME = 'CopieDouble';
|
||||
const URI = 'http://www.copie-double.com/';
|
||||
const CACHE_TIMEOUT = 14400; // 4h
|
||||
const DESCRIPTION = 'CopieDouble';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
$table = $html->find('table table', 2);
|
||||
|
||||
foreach($table->find('tr') as $element) {
|
||||
foreach ($table->find('tr') as $element) {
|
||||
$td = $element->find('td', 0);
|
||||
|
||||
if($td->class === 'couleur_1') {
|
||||
$item = array();
|
||||
if ($td->class === 'couleur_1') {
|
||||
$item = [];
|
||||
$title = $td->innertext;
|
||||
$pos = strpos($title, '<a');
|
||||
$title = substr($title, 0, $pos);
|
||||
$item['title'] = $title;
|
||||
} elseif(strpos($element->innertext, '/images/suivant.gif') === false) {
|
||||
} 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);
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
<?php
|
||||
class CourrierInternationalBridge extends FeedExpander {
|
||||
|
||||
class CourrierInternationalBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'teromene';
|
||||
const NAME = 'Courrier International Bridge';
|
||||
const URI = 'https://www.courrierinternational.com/';
|
||||
const CACHE_TIMEOUT = 300; // 5 min
|
||||
const DESCRIPTION = 'Returns the newest articles';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$this->collectExpandableDatas(static::URI . 'feed/all/rss.xml', 20);
|
||||
}
|
||||
|
||||
protected function parseItem($feedItem){
|
||||
protected function parseItem($feedItem)
|
||||
{
|
||||
$item = parent::parseItem($feedItem);
|
||||
|
||||
$articlePage = getSimpleHTMLDOMCached($feedItem->link);
|
||||
|
|
|
@ -1,51 +1,55 @@
|
|||
<?php
|
||||
class CraigslistBridge extends BridgeAbstract {
|
||||
|
||||
class CraigslistBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Craigslist Bridge';
|
||||
const URI = 'https://craigslist.org/';
|
||||
const DESCRIPTION = 'Returns craigslist search results';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'region' => array(
|
||||
const PARAMETERS = [ [
|
||||
'region' => [
|
||||
'name' => 'Region',
|
||||
'title' => 'The subdomain before craigslist.org in the URL',
|
||||
'exampleValue' => 'sfbay',
|
||||
'required' => true
|
||||
),
|
||||
'search' => array(
|
||||
],
|
||||
'search' => [
|
||||
'name' => 'Search Query',
|
||||
'title' => 'Everything in the URL after /search/',
|
||||
'exampleValue' => 'sya?query=laptop',
|
||||
'required' => true
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'Number of Posts',
|
||||
'type' => 'number',
|
||||
'title' => 'The maximum number of posts is 120. Use 0 for unlimited posts.',
|
||||
'defaultValue' => '25'
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
const TEST_DETECT_PARAMETERS = array(
|
||||
'https://sfbay.craigslist.org/search/sya?query=laptop' => array(
|
||||
const TEST_DETECT_PARAMETERS = [
|
||||
'https://sfbay.craigslist.org/search/sya?query=laptop' => [
|
||||
'region' => 'sfbay', 'search' => 'sya?query=laptop'
|
||||
),
|
||||
'https://newyork.craigslist.org/search/sss?query=32gb+flash+drive&bundleDuplicates=1&max_price=20' => array(
|
||||
],
|
||||
'https://newyork.craigslist.org/search/sss?query=32gb+flash+drive&bundleDuplicates=1&max_price=20' => [
|
||||
'region' => 'newyork', 'search' => 'sss?query=32gb+flash+drive&bundleDuplicates=1&max_price=20'
|
||||
),
|
||||
);
|
||||
],
|
||||
];
|
||||
|
||||
const URL_REGEX = '/^https:\/\/(?<region>\w+).craigslist.org\/search\/(?<search>.+)/';
|
||||
|
||||
public function detectParameters($url) {
|
||||
if(preg_match(self::URL_REGEX, $url, $matches)) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
if (preg_match(self::URL_REGEX, $url, $matches)) {
|
||||
$params = [];
|
||||
$params['region'] = $matches['region'];
|
||||
$params['search'] = $matches['search'];
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('region'))) {
|
||||
$domain = 'https://' . $this->getInput('region') . '.craigslist.org/search/';
|
||||
return urljoin($domain, $this->getInput('search'));
|
||||
|
@ -53,7 +57,8 @@ class CraigslistBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$uri = $this->getURI();
|
||||
$html = getSimpleHTMLDOM($uri);
|
||||
|
||||
|
@ -70,15 +75,14 @@ class CraigslistBridge extends BridgeAbstract {
|
|||
$results = array_slice($results, 0, $this->getInput('limit'));
|
||||
}
|
||||
|
||||
foreach($results as $post) {
|
||||
|
||||
foreach ($results as $post) {
|
||||
// Skip "nearby results" banner and results
|
||||
// This only appears when searchNearby is not specified
|
||||
if ($post->tag == 'h4') {
|
||||
break;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$heading = $post->find('.result-heading a', 0);
|
||||
$item['uri'] = $heading->href;
|
||||
|
@ -92,7 +96,7 @@ class CraigslistBridge extends BridgeAbstract {
|
|||
$images = $post->find('.result-image[data-ids]', 0);
|
||||
if (!is_null($images)) {
|
||||
$item['content'] .= '<br>';
|
||||
foreach(explode(',', $images->getAttribute('data-ids')) as $image) {
|
||||
foreach (explode(',', $images->getAttribute('data-ids')) as $image) {
|
||||
// Remove leading 3: from each image id
|
||||
$id = substr($image, 2);
|
||||
$image_uri = 'https://images.craigslist.org/' . $id . '_300x300.jpg';
|
||||
|
|
|
@ -1,39 +1,41 @@
|
|||
<?php
|
||||
class CrewbayBridge extends BridgeAbstract {
|
||||
|
||||
class CrewbayBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'couraudt';
|
||||
const NAME = 'Crewbay Bridge';
|
||||
const URI = 'https://www.crewbay.com';
|
||||
const DESCRIPTION = 'Returns the newest sailing offers.';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'keyword' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'keyword' => [
|
||||
'name' => 'Filter by keyword',
|
||||
'title' => 'Enter the keyword to filter here'
|
||||
),
|
||||
'type' => array(
|
||||
],
|
||||
'type' => [
|
||||
'name' => 'Type of search',
|
||||
'title' => 'Choose between finding a boat or a crew',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Find a boat' => 'boats',
|
||||
'Find a crew' => 'crew'
|
||||
)
|
||||
),
|
||||
'status' => array(
|
||||
]
|
||||
],
|
||||
'status' => [
|
||||
'name' => 'Status on the boat',
|
||||
'title' => 'Choose between recreational or professional classified ads',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Recreational' => 'recreational',
|
||||
'Professional' => 'professional'
|
||||
)
|
||||
),
|
||||
'recreational_position' => array(
|
||||
]
|
||||
],
|
||||
'recreational_position' => [
|
||||
'name' => 'Recreational position wanted',
|
||||
'title' => 'Filter by recreational position you wanted aboard',
|
||||
'required' => false,
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'' => '',
|
||||
'Amateur Crew' => 'Amateur Crew',
|
||||
'Friendship' => 'Friendship',
|
||||
|
@ -41,14 +43,14 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
'Racing' => 'Racing',
|
||||
'Voluntary work' => 'Voluntary work',
|
||||
'Mile building' => 'Mile building'
|
||||
)
|
||||
),
|
||||
'professional_position' => array(
|
||||
]
|
||||
],
|
||||
'professional_position' => [
|
||||
'name' => 'Professional position wanted',
|
||||
'title' => 'Filter by professional position you wanted aboard',
|
||||
'required' => false,
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'' => '',
|
||||
'1st Engineer' => '1st Engineer',
|
||||
'1st Mate' => '1st Mate',
|
||||
|
@ -99,12 +101,13 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
'Stew/Masseuse' => 'Stew/Masseuse',
|
||||
'Manager' => 'Manager',
|
||||
'Sailing instructor' => 'Sailing instructor'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$url = $this->getURI();
|
||||
$html = getSimpleHTMLDOM($url) or returnClientError('No results for this query.');
|
||||
|
||||
|
@ -118,9 +121,9 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
if (!empty($this->getInput('recreational_position')) || !empty($this->getInput('professional_position'))) {
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
if ($this->getInput('status') == 'professional') {
|
||||
$positions = array($annonce->find('.title .position', 0)->plaintext);
|
||||
$positions = [$annonce->find('.title .position', 0)->plaintext];
|
||||
} else {
|
||||
$positions = array(str_replace('Wanted:', '', $annonce->find('.content li', 0)->plaintext));
|
||||
$positions = [str_replace('Wanted:', '', $annonce->find('.content li', 0)->plaintext)];
|
||||
}
|
||||
} else {
|
||||
$list = $htmlDetail->find('.viewer-details .viewer-list');
|
||||
|
@ -141,7 +144,7 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
$titleSelector = '.title h2';
|
||||
|
@ -158,7 +161,7 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
|
||||
$item['uri'] = $detail->href;
|
||||
$images = $annonce->find('.avatar img');
|
||||
$item['enclosures'] = array(end($images)->getAttribute('src'));
|
||||
$item['enclosures'] = [end($images)->getAttribute('src')];
|
||||
|
||||
$content = $htmlDetail->find('.viewer-intro--info', 0)->innertext;
|
||||
|
||||
|
@ -166,7 +169,7 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
foreach ($sections as $section) {
|
||||
if ($section->find('.viewer-section-title', 0)) {
|
||||
$class = str_replace('viewer-', '', explode(' ', $section->getAttribute('class'))[0]);
|
||||
if (!in_array($class, array('apply', 'photos', 'reviews', 'contact', 'experience', 'qa'))) {
|
||||
if (!in_array($class, ['apply', 'photos', 'reviews', 'contact', 'experience', 'qa'])) {
|
||||
// Basic sections
|
||||
$content .= $section->find('.viewer-section-title h3', 0)->outertext;
|
||||
$content .= $section->find('.viewer-section-content', 0)->innertext;
|
||||
|
@ -192,7 +195,7 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
$tags = $htmlDetail->find('li.viewer-tags--tag');
|
||||
foreach ($tags as $tag) {
|
||||
if (!isset($item['categories'])) {
|
||||
$item['categories'] = array();
|
||||
$item['categories'] = [];
|
||||
}
|
||||
$text = trim($tag->plaintext);
|
||||
if (!in_array($text, $item['categories'])) {
|
||||
|
@ -203,11 +206,14 @@ class CrewbayBridge extends BridgeAbstract {
|
|||
$this->items[] = $item;
|
||||
$limit += 1;
|
||||
|
||||
if ($limit == 10) break;
|
||||
if ($limit == 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
$uri = parent::getURI();
|
||||
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
|
|
|
@ -1,35 +1,38 @@
|
|||
<?php
|
||||
class CryptomeBridge extends BridgeAbstract {
|
||||
|
||||
class CryptomeBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'BoboTiG';
|
||||
const NAME = 'Cryptome';
|
||||
const URI = 'https://cryptome.org/';
|
||||
const CACHE_TIMEOUT = 21600; // 6h
|
||||
const DESCRIPTION = 'Returns the N most recent documents.';
|
||||
const PARAMETERS = array( array(
|
||||
'n' => array(
|
||||
const PARAMETERS = [ [
|
||||
'n' => [
|
||||
'name' => 'number of elements',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => 10
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . '/favicon.ico';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
$number = $this->getInput('n');
|
||||
if(!empty($number)) {
|
||||
if (!empty($number)) {
|
||||
$num = min($number, 20);
|
||||
}
|
||||
$i = 0;
|
||||
foreach($html->find('pre', 1)->find('b') as $element) {
|
||||
foreach($element->find('a') as $element1) {
|
||||
$item = array();
|
||||
foreach ($html->find('pre', 1)->find('b') as $element) {
|
||||
foreach ($element->find('a') as $element1) {
|
||||
$item = [];
|
||||
$item['uri'] = $element1->href;
|
||||
$item['title'] = $element->plaintext;
|
||||
$this->items[] = $item;
|
||||
|
|
|
@ -1,36 +1,39 @@
|
|||
<?php
|
||||
|
||||
class CubariBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Cubari';
|
||||
const URI = 'https://cubari.moe';
|
||||
const DESCRIPTION = 'Parses given cubari-formatted JSON file for updates.';
|
||||
const MAINTAINER = 'KamaleiZestri';
|
||||
const PARAMETERS = array(array(
|
||||
'gist' => array(
|
||||
const PARAMETERS = [[
|
||||
'gist' => [
|
||||
'name' => 'Gist/Raw Url',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'https://raw.githubusercontent.com/kurisumx/baka/main/ikedan'
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
private $mangaTitle = '';
|
||||
|
||||
public function getName()
|
||||
{
|
||||
if (!empty($this->mangaTitle))
|
||||
if (!empty($this->mangaTitle)) {
|
||||
return $this->mangaTitle . ' - ' . self::NAME;
|
||||
else
|
||||
} else {
|
||||
return self::NAME;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI()
|
||||
{
|
||||
if ($this->getInput('gist') != '')
|
||||
if ($this->getInput('gist') != '') {
|
||||
return self::URI . '/read/gist/' . $this->getEncodedGist();
|
||||
else
|
||||
} else {
|
||||
return self::URI;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The Cubari bridge.
|
||||
|
@ -78,12 +81,13 @@ class CubariBridge extends BridgeAbstract
|
|||
|
||||
protected function getItemFromChapter($chapnum, $chapter)
|
||||
{
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $this->getURI() . '/' . $chapnum;
|
||||
$item['title'] = 'Chapter ' . $chapnum . ' - ' . $chapter['title'] . ' - ' . $this->mangaTitle;
|
||||
foreach ($chapter['groups'] as $key => $value)
|
||||
foreach ($chapter['groups'] as $key => $value) {
|
||||
$item['author'] = $key;
|
||||
}
|
||||
$item['timestamp'] = $chapter['last_updated'];
|
||||
|
||||
$item['content'] = '<p>Manga: <a href=' . $this->getURI() . '>' . $this->mangaTitle . '</a> </p>
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
<?php
|
||||
class CuriousCatBridge extends BridgeAbstract {
|
||||
|
||||
class CuriousCatBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Curious Cat Bridge';
|
||||
const URI = 'https://curiouscat.me';
|
||||
const DESCRIPTION = 'Returns list of newest questions and answers for a user profile';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(array(
|
||||
'username' => array(
|
||||
const PARAMETERS = [[
|
||||
'username' => [
|
||||
'name' => 'Username',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'koethekoethe',
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$url = self::URI . '/api/v2/profile?username=' . urlencode($this->getInput('username'));
|
||||
|
||||
$apiJson = getContents($url);
|
||||
|
||||
$apiData = json_decode($apiJson, true);
|
||||
|
||||
foreach($apiData['posts'] as $post) {
|
||||
$item = array();
|
||||
foreach ($apiData['posts'] as $post) {
|
||||
$item = [];
|
||||
|
||||
$item['author'] = 'Anonymous';
|
||||
|
||||
|
@ -42,8 +44,8 @@ class CuriousCatBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('username'))) {
|
||||
return self::URI . '/' . $this->getInput('username');
|
||||
}
|
||||
|
@ -51,8 +53,8 @@ class CuriousCatBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('username'))) {
|
||||
return $this->getInput('username') . ' - Curious Cat';
|
||||
}
|
||||
|
@ -60,8 +62,8 @@ class CuriousCatBridge extends BridgeAbstract {
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
private function processContent($post) {
|
||||
|
||||
private function processContent($post)
|
||||
{
|
||||
$author = 'Anonymous';
|
||||
|
||||
if ($post['senderData']['id'] !== false) {
|
||||
|
@ -85,7 +87,8 @@ EOD;
|
|||
return $content;
|
||||
}
|
||||
|
||||
private function ellipsisTitle($text) {
|
||||
private function ellipsisTitle($text)
|
||||
{
|
||||
$length = 150;
|
||||
|
||||
if (strlen($text) > $length) {
|
||||
|
@ -96,13 +99,12 @@ EOD;
|
|||
return $text;
|
||||
}
|
||||
|
||||
private function formatUrls($content) {
|
||||
|
||||
private function formatUrls($content)
|
||||
{
|
||||
return preg_replace(
|
||||
'/(http[s]{0,1}\:\/\/[a-zA-Z0-9.\/\?\&=\-_]{4,})/ims',
|
||||
'<a target="_blank" href="$1" target="_blank">$1</a> ',
|
||||
$content
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
<?php
|
||||
class CyanideAndHappinessBridge extends BridgeAbstract {
|
||||
|
||||
class CyanideAndHappinessBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Cyanide & Happiness';
|
||||
const URI = 'https://explosm.net/';
|
||||
const DESCRIPTION = 'The Webcomic from Explosm.';
|
||||
const MAINTAINER = 'sal0max';
|
||||
const CACHE_TIMEOUT = 60 * 60 * 2; // 2 hours
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return self::URI . 'favicon-32x32.png';
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
public function getURI()
|
||||
{
|
||||
return self::URI . 'comics/latest#comic';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM($this->getUri());
|
||||
|
||||
foreach ($html->find('[class*=ComicImage]') as $element) {
|
||||
|
@ -23,14 +28,14 @@ class CyanideAndHappinessBridge extends BridgeAbstract {
|
|||
$image = $element->find('img', 0)->src;
|
||||
$link = $html->find('[rel=canonical]', 0)->href;
|
||||
|
||||
$item = array(
|
||||
$item = [
|
||||
'uid' => $link,
|
||||
'author' => $author,
|
||||
'title' => $date,
|
||||
'uri' => $link . '#comic',
|
||||
'timestamp' => str_replace('.', '-', $date) . 'T00:00:00Z',
|
||||
'content' => "<img src=\"$image\" />"
|
||||
);
|
||||
];
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,55 @@
|
|||
<?php
|
||||
class DailymotionBridge extends BridgeAbstract {
|
||||
|
||||
class DailymotionBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'mitsukarenai';
|
||||
const NAME = 'Dailymotion Bridge';
|
||||
const URI = 'https://www.dailymotion.com/';
|
||||
const CACHE_TIMEOUT = 3600; // 1h
|
||||
const DESCRIPTION = 'Returns the 5 newest videos by username/playlist or search';
|
||||
|
||||
const PARAMETERS = array (
|
||||
'By username' => array(
|
||||
'u' => array(
|
||||
const PARAMETERS = [
|
||||
'By username' => [
|
||||
'u' => [
|
||||
'name' => 'username',
|
||||
'required' => true,
|
||||
'exampleValue' => 'moviepilot',
|
||||
)
|
||||
),
|
||||
'By playlist id' => array(
|
||||
'p' => array(
|
||||
]
|
||||
],
|
||||
'By playlist id' => [
|
||||
'p' => [
|
||||
'name' => 'playlist id',
|
||||
'required' => true,
|
||||
'exampleValue' => 'x6xyc6',
|
||||
)
|
||||
),
|
||||
'From search results' => array(
|
||||
's' => array(
|
||||
]
|
||||
],
|
||||
'From search results' => [
|
||||
's' => [
|
||||
'name' => 'Search keyword',
|
||||
'required' => true,
|
||||
'exampleValue' => 'matrix',
|
||||
),
|
||||
'pa' => array(
|
||||
],
|
||||
'pa' => [
|
||||
'name' => 'Page',
|
||||
'type' => 'number',
|
||||
'defaultValue' => 1,
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private $feedName = '';
|
||||
|
||||
private $apiUrl = 'https://api.dailymotion.com';
|
||||
private $apiFields = 'created_time,description,id,owner.screenname,tags,thumbnail_url,title,url';
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://static1-ssl.dmcdn.net/images/neon/favicons/android-icon-36x36.png.vf806ca4ed0deed812';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
if ($this->queriedContext === 'By username' || $this->queriedContext === 'By playlist id') {
|
||||
|
||||
$apiJson = getContents($this->getApiUrl());
|
||||
|
||||
$apiData = json_decode($apiJson, true);
|
||||
|
@ -56,7 +57,7 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
$this->feedName = $this->getPlaylistTitle($this->getInput('p'));
|
||||
|
||||
foreach ($apiData['list'] as $apiItem) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $apiItem['url'];
|
||||
$item['uid'] = $apiItem['id'];
|
||||
|
@ -73,16 +74,15 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
if ($this->queriedContext === 'From search results') {
|
||||
|
||||
$html = getSimpleHTMLDOM($this->getURI());
|
||||
|
||||
foreach($html->find('div.media a.preview_link') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.media a.preview_link') as $element) {
|
||||
$item = [];
|
||||
|
||||
$item['id'] = str_replace('/video/', '', strtok($element->href, '_'));
|
||||
$metadata = $this->getMetadata($item['id']);
|
||||
|
||||
if(empty($metadata)) {
|
||||
if (empty($metadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,9 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'By username':
|
||||
$specific = $this->getInput('u');
|
||||
break;
|
||||
|
@ -125,15 +126,17 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
case 'From search results':
|
||||
$specific = $this->getInput('s');
|
||||
break;
|
||||
default: return parent::getName();
|
||||
default:
|
||||
return parent::getName();
|
||||
}
|
||||
|
||||
return $specific . ' : Dailymotion';
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
public function getURI()
|
||||
{
|
||||
$uri = self::URI;
|
||||
switch($this->queriedContext) {
|
||||
switch ($this->queriedContext) {
|
||||
case 'By username':
|
||||
$uri .= 'user/' . urlencode($this->getInput('u'));
|
||||
break;
|
||||
|
@ -143,7 +146,7 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
case 'From search results':
|
||||
$uri .= 'search/' . urlencode($this->getInput('s'));
|
||||
|
||||
if(!is_null($this->getInput('pa'))) {
|
||||
if (!is_null($this->getInput('pa'))) {
|
||||
$pa = $this->getInput('pa');
|
||||
|
||||
if ($this->getInput('pa') < 1) {
|
||||
|
@ -153,17 +156,19 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
$uri .= '/' . $pa;
|
||||
}
|
||||
break;
|
||||
default: return parent::getURI();
|
||||
default:
|
||||
return parent::getURI();
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function getMetadata($id) {
|
||||
$metadata = array();
|
||||
private function getMetadata($id)
|
||||
{
|
||||
$metadata = [];
|
||||
|
||||
$html = getSimpleHTMLDOM(self::URI . 'video/' . $id);
|
||||
|
||||
if(!$html) {
|
||||
if (!$html) {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
|
@ -176,7 +181,8 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
return $metadata;
|
||||
}
|
||||
|
||||
private function getPlaylistTitle($id) {
|
||||
private function getPlaylistTitle($id)
|
||||
{
|
||||
$title = '';
|
||||
|
||||
$url = self::URI . 'playlist/' . $id;
|
||||
|
@ -187,9 +193,9 @@ class DailymotionBridge extends BridgeAbstract {
|
|||
return $title;
|
||||
}
|
||||
|
||||
private function getApiUrl() {
|
||||
|
||||
switch($this->queriedContext) {
|
||||
private function getApiUrl()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'By username':
|
||||
return $this->apiUrl . '/user/' . $this->getInput('u')
|
||||
. '/videos?fields=' . urlencode($this->apiFields) . '&availability=1&sort=recent&limit=5';
|
||||
|
|
|
@ -1,47 +1,51 @@
|
|||
<?php
|
||||
class DanbooruBridge extends BridgeAbstract {
|
||||
|
||||
class DanbooruBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'mitsukarenai, logmanoriginal';
|
||||
const NAME = 'Danbooru';
|
||||
const URI = 'http://donmai.us/';
|
||||
const CACHE_TIMEOUT = 1800; // 30min
|
||||
const DESCRIPTION = 'Returns images from given page';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'global' => array(
|
||||
'p' => array(
|
||||
const PARAMETERS = [
|
||||
'global' => [
|
||||
'p' => [
|
||||
'name' => 'page',
|
||||
'defaultValue' => 1,
|
||||
'type' => 'number'
|
||||
),
|
||||
't' => array(
|
||||
],
|
||||
't' => [
|
||||
'type' => 'text',
|
||||
'name' => 'tags',
|
||||
'exampleValue' => 'cosplay',
|
||||
)
|
||||
),
|
||||
0 => array()
|
||||
);
|
||||
]
|
||||
],
|
||||
0 => []
|
||||
];
|
||||
|
||||
const PATHTODATA = 'article';
|
||||
const IDATTRIBUTE = 'data-id';
|
||||
const TAGATTRIBUTE = 'alt';
|
||||
|
||||
protected function getFullURI(){
|
||||
protected function getFullURI()
|
||||
{
|
||||
return $this->getURI()
|
||||
. 'posts?&page=' . $this->getInput('p')
|
||||
. '&tags=' . urlencode($this->getInput('t'));
|
||||
}
|
||||
|
||||
protected function getTags($element){
|
||||
protected function getTags($element)
|
||||
{
|
||||
return $element->find('img', 0)->getAttribute(static::TAGATTRIBUTE);
|
||||
}
|
||||
|
||||
protected function getItemFromElement($element){
|
||||
protected function getItemFromElement($element)
|
||||
{
|
||||
// Fix links
|
||||
defaultLinkTo($element, $this->getURI());
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = html_entity_decode($element->find('a', 0)->href);
|
||||
$item['postid'] = (int)preg_replace('/[^0-9]/', '', $element->getAttribute(static::IDATTRIBUTE));
|
||||
$item['timestamp'] = time();
|
||||
|
@ -58,10 +62,11 @@ class DanbooruBridge extends BridgeAbstract {
|
|||
return $item;
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached($this->getFullURI());
|
||||
|
||||
foreach($html->find(static::PATHTODATA) as $element) {
|
||||
foreach ($html->find(static::PATHTODATA) as $element) {
|
||||
$this->items[] = $this->getItemFromElement($element);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<?php
|
||||
class DansTonChatBridge extends BridgeAbstract {
|
||||
|
||||
class DansTonChatBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Astalaseven';
|
||||
const NAME = 'DansTonChat Bridge';
|
||||
const URI = 'https://danstonchat.com/';
|
||||
const CACHE_TIMEOUT = 21600; //6h
|
||||
const DESCRIPTION = 'Returns latest quotes from DansTonChat.';
|
||||
|
||||
public function collectData(){
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI . 'latest.html');
|
||||
|
||||
foreach($html->find('div.item') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.item') as $element) {
|
||||
$item = [];
|
||||
$item['uri'] = $element->find('a', 0)->href;
|
||||
$titleContent = $element->find('h3 a', 0);
|
||||
if($titleContent) {
|
||||
if ($titleContent) {
|
||||
$item['title'] = 'DansTonChat ' . html_entity_decode($titleContent->plaintext, ENT_QUOTES);
|
||||
} else {
|
||||
$item['title'] = 'DansTonChat';
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
<?php
|
||||
class DarkReadingBridge extends FeedExpander {
|
||||
|
||||
class DarkReadingBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'Dark Reading Bridge';
|
||||
const URI = 'https://www.darkreading.com/';
|
||||
const DESCRIPTION = 'Returns the newest articles from Dark Reading';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'feed' => array(
|
||||
const PARAMETERS = [ [
|
||||
'feed' => [
|
||||
'name' => 'Feed',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'All Dark Reading Stories' => '000_AllArticles',
|
||||
'Attacks/Breaches' => '644_Attacks/Breaches',
|
||||
'Application Security' => '645_Application%20Security',
|
||||
|
@ -32,17 +34,18 @@ class DarkReadingBridge extends FeedExpander {
|
|||
'Advanced Threats' => '662_Advanced%20Threats',
|
||||
'Insider Threats' => '663_Insider%20Threats',
|
||||
'Vulnerability Management' => '664_Vulnerability%20Management',
|
||||
)
|
||||
),
|
||||
]
|
||||
],
|
||||
'limit' => self::LIMIT,
|
||||
));
|
||||
]];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$feed = $this->getInput('feed');
|
||||
$feed_splitted = explode('_', $feed);
|
||||
$feed_id = $feed_splitted[0];
|
||||
$feed_name = $feed_splitted[1];
|
||||
if(empty($feed) || !ctype_digit($feed_id) || !preg_match('/[A-Za-z%20\/]/', $feed_name)) {
|
||||
if (empty($feed) || !ctype_digit($feed_id) || !preg_match('/[A-Za-z%20\/]/', $feed_name)) {
|
||||
returnClientError('Invalid feed, please check the "feed" parameter.');
|
||||
}
|
||||
$feed_url = $this->getURI() . 'rss_simple.asp';
|
||||
|
@ -53,28 +56,32 @@ class DarkReadingBridge extends FeedExpander {
|
|||
$this->collectExpandableDatas($feed_url, $limit);
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
$item = parent::parseItem($newsItem);
|
||||
$article = getSimpleHTMLDOMCached($item['uri']);
|
||||
$item['content'] = $this->extractArticleContent($article);
|
||||
$item['enclosures'] = array(); //remove author profile picture
|
||||
$item['enclosures'] = []; //remove author profile picture
|
||||
$image = $article->find('meta[property="og:image"]', 0);
|
||||
if (is_object($image)) {
|
||||
$image = $image->content;
|
||||
$item['enclosures'] = array($image);
|
||||
$item['enclosures'] = [$image];
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
private function extractArticleContent($article){
|
||||
private function extractArticleContent($article)
|
||||
{
|
||||
$content = $article->find('div.article-content', 0)->innertext;
|
||||
|
||||
foreach (array(
|
||||
foreach (
|
||||
[
|
||||
'<div class="divsplitter',
|
||||
'<div style="float: left; margin-right: 2px;',
|
||||
'<div class="more-insights',
|
||||
'<div id="more-insights',
|
||||
) as $div_start) {
|
||||
] as $div_start
|
||||
) {
|
||||
$content = stripRecursiveHTMLSection($content, 'div', $div_start);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
class DauphineLibereBridge extends FeedExpander {
|
||||
|
||||
class DauphineLibereBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'qwertygc';
|
||||
const NAME = 'Dauphine Bridge';
|
||||
const URI = 'https://www.ledauphine.com/';
|
||||
const CACHE_TIMEOUT = 7200; // 2h
|
||||
const DESCRIPTION = 'Returns the newest articles.';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'u' => array(
|
||||
const PARAMETERS = [ [
|
||||
'u' => [
|
||||
'name' => 'Catégorie de l\'article',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'À la une' => '',
|
||||
'France Monde' => 'france-monde',
|
||||
'Faits Divers' => 'faits-divers',
|
||||
|
@ -27,27 +28,30 @@ class DauphineLibereBridge extends FeedExpander {
|
|||
'Savoie' => 'savoie',
|
||||
'Haute-Savoie' => 'haute-savoie',
|
||||
'Vaucluse' => 'vaucluse'
|
||||
)
|
||||
)
|
||||
));
|
||||
]
|
||||
]
|
||||
]];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$url = self::URI . 'rss';
|
||||
|
||||
if(empty($this->getInput('u'))) {
|
||||
if (empty($this->getInput('u'))) {
|
||||
$url = self::URI . $this->getInput('u') . '/rss';
|
||||
}
|
||||
|
||||
$this->collectExpandableDatas($url, 10);
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
$item = parent::parseItem($newsItem);
|
||||
$item['content'] = $this->extractContent($item['uri']);
|
||||
return $item;
|
||||
}
|
||||
|
||||
private function extractContent($url){
|
||||
private function extractContent($url)
|
||||
{
|
||||
$html2 = getSimpleHTMLDOMCached($url);
|
||||
foreach ($html2->find('.noprint, link, script, iframe, .shareTool, .contentInfo') as $remove) {
|
||||
$remove->outertext = '';
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<?php
|
||||
class DavesTrailerPageBridge extends BridgeAbstract {
|
||||
|
||||
class DavesTrailerPageBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'johnnygroovy';
|
||||
const NAME = 'Daves Trailer Page Bridge';
|
||||
const URI = 'https://www.davestrailerpage.co.uk/';
|
||||
const DESCRIPTION = 'Last trailers in HD thanks to Dave.';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(static::URI)
|
||||
or returnClientError('No results for this query.');
|
||||
|
||||
|
@ -17,7 +20,7 @@ class DavesTrailerPageBridge extends BridgeAbstract {
|
|||
continue;
|
||||
}
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
// title
|
||||
$item['title'] = $tr->find('td', 0)->find('b', 0)->plaintext;
|
||||
|
|
|
@ -1,47 +1,48 @@
|
|||
<?php
|
||||
class DealabsBridge extends PepperBridgeAbstract {
|
||||
|
||||
class DealabsBridge extends PepperBridgeAbstract
|
||||
{
|
||||
const NAME = 'Dealabs Bridge';
|
||||
const URI = 'https://www.dealabs.com/';
|
||||
const DESCRIPTION = 'Affiche les Deals de Dealabs';
|
||||
const MAINTAINER = 'sysadminstory';
|
||||
const PARAMETERS = array(
|
||||
'Recherche par Mot(s) clé(s)' => array (
|
||||
'q' => array(
|
||||
const PARAMETERS = [
|
||||
'Recherche par Mot(s) clé(s)' => [
|
||||
'q' => [
|
||||
'name' => 'Mot(s) clé(s)',
|
||||
'type' => 'text',
|
||||
'exampleValue' => 'lampe',
|
||||
'required' => true
|
||||
),
|
||||
'hide_expired' => array(
|
||||
],
|
||||
'hide_expired' => [
|
||||
'name' => 'Masquer les éléments expirés',
|
||||
'type' => 'checkbox',
|
||||
),
|
||||
'hide_local' => array(
|
||||
],
|
||||
'hide_local' => [
|
||||
'name' => 'Masquer les deals locaux',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Masquer les deals en magasins physiques',
|
||||
),
|
||||
'priceFrom' => array(
|
||||
],
|
||||
'priceFrom' => [
|
||||
'name' => 'Prix minimum',
|
||||
'type' => 'text',
|
||||
'title' => 'Prix mnimum en euros',
|
||||
'required' => false
|
||||
),
|
||||
'priceTo' => array(
|
||||
],
|
||||
'priceTo' => [
|
||||
'name' => 'Prix maximum',
|
||||
'type' => 'text',
|
||||
'title' => 'Prix maximum en euros',
|
||||
'required' => false
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
||||
'Deals par groupe' => array(
|
||||
'group' => array(
|
||||
'Deals par groupe' => [
|
||||
'group' => [
|
||||
'name' => 'Groupe',
|
||||
'type' => 'list',
|
||||
'title' => 'Groupe dont il faut afficher les deals',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Abattants WC' => 'abattants-wc',
|
||||
'Abonnement PlayStation Plus' => 'playstation-plus',
|
||||
'Abonnements cinéma' => 'abonnements-cinema',
|
||||
|
@ -1868,42 +1869,42 @@ class DealabsBridge extends PepperBridgeAbstract {
|
|||
'Yeelight' => 'xiaomi-yeelight',
|
||||
'Yoshi's Crafted World' => 'yoshi-crafted-world',
|
||||
'Zoos' => 'zoos',
|
||||
)
|
||||
),
|
||||
'order' => array(
|
||||
]
|
||||
],
|
||||
'order' => [
|
||||
'name' => 'Trier par',
|
||||
'type' => 'list',
|
||||
'title' => 'Ordre de tri des deals',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Du deal le plus Hot au moins Hot' => '-hot',
|
||||
'Du deal le plus récent au plus ancien' => '-nouveaux',
|
||||
)
|
||||
)
|
||||
),
|
||||
'Surveillance Discussion' => array(
|
||||
'url' => array(
|
||||
]
|
||||
]
|
||||
],
|
||||
'Surveillance Discussion' => [
|
||||
'url' => [
|
||||
'name' => 'URL de la discussion',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'URL discussion à surveiller: https://www.dealabs.com/discussions/titre-1234',
|
||||
'exampleValue' => 'https://www.dealabs.com/discussions/jeux-steam-gratuits-gleam-woobox-etc-1071415',
|
||||
),
|
||||
],
|
||||
|
||||
'only_with_url' => array(
|
||||
'only_with_url' => [
|
||||
'name' => 'Exclure les commentaires sans URL',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Exclure les commentaires ne contenant pas d\'URL dans le flux',
|
||||
'defaultValue' => false,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
)
|
||||
]
|
||||
|
||||
);
|
||||
];
|
||||
|
||||
public $lang = array(
|
||||
'bridge-uri' => SELF::URI,
|
||||
'bridge-name' => SELF::NAME,
|
||||
public $lang = [
|
||||
'bridge-uri' => self::URI,
|
||||
'bridge-name' => self::NAME,
|
||||
'context-keyword' => 'Recherche par Mot(s) clé(s)',
|
||||
'context-group' => 'Deals par groupe',
|
||||
'context-talk' => 'Surveillance Discussion',
|
||||
|
@ -1911,9 +1912,9 @@ class DealabsBridge extends PepperBridgeAbstract {
|
|||
'request-error' => 'Impossible de joindre Dealabs',
|
||||
'thread-error' => 'Impossible de déterminer l\'ID de la discussion. Vérifiez l\'URL que vous avez entré',
|
||||
'no-results' => 'Il n'y a rien à afficher pour le moment :(',
|
||||
'relative-date-indicator' => array(
|
||||
'relative-date-indicator' => [
|
||||
'il y a',
|
||||
),
|
||||
],
|
||||
'price' => 'Prix',
|
||||
'shipping' => 'Livraison',
|
||||
'origin' => 'Origine',
|
||||
|
@ -1921,7 +1922,7 @@ class DealabsBridge extends PepperBridgeAbstract {
|
|||
'title-keyword' => 'Recherche',
|
||||
'title-group' => 'Groupe',
|
||||
'title-talk' => 'Surveillance Discussion',
|
||||
'local-months' => array(
|
||||
'local-months' => [
|
||||
'janvier',
|
||||
'février',
|
||||
'mars',
|
||||
|
@ -1934,8 +1935,8 @@ class DealabsBridge extends PepperBridgeAbstract {
|
|||
'octobre',
|
||||
'novembre',
|
||||
'décembre'
|
||||
),
|
||||
'local-time-relative' => array(
|
||||
],
|
||||
'local-time-relative' => [
|
||||
'il y a ',
|
||||
'min',
|
||||
'h',
|
||||
|
@ -1944,22 +1945,19 @@ class DealabsBridge extends PepperBridgeAbstract {
|
|||
'mois',
|
||||
'ans',
|
||||
'et '
|
||||
),
|
||||
'date-prefixes' => array(
|
||||
],
|
||||
'date-prefixes' => [
|
||||
'Actualisé ',
|
||||
),
|
||||
'relative-date-alt-prefixes' => array(
|
||||
],
|
||||
'relative-date-alt-prefixes' => [
|
||||
'Actualisé ',
|
||||
),
|
||||
'relative-date-ignore-suffix' => array(
|
||||
),
|
||||
],
|
||||
'relative-date-ignore-suffix' => [
|
||||
],
|
||||
|
||||
'localdeal' => array(
|
||||
'localdeal' => [
|
||||
'Local',
|
||||
'Pays d\'expédition'
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,40 +1,41 @@
|
|||
<?php
|
||||
class DemoBridge extends BridgeAbstract {
|
||||
|
||||
class DemoBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'teromene';
|
||||
const NAME = 'DemoBridge';
|
||||
const URI = 'http://github.com/rss-bridge/rss-bridge';
|
||||
const DESCRIPTION = 'Bridge used for demos';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'testCheckbox' => array(
|
||||
'testCheckbox' => array(
|
||||
const PARAMETERS = [
|
||||
'testCheckbox' => [
|
||||
'testCheckbox' => [
|
||||
'type' => 'checkbox',
|
||||
'name' => 'test des checkbox'
|
||||
)
|
||||
),
|
||||
'testList' => array(
|
||||
'testList' => array(
|
||||
]
|
||||
],
|
||||
'testList' => [
|
||||
'testList' => [
|
||||
'type' => 'list',
|
||||
'name' => 'test des listes',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Test' => 'test',
|
||||
'Test 2' => 'test2'
|
||||
)
|
||||
)
|
||||
),
|
||||
'testNumber' => array(
|
||||
'testNumber' => array(
|
||||
]
|
||||
]
|
||||
],
|
||||
'testNumber' => [
|
||||
'testNumber' => [
|
||||
'type' => 'number',
|
||||
'name' => 'test des numéros',
|
||||
'exampleValue' => '1515632'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
|
||||
$item = array();
|
||||
public function collectData()
|
||||
{
|
||||
$item = [];
|
||||
$item['author'] = 'Me!';
|
||||
$item['title'] = 'Test';
|
||||
$item['content'] = 'Awesome content !';
|
||||
|
|
|
@ -1,48 +1,51 @@
|
|||
<?php
|
||||
class DerpibooruBridge extends BridgeAbstract {
|
||||
|
||||
class DerpibooruBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Derpibooru Bridge';
|
||||
const URI = 'https://derpibooru.org/';
|
||||
const DESCRIPTION = 'Returns newest images from a Derpibooru search';
|
||||
const CACHE_TIMEOUT = 300; // 5min
|
||||
const MAINTAINER = 'Roliga';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'f' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'f' => [
|
||||
'name' => 'Filter',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Everything' => 56027,
|
||||
'18+ R34' => 37432,
|
||||
'Legacy Default' => 37431,
|
||||
'18+ Dark' => 37429,
|
||||
'Maximum Spoilers' => 37430,
|
||||
'Default' => 100073
|
||||
),
|
||||
],
|
||||
'defaultValue' => 56027
|
||||
|
||||
),
|
||||
'q' => array(
|
||||
],
|
||||
'q' => [
|
||||
'name' => 'Query',
|
||||
'required' => true,
|
||||
'exampleValue' => 'dog',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function detectParameters($url){
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// Search page e.g. https://derpibooru.org/search?q=cute
|
||||
$regex = '/^(https?:\/\/)?(www\.)?derpibooru.org\/search.+q=([^\/&?\n]+)/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
$params['q'] = urldecode($matches[3]);
|
||||
return $params;
|
||||
}
|
||||
|
||||
// Tag page, e.g. https://derpibooru.org/tags/artist-colon-devinian
|
||||
$regex = '/^(https?:\/\/)?(www\.)?derpibooru.org\/tags\/([^\/&?\n]+)/';
|
||||
if(preg_match($regex, $url, $matches) > 0) {
|
||||
if (preg_match($regex, $url, $matches) > 0) {
|
||||
$params['q'] = str_replace('-colon-', ':', urldecode($matches[3]));
|
||||
return $params;
|
||||
}
|
||||
|
@ -50,8 +53,9 @@ class DerpibooruBridge extends BridgeAbstract {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('q'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('q'))) {
|
||||
return 'Derpibooru search for: '
|
||||
. $this->getInput('q');
|
||||
} else {
|
||||
|
@ -59,8 +63,9 @@ class DerpibooruBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getURI(){
|
||||
if(!is_null($this->getInput('f')) && !is_null($this->getInput('q'))) {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('f')) && !is_null($this->getInput('q'))) {
|
||||
return self::URI
|
||||
. 'search?filter_id='
|
||||
. urlencode($this->getInput('f'))
|
||||
|
@ -71,7 +76,8 @@ class DerpibooruBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$queryJson = json_decode(getContents(
|
||||
self::URI
|
||||
. 'api/v1/json/search/images?filter_id='
|
||||
|
@ -80,8 +86,8 @@ class DerpibooruBridge extends BridgeAbstract {
|
|||
. urlencode($this->getInput('q'))
|
||||
));
|
||||
|
||||
foreach($queryJson->images as $post) {
|
||||
$item = array();
|
||||
foreach ($queryJson->images as $post) {
|
||||
$item = [];
|
||||
|
||||
$postUri = self::URI . $post->id;
|
||||
|
||||
|
@ -89,7 +95,7 @@ class DerpibooruBridge extends BridgeAbstract {
|
|||
$item['title'] = $post->name;
|
||||
$item['timestamp'] = strtotime($post->created_at);
|
||||
$item['author'] = $post->uploader;
|
||||
$item['enclosures'] = array($post->view_url);
|
||||
$item['enclosures'] = [$post->view_url];
|
||||
$item['categories'] = $post->tags;
|
||||
|
||||
$item['content'] = '<p><a href="' // image preview
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class DesoutterBridge extends BridgeAbstract {
|
||||
|
||||
class DesoutterBridge extends BridgeAbstract
|
||||
{
|
||||
const CATEGORY_NEWS = 'News & Events';
|
||||
const CATEGORY_INDUSTRY = 'Industry 4.0 News';
|
||||
|
||||
|
@ -10,14 +11,14 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
const MAINTAINER = 'logmanoriginal';
|
||||
const CACHE_TIMEOUT = 86400; // 24 hours
|
||||
|
||||
const PARAMETERS = array(
|
||||
self::CATEGORY_NEWS => array(
|
||||
'news_lang' => array(
|
||||
const PARAMETERS = [
|
||||
self::CATEGORY_NEWS => [
|
||||
'news_lang' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'title' => 'Select your language',
|
||||
'defaultValue' => 'https://www.desouttertools.com/about-desoutter/news-events',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Corporate'
|
||||
=> 'https://www.desouttertools.com/about-desoutter/news-events',
|
||||
'Česko'
|
||||
|
@ -58,16 +59,16 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
=> 'https://www.desoutter.com.tr/desoutter-hakkinda/haberler-etkinlikler',
|
||||
'中国'
|
||||
=> 'https://www.desouttertools.com.cn/guan-yu-ma-tou/xin-wen-he-huo-dong',
|
||||
)
|
||||
),
|
||||
),
|
||||
self::CATEGORY_INDUSTRY => array(
|
||||
'industry_lang' => array(
|
||||
]
|
||||
],
|
||||
],
|
||||
self::CATEGORY_INDUSTRY => [
|
||||
'industry_lang' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'title' => 'Select your language',
|
||||
'defaultValue' => 'Corporate',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Corporate'
|
||||
=> 'https://www.desouttertools.com/industry-4-0/news',
|
||||
'Česko'
|
||||
|
@ -108,29 +109,30 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
=> 'https://www.desoutter.com.tr/endustri-4-0/haberler',
|
||||
'中国'
|
||||
=> 'https://www.desouttertools.com.cn/industry-4-0/news',
|
||||
)
|
||||
),
|
||||
),
|
||||
'global' => array(
|
||||
'full' => array(
|
||||
]
|
||||
],
|
||||
],
|
||||
'global' => [
|
||||
'full' => [
|
||||
'name' => 'Load full articles',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Enable to load the full article for each item'
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'Limit',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'defaultValue' => 3,
|
||||
'title' => "Maximum number of items to return in the feed.\n0 = unlimited"
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private $title;
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case self::CATEGORY_NEWS:
|
||||
return $this->getInput('news_lang') ?: parent::getURI();
|
||||
case self::CATEGORY_INDUSTRY:
|
||||
|
@ -140,12 +142,13 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return isset($this->title) ? $this->title . ' - ' . parent::getName() : parent::getName();
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
// Uncomment to generate list of languages automtically (dev mode)
|
||||
/*
|
||||
switch($this->queriedContext) {
|
||||
|
@ -164,13 +167,13 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
|
||||
$limit = $this->getInput('limit') ?: 0;
|
||||
|
||||
foreach($html->find('article') as $article) {
|
||||
$item = array();
|
||||
foreach ($html->find('article') as $article) {
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $article->find('a', 0)->href;
|
||||
$item['title'] = $article->find('a[title]', 0)->title;
|
||||
|
||||
if($this->getInput('full')) {
|
||||
if ($this->getInput('full')) {
|
||||
$item['content'] = $this->getFullNewsArticle($item['uri']);
|
||||
} else {
|
||||
$item['content'] = $article->find('div.tile-body p', 0)->plaintext;
|
||||
|
@ -178,12 +181,14 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
|
||||
if ($limit > 0 && count($this->items) >= $limit) break;
|
||||
if ($limit > 0 && count($this->items) >= $limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function getFullNewsArticle($uri) {
|
||||
private function getFullNewsArticle($uri)
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached($uri);
|
||||
|
||||
$html = defaultLinkTo($html, $this->getURI());
|
||||
|
@ -197,7 +202,8 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
* on the 'Corporate' site.
|
||||
* @return void
|
||||
*/
|
||||
private function extractNewsLanguages() {
|
||||
private function extractNewsLanguages()
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached('https://www.desouttertools.com/about-desoutter/news-events');
|
||||
|
||||
$html = defaultLinkTo($html, static::URI);
|
||||
|
@ -206,7 +212,7 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
|
||||
$list = "\t'Corporate'\n\t=> 'https://www.desouttertools.com/about-desoutter/news-events',\n";
|
||||
|
||||
foreach($items as $item) {
|
||||
foreach ($items as $item) {
|
||||
$lang = trim($item->plaintext);
|
||||
$uri = $item->find('a', 0)->href;
|
||||
|
||||
|
@ -222,7 +228,8 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
* on the 'Corporate' site.
|
||||
* @return void
|
||||
*/
|
||||
private function extractIndustryLanguages() {
|
||||
private function extractIndustryLanguages()
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached('https://www.desouttertools.com/industry-4-0/news');
|
||||
|
||||
$html = defaultLinkTo($html, static::URI);
|
||||
|
@ -231,7 +238,7 @@ class DesoutterBridge extends BridgeAbstract {
|
|||
|
||||
$list = "\t'Corporate'\n\t=> 'https://www.desouttertools.com/industry-4-0/news',\n";
|
||||
|
||||
foreach($items as $item) {
|
||||
foreach ($items as $item) {
|
||||
$lang = trim($item->plaintext);
|
||||
$uri = $item->find('a', 0)->href;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class DevToBridge extends BridgeAbstract {
|
||||
|
||||
class DevToBridge extends BridgeAbstract
|
||||
{
|
||||
const CONTEXT_BY_TAG = 'By tag';
|
||||
|
||||
const NAME = 'dev.to Bridge';
|
||||
|
@ -9,28 +10,29 @@ class DevToBridge extends BridgeAbstract {
|
|||
const MAINTAINER = 'logmanoriginal';
|
||||
const CACHE_TIMEOUT = 10800; // 15 min.
|
||||
|
||||
const PARAMETERS = array(
|
||||
self::CONTEXT_BY_TAG => array(
|
||||
'tag' => array(
|
||||
const PARAMETERS = [
|
||||
self::CONTEXT_BY_TAG => [
|
||||
'tag' => [
|
||||
'name' => 'Tag',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'Insert your tag',
|
||||
'exampleValue' => 'python'
|
||||
),
|
||||
'full' => array(
|
||||
],
|
||||
'full' => [
|
||||
'name' => 'Full article',
|
||||
'type' => 'checkbox',
|
||||
'required' => false,
|
||||
'title' => 'Enable to receive the full article for each item'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case self::CONTEXT_BY_TAG:
|
||||
if($tag = $this->getInput('tag')) {
|
||||
if ($tag = $this->getInput('tag')) {
|
||||
return static::URI . '/t/' . urlencode($tag);
|
||||
}
|
||||
break;
|
||||
|
@ -39,12 +41,14 @@ class DevToBridge extends BridgeAbstract {
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://practicaldev-herokuapp-com.freetls.fastly.net/assets/
|
||||
apple-icon-5c6fa9f2bce280428589c6195b7f1924206a53b782b371cfe2d02da932c8c173.png';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached($this->getURI());
|
||||
|
||||
$html = defaultLinkTo($html, static::URI);
|
||||
|
@ -52,8 +56,8 @@ apple-icon-5c6fa9f2bce280428589c6195b7f1924206a53b782b371cfe2d02da932c8c173.png'
|
|||
$articles = $html->find('div.crayons-story')
|
||||
or returnServerError('Could not find articles!');
|
||||
|
||||
foreach($articles as $article) {
|
||||
$item = array();
|
||||
foreach ($articles as $article) {
|
||||
$item = [];
|
||||
|
||||
$item['uri'] = $article->find('a[id*=article-link]', 0)->href;
|
||||
$item['title'] = $article->find('h2 > a', 0)->plaintext;
|
||||
|
@ -62,9 +66,9 @@ apple-icon-5c6fa9f2bce280428589c6195b7f1924206a53b782b371cfe2d02da932c8c173.png'
|
|||
$item['author'] = $article->find('a.crayons-story__secondary.fw-medium', 0)->plaintext;
|
||||
|
||||
// Profile image
|
||||
$item['enclosures'] = array($article->find('img', 0)->src);
|
||||
$item['enclosures'] = [$article->find('img', 0)->src];
|
||||
|
||||
if($this->getInput('full')) {
|
||||
if ($this->getInput('full')) {
|
||||
$fullArticle = $this->getFullArticle($item['uri']);
|
||||
$item['content'] = <<<EOD
|
||||
<p>{$fullArticle}</p>
|
||||
|
@ -85,7 +89,8 @@ EOD;
|
|||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('tag'))) {
|
||||
return ucfirst($this->getInput('tag')) . ' - dev.to';
|
||||
}
|
||||
|
@ -93,7 +98,8 @@ EOD;
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
private function getFullArticle($url) {
|
||||
private function getFullArticle($url)
|
||||
{
|
||||
$html = getSimpleHTMLDOMCached($url);
|
||||
|
||||
$html = defaultLinkTo($html, static::URI);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
class DeveloppezDotComBridge extends FeedExpander
|
||||
{
|
||||
|
||||
const MAINTAINER = 'Binnette';
|
||||
const NAME = 'Developpez.com Actus (FR)';
|
||||
const URI = 'https://www.developpez.com/';
|
||||
|
@ -11,20 +10,20 @@ class DeveloppezDotComBridge extends FeedExpander
|
|||
const CACHE_TIMEOUT = 1800; // 30min
|
||||
const DESCRIPTION = 'Returns complete posts from developpez.com';
|
||||
// Encodings used by Developpez.com in their articles body
|
||||
const ENCONDINGS = array('Windows-1252', 'UTF-8');
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'limit' => array(
|
||||
const ENCONDINGS = ['Windows-1252', 'UTF-8'];
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'limit' => [
|
||||
'name' => 'Max items',
|
||||
'type' => 'number',
|
||||
'defaultValue' => 5,
|
||||
),
|
||||
],
|
||||
// list of the differents RSS availables
|
||||
'domain' => array(
|
||||
'domain' => [
|
||||
'type' => 'list',
|
||||
'name' => 'Domaine',
|
||||
'title' => 'Chosissez un sous-domaine',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'= Domaine principal =' => 'www',
|
||||
'4d' => '4d',
|
||||
'abbyy' => 'abbyy',
|
||||
|
@ -159,10 +158,10 @@ class DeveloppezDotComBridge extends FeedExpander
|
|||
'xhtml' => 'xhtml',
|
||||
'xml' => 'xml',
|
||||
'zend-framework' => 'zend-framework'
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Return the RSS url for selected domain
|
||||
|
@ -364,7 +363,7 @@ class DeveloppezDotComBridge extends FeedExpander
|
|||
private function getAllVideoUrl($item)
|
||||
{
|
||||
// Array of video url
|
||||
$url = array();
|
||||
$url = [];
|
||||
|
||||
// Developpez use a div with the class video-container
|
||||
$divsVideo = $item->find('div.video-container');
|
||||
|
|
|
@ -1,20 +1,22 @@
|
|||
<?php
|
||||
class DiarioDeNoticiasBridge extends BridgeAbstract {
|
||||
|
||||
class DiarioDeNoticiasBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Diário de Notícias (PT)';
|
||||
const URI = 'https://dn.pt';
|
||||
const DESCRIPTION = 'Diário de Notícias (DN.PT)';
|
||||
const MAINTAINER = 'somini';
|
||||
const PARAMETERS = array(
|
||||
'Tag' => array(
|
||||
'n' => array(
|
||||
const PARAMETERS = [
|
||||
'Tag' => [
|
||||
'n' => [
|
||||
'name' => 'Tag Name',
|
||||
'required' => true,
|
||||
'exampleValue' => 'rogerio-casanova',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
const MONPT = array(
|
||||
const MONPT = [
|
||||
'jan',
|
||||
'fev',
|
||||
'mar',
|
||||
|
@ -27,14 +29,16 @@ class DiarioDeNoticiasBridge extends BridgeAbstract {
|
|||
'out',
|
||||
'nov',
|
||||
'dez',
|
||||
);
|
||||
];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://static.globalnoticias.pt/dn/common/images/favicons/favicon-128.png';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
switch($this->queriedContext) {
|
||||
public function getName()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Tag':
|
||||
$name = self::NAME . ' | Tag | ' . $this->getInput('n');
|
||||
break;
|
||||
|
@ -44,8 +48,9 @@ class DiarioDeNoticiasBridge extends BridgeAbstract {
|
|||
return $name;
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
switch($this->queriedContext) {
|
||||
public function getURI()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
case 'Tag':
|
||||
$url = self::URI . '/tag/' . $this->getInput('n') . '.html';
|
||||
break;
|
||||
|
@ -55,12 +60,13 @@ class DiarioDeNoticiasBridge extends BridgeAbstract {
|
|||
return $url;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$archives = self::getURI();
|
||||
$html = getSimpleHTMLDOMCached($archives);
|
||||
|
||||
foreach($html->find('article') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('article') as $element) {
|
||||
$item = [];
|
||||
|
||||
$title = $element->find('.t-am-title', 0);
|
||||
$link = $element->find('a.t-am-text', 0);
|
||||
|
@ -79,6 +85,5 @@ class DiarioDeNoticiasBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
class DiarioDoAlentejoBridge extends BridgeAbstract {
|
||||
|
||||
class DiarioDoAlentejoBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'somini';
|
||||
const NAME = 'Diário do Alentejo';
|
||||
const URI = 'https://www.diariodoalentejo.pt';
|
||||
|
@ -7,7 +9,7 @@ class DiarioDoAlentejoBridge extends BridgeAbstract {
|
|||
const CACHE_TIMEOUT = 28800; // 8h
|
||||
|
||||
/* This is used to hack around obtaining a timestamp. It's just a list of Month names in Portuguese ... */
|
||||
const PT_MONTH_NAMES = array(
|
||||
const PT_MONTH_NAMES = [
|
||||
'janeiro',
|
||||
'fevereiro',
|
||||
'março',
|
||||
|
@ -19,18 +21,20 @@ class DiarioDoAlentejoBridge extends BridgeAbstract {
|
|||
'setembro',
|
||||
'outubro',
|
||||
'novembro',
|
||||
'dezembro');
|
||||
'dezembro'];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.diariodoalentejo.pt/images/favicon/apple-touch-icon.png';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
/* This is slow as molasses (>30s!), keep the cache timeout high to avoid killing the host */
|
||||
$html = getSimpleHTMLDOMCached($this->getURI() . '/pt/noticias-listagem.aspx');
|
||||
|
||||
foreach($html->find('.list_news .item') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('.list_news .item') as $element) {
|
||||
$item = [];
|
||||
|
||||
$item_link = $element->find('.body h2.title a', 0);
|
||||
/* Another broken URL, see also `bridges/ComboiosDePortugalBridge.php` */
|
||||
|
@ -38,9 +42,14 @@ class DiarioDoAlentejoBridge extends BridgeAbstract {
|
|||
$item['title'] = $item_link->innertext;
|
||||
|
||||
$item['timestamp'] = str_ireplace(
|
||||
array_map(function($name) { return ' ' . $name . ' '; }, self::PT_MONTH_NAMES),
|
||||
array_map(function($num) { return sprintf('-%02d-', $num); }, range(1, sizeof(self::PT_MONTH_NAMES))),
|
||||
$element->find('span.date', 0)->innertext);
|
||||
array_map(function ($name) {
|
||||
return ' ' . $name . ' ';
|
||||
}, self::PT_MONTH_NAMES),
|
||||
array_map(function ($num) {
|
||||
return sprintf('-%02d-', $num);
|
||||
}, range(1, sizeof(self::PT_MONTH_NAMES))),
|
||||
$element->find('span.date', 0)->innertext
|
||||
);
|
||||
|
||||
/* Fix the Image URL */
|
||||
$item_image = $element->find('img.thumb', 0);
|
||||
|
|
|
@ -1,46 +1,47 @@
|
|||
<?php
|
||||
class DiceBridge extends BridgeAbstract {
|
||||
|
||||
class DiceBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'rogerdc';
|
||||
const NAME = 'Dice Unofficial RSS';
|
||||
const URI = 'https://www.dice.com/';
|
||||
const DESCRIPTION = 'The Unofficial Dice RSS';
|
||||
// const CACHE_TIMEOUT = 86400; // 1 day
|
||||
|
||||
const PARAMETERS = array(array(
|
||||
'for_one' => array(
|
||||
const PARAMETERS = [[
|
||||
'for_one' => [
|
||||
'name' => 'With at least one of the words',
|
||||
'required' => false,
|
||||
),
|
||||
'for_all' => array(
|
||||
],
|
||||
'for_all' => [
|
||||
'name' => 'With all of the words',
|
||||
'required' => false,
|
||||
),
|
||||
'for_exact' => array(
|
||||
],
|
||||
'for_exact' => [
|
||||
'name' => 'With the exact phrase',
|
||||
'required' => false,
|
||||
),
|
||||
'for_none' => array(
|
||||
],
|
||||
'for_none' => [
|
||||
'name' => 'With none of these words',
|
||||
'required' => false,
|
||||
),
|
||||
'for_jt' => array(
|
||||
],
|
||||
'for_jt' => [
|
||||
'name' => 'Within job title',
|
||||
'required' => false,
|
||||
),
|
||||
'for_com' => array(
|
||||
],
|
||||
'for_com' => [
|
||||
'name' => 'Within company name',
|
||||
'required' => false,
|
||||
),
|
||||
'for_loc' => array(
|
||||
],
|
||||
'for_loc' => [
|
||||
'name' => 'City, State, or ZIP code',
|
||||
'required' => false,
|
||||
),
|
||||
'radius' => array(
|
||||
],
|
||||
'radius' => [
|
||||
'name' => 'Radius in miles',
|
||||
'type' => 'list',
|
||||
'required' => false,
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Exact Location' => 'El',
|
||||
'Within 5 miles' => '5',
|
||||
'Within 10 miles' => '10',
|
||||
|
@ -50,14 +51,14 @@ class DiceBridge extends BridgeAbstract {
|
|||
'Within 50 miles' => '50',
|
||||
'Within 75 miles' => '75',
|
||||
'Within 100 miles' => '100',
|
||||
),
|
||||
],
|
||||
'defaultValue' => '0',
|
||||
),
|
||||
'jtype' => array(
|
||||
],
|
||||
'jtype' => [
|
||||
'name' => 'Job type',
|
||||
'type' => 'list',
|
||||
'required' => false,
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Full-Time' => 'Full Time',
|
||||
'Part-Time' => 'Part Time',
|
||||
'Contract - Independent' => 'Contract Independent',
|
||||
|
@ -66,20 +67,22 @@ class DiceBridge extends BridgeAbstract {
|
|||
'Contract to Hire - W2' => 'C2H W2',
|
||||
'Third Party - Contract - Corp-to-Corp' => 'Contract Corp-To-Corp',
|
||||
'Third Party - Contract to Hire - Corp-to-Corp' => 'C2H Corp-To-Corp',
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'Full Time',
|
||||
),
|
||||
'telecommute' => array(
|
||||
],
|
||||
'telecommute' => [
|
||||
'name' => 'Telecommute',
|
||||
'type' => 'checkbox',
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://assets.dice.com/techpro/img/favicons/favicon.ico';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$uri = 'https://www.dice.com/jobs/advancedResult.html';
|
||||
$uri .= '?for_one=' . urlencode($this->getInput('for_one'));
|
||||
$uri .= '&for_all=' . urlencode($this->getInput('for_all'));
|
||||
|
@ -98,8 +101,8 @@ class DiceBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
$html = getSimpleHTMLDOM($uri);
|
||||
foreach($html->find('div.complete-serp-result-div') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.complete-serp-result-div') as $element) {
|
||||
$item = [];
|
||||
// Title
|
||||
$masterLink = $element->find('a[id^=position]', 0);
|
||||
$item['title'] = $masterLink->title;
|
||||
|
@ -111,8 +114,9 @@ class DiceBridge extends BridgeAbstract {
|
|||
$item['id'] = $masterLink->value;
|
||||
// Image
|
||||
$image = $element->find('img', 0);
|
||||
if ($image)
|
||||
if ($image) {
|
||||
$item['image'] = $image->getAttribute('src');
|
||||
}
|
||||
// Content
|
||||
$shortdesc = $element->find('.shortdesc', '0');
|
||||
$shortdesc = ($shortdesc) ? $shortdesc->innertext : '';
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
<?php
|
||||
class DilbertBridge extends BridgeAbstract {
|
||||
|
||||
class DilbertBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'kranack';
|
||||
const NAME = 'Dilbert Daily Strip';
|
||||
const URI = 'https://dilbert.com';
|
||||
const CACHE_TIMEOUT = 21600; // 6h
|
||||
const DESCRIPTION = 'The Unofficial Dilbert Daily Comic Strip';
|
||||
|
||||
public function collectData(){
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
foreach($html->find('section.comic-item') as $element) {
|
||||
|
||||
foreach ($html->find('section.comic-item') as $element) {
|
||||
$img = $element->find('img', 0);
|
||||
$link = $element->find('a', 0);
|
||||
$comic = $img->src;
|
||||
$title = $img->alt;
|
||||
$url = $link->href;
|
||||
$date = substr(strrchr($url, '/'), 1);
|
||||
if (empty($title))
|
||||
if (empty($title)) {
|
||||
$title = 'Dilbert Comic Strip on ' . $date;
|
||||
}
|
||||
$date = strtotime($date);
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $url;
|
||||
$item['title'] = $title;
|
||||
$item['author'] = 'Scott Adams';
|
||||
|
|
|
@ -1,91 +1,86 @@
|
|||
<?php
|
||||
|
||||
class DiscogsBridge extends BridgeAbstract {
|
||||
|
||||
class DiscogsBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'teromene';
|
||||
const NAME = 'DiscogsBridge';
|
||||
const URI = 'https://www.discogs.com/';
|
||||
const DESCRIPTION = 'Returns releases from discogs';
|
||||
const PARAMETERS = array(
|
||||
'Artist Releases' => array(
|
||||
'artistid' => array(
|
||||
const PARAMETERS = [
|
||||
'Artist Releases' => [
|
||||
'artistid' => [
|
||||
'name' => 'Artist ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => '28104',
|
||||
'title' => 'Only the ID from an artist page. EG /artist/28104-Aesop-Rock is 28104'
|
||||
)
|
||||
),
|
||||
'Label Releases' => array(
|
||||
'labelid' => array(
|
||||
]
|
||||
],
|
||||
'Label Releases' => [
|
||||
'labelid' => [
|
||||
'name' => 'Label ID',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'exampleValue' => '8201',
|
||||
'title' => 'Only the ID from a label page. EG /label/8201-Rhymesayers-Entertainment is 8201'
|
||||
)
|
||||
),
|
||||
'User Wantlist' => array(
|
||||
'username_wantlist' => array(
|
||||
]
|
||||
],
|
||||
'User Wantlist' => [
|
||||
'username_wantlist' => [
|
||||
'name' => 'Username',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'TheBlindMaster',
|
||||
)
|
||||
),
|
||||
'User Folder' => array(
|
||||
'username_folder' => array(
|
||||
]
|
||||
],
|
||||
'User Folder' => [
|
||||
'username_folder' => [
|
||||
'name' => 'Username',
|
||||
'type' => 'text',
|
||||
),
|
||||
'folderid' => array(
|
||||
],
|
||||
'folderid' => [
|
||||
'name' => 'Folder ID',
|
||||
'type' => 'number',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
|
||||
if(!empty($this->getInput('artistid')) || !empty($this->getInput('labelid'))) {
|
||||
|
||||
if(!empty($this->getInput('artistid'))) {
|
||||
public function collectData()
|
||||
{
|
||||
if (!empty($this->getInput('artistid')) || !empty($this->getInput('labelid'))) {
|
||||
if (!empty($this->getInput('artistid'))) {
|
||||
$data = getContents('https://api.discogs.com/artists/'
|
||||
. $this->getInput('artistid')
|
||||
. '/releases?sort=year&sort_order=desc');
|
||||
} elseif(!empty($this->getInput('labelid'))) {
|
||||
} elseif (!empty($this->getInput('labelid'))) {
|
||||
$data = getContents('https://api.discogs.com/labels/'
|
||||
. $this->getInput('labelid')
|
||||
. '/releases?sort=year&sort_order=desc');
|
||||
}
|
||||
|
||||
$jsonData = json_decode($data, true);
|
||||
foreach($jsonData['releases'] as $release) {
|
||||
|
||||
$item = array();
|
||||
foreach ($jsonData['releases'] as $release) {
|
||||
$item = [];
|
||||
$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;
|
||||
|
||||
if(isset($release['year'])) {
|
||||
if (isset($release['year'])) {
|
||||
$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'))) {
|
||||
|
||||
if(!empty($this->getInput('username_wantlist'))) {
|
||||
} elseif (!empty($this->getInput('username_wantlist')) || !empty($this->getInput('username_folder'))) {
|
||||
if (!empty($this->getInput('username_wantlist'))) {
|
||||
$data = getContents('https://api.discogs.com/users/'
|
||||
. $this->getInput('username_wantlist')
|
||||
. '/wants?sort=added&sort_order=desc');
|
||||
$jsonData = json_decode($data, true)['wants'];
|
||||
|
||||
} elseif(!empty($this->getInput('username_folder'))) {
|
||||
} elseif (!empty($this->getInput('username_folder'))) {
|
||||
$data = getContents('https://api.discogs.com/users/'
|
||||
. $this->getInput('username_folder')
|
||||
. '/collection/folders/'
|
||||
|
@ -93,10 +88,9 @@ class DiscogsBridge extends BridgeAbstract {
|
|||
. '/releases?sort=added&sort_order=desc');
|
||||
$jsonData = json_decode($data, true)['releases'];
|
||||
}
|
||||
foreach($jsonData as $element) {
|
||||
|
||||
foreach ($jsonData as $element) {
|
||||
$infos = $element['basic_information'];
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $infos['title'];
|
||||
$item['author'] = $infos['artists'][0]['name'];
|
||||
$item['id'] = $infos['artists'][0]['id'];
|
||||
|
@ -104,17 +98,17 @@ class DiscogsBridge extends BridgeAbstract {
|
|||
$item['timestamp'] = strtotime($element['date_added']);
|
||||
$item['content'] = $item['author'] . ' - ' . $item['title'];
|
||||
$this->items[] = $item;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
return self::URI;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return static::NAME;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,35 @@
|
|||
<?php
|
||||
class DockerHubBridge extends BridgeAbstract {
|
||||
|
||||
class DockerHubBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Docker Hub Bridge';
|
||||
const URI = 'https://hub.docker.com';
|
||||
const DESCRIPTION = 'Returns new images for a container';
|
||||
const MAINTAINER = 'VerifiedJoseph';
|
||||
const PARAMETERS = array(
|
||||
'User Submitted Image' => array(
|
||||
'user' => array(
|
||||
const PARAMETERS = [
|
||||
'User Submitted Image' => [
|
||||
'user' => [
|
||||
'name' => 'User',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'rssbridge',
|
||||
),
|
||||
'repo' => array(
|
||||
],
|
||||
'repo' => [
|
||||
'name' => 'Repository',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'rss-bridge',
|
||||
)
|
||||
),
|
||||
'Official Image' => array(
|
||||
'repo' => array(
|
||||
]
|
||||
],
|
||||
'Official Image' => [
|
||||
'repo' => [
|
||||
'name' => 'Repository',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'postgres',
|
||||
)
|
||||
),
|
||||
);
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
|
||||
|
@ -35,11 +37,12 @@ class DockerHubBridge extends BridgeAbstract {
|
|||
private $imageUrlRegex = '/hub\.docker\.com\/r\/([\w]+)\/([\w-]+)\/?/';
|
||||
private $officialImageUrlRegex = '/hub\.docker\.com\/_\/([\w-]+)\/?/';
|
||||
|
||||
public function detectParameters($url) {
|
||||
$params = array();
|
||||
public function detectParameters($url)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
// user submitted image
|
||||
if(preg_match($this->imageUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->imageUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'User Submitted Image';
|
||||
$params['user'] = $matches[1];
|
||||
$params['repo'] = $matches[2];
|
||||
|
@ -47,7 +50,7 @@ class DockerHubBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
// official image
|
||||
if(preg_match($this->officialImageUrlRegex, $url, $matches)) {
|
||||
if (preg_match($this->officialImageUrlRegex, $url, $matches)) {
|
||||
$params['context'] = 'Official Image';
|
||||
$params['repo'] = $matches[1];
|
||||
return $params;
|
||||
|
@ -56,13 +59,14 @@ class DockerHubBridge extends BridgeAbstract {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$json = getContents($this->getApiUrl());
|
||||
|
||||
$data = json_decode($json, false);
|
||||
|
||||
foreach ($data->results as $result) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
|
||||
$lastPushed = date('Y-m-d H:i:s', strtotime($result->tag_last_pushed));
|
||||
|
||||
|
@ -82,10 +86,10 @@ EOD;
|
|||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
if ($this->queriedContext === 'Official Image') {
|
||||
return self::URI . '/_/' . $this->getRepo();
|
||||
}
|
||||
|
@ -97,7 +101,8 @@ EOD;
|
|||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
if ($this->getInput('repo')) {
|
||||
return $this->getRepo() . ' - Docker Hub';
|
||||
}
|
||||
|
@ -105,7 +110,8 @@ EOD;
|
|||
return parent::getName();
|
||||
}
|
||||
|
||||
private function getRepo() {
|
||||
private function getRepo()
|
||||
{
|
||||
if ($this->queriedContext === 'Official Image') {
|
||||
return $this->getInput('repo');
|
||||
}
|
||||
|
@ -113,7 +119,8 @@ EOD;
|
|||
return $this->getInput('user') . '/' . $this->getInput('repo');
|
||||
}
|
||||
|
||||
private function getApiUrl() {
|
||||
private function getApiUrl()
|
||||
{
|
||||
if ($this->queriedContext === 'Official Image') {
|
||||
return $this->apiURL . 'library/' . $this->getRepo() . '/tags/?page_size=25&page=1';
|
||||
}
|
||||
|
@ -121,7 +128,8 @@ EOD;
|
|||
return $this->apiURL . $this->getRepo() . '/tags/?page_size=25&page=1';
|
||||
}
|
||||
|
||||
private function getLayerUrl($name, $digest) {
|
||||
private function getLayerUrl($name, $digest)
|
||||
{
|
||||
if ($this->queriedContext === 'Official Image') {
|
||||
return self::URI . '/layers/' . $this->getRepo() . '/library/' .
|
||||
$this->getRepo() . '/' . $name . '/images/' . $digest;
|
||||
|
@ -130,7 +138,8 @@ EOD;
|
|||
return self::URI . '/layers/' . $this->getRepo() . '/' . $name . '/images/' . $digest;
|
||||
}
|
||||
|
||||
private function getTagUrl($name) {
|
||||
private function getTagUrl($name)
|
||||
{
|
||||
if ($this->queriedContext === 'Official Image') {
|
||||
return self::URI . '/_/' . $this->getRepo() . '?tab=tags&name=' . $name;
|
||||
}
|
||||
|
@ -138,7 +147,8 @@ EOD;
|
|||
return self::URI . '/r/' . $this->getRepo() . '/tags?name=' . $name;
|
||||
}
|
||||
|
||||
private function getImages($result) {
|
||||
private function getImages($result)
|
||||
{
|
||||
$html = <<<EOD
|
||||
<table style="width:300px;"><thead><tr><th>Digest</th><th>OS/architecture</th></tr></thead></tbody>
|
||||
EOD;
|
||||
|
@ -158,7 +168,8 @@ EOD;
|
|||
return $html . '</tbody></table>';
|
||||
}
|
||||
|
||||
private function getShortDigestId($digest) {
|
||||
private function getShortDigestId($digest)
|
||||
{
|
||||
$parts = explode(':', $digest);
|
||||
return substr($parts[1], 0, 12);
|
||||
}
|
||||
|
|
|
@ -1,54 +1,57 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Retourne les dons d'une recherche filtrée sur le site Donnons.org
|
||||
* Example: https://donnons.org/Sport/Ile-de-France
|
||||
*/
|
||||
class DonnonsBridge extends BridgeAbstract {
|
||||
|
||||
class DonnonsBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Binnette';
|
||||
const NAME = 'Donnons.org';
|
||||
const URI = 'https://donnons.org';
|
||||
const CACHE_TIMEOUT = 1800; // 30min
|
||||
const DESCRIPTION = 'Retourne les dons depuis le site Donnons.org.';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'q' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'q' => [
|
||||
'name' => 'Url de recherche',
|
||||
'required' => true,
|
||||
'exampleValue' => '/Sport/Ile-de-France',
|
||||
'pattern' => '\/.*',
|
||||
'title' => 'Faites une recherche sur le site. Puis copiez ici la fin de l’url. Doit commencer par /',
|
||||
),
|
||||
'p' => array(
|
||||
],
|
||||
'p' => [
|
||||
'name' => 'Nombre de pages à scanner',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'defaultValue' => 5,
|
||||
'title' => 'Indique le nombre de pages de donnons.org qui seront scannées'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$pages = $this->getInput('p');
|
||||
|
||||
for($i = 1; $i <= $pages; $i++) {
|
||||
for ($i = 1; $i <= $pages; $i++) {
|
||||
$this->collectDataByPage($i);
|
||||
}
|
||||
}
|
||||
|
||||
private function collectDataByPage($page) {
|
||||
private function collectDataByPage($page)
|
||||
{
|
||||
$uri = $this->getPageURI($page);
|
||||
|
||||
$html = getSimpleHTMLDOM($uri);
|
||||
|
||||
$searchDiv = $html->find('div[id=search]', 0);
|
||||
|
||||
if(!is_null($searchDiv)) {
|
||||
if (!is_null($searchDiv)) {
|
||||
$elements = $searchDiv->find('a.lst-annonce');
|
||||
foreach($elements as $element) {
|
||||
$item = array();
|
||||
foreach ($elements as $element) {
|
||||
$item = [];
|
||||
|
||||
// Lien vers le don
|
||||
$item['uri'] = self::URI . $element->href;
|
||||
|
@ -89,34 +92,37 @@ class DonnonsBridge extends BridgeAbstract {
|
|||
$item['timestamp'] = $date;
|
||||
$item['author'] = $author;
|
||||
$item['content'] = $content;
|
||||
$item['enclosures'] = array($image);
|
||||
$item['enclosures'] = [$image];
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getPageURI($page) {
|
||||
private function getPageURI($page)
|
||||
{
|
||||
$uri = $this->getURI();
|
||||
$haveQueryParams = strpos($uri, '?') !== false;
|
||||
|
||||
if($haveQueryParams) {
|
||||
if ($haveQueryParams) {
|
||||
return $uri . '&page=' . $page;
|
||||
} else {
|
||||
return $uri . '?page=' . $page;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
if(!is_null($this->getInput('q'))) {
|
||||
public function getURI()
|
||||
{
|
||||
if (!is_null($this->getInput('q'))) {
|
||||
return self::URI . $this->getInput('q');
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
if(!is_null($this->getInput('q'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('q'))) {
|
||||
return 'Donnons.org - ' . $this->getInput('q');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
<?php
|
||||
class DribbbleBridge extends BridgeAbstract {
|
||||
|
||||
class DribbbleBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'quentinus95';
|
||||
const NAME = 'Dribbble popular shots';
|
||||
const URI = 'https://dribbble.com';
|
||||
const CACHE_TIMEOUT = 1800;
|
||||
const DESCRIPTION = 'Returns the newest popular shots from Dribbble.';
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://cdn.dribbble.com/assets/
|
||||
favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
$json = $this->loadEmbeddedJsonData($html);
|
||||
|
||||
foreach($html->find('li[id^="screenshot-"]') as $shot) {
|
||||
$item = array();
|
||||
foreach ($html->find('li[id^="screenshot-"]') as $shot) {
|
||||
$item = [];
|
||||
|
||||
$additional_data = $this->findJsonForShot($shot, $json);
|
||||
if ($additional_data === null) {
|
||||
|
@ -37,18 +40,19 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
|||
|
||||
$preview_path = $shot->find('figure img', 1)->attr['data-srcset'];
|
||||
$item['content'] .= $this->getImageTag($preview_path, $item['title']);
|
||||
$item['enclosures'] = array($this->getFullSizeImagePath($preview_path));
|
||||
$item['enclosures'] = [$this->getFullSizeImagePath($preview_path)];
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
private function loadEmbeddedJsonData($html){
|
||||
$json = array();
|
||||
private function loadEmbeddedJsonData($html)
|
||||
{
|
||||
$json = [];
|
||||
$scripts = $html->find('script');
|
||||
|
||||
foreach($scripts as $script) {
|
||||
if(strpos($script->innertext, 'newestShots') !== false) {
|
||||
foreach ($scripts as $script) {
|
||||
if (strpos($script->innertext, 'newestShots') !== false) {
|
||||
// fix single quotes
|
||||
$script->innertext = preg_replace('/\'(.*)\'(,?)$/im', '"\1"\2', $script->innertext);
|
||||
|
||||
|
@ -73,9 +77,10 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
|||
return $json;
|
||||
}
|
||||
|
||||
private function findJsonForShot($shot, $json){
|
||||
foreach($json as $element) {
|
||||
if(strpos($shot->getAttribute('id'), (string)$element['id']) !== false) {
|
||||
private function findJsonForShot($shot, $json)
|
||||
{
|
||||
foreach ($json as $element) {
|
||||
if (strpos($shot->getAttribute('id'), (string)$element['id']) !== false) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +88,8 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
|||
return null;
|
||||
}
|
||||
|
||||
private function getImageTag($preview_path, $title){
|
||||
private function getImageTag($preview_path, $title)
|
||||
{
|
||||
return sprintf(
|
||||
'<br /> <a href="%s"><img srcset="%s" alt="%s" /></a>',
|
||||
$this->getFullSizeImagePath($preview_path),
|
||||
|
@ -92,7 +98,8 @@ favicon-63b2904a073c89b52b19aa08cebc16a154bcf83fee8ecc6439968b1e6db569c7.ico';
|
|||
);
|
||||
}
|
||||
|
||||
private function getFullSizeImagePath($preview_path){
|
||||
private function getFullSizeImagePath($preview_path)
|
||||
{
|
||||
// Get last image from srcset
|
||||
$src_set_urls = explode(',', $preview_path);
|
||||
$url = end($src_set_urls);
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
<?php
|
||||
class Drive2ruBridge extends BridgeAbstract {
|
||||
|
||||
class Drive2ruBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'dotter-ak';
|
||||
const NAME = 'Drive2.ru';
|
||||
const URI = 'https://drive2.ru/';
|
||||
const DESCRIPTION = 'Лента новостей и тестдрайвов, бортжурналов по выбранной марке или модели
|
||||
(также работает с фильтром по категориям), блогов пользователей и публикаций по темам.';
|
||||
const PARAMETERS = array(
|
||||
'Новости и тест-драйвы' => array(),
|
||||
'Бортжурналы (По модели или марке)' => array(
|
||||
'url' => array(
|
||||
const PARAMETERS = [
|
||||
'Новости и тест-драйвы' => [],
|
||||
'Бортжурналы (По модели или марке)' => [
|
||||
'url' => [
|
||||
'name' => 'Ссылка на страницу с бортжурналом',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'Например: https://www.drive2.ru/experience/suzuki/g4895/',
|
||||
'exampleValue' => 'https://www.drive2.ru/experience/suzuki/g4895/'
|
||||
),
|
||||
),
|
||||
'Личные блоги' => array(
|
||||
'username' => array(
|
||||
],
|
||||
],
|
||||
'Личные блоги' => [
|
||||
'username' => [
|
||||
'name' => 'Никнейм пользователя на сайте',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'title' => 'Например: Mickey',
|
||||
'exampleValue' => 'Mickey'
|
||||
)
|
||||
),
|
||||
'Публикации по темам (Стоит почитать)' => array(
|
||||
'topic' => array(
|
||||
]
|
||||
],
|
||||
'Публикации по темам (Стоит почитать)' => [
|
||||
'topic' => [
|
||||
'name' => 'Темы',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Автозвук' => '16',
|
||||
'Автомобильный дизайн' => '10',
|
||||
'Автоспорт' => '11',
|
||||
|
@ -62,29 +64,30 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
'Шины и диски' => '140',
|
||||
'Электрика' => '130',
|
||||
'Электромобили' => '131'
|
||||
),
|
||||
],
|
||||
'defaultValue' => '16',
|
||||
)
|
||||
),
|
||||
'global' => array(
|
||||
'full_articles' => array(
|
||||
]
|
||||
],
|
||||
'global' => [
|
||||
'full_articles' => [
|
||||
'name' => 'Загружать в ленту полный текст',
|
||||
'type' => 'checkbox'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
private $title;
|
||||
|
||||
private function getUserContent($url) {
|
||||
private function getUserContent($url)
|
||||
{
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
$this->title = $html->find('title', 0)->innertext;
|
||||
$articles = $html->find('div.js-entity');
|
||||
foreach ($articles as $article) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $article->find('a.c-link--text', 0)->plaintext;
|
||||
$item['uri'] = urljoin(self::URI, $article->find('a.c-link--text', 0)->href);
|
||||
if($this->getInput('full_articles')) {
|
||||
if ($this->getInput('full_articles')) {
|
||||
$item['content'] = $this->addCommentsLink(
|
||||
$this->adjustContent(getSimpleHTMLDomCached($item['uri'])->find('div.c-post__body', 0))->innertext,
|
||||
$item['uri']
|
||||
|
@ -93,20 +96,23 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
$item['content'] = $this->addReadMoreLink($article->find('div.c-post-preview__lead', 0), $item['uri']);
|
||||
}
|
||||
$item['author'] = $article->find('a.c-username--wrap', 0)->plaintext;
|
||||
if (!is_null($article->find('img', 1))) $item['enclosures'][] = $article->find('img', 1)->src;
|
||||
if (!is_null($article->find('img', 1))) {
|
||||
$item['enclosures'][] = $article->find('img', 1)->src;
|
||||
}
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
private function getLogbooksContent($url) {
|
||||
private function getLogbooksContent($url)
|
||||
{
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
$this->title = $html->find('title', 0)->innertext;
|
||||
$articles = $html->find('div.js-entity');
|
||||
foreach ($articles as $article) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $article->find('a.c-link--text', 1)->plaintext;
|
||||
$item['uri'] = urljoin(self::URI, $article->find('a.c-link--text', 1)->href);
|
||||
if($this->getInput('full_articles')) {
|
||||
if ($this->getInput('full_articles')) {
|
||||
$item['content'] = $this->addCommentsLink(
|
||||
$this->adjustContent(getSimpleHTMLDomCached($item['uri'])->find('div.c-post__body', 0))->innertext,
|
||||
$item['uri']
|
||||
|
@ -115,20 +121,23 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
$item['content'] = $this->addReadMoreLink($article->find('div.c-post-preview__lead', 0), $item['uri']);
|
||||
}
|
||||
$item['author'] = $article->find('a.c-username--wrap', 0)->plaintext;
|
||||
if (!is_null($article->find('img', 1))) $item['enclosures'][] = $article->find('img', 1)->src;
|
||||
if (!is_null($article->find('img', 1))) {
|
||||
$item['enclosures'][] = $article->find('img', 1)->src;
|
||||
}
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
private function getNews() {
|
||||
private function getNews()
|
||||
{
|
||||
$html = getSimpleHTMLDOM('https://www.drive2.ru/editorial/');
|
||||
$this->title = $html->find('title', 0)->innertext;
|
||||
$articles = $html->find('div.c-article-card');
|
||||
foreach ($articles as $article) {
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['title'] = $article->find('a.c-link--text', 0)->plaintext;
|
||||
$item['uri'] = urljoin(self::URI, $article->find('a.c-link--text', 0)->href);
|
||||
if($this->getInput('full_articles')) {
|
||||
if ($this->getInput('full_articles')) {
|
||||
$item['content'] = $this->addCommentsLink(
|
||||
$this->adjustContent(getSimpleHTMLDomCached($item['uri'])->find('div.article', 0))->innertext,
|
||||
$item['uri']
|
||||
|
@ -137,23 +146,32 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
$item['content'] = $this->addReadMoreLink($article->find('div.c-article-card__lead', 0), $item['uri']);
|
||||
}
|
||||
$item['author'] = 'Новости и тест-драйвы на Drive2.ru';
|
||||
if (!is_null($article->find('img', 0))) $item['enclosures'][] = $article->find('img', 0)->src;
|
||||
if (!is_null($article->find('img', 0))) {
|
||||
$item['enclosures'][] = $article->find('img', 0)->src;
|
||||
}
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
private function adjustContent($content) {
|
||||
foreach ($content->find('div.o-group') as $node)
|
||||
private function adjustContent($content)
|
||||
{
|
||||
foreach ($content->find('div.o-group') as $node) {
|
||||
$node->outertext = '';
|
||||
foreach($content->find('div, span') as $attrs)
|
||||
foreach ($attrs->getAllAttributes() as $attr => $val)
|
||||
}
|
||||
foreach ($content->find('div, span') as $attrs) {
|
||||
foreach ($attrs->getAllAttributes() as $attr => $val) {
|
||||
$attrs->removeAttribute($attr);
|
||||
foreach ($content->getElementsByTagName('figcaption') as $attrs)
|
||||
}
|
||||
}
|
||||
foreach ($content->getElementsByTagName('figcaption') as $attrs) {
|
||||
$attrs->setAttribute(
|
||||
'style',
|
||||
'font-style: italic; font-size: small; margin: 0 100px 75px;');
|
||||
foreach ($content->find('script') as $node)
|
||||
'font-style: italic; font-size: small; margin: 0 100px 75px;'
|
||||
);
|
||||
}
|
||||
foreach ($content->find('script') as $node) {
|
||||
$node->outertext = '';
|
||||
}
|
||||
foreach ($content->find('iframe') as $node) {
|
||||
preg_match('/embed\/(.*?)\?/', $node->src, $match);
|
||||
$node->outertext = '<a href="https://www.youtube.com/watch?v=' . $match[1] .
|
||||
|
@ -162,31 +180,38 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
return $content;
|
||||
}
|
||||
|
||||
private function addCommentsLink ($content, $url) {
|
||||
private function addCommentsLink($content, $url)
|
||||
{
|
||||
return $content . '<br><a href="' . $url . '#comments">Перейти к комментариям</a>';
|
||||
}
|
||||
|
||||
private function addReadMoreLink ($content, $url) {
|
||||
if (!is_null($content))
|
||||
private function addReadMoreLink($content, $url)
|
||||
{
|
||||
if (!is_null($content)) {
|
||||
return preg_replace('!\s+!', ' ', str_replace('Читать дальше', '', $content->plaintext)) .
|
||||
'<br><a href="' . $url . '">Читать далее</a>';
|
||||
else return '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
switch($this->queriedContext) {
|
||||
public function collectData()
|
||||
{
|
||||
switch ($this->queriedContext) {
|
||||
default:
|
||||
case 'Новости и тест-драйвы':
|
||||
$this->getNews();
|
||||
break;
|
||||
case 'Бортжурналы (По модели или марке)':
|
||||
if (!preg_match('/^https:\/\/www.drive2.ru\/experience/', $this->getInput('url')))
|
||||
if (!preg_match('/^https:\/\/www.drive2.ru\/experience/', $this->getInput('url'))) {
|
||||
returnServerError('Invalid url');
|
||||
}
|
||||
$this->getLogbooksContent($this->getInput('url'));
|
||||
break;
|
||||
case 'Личные блоги':
|
||||
if (!preg_match('/^[a-zA-Z0-9-]{3,16}$/', $this->getInput('username')))
|
||||
if (!preg_match('/^[a-zA-Z0-9-]{3,16}$/', $this->getInput('username'))) {
|
||||
returnServerError('Invalid username');
|
||||
}
|
||||
$this->getUserContent('https://www.drive2.ru/users/' . $this->getInput('username'));
|
||||
break;
|
||||
case 'Публикации по темам (Стоит почитать)':
|
||||
|
@ -195,11 +220,13 @@ class Drive2ruBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return $this->title ?: parent::getName();
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.drive2.ru/favicon.ico';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
class DuckDuckGoBridge extends BridgeAbstract {
|
||||
|
||||
class DuckDuckGoBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'Astalaseven';
|
||||
const NAME = 'DuckDuckGo';
|
||||
const URI = 'https://duckduckgo.com/';
|
||||
|
@ -10,29 +11,30 @@ class DuckDuckGoBridge extends BridgeAbstract {
|
|||
const SORT_DATE = '+sort:date';
|
||||
const SORT_RELEVANCE = '';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'u' => array(
|
||||
const PARAMETERS = [ [
|
||||
'u' => [
|
||||
'name' => 'keyword',
|
||||
'exampleValue' => 'duck',
|
||||
'required' => true
|
||||
),
|
||||
'sort' => array(
|
||||
],
|
||||
'sort' => [
|
||||
'name' => 'sort by',
|
||||
'type' => 'list',
|
||||
'required' => false,
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'date' => self::SORT_DATE,
|
||||
'relevance' => self::SORT_RELEVANCE
|
||||
),
|
||||
],
|
||||
'defaultValue' => self::SORT_DATE
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI . 'html/?kd=-1&q=' . $this->getInput('u') . $this->getInput('sort'));
|
||||
|
||||
foreach($html->find('div.result') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.result') as $element) {
|
||||
$item = [];
|
||||
$item['uri'] = $element->find('a.result__a', 0)->href;
|
||||
$item['title'] = $element->find('h2.result__title', 0)->plaintext;
|
||||
$item['content'] = $element->find('a.result__snippet', 0)->plaintext;
|
||||
|
|
|
@ -1,51 +1,53 @@
|
|||
<?php
|
||||
class EZTVBridge extends BridgeAbstract {
|
||||
|
||||
class EZTVBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'alexAubin';
|
||||
const NAME = 'EZTV';
|
||||
const URI = 'https://eztv.re/';
|
||||
const DESCRIPTION = 'Returns list of torrents for specific show(s)
|
||||
on EZTV. Get IMDB IDs from IMDB.';
|
||||
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'ids' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'ids' => [
|
||||
'name' => 'Show IMDB IDs',
|
||||
'exampleValue' => '8740790,1733785',
|
||||
'required' => true,
|
||||
'title' => 'One or more IMDB show IDs (can be found in the IMDB show URL)'
|
||||
),
|
||||
'no480' => array(
|
||||
],
|
||||
'no480' => [
|
||||
'name' => 'No 480p',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Activate to exclude 480p torrents'
|
||||
),
|
||||
'no720' => array(
|
||||
],
|
||||
'no720' => [
|
||||
'name' => 'No 720p',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Activate to exclude 720p torrents'
|
||||
),
|
||||
'no1080' => array(
|
||||
],
|
||||
'no1080' => [
|
||||
'name' => 'No 1080p',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Activate to exclude 1080p torrents'
|
||||
),
|
||||
'no2160' => array(
|
||||
],
|
||||
'no2160' => [
|
||||
'name' => 'No 2160p',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Activate to exclude 2160p torrents'
|
||||
),
|
||||
'noUnknownRes' => array(
|
||||
],
|
||||
'noUnknownRes' => [
|
||||
'name' => 'No Unknown resolution',
|
||||
'type' => 'checkbox',
|
||||
'title' => 'Activate to exclude unknown resolution torrents'
|
||||
),
|
||||
)
|
||||
);
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Shamelessly lifted from https://stackoverflow.com/a/2510459
|
||||
protected function formatBytes($bytes, $precision = 2) {
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
protected function formatBytes($bytes, $precision = 2)
|
||||
{
|
||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
|
@ -55,8 +57,9 @@ on EZTV. Get IMDB IDs from IMDB.';
|
|||
return round($bytes, $precision) . ' ' . $units[$pow];
|
||||
}
|
||||
|
||||
protected function getItemFromTorrent($torrent){
|
||||
$item = array();
|
||||
protected function getItemFromTorrent($torrent)
|
||||
{
|
||||
$item = [];
|
||||
$item['uri'] = $torrent->episode_url;
|
||||
$item['author'] = $torrent->imdb_id;
|
||||
$item['timestamp'] = date('d F Y H:i:s', $torrent->date_released_unix);
|
||||
|
@ -74,18 +77,20 @@ on EZTV. Get IMDB IDs from IMDB.';
|
|||
return $item;
|
||||
}
|
||||
|
||||
private static function compareDate($torrent1, $torrent2) {
|
||||
private static function compareDate($torrent1, $torrent2)
|
||||
{
|
||||
return (strtotime($torrent1['timestamp']) < strtotime($torrent2['timestamp']) ? 1 : -1);
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$showIds = explode(',', $this->getInput('ids'));
|
||||
|
||||
foreach($showIds as $showId) {
|
||||
foreach ($showIds as $showId) {
|
||||
$eztvUri = $this->getURI() . 'api/get-torrents?imdb_id=' . $showId;
|
||||
$content = getContents($eztvUri);
|
||||
$torrents = json_decode($content)->torrents;
|
||||
foreach($torrents as $torrent) {
|
||||
foreach ($torrents as $torrent) {
|
||||
$title = $torrent->title;
|
||||
$regex480 = '/480p/';
|
||||
$regex720 = '/720p/';
|
||||
|
@ -93,11 +98,13 @@ on EZTV. Get IMDB IDs from IMDB.';
|
|||
$regex2160 = '/2160p/';
|
||||
$regexUnknown = '/(480p|720p|1080p|2160p)/';
|
||||
// Skip unwanted resolution torrents
|
||||
if ((preg_match($regex480, $title) === 1 && $this->getInput('no480'))
|
||||
if (
|
||||
(preg_match($regex480, $title) === 1 && $this->getInput('no480'))
|
||||
|| (preg_match($regex720, $title) === 1 && $this->getInput('no720'))
|
||||
|| (preg_match($regex1080, $title) === 1 && $this->getInput('no1080'))
|
||||
|| (preg_match($regex2160, $title) === 1 && $this->getInput('no2160'))
|
||||
|| (preg_match($regexUnknown, $title) !== 1 && $this->getInput('noUnknownRes'))) {
|
||||
|| (preg_match($regexUnknown, $title) !== 1 && $this->getInput('noUnknownRes'))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -106,6 +113,6 @@ on EZTV. Get IMDB IDs from IMDB.';
|
|||
}
|
||||
|
||||
// Sort all torrents in array by date
|
||||
usort($this->items, array('EZTVBridge', 'compareDate'));
|
||||
usort($this->items, ['EZTVBridge', 'compareDate']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
<?php
|
||||
class EconomistBridge extends FeedExpander {
|
||||
|
||||
class EconomistBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'bockiii';
|
||||
const NAME = 'Economist Bridge';
|
||||
const URI = 'https://www.economist.com/';
|
||||
const CACHE_TIMEOUT = 3600; //1hour
|
||||
const DESCRIPTION = 'Returns the latest articles for the selected category';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'global' => array(
|
||||
'limit' => array(
|
||||
const PARAMETERS = [
|
||||
'global' => [
|
||||
'limit' => [
|
||||
'name' => 'Feed Item Limit',
|
||||
'required' => true,
|
||||
'type' => 'number',
|
||||
'defaultValue' => 10,
|
||||
'title' => 'Maximum number of returned feed items. Maximum 30, default 10'
|
||||
)
|
||||
),
|
||||
'Topics' => array(
|
||||
'topic' => array(
|
||||
]
|
||||
],
|
||||
'Topics' => [
|
||||
'topic' => [
|
||||
'name' => 'Topics',
|
||||
'type' => 'list',
|
||||
'title' => 'Select a Topic',
|
||||
'defaultValue' => 'latest',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Latest' => 'latest',
|
||||
'The world this week' => 'the-world-this-week',
|
||||
'Letters' => 'letters',
|
||||
|
@ -45,15 +46,15 @@ class EconomistBridge extends FeedExpander {
|
|||
'Obituaries' => 'obituary',
|
||||
'Graphic detail' => 'graphic-detail',
|
||||
'Indicators' => 'economic-and-financial-indicators',
|
||||
)
|
||||
)
|
||||
),
|
||||
'Blogs' => array(
|
||||
'blog' => array(
|
||||
]
|
||||
]
|
||||
],
|
||||
'Blogs' => [
|
||||
'blog' => [
|
||||
'name' => 'Blogs',
|
||||
'type' => 'list',
|
||||
'title' => 'Select a Blog',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Bagehots notebook' => 'bagehots-notebook',
|
||||
'Bartleby' => 'bartleby',
|
||||
'Buttonwoods notebook' => 'buttonwoods-notebook',
|
||||
|
@ -66,12 +67,13 @@ class EconomistBridge extends FeedExpander {
|
|||
'Kaffeeklatsch' => 'kaffeeklatsch',
|
||||
'Prospero' => 'prospero',
|
||||
'The Economist Explains' => 'the-economist-explains',
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
// get if topics or blogs were selected and store the selected category
|
||||
switch ($this->queriedContext) {
|
||||
case 'Topics':
|
||||
|
@ -93,7 +95,8 @@ class EconomistBridge extends FeedExpander {
|
|||
$this->collectExpandableDatas('https://www.economist.com/' . $category . '/rss.xml', $limit);
|
||||
}
|
||||
|
||||
protected function parseItem($feedItem){
|
||||
protected function parseItem($feedItem)
|
||||
{
|
||||
$item = parent::parseItem($feedItem);
|
||||
$article = getSimpleHTMLDOM($item['uri']);
|
||||
// before the article can be added, it needs to be cleaned up, thus, the extra function
|
||||
|
@ -124,13 +127,16 @@ class EconomistBridge extends FeedExpander {
|
|||
return $item;
|
||||
}
|
||||
|
||||
private function cleanContent($article, $contentNode){
|
||||
private function cleanContent($article, $contentNode)
|
||||
{
|
||||
// the actual article is in this div
|
||||
$content = $article->find($contentNode, 0)->innertext;
|
||||
// clean the article content. Remove all div's since the text is in paragraph elements
|
||||
foreach (array(
|
||||
foreach (
|
||||
[
|
||||
'<div '
|
||||
) as $tag_start) {
|
||||
] as $tag_start
|
||||
) {
|
||||
$content = stripRecursiveHTMLSection($content, 'div', $tag_start);
|
||||
}
|
||||
// now remove embedded iframes. The podcast postings contain these for example
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
class EconomistWorldInBriefBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'sqrtminusone';
|
||||
|
@ -8,35 +9,35 @@ class EconomistWorldInBriefBridge extends BridgeAbstract
|
|||
const CACHE_TIMEOUT = 3600; // 1 hour
|
||||
const DESCRIPTION = 'Returns stories from the World in Brief section';
|
||||
|
||||
const PARAMETERS = array(
|
||||
'' => array(
|
||||
'splitGobbets' => array(
|
||||
const PARAMETERS = [
|
||||
'' => [
|
||||
'splitGobbets' => [
|
||||
'name' => 'Split the short stories',
|
||||
'type' => 'checkbox',
|
||||
'defaultValue' => false,
|
||||
'title' => 'Whether to split the short stories into separate entries'
|
||||
),
|
||||
'limit' => array(
|
||||
],
|
||||
'limit' => [
|
||||
'name' => 'Truncate headers for the short stories',
|
||||
'type' => 'number',
|
||||
'defaultValue' => 100
|
||||
),
|
||||
'agenda' => array(
|
||||
],
|
||||
'agenda' => [
|
||||
'name' => 'Add agenda for the day',
|
||||
'type' => 'checkbox',
|
||||
'defaultValue' => 'checked'
|
||||
),
|
||||
'agendaPictures' => array(
|
||||
],
|
||||
'agendaPictures' => [
|
||||
'name' => 'Include pictures to the agenda',
|
||||
'type' => 'checkbox',
|
||||
'defaultValue' => 'checked'
|
||||
),
|
||||
'quote' => array(
|
||||
],
|
||||
'quote' => [
|
||||
'name' => 'Include the quote of the day',
|
||||
'type' => 'checkbox'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
|
@ -72,13 +73,13 @@ class EconomistWorldInBriefBridge extends BridgeAbstract
|
|||
if ($limit && mb_strlen($title) > $limit) {
|
||||
$title = mb_substr($title, 0, $limit) . '...';
|
||||
}
|
||||
$item = array(
|
||||
$item = [
|
||||
'uri' => self::URI,
|
||||
'title' => $title,
|
||||
'content' => $gobbet->innertext,
|
||||
'timestamp' => $today->format('U'),
|
||||
'uid' => md5($gobbet->plaintext)
|
||||
);
|
||||
];
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
@ -91,13 +92,13 @@ class EconomistWorldInBriefBridge extends BridgeAbstract
|
|||
foreach ($gobbets->find('._gobbet') as $gobbet) {
|
||||
$contents .= "<p>{$gobbet->innertext}";
|
||||
}
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'uri' => self::URI,
|
||||
'title' => 'World in brief at ' . $today->format('Y.m.d'),
|
||||
'content' => $contents,
|
||||
'timestamp' => $today->format('U'),
|
||||
'uid' => 'world-in-brief-' . $today->format('U')
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
private function collectArticles($articles)
|
||||
|
@ -116,26 +117,27 @@ class EconomistWorldInBriefBridge extends BridgeAbstract
|
|||
$res_content .= '<img src="' . $img->src . '" />';
|
||||
}
|
||||
$res_content .= $content->innertext;
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'uri' => self::URI,
|
||||
'title' => $title,
|
||||
'content' => $res_content,
|
||||
'timestamp' => $today->format('U'),
|
||||
'uid' => 'story-' . $today->format('U') . "{$i}",
|
||||
);
|
||||
];
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
private function addQuote($quote) {
|
||||
private function addQuote($quote)
|
||||
{
|
||||
$today = new Datetime();
|
||||
$today->setTime(0, 0, 0, 0);
|
||||
$this->items[] = array(
|
||||
$this->items[] = [
|
||||
'uri' => self::URI,
|
||||
'title' => 'Quote of the day ' . $today->format('Y.m.d'),
|
||||
'content' => $quote->innertext,
|
||||
'timestamp' => $today->format('U'),
|
||||
'uid' => 'quote-' . $today->format('U')
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,36 @@
|
|||
<?php
|
||||
class EliteDangerousGalnetBridge extends BridgeAbstract {
|
||||
|
||||
class EliteDangerousGalnetBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'corenting';
|
||||
const NAME = 'Elite: Dangerous Galnet';
|
||||
const URI = 'https://community.elitedangerous.com/galnet/';
|
||||
const CACHE_TIMEOUT = 7200; // 2h
|
||||
const DESCRIPTION = 'Returns the latest page of news from Galnet';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'language' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'language' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'English' => 'en',
|
||||
'French' => 'fr',
|
||||
'German' => 'de'
|
||||
),
|
||||
],
|
||||
'defaultValue' => 'en'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$language = $this->getInput('language');
|
||||
$url = 'https://community.elitedangerous.com/';
|
||||
$url = $url . $language . '/galnet';
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
|
||||
foreach($html->find('div.article') as $element) {
|
||||
$item = array();
|
||||
foreach ($html->find('div.article') as $element) {
|
||||
$item = [];
|
||||
|
||||
$uri = $element->find('h3 a', 0)->href;
|
||||
$uri = 'https://community.elitedangerous.com/' . $language . $uri;
|
||||
|
|
|
@ -1,38 +1,39 @@
|
|||
<?php
|
||||
class ElloBridge extends BridgeAbstract {
|
||||
|
||||
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(
|
||||
const PARAMETERS = [
|
||||
'By User' => [
|
||||
'u' => [
|
||||
'name' => 'Username',
|
||||
'required' => true,
|
||||
'exampleValue' => 'zteph',
|
||||
'title' => 'Username'
|
||||
)
|
||||
),
|
||||
'Search' => array(
|
||||
's' => array(
|
||||
]
|
||||
],
|
||||
'Search' => [
|
||||
's' => [
|
||||
'name' => 'Search',
|
||||
'required' => true,
|
||||
'exampleValue' => 'bird',
|
||||
'title' => 'Search'
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function collectData() {
|
||||
|
||||
$header = array(
|
||||
public function collectData()
|
||||
{
|
||||
$header = [
|
||||
'Authorization: Bearer ' . $this->getAPIKey()
|
||||
);
|
||||
];
|
||||
|
||||
if(!empty($this->getInput('u'))) {
|
||||
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 {
|
||||
|
@ -42,9 +43,8 @@ class ElloBridge extends BridgeAbstract {
|
|||
|
||||
$postData = json_decode($postData);
|
||||
$count = 0;
|
||||
foreach($postData->posts as $post) {
|
||||
|
||||
$item = array();
|
||||
foreach ($postData->posts as $post) {
|
||||
$item = [];
|
||||
$item['author'] = $this->getUsername($post, $postData);
|
||||
$item['timestamp'] = strtotime($post->created_at);
|
||||
$item['title'] = strip_tags($this->findText($post->summary));
|
||||
|
@ -55,52 +55,44 @@ class ElloBridge extends BridgeAbstract {
|
|||
|
||||
$this->items[] = $item;
|
||||
$count += 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function findText($path) {
|
||||
|
||||
foreach($path as $summaryElement) {
|
||||
|
||||
if($summaryElement->kind == 'text') {
|
||||
private function findText($path)
|
||||
{
|
||||
foreach ($path as $summaryElement) {
|
||||
if ($summaryElement->kind == 'text') {
|
||||
return $summaryElement->data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
private function getPostContent($path) {
|
||||
|
||||
private function getPostContent($path)
|
||||
{
|
||||
$content = '';
|
||||
foreach($path as $summaryElement) {
|
||||
|
||||
if($summaryElement->kind == 'text') {
|
||||
foreach ($path as $summaryElement) {
|
||||
if ($summaryElement->kind == 'text') {
|
||||
$content .= $summaryElement->data;
|
||||
} elseif ($summaryElement->kind == 'image') {
|
||||
$alt = '';
|
||||
if(property_exists($summaryElement->data, 'alt')) {
|
||||
if (property_exists($summaryElement->data, 'alt')) {
|
||||
$alt = $summaryElement->data->alt;
|
||||
}
|
||||
$content .= '<img src="' . $summaryElement->data->url . '" alt="' . $alt . '" />';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $content;
|
||||
|
||||
}
|
||||
|
||||
private function getEnclosures($post, $postData) {
|
||||
|
||||
$assets = array();
|
||||
foreach($post->links->assets as $asset) {
|
||||
foreach($postData->linked->assets as $assetLink) {
|
||||
if($asset == $assetLink->id) {
|
||||
private 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;
|
||||
}
|
||||
|
@ -108,28 +100,27 @@ class ElloBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
return $assets;
|
||||
|
||||
}
|
||||
|
||||
private function getUsername($post, $postData) {
|
||||
|
||||
foreach($postData->linked->users as $user) {
|
||||
if($user->id == $post->links->author->id) {
|
||||
private function getUsername($post, $postData)
|
||||
{
|
||||
foreach ($postData->linked->users as $user) {
|
||||
if ($user->id == $post->links->author->id) {
|
||||
return $user->username;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function getAPIKey() {
|
||||
private function getAPIKey()
|
||||
{
|
||||
$cacheFac = new CacheFactory();
|
||||
|
||||
$cache = $cacheFac->create(Configuration::getConfig('cache', 'type'));
|
||||
$cache->setScope(get_called_class());
|
||||
$cache->setKey(array('key'));
|
||||
$cache->setKey(['key']);
|
||||
$key = $cache->loadData();
|
||||
|
||||
if($key == null) {
|
||||
if ($key == null) {
|
||||
$keyInfo = getContents(self::URI . 'api/webapp-token') or
|
||||
returnServerError('Unable to get token.');
|
||||
$key = json_decode($keyInfo)->token->access_token;
|
||||
|
@ -137,11 +128,11 @@ class ElloBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
return $key;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
public function getName()
|
||||
{
|
||||
if (!is_null($this->getInput('u'))) {
|
||||
return $this->getInput('u') . ' - Ello Bridge';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
<?php
|
||||
class ElsevierBridge extends BridgeAbstract {
|
||||
|
||||
class ElsevierBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'dvikan';
|
||||
const NAME = 'Elsevier journals recent articles';
|
||||
const URI = 'https://www.journals.elsevier.com/';
|
||||
const CACHE_TIMEOUT = 43200; //12h
|
||||
const DESCRIPTION = 'Returns the recent articles published in Elsevier journals';
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'j' => array(
|
||||
const PARAMETERS = [ [
|
||||
'j' => [
|
||||
'name' => 'Journal name',
|
||||
'required' => true,
|
||||
'exampleValue' => 'academic-pediatrics',
|
||||
'title' => 'Insert html-part of your journal'
|
||||
)
|
||||
));
|
||||
]
|
||||
]];
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
// Not all journals have the /recent-articles page
|
||||
$url = sprintf('https://www.journals.elsevier.com/%s/recent-articles/', $this->getInput('j'));
|
||||
$html = getSimpleHTMLDOM($url);
|
||||
|
||||
foreach($html->find('article') as $recentArticle) {
|
||||
foreach ($html->find('article') as $recentArticle) {
|
||||
$item = [];
|
||||
$item['uri'] = $recentArticle->find('a', 0)->getAttribute('href');
|
||||
$item['title'] = $recentArticle->find('h2', 0)->plaintext;
|
||||
|
@ -35,7 +37,8 @@ class ElsevierBridge extends BridgeAbstract {
|
|||
}
|
||||
}
|
||||
|
||||
public function getIcon(): string {
|
||||
public function getIcon(): string
|
||||
{
|
||||
return 'https://cdn.elsevier.io/verona/includes/favicons/favicon-32x32.png';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
<?php
|
||||
class EngadgetBridge extends FeedExpander {
|
||||
|
||||
class EngadgetBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'IceWreck';
|
||||
const NAME = 'Engadget Bridge';
|
||||
const URI = 'https://www.engadget.com/';
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
const DESCRIPTION = 'Article content for Engadget.';
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
$this->collectExpandableDatas(static::URI . 'rss.xml', 15);
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
$item = parent::parseItem($newsItem);
|
||||
// $articlePage gets the entire page's contents
|
||||
$articlePage = getSimpleHTMLDOM($newsItem->link);
|
||||
// figure contain's the main article image
|
||||
$article = $articlePage->find('figure', 0);
|
||||
// .article-text has the actual article
|
||||
foreach($articlePage->find('.article-text') as $element)
|
||||
foreach ($articlePage->find('.article-text') as $element) {
|
||||
$article = $article . $element;
|
||||
}
|
||||
$item['content'] = $article;
|
||||
return $item;
|
||||
}
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
<?php
|
||||
class EpicgamesBridge extends BridgeAbstract {
|
||||
|
||||
class EpicgamesBridge extends BridgeAbstract
|
||||
{
|
||||
const NAME = 'Epic Games Store News';
|
||||
const MAINTAINER = 'otakuf';
|
||||
const URI = 'https://www.epicgames.com';
|
||||
const DESCRIPTION = 'Returns the latest posts from epicgames.com';
|
||||
const CACHE_TIMEOUT = 3600; // 60min
|
||||
|
||||
const PARAMETERS = array( array(
|
||||
'postcount' => array(
|
||||
const PARAMETERS = [ [
|
||||
'postcount' => [
|
||||
'name' => 'Limit',
|
||||
'type' => 'number',
|
||||
'required' => true,
|
||||
'title' => 'Maximum number of items to return',
|
||||
'defaultValue' => 10,
|
||||
),
|
||||
'language' => array(
|
||||
],
|
||||
'language' => [
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'English' => 'en',
|
||||
'العربية' => 'ar',
|
||||
'Deutsch' => 'de',
|
||||
|
@ -35,13 +36,14 @@ class EpicgamesBridge extends BridgeAbstract {
|
|||
'Türkçe' => 'tr',
|
||||
'简体中文' => 'zh-CN',
|
||||
'繁體中文' => 'zh-Hant',
|
||||
),
|
||||
],
|
||||
'title' => 'Language of blog posts',
|
||||
'defaultValue' => 'en',
|
||||
),
|
||||
));
|
||||
],
|
||||
]];
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$api = 'https://store-content.ak.epicgames.com/api/';
|
||||
|
||||
// Get sticky posts first
|
||||
|
@ -57,19 +59,19 @@ class EpicgamesBridge extends BridgeAbstract {
|
|||
// Merge data
|
||||
$decodedData = array_merge(json_decode($dataSticky), json_decode($dataBlog));
|
||||
|
||||
foreach($decodedData as $key => $value) {
|
||||
$item = array();
|
||||
foreach ($decodedData as $key => $value) {
|
||||
$item = [];
|
||||
$item['uri'] = self::URI . $value->url;
|
||||
$item['title'] = $value->title;
|
||||
$item['timestamp'] = $value->date;
|
||||
$item['author'] = 'Epic Games Store';
|
||||
if(!empty($value->author)) {
|
||||
if (!empty($value->author)) {
|
||||
$item['author'] = $value->author;
|
||||
}
|
||||
if(!empty($value->content)) {
|
||||
if (!empty($value->content)) {
|
||||
$item['content'] = defaultLinkTo($value->content, self::URI);
|
||||
}
|
||||
if(!empty($value->image)) {
|
||||
if (!empty($value->image)) {
|
||||
$item['enclosures'][] = $value->image;
|
||||
}
|
||||
$item['uid'] = $value->_id;
|
||||
|
|
|
@ -1,40 +1,46 @@
|
|||
<?php
|
||||
class EsquerdaNetBridge extends FeedExpander {
|
||||
|
||||
class EsquerdaNetBridge extends FeedExpander
|
||||
{
|
||||
const MAINTAINER = 'somini';
|
||||
const NAME = 'Esquerda.net';
|
||||
const URI = 'https://www.esquerda.net';
|
||||
const DESCRIPTION = 'Esquerda.net';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'feed' => array(
|
||||
const PARAMETERS = [
|
||||
[
|
||||
'feed' => [
|
||||
'name' => 'Feed',
|
||||
'type' => 'list',
|
||||
'defaultValue' => 'Geral',
|
||||
'values' => array(
|
||||
'values' => [
|
||||
'Geral' => 'geral',
|
||||
'Dossier' => 'artigos-dossier',
|
||||
'Vídeo' => 'video',
|
||||
'Opinião' => 'opinioes',
|
||||
'Rádio' => 'radio',
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function getURI() {
|
||||
public function getURI()
|
||||
{
|
||||
$type = $this->getInput('feed');
|
||||
return self::URI . '/rss/' . $type;
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
public function getIcon()
|
||||
{
|
||||
return 'https://www.esquerda.net/sites/default/files/favicon_0.ico';
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
public function collectData()
|
||||
{
|
||||
parent::collectExpandableDatas($this->getURI());
|
||||
}
|
||||
|
||||
protected function parseItem($newsItem){
|
||||
protected function parseItem($newsItem)
|
||||
{
|
||||
# Fix Publish date
|
||||
$badDate = $newsItem->pubDate;
|
||||
preg_match('|(?P<day>\d\d)/(?P<month>\d\d)/(?P<year>\d\d\d\d) - (?P<hour>\d\d):(?P<minute>\d\d)|', $badDate, $d);
|
||||
|
@ -55,7 +61,7 @@ class EsquerdaNetBridge extends FeedExpander {
|
|||
## Fix links
|
||||
$content = defaultLinkTo($content, self::URI);
|
||||
## Fix Images
|
||||
foreach($content->find('img') as $img) {
|
||||
foreach ($content->find('img') as $img) {
|
||||
$altSrc = $img->getAttribute('data-src');
|
||||
if ($altSrc) {
|
||||
$img->setAttribute('src', $altSrc);
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<?php
|
||||
class EstCeQuonMetEnProdBridge extends BridgeAbstract {
|
||||
|
||||
class EstCeQuonMetEnProdBridge extends BridgeAbstract
|
||||
{
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'Est-ce qu\'on met en prod aujourd\'hui ?';
|
||||
const URI = 'https://www.estcequonmetenprodaujourdhui.info/';
|
||||
const CACHE_TIMEOUT = 21600; // 6h
|
||||
const DESCRIPTION = 'Should we put a website in production today? (French)';
|
||||
|
||||
public function collectData() {
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI);
|
||||
|
||||
$item = array();
|
||||
$item = [];
|
||||
$item['uri'] = $this->getURI() . '#' . date('Y-m-d');
|
||||
$item['title'] = $this->getName();
|
||||
$item['author'] = 'Nicolas Hoffmann';
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue