Merge remote-tracking branch 'origin/master' into kt_bridge
This commit is contained in:
commit
aed4f94ba2
133 changed files with 7696 additions and 1026 deletions
35
.github/workflows/lint.yml
vendored
Normal file
35
.github/workflows/lint.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
phpcs:
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpcs
|
||||
- run: phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p
|
||||
|
||||
phpcompatibility:
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['5.6', '7.4']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
- run: composer global require dealerdirect/phpcodesniffer-composer-installer
|
||||
- run: composer global require phpcompatibility/php-compatibility
|
||||
- run: ~/.composer/vendor/bin/phpcs . --standard=phpcompatibility.xml --warning-severity=0 --extensions=php -p
|
47
.github/workflows/tests.yml
vendored
Normal file
47
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
phpunit6:
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.0', '7.1', '7.2']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
- run: composer global require phpunit/phpunit ^6
|
||||
- run: phpunit --configuration=phpunit.xml --include-path=lib/
|
||||
|
||||
phpunit7:
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.1', '7.2', '7.3']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
- run: composer global require phpunit/phpunit ^7
|
||||
- run: phpunit --configuration=phpunit.xml --include-path=lib/
|
||||
|
||||
phpunit8:
|
||||
runs-on: ubuntu-16.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.3', '7.4']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
- run: composer global require phpunit/phpunit ^8
|
||||
- run: phpunit --configuration=phpunit.xml --include-path=lib/
|
46
.travis.yml
46
.travis.yml
|
@ -1,46 +0,0 @@
|
|||
dist: trusty
|
||||
language: php
|
||||
|
||||
install:
|
||||
- composer global require dealerdirect/phpcodesniffer-composer-installer;
|
||||
- composer global require phpcompatibility/php-compatibility;
|
||||
- if [[ "$PHPUNIT" ]]; then
|
||||
composer global require phpunit/phpunit ^$PHPUNIT;
|
||||
fi
|
||||
|
||||
script:
|
||||
- phpenv rehash
|
||||
# Run PHP_CodeSniffer on all versions
|
||||
- ~/.config/composer/vendor/bin/phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p;
|
||||
# Check PHP compatibility for the lowest and highest supported version
|
||||
- if [[ $TRAVIS_PHP_VERSION == "5.6" || $TRAVIS_PHP_VERSION == "7.3" ]]; then
|
||||
~/.config/composer/vendor/bin/phpcs . --standard=phpcompatibility.xml --extensions=php -p;
|
||||
fi
|
||||
# Run unit tests on highest major version
|
||||
- if [[ ${TRAVIS_PHP_VERSION:0:1} == "7" ]]; then
|
||||
~/.config/composer/vendor/bin/phpunit --configuration=phpunit.xml --include-path=lib/;
|
||||
fi
|
||||
|
||||
php:
|
||||
- 7.3
|
||||
|
||||
env:
|
||||
- PHPUNIT=6
|
||||
- PHPUNIT=7
|
||||
- PHPUNIT=8
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
include:
|
||||
- php: 5.6
|
||||
env: PHPUNIT=
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
- php: 7.2
|
||||
|
||||
allow_failures:
|
||||
- php: 7.3
|
||||
env: PHPUNIT=7
|
||||
- php: 7.3
|
||||
env: PHPUNIT=8
|
|
@ -3,8 +3,13 @@ FROM php:7-apache
|
|||
ENV APACHE_DOCUMENT_ROOT=/app
|
||||
|
||||
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
|
||||
&& apt-get --yes update && apt-get --yes install libxml2-dev \
|
||||
&& docker-php-ext-install -j$(nproc) simplexml \
|
||||
&& apt-get --yes update \
|
||||
&& apt-get --yes --no-install-recommends install \
|
||||
zlib1g-dev \
|
||||
libmemcached-dev \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& pecl install memcached \
|
||||
&& docker-php-ext-enable memcached \
|
||||
&& sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
|
||||
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \
|
||||
&& sed -ri -e 's/(MinProtocol\s*=\s*)TLSv1\.2/\1None/' /etc/ssl/openssl.cnf \
|
||||
|
|
36
README.md
36
README.md
|
@ -65,6 +65,7 @@ RSS-Bridge requires PHP 5.6 or higher with following extensions enabled:
|
|||
- [`simplexml`](https://secure.php.net/manual/en/book.simplexml.php)
|
||||
- [`curl`](https://secure.php.net/manual/en/book.curl.php)
|
||||
- [`json`](https://secure.php.net/manual/en/book.json.php)
|
||||
- [`filter`](https://secure.php.net/manual/en/book.filter.php)
|
||||
- [`sqlite3`](http://php.net/manual/en/book.sqlite3.php) (only when using SQLiteCache)
|
||||
|
||||
Find more information on our [Wiki](https://github.com/rss-bridge/rss-bridge/wiki)
|
||||
|
@ -119,19 +120,24 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [alexAubin](https://github.com/alexAubin)
|
||||
* [AmauryCarrade](https://github.com/AmauryCarrade)
|
||||
* [AntoineTurmel](https://github.com/AntoineTurmel)
|
||||
* [arnd-s](https://github.com/arnd-s)
|
||||
* [ArthurHoaro](https://github.com/ArthurHoaro)
|
||||
* [Astalaseven](https://github.com/Astalaseven)
|
||||
* [Astyan-42](https://github.com/Astyan-42)
|
||||
* [AxorPL](https://github.com/AxorPL)
|
||||
* [ayacoo](https://github.com/ayacoo)
|
||||
* [az5he6ch](https://github.com/az5he6ch)
|
||||
* [azdkj532](https://github.com/azdkj532)
|
||||
* [b1nj](https://github.com/b1nj)
|
||||
* [benasse](https://github.com/benasse)
|
||||
* [Binnette](https://github.com/Binnette)
|
||||
* [captn3m0](https://github.com/captn3m0)
|
||||
* [chemel](https://github.com/chemel)
|
||||
* [ckiw](https://github.com/ckiw)
|
||||
* [cnlpete](https://github.com/cnlpete)
|
||||
* [corenting](https://github.com/corenting)
|
||||
* [couraudt](https://github.com/couraudt)
|
||||
* [csisoap](https://github.com/csisoap)
|
||||
* [cyberjacob](https://github.com/cyberjacob)
|
||||
* [da2x](https://github.com/da2x)
|
||||
* [Daiyousei](https://github.com/Daiyousei)
|
||||
|
@ -146,27 +152,36 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [em92](https://github.com/em92)
|
||||
* [eMerzh](https://github.com/eMerzh)
|
||||
* [EtienneM](https://github.com/EtienneM)
|
||||
* [fanch317](https://github.com/fanch317)
|
||||
* [floviolleau](https://github.com/floviolleau)
|
||||
* [fluffy-critter](https://github.com/fluffy-critter)
|
||||
* [Frenzie](https://github.com/Frenzie)
|
||||
* [fulmeek](https://github.com/fulmeek)
|
||||
* [ggiessen](https://github.com/ggiessen)
|
||||
* [Ginko-Aloe](https://github.com/Ginko-Aloe)
|
||||
* [Glandos](https://github.com/Glandos)
|
||||
* [gloony](https://github.com/gloony)
|
||||
* [GregThib](https://github.com/GregThib)
|
||||
* [griffaurel](https://github.com/griffaurel)
|
||||
* [Grummfy](https://github.com/Grummfy)
|
||||
* [gsantner](https://github.com/gsantner)
|
||||
* [hunhejj](https://github.com/hunhejj)
|
||||
* [husim0](https://github.com/husim0)
|
||||
* [IceWreck](https://github.com/IceWreck)
|
||||
* [j0k3r](https://github.com/j0k3r)
|
||||
* [JackNUMBER](https://github.com/JackNUMBER)
|
||||
* [jannyba](https://github.com/jannyba)
|
||||
* [JasonGhent](https://github.com/JasonGhent)
|
||||
* [jdesgats](https://github.com/jdesgats)
|
||||
* [jdigilio](https://github.com/jdigilio)
|
||||
* [JeremyRand](https://github.com/JeremyRand)
|
||||
* [Jocker666z](https://github.com/Jocker666z)
|
||||
* [johnnygroovy](https://github.com/johnnygroovy)
|
||||
* [killruana](https://github.com/killruana)
|
||||
* [johnpc](https://github.com/johnpc)
|
||||
* [joni1993](https://github.com/joni1993)
|
||||
* [joshcoales](https://github.com/joshcoales)
|
||||
* [klimplant](https://github.com/klimplant)
|
||||
* [kolarcz](https://github.com/kolarcz)
|
||||
* [kranack](https://github.com/kranack)
|
||||
* [kraoc](https://github.com/kraoc)
|
||||
* [l1n](https://github.com/l1n)
|
||||
|
@ -175,6 +190,7 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [lalannev](https://github.com/lalannev)
|
||||
* [ldidry](https://github.com/ldidry)
|
||||
* [Leomaradan](https://github.com/Leomaradan)
|
||||
* [liamka](https://github.com/liamka)
|
||||
* [Limero](https://github.com/Limero)
|
||||
* [LogMANOriginal](https://github.com/LogMANOriginal)
|
||||
* [lorenzos](https://github.com/lorenzos)
|
||||
|
@ -185,18 +201,25 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [mdemoss](https://github.com/mdemoss)
|
||||
* [melangue](https://github.com/melangue)
|
||||
* [metaMMA](https://github.com/metaMMA)
|
||||
* [mibe](https://github.com/mibe)
|
||||
* [mightymt](https://github.com/mightymt)
|
||||
* [mitsukarenai](https://github.com/mitsukarenai)
|
||||
* [MonsieurPoutounours](https://github.com/MonsieurPoutounours)
|
||||
* [mr-flibble](https://github.com/mr-flibble)
|
||||
* [mro](https://github.com/mro)
|
||||
* [mschwld](https://github.com/mschwld)
|
||||
* [mxmehl](https://github.com/mxmehl)
|
||||
* [nel50n](https://github.com/nel50n)
|
||||
* [niawag](https://github.com/niawag)
|
||||
* [Niehztog](https://github.com/Niehztog)
|
||||
* [Nono-m0le](https://github.com/Nono-m0le)
|
||||
* [ObsidianWitch](https://github.com/ObsidianWitch)
|
||||
* [OliverParoczai](https://github.com/OliverParoczai)
|
||||
* [oratosquilla-oratoria](https://github.com/oratosquilla-oratoria)
|
||||
* [Ololbu](https://github.com/Ololbu)
|
||||
* [ORelio](https://github.com/ORelio)
|
||||
* [otakuf](https://github.com/otakuf)
|
||||
* [Park0](https://github.com/Park0)
|
||||
* [Paroleen](https://github.com/Paroleen)
|
||||
* [PaulVayssiere](https://github.com/PaulVayssiere)
|
||||
* [pellaeon](https://github.com/pellaeon)
|
||||
* [Piranhaplant](https://github.com/Piranhaplant)
|
||||
|
@ -206,24 +229,31 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [Pofilo](https://github.com/Pofilo)
|
||||
* [prysme01](https://github.com/prysme01)
|
||||
* [quentinus95](https://github.com/quentinus95)
|
||||
* [RawkBob](https://github.com/RawkBob)
|
||||
* [regisenguehard](https://github.com/regisenguehard)
|
||||
* [Riduidel](https://github.com/Riduidel)
|
||||
* [rogerdc](https://github.com/rogerdc)
|
||||
* [Roliga](https://github.com/Roliga)
|
||||
* [ronansalmon](https://github.com/ronansalmon)
|
||||
* [rremizov](https://github.com/rremizov)
|
||||
* [sebsauvage](https://github.com/sebsauvage)
|
||||
* [shutosg](https://github.com/shutosg)
|
||||
* [Simounet](https://github.com/Simounet)
|
||||
* [somini](https://github.com/somini)
|
||||
* [squeek502](https://github.com/squeek502)
|
||||
* [stjohnjohnson](https://github.com/stjohnjohnson)
|
||||
* [Strubbl](https://github.com/Strubbl)
|
||||
* [sublimz](https://github.com/sublimz)
|
||||
* [sunchaserinfo](https://github.com/sunchaserinfo)
|
||||
* [SuperSandro2000](https://github.com/SuperSandro2000)
|
||||
* [sysadminstory](https://github.com/sysadminstory)
|
||||
* [tameroski](https://github.com/tameroski)
|
||||
* [teromene](https://github.com/teromene)
|
||||
* [tgkenney](https://github.com/tgkenney)
|
||||
* [thefranke](https://github.com/thefranke)
|
||||
* [ThePadawan](https://github.com/ThePadawan)
|
||||
* [TheRadialActive](https://github.com/TheRadialActive)
|
||||
* [theScrabi](https://github.com/theScrabi)
|
||||
* [TitiTestScalingo](https://github.com/TitiTestScalingo)
|
||||
* [triatic](https://github.com/triatic)
|
||||
* [VerifiedJoseph](https://github.com/VerifiedJoseph)
|
||||
|
@ -231,6 +261,7 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
|
|||
* [wtuuju](https://github.com/wtuuju)
|
||||
* [xurxof](https://github.com/xurxof)
|
||||
* [yardenac](https://github.com/yardenac)
|
||||
* [ymeister](https://github.com/ymeister)
|
||||
* [ZeNairolf](https://github.com/ZeNairolf)
|
||||
|
||||
Licenses
|
||||
|
@ -240,6 +271,7 @@ The source code for RSS-Bridge is [Public Domain](UNLICENSE).
|
|||
|
||||
RSS-Bridge uses third party libraries with their own license:
|
||||
|
||||
* [`Parsedown`](https://github.com/erusev/parsedown) licensed under the [MIT License](http://opensource.org/licenses/MIT)
|
||||
* [`PHP Simple HTML DOM Parser`](http://simplehtmldom.sourceforge.net/) licensed under the [MIT License](http://opensource.org/licenses/MIT)
|
||||
* [`php-urljoin`](https://github.com/fluffy-critter/php-urljoin) licensed under the [MIT License](http://opensource.org/licenses/MIT)
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ class DisplayAction extends ActionAbstract {
|
|||
|
||||
try {
|
||||
$bridge->setDatas($bridge_params);
|
||||
$bridge->loadConfiguration();
|
||||
$bridge->collectData();
|
||||
|
||||
$items = $bridge->getItems();
|
||||
|
|
57
bridges/ASRockNewsBridge.php
Normal file
57
bridges/ASRockNewsBridge.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
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 CACHE_TIMEOUT = 3600; // 1 hour
|
||||
|
||||
public function collectData() {
|
||||
|
||||
$html = getSimpleHTMLDOM(self::URI . '/news/index.asp')
|
||||
or returnServerError('Could not request: ' . self::URI . '/news/index.asp');
|
||||
|
||||
$html = defaultLinkTo($html, self::URI . '/news/');
|
||||
|
||||
foreach($html->find('div.inner > a') as $index => $a) {
|
||||
$item = array();
|
||||
|
||||
$articlePath = $a->href;
|
||||
|
||||
$articlePageHtml = getSimpleHTMLDOMCached($articlePath, self::CACHE_TIMEOUT)
|
||||
or returnServerError('Could not request: ' . $articlePath);
|
||||
|
||||
$articlePageHtml = defaultLinkTo($articlePageHtml, self::URI);
|
||||
|
||||
$contents = $articlePageHtml->find('div.Contents', 0);
|
||||
|
||||
$item['uri'] = $articlePath;
|
||||
$item['title'] = $contents->find('h5', 0)->innertext;
|
||||
|
||||
$contents->find('h5', 0)->outertext = '';
|
||||
|
||||
$item['content'] = $contents->innertext;
|
||||
$item['timestamp'] = $this->extractDate($a->plaintext);
|
||||
$item['enclosures'][] = $a->find('img', 0)->src;
|
||||
$this->items[] = $item;
|
||||
|
||||
if (count($this->items) >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function extractDate($text) {
|
||||
$dateRegex = '/^([0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2})/';
|
||||
|
||||
$text = trim($text);
|
||||
|
||||
if (preg_match($dateRegex, $text, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
54
bridges/AirBreizhBridge.php
Normal file
54
bridges/AirBreizhBridge.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
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(
|
||||
'name' => 'Thematique',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Tout' => '',
|
||||
'Rapport d\'activite' => 'rapport-dactivite',
|
||||
'Etude' => 'etudes',
|
||||
'Information' => 'information',
|
||||
'Autres documents' => 'autres-documents',
|
||||
'Plan Régional de Surveillance de la qualité de l’air' => 'prsqa',
|
||||
'Transport' => 'transport'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function getIcon() {
|
||||
return 'https://www.airbreizh.asso.fr/voy_content/uploads/2017/11/favicon.png';
|
||||
}
|
||||
|
||||
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();
|
||||
// Title
|
||||
$item['title'] = $article->find('h2', 0)->plaintext;
|
||||
// Author
|
||||
$item['author'] = 'Air Breizh';
|
||||
// Image
|
||||
$imagelink = $article->find('.card__image', 0)->find('img', 0)->getAttribute('src');
|
||||
// Content preview
|
||||
$item['content'] = '<img src="' . $imagelink . '" />
|
||||
<br/>'
|
||||
. $article->find('.card__text', 0)->plaintext;
|
||||
// URL
|
||||
$item['uri'] = $article->find('.publi__buttons', 0)->find('a', 0)->getAttribute('href');
|
||||
// ID
|
||||
$item['id'] = $article->find('.publi__buttons', 0)->find('a', 0)->getAttribute('href');
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
74
bridges/AlbionOnlineBridge.php
Normal file
74
bridges/AlbionOnlineBridge.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
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(
|
||||
'name' => 'Limit',
|
||||
'type' => 'number',
|
||||
'title' => 'Maximum number of items to return',
|
||||
'defaultValue' => 5,
|
||||
),
|
||||
'language' => array(
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'English' => 'en',
|
||||
'Deutsch' => 'de',
|
||||
'Polski' => 'pl',
|
||||
'Français' => 'fr',
|
||||
'Русский' => 'ru',
|
||||
'Português' => 'pt',
|
||||
'Español' => 'es',
|
||||
),
|
||||
'title' => 'Language of changelog posts',
|
||||
'defaultValue' => 'en',
|
||||
),
|
||||
'full' => array(
|
||||
'name' => 'Full changelog',
|
||||
'type' => 'checkbox',
|
||||
'required' => false,
|
||||
'title' => 'Enable to receive the full changelog post for each item'
|
||||
),
|
||||
));
|
||||
|
||||
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');
|
||||
|
||||
$html = getSimpleHTMLDOM($url)
|
||||
or returnServerError('Unable to get changelog data from "' . $url . '"!');
|
||||
|
||||
foreach ($html->find('li') as $data) {
|
||||
$item = array();
|
||||
$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')) {
|
||||
$item['content'] = $this->getFullChangelog($item['uri']);
|
||||
} else {
|
||||
//$item['content'] = trim(preg_replace('/\s+/', ' ', $data->find('span', 0)->plaintext));
|
||||
// Just use title, no info at all or use title and date, see above
|
||||
$item['content'] = $item['title'];
|
||||
}
|
||||
$item['uid'] = hash('sha256', $item['title']);
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
private function getFullChangelog($url) {
|
||||
$html = getSimpleHTMLDOMCached($url)
|
||||
or returnServerError('Unable to load changelog post from "' . $url . '"!');
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
return $html->find('div.small-12.columns', 1)->innertext;
|
||||
}
|
||||
}
|
|
@ -8,14 +8,25 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
const DESCRIPTION = 'Bridge for allocine.fr';
|
||||
const PARAMETERS = array( array(
|
||||
'category' => array(
|
||||
'name' => 'category',
|
||||
'name' => 'Emission',
|
||||
'type' => 'list',
|
||||
'exampleValue' => 'Faux Raccord',
|
||||
'title' => 'Select your category',
|
||||
'title' => 'Sélectionner l\'emission',
|
||||
'values' => array(
|
||||
'Faux Raccord' => 'faux-raccord',
|
||||
'Top 5' => 'top-5',
|
||||
'Tueurs en Séries' => 'tueurs-en-serie'
|
||||
'Fanzone' => 'fanzone',
|
||||
'Game In Ciné' => 'game-in-cine',
|
||||
'Pour la faire courte' => 'pour-la-faire-courte',
|
||||
'Home Cinéma' => 'home-cinema',
|
||||
'PILS - Par Ici Les Sorties' => 'pils-par-ici-les-sorties',
|
||||
'AlloCiné : l\'émission, sur LeStream' => 'allocine-lemission-sur-lestream',
|
||||
'Give Me Five' => 'give-me-five',
|
||||
'Aviez-vous remarqué ?' => 'aviez-vous-remarque',
|
||||
'Et paf, il est mort' => 'et-paf-il-est-mort',
|
||||
'The Big Fan Theory' => 'the-big-fan-theory',
|
||||
'Clichés' => 'cliches',
|
||||
'Complètement...' => 'completement',
|
||||
'#Fun Facts' => 'fun-facts',
|
||||
'Origin Story' => 'origin-story',
|
||||
)
|
||||
)
|
||||
));
|
||||
|
@ -23,19 +34,30 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
public function getURI(){
|
||||
if(!is_null($this->getInput('category'))) {
|
||||
|
||||
switch($this->getInput('category')) {
|
||||
case 'faux-raccord':
|
||||
$uri = static::URI . 'video/programme-12284/saison-32180/';
|
||||
break;
|
||||
case 'top-5':
|
||||
$uri = static::URI . 'video/programme-12299/saison-29561/';
|
||||
break;
|
||||
case 'tueurs-en-serie':
|
||||
$uri = static::URI . 'video/programme-12286/saison-22938/';
|
||||
break;
|
||||
}
|
||||
$categories = array(
|
||||
'faux-raccord' => 'video/programme-12284/saison-37054/',
|
||||
'fanzone' => 'video/programme-12298/saison-37059/',
|
||||
'game-in-cine' => 'video/programme-12288/saison-22971/',
|
||||
'pour-la-faire-courte' => 'video/programme-20960/saison-29678/',
|
||||
'home-cinema' => 'video/programme-12287/saison-34703/',
|
||||
'pils-par-ici-les-sorties' => 'video/programme-25789/saison-37253/',
|
||||
'allocine-lemission-sur-lestream' => 'video/programme-25123/saison-36067/',
|
||||
'give-me-five' => 'video/programme-21919/saison-34518/',
|
||||
'aviez-vous-remarque' => 'video/programme-19518/saison-37084/',
|
||||
'et-paf-il-est-mort' => 'video/programme-25113/saison-36657/',
|
||||
'the-big-fan-theory' => 'video/programme-20403/saison-37419/',
|
||||
'cliches' => 'video/programme-24834/saison-35591/',
|
||||
'completement' => 'video/programme-23859/saison-34102/',
|
||||
'fun-facts' => 'video/programme-23040/saison-32686/',
|
||||
'origin-story' => 'video/programme-25667/saison-37041/'
|
||||
);
|
||||
|
||||
return $uri;
|
||||
$category = $this->getInput('category');
|
||||
if(array_key_exists($category, $categories)) {
|
||||
return static::URI . $categories[$category];
|
||||
} else {
|
||||
returnClientError('Emission inconnue');
|
||||
}
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
|
@ -63,23 +85,23 @@ class AllocineFRBridge extends BridgeAbstract {
|
|||
self::PARAMETERS[$this->queriedContext]['category']['values']
|
||||
);
|
||||
|
||||
foreach($html->find('.media-meta-list figure.media-meta-fig') as $element) {
|
||||
foreach($html->find('div[class=gd-col-left]', 0)->find('div[class*=video-card]') as $element) {
|
||||
$item = array();
|
||||
|
||||
$title = $element->find('div.titlebar h3.title a', 0);
|
||||
$content = trim($element->innertext);
|
||||
$figCaption = strpos($content, $category);
|
||||
$title = $element->find('a[class*=meta-title-link]', 0);
|
||||
$content = trim($element->outertext);
|
||||
|
||||
if($figCaption !== false) {
|
||||
$content = str_replace('src="/', 'src="' . static::URI, $content);
|
||||
$content = str_replace('href="/', 'href="' . static::URI, $content);
|
||||
$content = str_replace('src=\'/', 'src=\'' . static::URI, $content);
|
||||
$content = str_replace('href=\'/', 'href=\'' . static::URI, $content);
|
||||
$item['content'] = $content;
|
||||
$item['title'] = trim($title->innertext);
|
||||
$item['uri'] = static::URI . $title->href;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
// Replace image 'src' with the one in 'data-src'
|
||||
$content = preg_replace('@src="data:image/gif;base64,[A-Za-z0-9+\/]*"@', '', $content);
|
||||
$content = preg_replace('@data-src=@', 'src=', $content);
|
||||
|
||||
// Remove date in the content to prevent content update while the video is getting older
|
||||
$content = preg_replace('@<div class="meta-sub light">.*<span>[^<]*</span>[^<]*</div>@', '', $content);
|
||||
|
||||
$item['content'] = $content;
|
||||
$item['title'] = trim($title->innertext);
|
||||
$item['uri'] = static::URI . substr($title->href, 1);
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ class AmazonPriceTrackerBridge extends BridgeAbstract {
|
|||
'Mexico' => 'com.mx',
|
||||
'Netherlands' => 'nl',
|
||||
'Spain' => 'es',
|
||||
'Sweden' => 'se',
|
||||
'United Kingdom' => 'co.uk',
|
||||
'United States' => 'com',
|
||||
),
|
||||
|
|
|
@ -3,7 +3,9 @@ class AnidexBridge extends BridgeAbstract {
|
|||
|
||||
const MAINTAINER = 'ORelio';
|
||||
const NAME = 'Anidex';
|
||||
const URI = 'https://anidex.info/';
|
||||
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(
|
||||
|
@ -108,7 +110,7 @@ class AnidexBridge extends BridgeAbstract {
|
|||
public function collectData() {
|
||||
|
||||
// Build Search URL from user-provided parameters
|
||||
$search_url = self::URI . '?s=upload_timestamp&o=desc';
|
||||
$search_url = self::ALTERNATE_URI . '?s=upload_timestamp&o=desc';
|
||||
foreach (array('id', 'lang_id', 'group_id') as $param_name) {
|
||||
$param = $this->getInput($param_name);
|
||||
if (!empty($param) && intval($param) != 0 && ctype_digit(str_replace(',', '', $param))) {
|
||||
|
@ -131,8 +133,16 @@ class AnidexBridge extends BridgeAbstract {
|
|||
$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);
|
||||
|
||||
// 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://
|
||||
$opt[CURLOPT_SSL_VERIFYHOST] = 0;
|
||||
$opt[CURLOPT_SSL_VERIFYPEER] = 0;
|
||||
|
||||
// Retrieve torrent listing from search results, which does not contain torrent description
|
||||
$html = getSimpleHTMLDOM($search_url, array(), $opt)
|
||||
$html = getSimpleHTMLDOM($search_url, $headers, $opt)
|
||||
or returnServerError('Could not request Anidex: ' . $search_url);
|
||||
$links = $html->find('a');
|
||||
$results = array();
|
||||
|
@ -156,10 +166,11 @@ class AnidexBridge extends BridgeAbstract {
|
|||
if ($torrent_id != 0 && ctype_digit($torrent_id)) {
|
||||
|
||||
//Retrieve data for this torrent ID
|
||||
$item_uri = self::URI . 'torrent/' . $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
|
||||
if ($item_html = getSimpleHTMLDOMCached($item_uri)) {
|
||||
//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);
|
||||
|
@ -191,7 +202,7 @@ class AnidexBridge extends BridgeAbstract {
|
|||
|
||||
//Build and add final item
|
||||
$item = array();
|
||||
$item['uri'] = $item_uri;
|
||||
$item['uri'] = $item_browse_uri;
|
||||
$item['title'] = $item_title;
|
||||
$item['author'] = $item_author;
|
||||
$item['timestamp'] = $item_date;
|
||||
|
|
|
@ -102,7 +102,6 @@ class AnimeUltimeBridge extends BridgeAbstract {
|
|||
$item_description = defaultLinkTo($item_description, self::URI);
|
||||
$item_description = str_replace("\r", '', $item_description);
|
||||
$item_description = str_replace("\n", '', $item_description);
|
||||
$item_description = utf8_encode($item_description);
|
||||
|
||||
//Build and add final item
|
||||
$item = array();
|
||||
|
|
|
@ -20,6 +20,8 @@ class AppleMusicBridge extends BridgeAbstract {
|
|||
));
|
||||
const CACHE_TIMEOUT = 21600; // 6 hours
|
||||
|
||||
private $title;
|
||||
|
||||
public function collectData() {
|
||||
$url = $this->getInput('url');
|
||||
$html = getSimpleHTMLDOM($url)
|
||||
|
@ -27,6 +29,8 @@ class AppleMusicBridge extends BridgeAbstract {
|
|||
|
||||
$imgSize = $this->getInput('imgSize');
|
||||
|
||||
$this->title = $html->find('title', 0)->innertext;
|
||||
|
||||
// Grab the json data from the page
|
||||
$html = $html->find('script[id=shoebox-ember-data-store]', 0);
|
||||
$html = strstr($html, '{');
|
||||
|
@ -59,4 +63,8 @@ class AppleMusicBridge extends BridgeAbstract {
|
|||
return $a['timestamp'] < $b['timestamp'];
|
||||
});
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return $this->title ?: parent::getName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
class Arte7Bridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = 'mitsukarenai';
|
||||
// const MAINTAINER = 'mitsukarenai';
|
||||
const NAME = 'Arte +7';
|
||||
const URI = 'https://www.arte.tv/';
|
||||
const CACHE_TIMEOUT = 1800; // 30min
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
||||
|
||||
const NAME = 'Atmo Nouvelle Aquitaine';
|
||||
const URI = 'https://www.atmo-nouvelleaquitaine.org/monair/commune/';
|
||||
const DESCRIPTION = 'Fetches the latest air polution of Bordeaux from 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(
|
||||
|
@ -27,7 +27,7 @@ class AtmoNouvelleAquitaineBridge extends BridgeAbstract {
|
|||
}
|
||||
|
||||
public function collectData() {
|
||||
$uri = self::URI . $this->getInput('cities');
|
||||
$uri = self::URI . '/monair/commune/' . $this->getInput('cities');
|
||||
|
||||
$html = getSimpleHTMLDOM($uri)
|
||||
or returnServerError('Could not request ' . $uri);
|
||||
|
|
58
bridges/AtmoOccitanieBridge.php
Normal file
58
bridges/AtmoOccitanieBridge.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
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(
|
||||
'name' => 'Ville',
|
||||
'required' => true
|
||||
)
|
||||
));
|
||||
const CACHE_TIMEOUT = 7200;
|
||||
|
||||
public function collectData() {
|
||||
$uri = self::URI . $this->getInput('city');
|
||||
|
||||
$html = getSimpleHTMLDOM($uri)
|
||||
or returnServerError('Could not request ' . $uri);
|
||||
|
||||
$generalMessage = $html->find('.landing-ville .city-banner .iqa-avertissement', 0)->innertext;
|
||||
$recommendationsDom = $html->find('.landing-ville .recommandations', 0);
|
||||
$recommendationsItemDom = $recommendationsDom->find('.recommandation-item .label');
|
||||
|
||||
$recommendationsMessage = '';
|
||||
|
||||
$i = 0;
|
||||
$len = count($recommendationsItemDom);
|
||||
foreach ($recommendationsItemDom as $key => $value) {
|
||||
if ($i == 0) {
|
||||
$recommendationsMessage .= trim($value->innertext) . '.';
|
||||
} else {
|
||||
$recommendationsMessage .= ' ' . trim($value->innertext) . '.';
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
$lastRecommendationsDom = $recommendationsDom->find('.col-md-6', -1);
|
||||
$informationHeaderMessage = $lastRecommendationsDom->find('.heading', 0)->innertext;
|
||||
$indice = $lastRecommendationsDom->find('.current-indice .indice div', 0)->innertext;
|
||||
$informationDescriptionMessage = $lastRecommendationsDom->find('.current-indice .description p', 0)->innertext;
|
||||
|
||||
$message = "$generalMessage L'indice est de $indice/10. $informationDescriptionMessage. $recommendationsMessage";
|
||||
$city = $this->getInput('city');
|
||||
|
||||
$item['uri'] = $uri;
|
||||
$today = date('d/m/Y');
|
||||
$item['title'] = "Bulletin de l'air du $today pour la ville : $city.";
|
||||
//$item['title'] .= ' Retrouvez plus d\'informations en allant sur atmo-occitanie.org #QualiteAir. ' . $message;
|
||||
$item['title'] .= ' #QualiteAir. ' . $message;
|
||||
$item['author'] = 'floviolleau';
|
||||
$item['content'] = $message;
|
||||
$item['uid'] = hash('sha256', $item['title']);
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
|
@ -77,110 +77,69 @@ class AutoJMBridge extends BridgeAbstract {
|
|||
|
||||
$model_url = self::URI . $this->getInput('url');
|
||||
|
||||
// Get the session cookies and the form token
|
||||
$this->getInitialParameters($model_url);
|
||||
// Build the GET data
|
||||
$get_data = 'form[energy]=' . $this->getInput('energy') .
|
||||
'&form[transmission]=' . $this->getInput('transmission') .
|
||||
'&form[priceMin]=' . $this->getInput('priceMin') .
|
||||
'&form[priceMin]=' . $this->getInput('priceMin');
|
||||
|
||||
// Build the form
|
||||
$post_data = array(
|
||||
'form[energy]' => $this->getInput('energy'),
|
||||
'form[transmission]' => $this->getInput('transmission'),
|
||||
'form[priceMin]' => $this->getInput('priceMin'),
|
||||
'form[priceMin]' => $this->getInput('priceMin'),
|
||||
'form[_token]' => $this->token
|
||||
);
|
||||
|
||||
// Set the Form request content type
|
||||
// Set the header 'X-Requested-With' like the website does it
|
||||
$header = array(
|
||||
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
|
||||
);
|
||||
|
||||
// Set the curl options (POST query and content, and session cookies
|
||||
$curl_opts = array(
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => http_build_query($post_data),
|
||||
CURLOPT_COOKIE => $this->cookies
|
||||
'X-Requested-With: XMLHttpRequest'
|
||||
);
|
||||
|
||||
// Get the JSON content of the form
|
||||
$json = getContents($model_url, $header, $curl_opts)
|
||||
$json = getContents($model_url . '?' . $get_data, $header)
|
||||
or returnServerError('Could not request AutoJM.');
|
||||
|
||||
// Extract the HTML content from the JSON result
|
||||
$data = json_decode($json);
|
||||
$html = str_get_html($data->content);
|
||||
$html = str_get_html($data->results);
|
||||
|
||||
// Go through every finisha of the model
|
||||
$list = $html->find('h3');
|
||||
foreach ($list as $finish) {
|
||||
$finish_name = $finish->plaintext;
|
||||
$motorizations = $finish->next_sibling()->find('li');
|
||||
foreach ($motorizations as $element) {
|
||||
$image = $element->find('div[class=block-product-image]', 0)->{'data-ga-banner'};
|
||||
$serie = $element->find('span[class=model]', 0)->plaintext;
|
||||
$url = self::URI . substr($element->find('a', 0)->href, 1);
|
||||
if ($element->find('span[class*=block-product-nbModel]', 0) != null) {
|
||||
$availability = 'En Stock';
|
||||
} else {
|
||||
$availability = 'Sur commande';
|
||||
}
|
||||
$discount_html = $element->find('span[class*=tag--promo]', 0);
|
||||
if ($discount_html != null) {
|
||||
$discount = $discount_html->plaintext;
|
||||
} else {
|
||||
$discount = 'inconnue';
|
||||
}
|
||||
$price = $element->find('span[class=price red h1]', 0)->plaintext;
|
||||
$item = array();
|
||||
$item['title'] = $finish_name . ' ' . $serie;
|
||||
$item['content'] = '<p><img style="vertical-align:middle ; padding: 10px" src="' . $image . '" />'
|
||||
. $finish_name . ' ' . $serie . '</p>';
|
||||
$item['content'] .= '<ul><li>Disponibilité : ' . $availability . '</li>';
|
||||
$item['content'] .= '<li>Série : ' . $serie . '</li>';
|
||||
$item['content'] .= '<li>Remise : ' . $discount . '</li>';
|
||||
$item['content'] .= '<li>Prix : ' . $price . '</li></ul>';
|
||||
// Go through every car of the model
|
||||
$list = $html->find('div[class=car-card]');
|
||||
foreach ($list as $car) {
|
||||
|
||||
// Add a fictionnal anchor to the RSS element URL, based on the item content ;
|
||||
// As the URL could be identical even if the price change, some RSS reader will not show those offers as new items
|
||||
$item['uri'] = $url . '#' . md5($item['content']);
|
||||
|
||||
$this->items[] = $item;
|
||||
// Get the Finish name if this car is the first of a new finish
|
||||
$prev_tag = $car->prev_sibling();
|
||||
if($prev_tag->tag == 'div' && $prev_tag->class == 'results-title') {
|
||||
$finish_name = $prev_tag->plaintext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the session cookie and the form token
|
||||
*
|
||||
* @param string $pageURL The URL from which to get the values
|
||||
*/
|
||||
private function getInitialParameters($pageURL) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $pageURL);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$data = curl_exec($ch);
|
||||
|
||||
// Separate the response header and the content
|
||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$header = substr($data, 0, $headerSize);
|
||||
$content = substr($data, $headerSize);
|
||||
curl_close($ch);
|
||||
|
||||
// Extract the cookies from the headers
|
||||
$cookies = '';
|
||||
$http_response_header = explode("\r\n", $header);
|
||||
foreach ($http_response_header as $hdr) {
|
||||
if (strpos($hdr, 'Set-Cookie') !== false) {
|
||||
$cLine = explode(':', $hdr)[1];
|
||||
$cLine = explode(';', $cLine)[0];
|
||||
$cookies .= ';' . $cLine;
|
||||
// Get the info about the car offer
|
||||
$image = $car->find('div[class=car-card__visual]', 0)->find('img', 0)->src;
|
||||
$serie = $car->find('div[class=car-card__title]', 0)->plaintext;
|
||||
$url = $car->find('a', 0)->href;
|
||||
// Check if the car model is in stock or available only on order
|
||||
if($car->find('span[class*=tag--dispo]', 0) != null) {
|
||||
$availability = 'En Stock';
|
||||
} else {
|
||||
$availability = 'Sur commande';
|
||||
}
|
||||
}
|
||||
$this->cookies = trim(substr($cookies, 1));
|
||||
$discount_html = $car->find('span[class=promo]', 0);
|
||||
// Check if there is any discount dsiplayed
|
||||
if ($discount_html != null) {
|
||||
$discount = $discount_html->plaintext;
|
||||
} else {
|
||||
$discount = 'inconnue';
|
||||
}
|
||||
$price = $car->find('span[class=price]', 0)->plaintext;
|
||||
|
||||
// Get the token from the content
|
||||
$html = str_get_html($content);
|
||||
$token = $html->find('input[type=hidden][id=form__token]', 0);
|
||||
$this->token = $token->value;
|
||||
// Construct the new item
|
||||
$item = array();
|
||||
$item['title'] = $finish_name . ' ' . $serie;
|
||||
$item['content'] = '<p><img style="vertical-align:middle ; padding: 10px" src="' . $image . '" />'
|
||||
. $finish_name . ' ' . $serie . '</p>';
|
||||
$item['content'] .= '<ul><li>Disponibilité : ' . $availability . '</li>';
|
||||
$item['content'] .= '<li>Série : ' . $serie . '</li>';
|
||||
$item['content'] .= '<li>Remise : ' . $discount . '</li>';
|
||||
$item['content'] .= '<li>Prix : ' . $price . '</li></ul>';
|
||||
|
||||
// Add a fictionnal anchor to the RSS element URL, based on the item content ;
|
||||
// As the URL could be identical even if the price change, some RSS reader will not show those offers as new items
|
||||
$item['uri'] = $url . '#' . md5($item['content']);
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
55
bridges/AwwwardsBridge.php
Normal file
55
bridges/AwwwardsBridge.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
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';
|
||||
const MAINTAINER = 'Paroleen';
|
||||
const CACHE_TIMEOUT = 3600;
|
||||
|
||||
const SITESURI = 'https://www.awwwards.com/websites/sites_of_the_day/';
|
||||
const SITEURI = 'https://www.awwwards.com/sites/';
|
||||
const ASSETSURI = 'https://assets.awwwards.com/awards/media/cache/thumb_417_299/';
|
||||
|
||||
private $sites = array();
|
||||
|
||||
public function getIcon() {
|
||||
return 'https://www.awwwards.com/favicon.ico';
|
||||
}
|
||||
|
||||
private function fetchSites() {
|
||||
Debug::log('Fetching all sites');
|
||||
$sites = getSimpleHTMLDOM(self::SITESURI)
|
||||
or returnServerError('Could not fetch JSON for sites.');
|
||||
|
||||
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');
|
||||
$decode = json_decode($decode, true);
|
||||
$this->sites[] = $decode;
|
||||
}
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
$this->fetchSites();
|
||||
|
||||
Debug::log('Building RSS feed');
|
||||
foreach($this->sites as $site) {
|
||||
$item = array();
|
||||
$item['title'] = $site['title'];
|
||||
$item['timestamp'] = $site['createdAt'];
|
||||
$item['categories'] = $site['tags'];
|
||||
|
||||
$item['content'] = '<img src="'
|
||||
. self::ASSETSURI
|
||||
. $site['images']['thumbnail']
|
||||
. '">';
|
||||
$item['uri'] = self::SITEURI . $site['slug'];
|
||||
|
||||
$this->items[] = $item;
|
||||
|
||||
if(count($this->items) >= 10)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,13 +19,11 @@ class BastaBridge extends BridgeAbstract {
|
|||
$item['title'] = $element->find('title', 0)->innertext;
|
||||
$item['uri'] = $element->find('guid', 0)->plaintext;
|
||||
$item['timestamp'] = strtotime($element->find('dc:date', 0)->plaintext);
|
||||
// Replaces all relative image URLs by absolute URLs.
|
||||
// Relative URLs always start with 'local/'!
|
||||
$item['content'] = preg_replace(
|
||||
'/src=["\']{1}([^"\']+)/ims',
|
||||
'src=\'' . self::URI . '$1\'',
|
||||
getSimpleHTMLDOM($item['uri'])->find('div.texte', 0)->innertext
|
||||
);
|
||||
|
||||
$html = getSimpleHTMLDOM($item['uri']);
|
||||
$html = defaultLinkTo($html, self::URI);
|
||||
|
||||
$item['content'] = $html->find('div.texte', 0)->innertext;
|
||||
$this->items[] = $item;
|
||||
$limit++;
|
||||
}
|
||||
|
|
29
bridges/BleepingComputerBridge.php
Normal file
29
bridges/BleepingComputerBridge.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
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){
|
||||
$item = parent::parseItem($item);
|
||||
|
||||
$article_html = getSimpleHTMLDOMCached($item['uri']);
|
||||
if(!$article_html) {
|
||||
$item['content'] .= '<p><em>Could not request ' . $this->getName() . ': ' . $item['uri'] . '</em></p>';
|
||||
return $item;
|
||||
}
|
||||
|
||||
$article_content = $article_html->find('div.articleBody', 0)->innertext;
|
||||
$article_content = stripRecursiveHTMLSection($article_content, 'div', '<div class="cz-related-article-wrapp');
|
||||
$item['content'] = trim($article_content);
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
$feed = static::URI . 'feed/';
|
||||
$this->collectExpandableDatas($feed);
|
||||
}
|
||||
}
|
60
bridges/BlizzardNewsBridge.php
Normal file
60
bridges/BlizzardNewsBridge.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
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(
|
||||
'name' => 'Language',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Deutsch' => 'de-de',
|
||||
'English (EU)' => 'en-gb',
|
||||
'English (US)' => 'en-us',
|
||||
'Español (EU)' => 'es-es',
|
||||
'Español (AL)' => 'es-mx',
|
||||
'Français' => 'fr-fr',
|
||||
'Italiano' => 'it-it',
|
||||
'日本語' => 'ja-jp',
|
||||
'한국어' => 'ko-kr',
|
||||
'Polski' => 'pl-pl',
|
||||
'Português (AL)' => 'pt-br',
|
||||
'Русский' => 'ru-ru',
|
||||
'ภาษาไทย' => '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';
|
||||
const XPATH_EXPRESSION_ITEM_TITLE = './/div/div[2]/h2';
|
||||
const XPATH_EXPRESSION_ITEM_CONTENT = './/div[@class="ArticleListItem-description"]/div[@class="h6"]';
|
||||
const XPATH_EXPRESSION_ITEM_URI = './/a[@class="ArticleLink ArticleLink"]/@href';
|
||||
const XPATH_EXPRESSION_ITEM_AUTHOR = '';
|
||||
const XPATH_EXPRESSION_ITEM_TIMESTAMP = './/time[@class="ArticleListItem-footerTimestamp"]/@timestamp';
|
||||
const XPATH_EXPRESSION_ITEM_ENCLOSURES = './/div[@class="ArticleListItem-image"]/@style';
|
||||
const XPATH_EXPRESSION_ITEM_CATEGORIES = './/div[@class="ArticleListItem-label"]';
|
||||
const SETTING_FIX_ENCODING = true;
|
||||
|
||||
/**
|
||||
* Source Web page URL (should provide either HTML or XML content)
|
||||
* @return string
|
||||
*/
|
||||
protected function getSourceUrl(){
|
||||
|
||||
$locale = $this->getInput('locale');
|
||||
if('zh-cn' === $locale) {
|
||||
return 'https://cn.news.blizzard.com';
|
||||
}
|
||||
return 'https://news.blizzard.com/' . $locale;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ class BrutBridge extends BridgeAbstract {
|
|||
'Entertainment' => 'entertainment',
|
||||
'Sports' => 'sport',
|
||||
'Nature' => 'nature',
|
||||
'Health' => 'health',
|
||||
),
|
||||
'defaultValue' => 'news',
|
||||
),
|
||||
|
@ -26,6 +27,7 @@ class BrutBridge extends BridgeAbstract {
|
|||
'United States' => 'us',
|
||||
'United Kingdom' => 'uk',
|
||||
'France' => 'fr',
|
||||
'Spain' => 'es',
|
||||
'India' => 'in',
|
||||
'Mexico' => 'mx',
|
||||
),
|
||||
|
|
84
bridges/CeskaTelevizeBridge.php
Normal file
84
bridges/CeskaTelevizeBridge.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
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(
|
||||
'name' => 'url to the show',
|
||||
'required' => true,
|
||||
'exampleValue' => 'https://www.ceskatelevize.cz/porady/1097181328-udalosti/dily/'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
private function fixChars($text) {
|
||||
return html_entity_decode($text, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
private function getUploadTimeFromString($string) {
|
||||
if (strpos($string, 'dnes') !== false) {
|
||||
return strtotime('today');
|
||||
} elseif (strpos($string, 'včera') !== false) {
|
||||
return strtotime('yesterday');
|
||||
} elseif (!preg_match('/(\d+).\s(\d+).(\s(\d+))?/', $string, $match)) {
|
||||
returnServerError('Could not get date from Česká televize string');
|
||||
}
|
||||
|
||||
$date = sprintf('%04d-%02d-%02d', isset($match[3]) ? $match[3] : date('Y'), $match[2], $match[1]);
|
||||
return strtotime($date);
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
$url = $this->getInput('url');
|
||||
|
||||
$validUrl = '/^(https:\/\/www\.ceskatelevize\.cz\/porady\/\d+-[a-z0-9-]+\/)(dily\/((nove|vysilani)\/)?)?$/';
|
||||
if (!preg_match($validUrl, $url, $match)) {
|
||||
returnServerError('Invalid url');
|
||||
}
|
||||
|
||||
$category = isset($match[4]) ? $match[4] : 'nove';
|
||||
$fixedUrl = "{$match[1]}dily/{$category}/";
|
||||
|
||||
$html = getSimpleHTMLDOM($fixedUrl)
|
||||
or returnServerError('Could not request Česká televize');
|
||||
|
||||
$this->feedUri = $fixedUrl;
|
||||
$this->feedName = str_replace('Přehled dílů — ', '', $this->fixChars($html->find('title', 0)->plaintext));
|
||||
if ($category !== 'nove') {
|
||||
$this->feedName .= " ({$category})";
|
||||
}
|
||||
|
||||
foreach ($html->find('.episodes-broadcast-content a.episode_list_item') as $element) {
|
||||
$itemTitle = $element->find('.episode_list_item-title', 0);
|
||||
$itemContent = $element->find('.episode_list_item-desc', 0);
|
||||
$itemDate = $element->find('.episode_list_item-date', 0);
|
||||
$itemThumbnail = $element->find('img', 0);
|
||||
$itemUri = self::URI . $element->getAttribute('href');
|
||||
|
||||
$item = array(
|
||||
'title' => $this->fixChars($itemTitle->plaintext),
|
||||
'uri' => $itemUri,
|
||||
'content' => '<img src="https:' . $itemThumbnail->getAttribute('src') . '" /><br />'
|
||||
. $this->fixChars($itemContent->plaintext),
|
||||
'timestamp' => $this->getUploadTimeFromString($itemDate->plaintext)
|
||||
);
|
||||
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
return isset($this->feedUri) ? $this->feedUri : parent::getURI();
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return isset($this->feedName) ? $this->feedName : parent::getName();
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
<?php
|
||||
class ChristianDailyReporterBridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = 'rogerdc';
|
||||
const NAME = 'Christian Daily Reporter Unofficial RSS';
|
||||
const URI = 'https://www.christiandailyreporter.com/';
|
||||
const DESCRIPTION = 'The Unofficial Christian Daily Reporter RSS';
|
||||
// const CACHE_TIMEOUT = 86400; // 1 day
|
||||
|
||||
public function getIcon() {
|
||||
return self::URI . 'images/cdrfavicon.png';
|
||||
}
|
||||
|
||||
public function collectData() {
|
||||
$uri = 'https://www.christiandailyreporter.com/';
|
||||
|
||||
$html = getSimpleHTMLDOM($uri)
|
||||
or returnServerError('Could not request Christian Daily Reporter.');
|
||||
foreach($html->find('div.top p a,div.column p a') as $element) {
|
||||
$item = array();
|
||||
// Title
|
||||
$item['title'] = $element->innertext;
|
||||
// URL
|
||||
$item['uri'] = $element->href;
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -53,6 +53,8 @@ class DarkReadingBridge extends FeedExpander {
|
|||
|
||||
protected function parseItem($newsItem){
|
||||
$item = parent::parseItem($newsItem);
|
||||
if (empty($item['content']))
|
||||
return null; //ignore dummy articles
|
||||
$article = getSimpleHTMLDOMCached($item['uri'])
|
||||
or returnServerError('Could not request Dark Reading: ' . $item['uri']);
|
||||
$item['content'] = $this->extractArticleContent($article);
|
||||
|
|
24
bridges/DaveRamseyBlogBridge.php
Normal file
24
bridges/DaveRamseyBlogBridge.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
class DaveRamseyBlogBridge extends BridgeAbstract {
|
||||
const MAINTAINER = 'johnpc';
|
||||
const NAME = 'Dave Ramsey Blog';
|
||||
const URI = 'https://www.daveramsey.com/blog';
|
||||
const CACHE_TIMEOUT = 7200; // 2h
|
||||
const DESCRIPTION = 'Returns blog posts from daveramsey.com';
|
||||
|
||||
public function collectData()
|
||||
{
|
||||
$html = getSimpleHTMLDOM(self::URI)
|
||||
or returnServerError('Could not request daveramsey.com.');
|
||||
|
||||
foreach ($html->find('.Post') as $element) {
|
||||
$this->items[] = array(
|
||||
'uri' => 'https://www.daveramsey.com' . $element->find('header > a', 0)->href,
|
||||
'title' => $element->find('header > h2 > a', 0)->plaintext,
|
||||
'tags' => $element->find('.Post-topic', 0)->plaintext,
|
||||
'content' => $element->find('.Post-body', 0)->plaintext,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,29 +45,22 @@ apple-icon-5c6fa9f2bce280428589c6195b7f1924206a53b782b371cfe2d02da932c8c173.png'
|
|||
}
|
||||
|
||||
public function collectData() {
|
||||
|
||||
$html = getSimpleHTMLDOMCached($this->getURI())
|
||||
or returnServerError('Could not request ' . $this->getURI());
|
||||
|
||||
$html = defaultLinkTo($html, static::URI);
|
||||
|
||||
$articles = $html->find('div[class="single-article"]')
|
||||
$articles = $html->find('div.crayons-story')
|
||||
or returnServerError('Could not find articles!');
|
||||
|
||||