mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-08-17 22:02:09 +02:00
Compare commits
37 Commits
revert-909
...
2018-11-10
Author | SHA1 | Date | |
---|---|---|---|
|
a08811f147 | ||
|
a935e310ff | ||
|
7e3787a185 | ||
|
039c032798 | ||
|
cb91d9cce8 | ||
|
bf91f106b4 | ||
|
0b2ede35cd | ||
|
5842bdfc83 | ||
|
68ee24d6bd | ||
|
104ae2298e | ||
|
7026684e34 | ||
|
0b792d77eb | ||
|
110b865a54 | ||
|
19a7f10160 | ||
|
42e25e7fc0 | ||
|
4b7fea5ebc | ||
|
95bd206e9d | ||
|
9910310652 | ||
|
12f0e5a360 | ||
|
81ba96ff94 | ||
|
984f0b24d0 | ||
|
2126db84ac | ||
|
4bf45df18e | ||
|
a88b148d20 | ||
|
f564925ba0 | ||
|
22e8f8b4aa | ||
|
bfae04d1fe | ||
|
723bd1150a | ||
|
53d2fbe3a5 | ||
|
3babd02658 | ||
|
3031fa406d | ||
|
85c34a0960 | ||
|
5deb86acff | ||
|
946e66e9df | ||
|
1a00dfa412 | ||
|
0f8443e1d3 | ||
|
7d474e5361 |
@@ -4,5 +4,4 @@ DEBUG
|
||||
Dockerfile
|
||||
whitelist.txt
|
||||
phpcs.xml
|
||||
CHANGELOG.md
|
||||
CONTRIBUTING.md
|
61
.github/ISSUE_TEMPLATE/bridge-request-template.md
vendored
Normal file
61
.github/ISSUE_TEMPLATE/bridge-request-template.md
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: Bridge request template
|
||||
about: Use this template for requesting a new bridge
|
||||
|
||||
---
|
||||
|
||||
# Bridge request
|
||||
|
||||
<!--
|
||||
This is a bridge request. Start by adding a descriptive title (i.e. `Bridge request for GitHub`). Use the "Preview" button to see a preview of your request. Make sure your request is complete before submitting!
|
||||
|
||||
Notice: This comment is only visible to you while you work on your request. Please do not remove any of the lines in the template (you may add your own outside the "<!--" and "- ->" lines!)
|
||||
-->
|
||||
|
||||
## General information
|
||||
|
||||
<!--
|
||||
Please describe what you expect from the bridge. Whenever possible provide sample links and screenshots (you can just paste them here) to express your expectations and help others understand your request. If possible, mark relevant areas in your screenshot. Use the following questions for reference:
|
||||
-->
|
||||
|
||||
- _Host URI for the bridge_ (i.e. `https://github.com`):
|
||||
|
||||
- Which information would you like to see?
|
||||
|
||||
|
||||
|
||||
- How should the information be displayed/formatted?
|
||||
|
||||
|
||||
|
||||
- Which of the following parameters do you expect?
|
||||
|
||||
- [X] Title
|
||||
- [X] URI (link to the original article)
|
||||
- [ ] Author
|
||||
- [ ] Timestamp
|
||||
- [X] Content (the content of the article)
|
||||
- [ ] Enclosures (pictures, videos, etc...)
|
||||
- [ ] Categories (categories, tags, etc...)
|
||||
|
||||
## Options
|
||||
|
||||
<!--Select options from the list below. Add your own option if one is missing:-->
|
||||
|
||||
- [ ] Limit number of returned items
|
||||
- _Default limit_: 5
|
||||
- [ ] Load full articles
|
||||
- _Cache articles_ (articles are stored in a local cache on first request): yes
|
||||
- _Cache timeout_ (max = 24 hours): 24 hours
|
||||
- [X] Balance requests (RSS-Bridge uses cached versions to reduce bandwith usage)
|
||||
- _Timeout_ (default = 5 minutes, max = 24 hours): 5 minutes
|
||||
|
||||
<!--Be aware that some options might not be available for your specific request due to technical limitations!-->
|
||||
|
||||
<!--
|
||||
## Additional notes
|
||||
|
||||
Keep in mind that opening a request does not guarantee the bridge being implemented! That depends entirely on the interest and time of others to make the bridge for you.
|
||||
|
||||
You can also implement your own bridge (with support of the community if needed). Find more information in the [RSS-Bridge Wiki](https://github.com/RSS-Bridge/rss-bridge/wiki/For-developers) developer section.
|
||||
-->
|
31
.travis.yml
31
.travis.yml
@@ -3,26 +3,35 @@ sudo: false
|
||||
language: php
|
||||
|
||||
install:
|
||||
- if [[ $TRAVIS_PHP_VERSION == "hhvm" ]]; then
|
||||
composer global require squizlabs/PHP_CodeSniffer;
|
||||
else
|
||||
pear channel-update pear.php.net;
|
||||
pear install PHP_CodeSniffer;
|
||||
fi
|
||||
- composer global require dealerdirect/phpcodesniffer-composer-installer;
|
||||
- composer global require phpcompatibility/php-compatibility;
|
||||
# Use PHPUnit 6 for unit tests (stable), requires PHP 7
|
||||
- if [[ $TRAVIS_PHP_VERSION == "7.0" ]]; then
|
||||
composer global require phpunit/phpunit ^6;
|
||||
fi
|
||||
# Use latest PHPUnit on nightly to detect breaking changes
|
||||
- if [[ $TRAVIS_PHP_VERSION == "nightly" ]]; then
|
||||
composer global require phpunit/phpunit;
|
||||
fi
|
||||
|
||||
script:
|
||||
- phpenv rehash
|
||||
- if [[ $TRAVIS_PHP_VERSION == "hhvm" ]]; then
|
||||
/home/travis/.composer/vendor/bin/phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p;
|
||||
else
|
||||
phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p;
|
||||
# Run PHP_CodeSniffer on all versions
|
||||
- ~/.composer/vendor/bin/phpcs . --standard=phpcs.xml --warning-severity=0 --extensions=php -p;
|
||||
# Check PHP compatibility for the lowest supported version
|
||||
- if [[ $TRAVIS_PHP_VERSION == "5.6" ]]; then
|
||||
~/.composer/vendor/bin/phpcs . --standard=phpcompatibility.xml --warning-severity=0 --extensions=php -p;
|
||||
fi
|
||||
# Run unit tests (stable)
|
||||
- if [[ $TRAVIS_PHP_VERSION == "7.0" ]]; then
|
||||
phpunit --configuration=phpunit.xml --include-path=lib/;
|
||||
fi
|
||||
# Run unit tests (latest/nightly)
|
||||
# Check PHP compatibility for all versions, starting at the lowest supported version in order to detect breaking changes
|
||||
- if [[ $TRAVIS_PHP_VERSION == "nightly" ]]; then
|
||||
phpunit --configuration=phpunit.xml --include-path=lib/;
|
||||
~/.composer/vendor/bin/phpcs . --standard=PHPCompatibility --warning-severity=0 --extensions=php -p --runtime-set testVersion 5.6-;
|
||||
fi
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
@@ -30,9 +39,7 @@ matrix:
|
||||
include:
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: hhvm
|
||||
- php: nightly
|
||||
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
- php: nightly
|
||||
|
263
CHANGELOG.md
263
CHANGELOG.md
@@ -1,263 +0,0 @@
|
||||
rss-bridge Changelog
|
||||
===
|
||||
|
||||
RSS-Bridge 2017-08-19
|
||||
==
|
||||
|
||||
## General changes
|
||||
* whitelist: Do case-insensitive whitelist matching
|
||||
* [FeedExpander] Fix Serialization of 'SimpleXMLElement' is not allowed
|
||||
* [FeedExpander] Remove whitespace from source content
|
||||
* [index] Add GET parameter 'q' for search queries
|
||||
- **Example**: You can now add `&q=Twitter` to load into the search field
|
||||
* [index] Check permissions for cache folder and whitelist file
|
||||
* [index] Show bridge options when loading with URL fragment
|
||||
- **Example**: You can now add `#bridge-Twitter` to load the card with all
|
||||
parameters visible
|
||||
* [style] Center search cursor and hide placeholder
|
||||
* [validation] Fix error on undefined optional numeric value
|
||||
|
||||
## Modified bridges
|
||||
* [DanbooruBridge] Allow descendant classes to override tag collection
|
||||
* [DribbbleBridge] Add dribble bridge listing last dribble popular shots (#558)
|
||||
* [FacebookBridge] Fix & in URLs
|
||||
* [GelbooruBridge] Fix bridge not getting tags correctly
|
||||
* [GoComicsBridge] Fix for page structure changes (#568)
|
||||
* [LeBonCoinBridge] Fix bridge is marked executable
|
||||
* [LWNprevBridge] Fix everchanging url
|
||||
* [YoutubeBridge] Fix error on certain keywords
|
||||
* [YoutubeBridge] Fix issues loading playlists
|
||||
|
||||
## Removed bridges
|
||||
* VineBridge
|
||||
|
||||
RSS-Bridge 2017-08-03
|
||||
==
|
||||
|
||||
## Important changes
|
||||
* RSS-Bridge now has [contribution guidelines](CONTRIBUTING.md)
|
||||
* [phpcs rules](phpcs.xml) follow the [contribution guidelines](CONTRIBUTING.md)
|
||||
|
||||
## General changes
|
||||
* Added a search bar to make searching for bridges easier
|
||||
* Added user friendly error page for when a bridge fails
|
||||
* Added caching of extraInfos (name, uri)
|
||||
* Added an indicator to warn for bridges using HTTP instead of HTTPS
|
||||
* Various bug fixes and improvements
|
||||
|
||||
## Modified bridges
|
||||
* AllocineFRBridge] Update Faux Raccord link
|
||||
* [DanbooruBridge] Fix broken URI
|
||||
* [DuckDuckGoBridge] Disable DuckDuckGo redirects so that the links returned are correct.
|
||||
* [FacebookBridge] Add option to hide posts with facebook videos
|
||||
* [FacebookBridge] Add requester languages to HTTP header
|
||||
* [FacebookBridge] Handle summary posts
|
||||
* [FacebookBridge] Replace 'novideo' with 'media_type'
|
||||
* [FilterBridge] Initial implementation of basic title permit and block
|
||||
* [FlickrTagBridge] Fix and improve bridge by using the FlickrExploreBridge approach
|
||||
* [GooglePlusPostBridge] Autofix user names
|
||||
* [GooglePlusPostBridge] Fix bridge implementation
|
||||
* [GooglePlusPostBridge] Fix content loading
|
||||
* [InstagramBridge] Add option to filter for videos and pictures
|
||||
* [LWNprevBridge] full rewrite
|
||||
* [MangareaderBridge] Fix double forward slashes
|
||||
* [NasaApodBridge] Use HTTPS instead of HTTP
|
||||
* [PinterestBridge] Fix checkbox not working
|
||||
* [PinterestBridge] Fix implementation after DOM changes
|
||||
* [RTBFBridge] Update URI
|
||||
* [SexactuBridge] Fix URI and timestamp
|
||||
* [SexactuBridge] Use most modern version of bridge api and cached pages (#504)
|
||||
* [ShanaprojectBridge] Don't throw error if timestamp is missing
|
||||
* [TwitterBridge] Add option to hide retweets
|
||||
* [TwitterBridge] Avoid empty content caused by new login policy
|
||||
* [TwitterBridge] Fix double slashes in URI
|
||||
* [TwitterBridge] Fix missing spaces
|
||||
* [TwitterBridge] Fix title includes anchors in plaintext format
|
||||
* [TwitterBridge] ignore promoted tweets
|
||||
* [TwitterBridge] Optimize returned image sizes
|
||||
* [TwitterBridge] Show quotes and pictures
|
||||
* [WebfailBridge] Properly handle gifs (DOM changed)
|
||||
* [YoutubeBridge] Improve readability of feed contents
|
||||
* [YoutubeBridge] Improve URL handling in video descriptions
|
||||
|
||||
## New bridges
|
||||
* AmazonBridge
|
||||
* DiceBridge
|
||||
* EtsyBridge
|
||||
* FB2Bridge
|
||||
* FilterBridge
|
||||
* FlickrBridge
|
||||
* GithubSearchBridge
|
||||
* GoComicsBridge
|
||||
* KATBridge
|
||||
* KernelBugTrackerBridge
|
||||
* MixCloudBridge
|
||||
* MoinMoinBridge
|
||||
* RainbowSixSiegeBridge
|
||||
* SteamBridge
|
||||
* TheTVDBBridge
|
||||
* Torrent9Bridge
|
||||
* UsbekEtRicaBridge
|
||||
* WikiLeaksBridge
|
||||
* WordPressPluginUpdateBridge
|
||||
|
||||
Alpha 0.2
|
||||
===
|
||||
|
||||
## Important changes
|
||||
* RSS-Bridge has been [UNLICENSED](UNLICENSE)
|
||||
* RSS-Bridge is now a community-managed project on [GitHub](https://github.com/rss-bridge/rss-bridge)
|
||||
* RSS-Bridge now has a [Wiki](https://github.com/rss-bridge/rss-bridge/wiki)
|
||||
* RSS-Bridge now supports [Travis-CI](https://travis-ci.org)
|
||||
|
||||
## General changes
|
||||
* Added [CHANGELOG](CHANGELOG.md) (this file)
|
||||
* Added [PHP Simple HTML DOM Parser](http://simplehtmldom.sourceforge.net) to [vendor](vendor/simplehtmldom/)
|
||||
* Added cache purging function (cache will be force-purged after 24 hours or as defined by bridge)
|
||||
* Added new format [MrssFormat](formats/MrssFormat.php)
|
||||
* Added parameter `author` - for display of the feed author name - to all formats
|
||||
* Added new abstraction of the BridgeInterface:
|
||||
- [FeedExpander](https://github.com/RSS-Bridge/rss-bridge/wiki/Bridge-API)
|
||||
* Added optional support for proxy usage on each individual bridge
|
||||
* Added support for [custom bridge parameter](https://github.com/RSS-Bridge/rss-bridge/wiki/BridgeAbstract#format-specifications) (text, number, list, checkbox)
|
||||
* Changed design of the welcome screen
|
||||
* Changed design of HtmlFormat
|
||||
* Changed behavior of debug mode:
|
||||
- Enable debug mode by placing a file called "DEBUG" in the root folder
|
||||
- Debug mode automatically disables cache file loading
|
||||
* Changed implementation of bridges - see [Wiki](https://github.com/rss-bridge/rss-bridge/wiki)
|
||||
- Changed comment-style metadata to constants
|
||||
- Added support for multiple utilizations per bridge
|
||||
- Changed the parameter loading algorithm to be loaded by RSS-Bridge core
|
||||
* Improved checks for PHP version, configuration and extensions
|
||||
* Many bug fixes
|
||||
|
||||
## Modified Bridges
|
||||
* FlickrExploreBridge
|
||||
* GoogleSearchBridge
|
||||
* TwitterBridge
|
||||
|
||||
## New Bridges
|
||||
* ABCTabsBridge
|
||||
* AcrimedBridge
|
||||
* AllocineFRBridge
|
||||
* AnimeUltimeBridge
|
||||
* Arte7Bridge
|
||||
* AskfmBridge
|
||||
* BandcampBridge
|
||||
* BastaBridge
|
||||
* BlaguesDeMerdeBridge
|
||||
* BooruprojectBridge
|
||||
* CADBridge
|
||||
* CNETBridge
|
||||
* CastorusBridge
|
||||
* CollegeDeFranceBridge
|
||||
* CommonDreamsBridge
|
||||
* CopieDoubleBridge
|
||||
* CourrierInternationalBridge
|
||||
* CpasbienBridge
|
||||
* CryptomeBridge
|
||||
* DailymotionBridge
|
||||
* DanbooruBridge
|
||||
* DansTonChatBridge
|
||||
* DauphineLibereBridge
|
||||
* DemoBridge
|
||||
* DeveloppezDotComBridge
|
||||
* DilbertBridge
|
||||
* DollbooruBridge
|
||||
* DuckDuckGoBridge
|
||||
* EZTVBridge
|
||||
* EliteDangerousGalnetBridge
|
||||
* ElsevierBridge
|
||||
* EstCeQuonMetEnProdBridge
|
||||
* FacebookBridge
|
||||
* FierPandaBridge
|
||||
* FlickrTagBridge
|
||||
* FootitoBridge
|
||||
* FourchanBridge
|
||||
* FuturaSciencesBridge
|
||||
* GBAtempBridge
|
||||
* GelbooruBridge
|
||||
* GiphyBridge
|
||||
* GithubIssueBridge
|
||||
* GizmodoBridge
|
||||
* GooglePlusPostBridge
|
||||
* HDWallpapersBridge
|
||||
* HentaiHavenBridge
|
||||
* IdenticaBridge
|
||||
* InstagramBridge
|
||||
* IsoHuntBridge
|
||||
* JapanExpoBridge
|
||||
* KonachanBridge
|
||||
* KoreusBridge
|
||||
* KununuBridge
|
||||
* LWNprevBridge
|
||||
* LeBonCoinBridge
|
||||
* LegifranceJOBridge
|
||||
* LeMondeInformatiqueBridge
|
||||
* LesJoiesDuCodeBridge
|
||||
* LichessBridge
|
||||
* LinkedInCompanyBridge
|
||||
* LolibooruBridge
|
||||
* MangareaderBridge
|
||||
* MilbooruBridge
|
||||
* MoebooruBridge
|
||||
* MondeDiploBridge
|
||||
* MsnMondeBridge
|
||||
* MspabooruBridge
|
||||
* NasaApodBridge
|
||||
* NeuviemeArtBridge
|
||||
* NextInpactBridge
|
||||
* NextgovBridge
|
||||
* NiceMatinBridge
|
||||
* NovelUpdatesBridge
|
||||
* OpenClassroomsBridge
|
||||
* ParuVenduImmoBridge
|
||||
* PickyWallpapersBridge
|
||||
* PinterestBridge
|
||||
* PlanetLibreBridge
|
||||
* RTBFBridge
|
||||
* ReadComicsBridge
|
||||
* Releases3DSBridge
|
||||
* ReporterreBridge
|
||||
* Rue89Bridge
|
||||
* Rule34Bridge
|
||||
* Rule34pahealBridge
|
||||
* SafebooruBridge
|
||||
* SakugabooruBridge
|
||||
* ScmbBridge
|
||||
* ScoopItBridge
|
||||
* SensCritiqueBridge
|
||||
* SexactuBridge
|
||||
* ShanaprojectBridge
|
||||
* Shimmie2Bridge
|
||||
* SoundcloudBridge
|
||||
* StripeAPIChangeLogBridge
|
||||
* SuperbWallpapersBridge
|
||||
* T411Bridge
|
||||
* TagBoardBridge
|
||||
* TbibBridge
|
||||
* TheCodingLoveBridge
|
||||
* TheHackerNewsBridge
|
||||
* ThePirateBayBridge
|
||||
* UnsplashBridge
|
||||
* ViadeoCompanyBridge
|
||||
* VineBridge
|
||||
* VkBridge
|
||||
* WallpaperStopBridge
|
||||
* WebfailBridge
|
||||
* WeLiveSecurityBridge
|
||||
* WhydBridge
|
||||
* WikipediaBridge
|
||||
* WordPressBridge
|
||||
* WorldOfTanksBridge
|
||||
* XbooruBridge
|
||||
* YandereBridge
|
||||
* YoutubeBridge
|
||||
* ZDNetBridge
|
||||
|
||||
Alpha 0.1
|
||||
===
|
||||
* First tagged version.
|
||||
* Includes refactoring.
|
||||
* Unstable.
|
211
bridges/CrewbayBridge.php
Normal file
211
bridges/CrewbayBridge.php
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
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(
|
||||
'name' => 'Filter by keyword',
|
||||
'title' => 'Enter the keyword to filter here'
|
||||
),
|
||||
'type' => array(
|
||||
'name' => 'Type of search',
|
||||
'title' => 'Choose between finding a boat or a crew',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Find a boat' => 'boats',
|
||||
'Find a crew' => 'crew'
|
||||
)
|
||||
),
|
||||
'status' => array(
|
||||
'name' => 'Status on the boat',
|
||||
'title' => 'Choose between recreational or professional classified ads',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Recreational' => 'recreational',
|
||||
'Professional' => 'professional'
|
||||
)
|
||||
),
|
||||
'recreational_position' => array(
|
||||
'name' => 'Recreational position wanted',
|
||||
'title' => 'Filter by recreational position you wanted aboard',
|
||||
'required' => false,
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'' => '',
|
||||
'Amateur Crew' => 'Amateur Crew',
|
||||
'Friendship' => 'Friendship',
|
||||
'Competent Crew' => 'Competent Crew',
|
||||
'Racing' => 'Racing',
|
||||
'Voluntary work' => 'Voluntary work',
|
||||
'Mile building' => 'Mile building'
|
||||
)
|
||||
),
|
||||
'professional_position' => array(
|
||||
'name' => 'Professional position wanted',
|
||||
'title' => 'Filter by professional position you wanted aboard',
|
||||
'required' => false,
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'' => '',
|
||||
'1st Engineer' => '1st Engineer',
|
||||
'1st Mate' => '1st Mate',
|
||||
'Beautician' => 'Beautician',
|
||||
'Bosun' => 'Bosun',
|
||||
'Captain' => 'Captain',
|
||||
'Chef' => 'Chef',
|
||||
'Steward(ess)' => 'Steward(ess)',
|
||||
'Deckhand' => 'Deckhand',
|
||||
'Delivery Crew' => 'Delivery Crew',
|
||||
'Dive Instructor' => 'Dive Instructor',
|
||||
'Masseur' => 'Masseur',
|
||||
'Medical Staff' => 'Medical Staff',
|
||||
'Nanny' => 'Nanny',
|
||||
'Navigator' => 'Navigator',
|
||||
'Racing Crew' => 'Racing Crew',
|
||||
'Teacher' => 'Teacher',
|
||||
'Electrical Engineer' => 'Electrical Engineer',
|
||||
'Fitter' => 'Fitter',
|
||||
'2nd Engineer' => '2nd Engineer',
|
||||
'3rd Engineer' => '3rd Engineer',
|
||||
'Lead Deckhand' => 'Lead Deckhand',
|
||||
'Security Officer' => 'Security Officer',
|
||||
'O.O.W' => 'O.O.W',
|
||||
'1st Officer' => '1st Officer',
|
||||
'2nd Officer' => '2nd Officer',
|
||||
'3rd Officer' => '3rd Officer',
|
||||
'Captain/Engineer' => 'Captain/Engineer',
|
||||
'Hairdresser' => 'Hairdresser',
|
||||
'Fitness Trainer' => 'Fitness Trainer',
|
||||
'Laundry' => 'Laundry',
|
||||
'Solo Steward/ess' => 'Solo Steward/ess',
|
||||
'Stew/Deck' => 'Stew/Deck',
|
||||
'2nd Steward/ess' => '2nd Steward/ess',
|
||||
'3rd Steward/ess' => '3rd Steward/ess',
|
||||
'Chief Steward/ess' => 'Chief Steward/ess',
|
||||
'Head Housekeeper' => 'Head Housekeeper',
|
||||
'Purser' => 'Purser',
|
||||
'Cook' => 'Cook',
|
||||
'Cook/Stew' => 'Cook/Stew',
|
||||
'2nd Chef' => '2nd Chef',
|
||||
'Head Chef' => 'Head Chef',
|
||||
'Administrator' => 'Administrator',
|
||||
'P.A' => 'P.A',
|
||||
'Villa staff' => 'Villa staff',
|
||||
'Housekeeping/Stew' => 'Housekeeping/Stew',
|
||||
'Stew/Beautician' => 'Stew/Beautician',
|
||||
'Stew/Masseuse' => 'Stew/Masseuse',
|
||||
'Manager' => 'Manager',
|
||||
'Sailing instructor' => 'Sailing instructor'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function collectData() {
|
||||
$url = $this->getURI();
|
||||
$html = getSimpleHTMLDOM($url) or returnClientError('No results for this query.');
|
||||
|
||||
$annonces = $html->find('#SearchResults div.result');
|
||||
$limit = 0;
|
||||
|
||||
foreach ($annonces as $annonce) {
|
||||
$detail = $annonce->find('.btn--profile', 0);
|
||||
$htmlDetail = getSimpleHTMLDOMCached($detail->getAttribute('data-modal-href'));
|
||||
|
||||
$item = array();
|
||||
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
$titleSelector = '.title h2';
|
||||
} else {
|
||||
$titleSelector = '.layout__item h2';
|
||||
}
|
||||
$userName = $annonce->find('.result--description a', 0)->plaintext;
|
||||
$annonceTitle = trim($annonce->find($titleSelector, 0)->plaintext);
|
||||
if (empty($annonceTitle)) {
|
||||
$item['title'] = $userName;
|
||||
} else {
|
||||
$item['title'] = $userName . ' - ' . $annonceTitle;
|
||||
}
|
||||
|
||||
$item['uri'] = $detail->href;
|
||||
$images = $annonce->find('.avatar img');
|
||||
$item['enclosures'] = array(end($images)->getAttribute('src'));
|
||||
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
$fields = array('job', 'boat', 'skipper');
|
||||
} else {
|
||||
$fields = array('profile', 'positions', 'info', 'qualifications' , 'skills', 'references');
|
||||
}
|
||||
|
||||
$content = '';
|
||||
foreach ($fields as $field) {
|
||||
$info = $htmlDetail->find('.profile--modal-body .info-' . $field, 0);
|
||||
if ($info) {
|
||||
$content .= $htmlDetail->find('.profile--modal-body .info-' . $field, 0)->innertext;
|
||||
}
|
||||
}
|
||||
|
||||
$item['content'] = $content;
|
||||
|
||||
if (!empty($this->getInput('keyword'))) {
|
||||
$keyword = strtolower($this->getInput('keyword'));
|
||||
if (strpos(strtolower($item['title']), $keyword) === false) {
|
||||
if (strpos(strtolower($content), $keyword) === false) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
$positions = array(str_replace('Wanted:', '', $annonce->find('.content li', 0)->plaintext));
|
||||
}
|
||||
} else {
|
||||
$positions = explode("\r\n", trim($htmlDetail->find('.info-positions .value', 0)->plaintext));
|
||||
}
|
||||
|
||||
$found = false;
|
||||
$keyword = $this->getInput('status') == 'professional' ? 'professional_position' : 'recreational_position';
|
||||
foreach ($positions as $position) {
|
||||
if (strpos(trim($position), $this->getInput($keyword)) !== false) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$this->items[] = $item;
|
||||
$limit += 1;
|
||||
|
||||
if ($limit == 10) break;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
$uri = parent::getURI();
|
||||
|
||||
if ($this->getInput('type') == 'boats') {
|
||||
$uri .= '/boats';
|
||||
} else {
|
||||
$uri .= '/crew';
|
||||
}
|
||||
|
||||
if ($this->getInput('status') == 'professional') {
|
||||
$uri .= '/professional';
|
||||
} else {
|
||||
$uri .= '/recreational';
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
}
|
@@ -121,7 +121,7 @@ class ElloBridge extends BridgeAbstract {
|
||||
|
||||
private function getAPIKey() {
|
||||
$cache = Cache::create('FileCache');
|
||||
$cache->setPath(CACHE_DIR);
|
||||
$cache->setPath(PATH_CACHE);
|
||||
$cache->setParameters(['key']);
|
||||
$key = $cache->loadData();
|
||||
|
||||
|
@@ -364,6 +364,26 @@ class FacebookBridge extends BridgeAbstract {
|
||||
}, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Facebook's tracking code
|
||||
*/
|
||||
private function remove_tracking_codes($content){
|
||||
return preg_replace_callback('/ href=\"([^"]+)\"/i', function($matches){
|
||||
if(is_array($matches) && count($matches) > 1) {
|
||||
|
||||
$link = $matches[1];
|
||||
|
||||
if(strpos($link, 'facebook.com') !== false) {
|
||||
if(strpos($link, '?') !== false) {
|
||||
$link = substr($link, 0, strpos($link, '?'));
|
||||
}
|
||||
}
|
||||
return ' href="' . $link . '"';
|
||||
|
||||
}
|
||||
}, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert textual representation of emoticons back to ASCII emoticons.
|
||||
* i.e. "<i><u>smile emoticon</u></i>" => ":)"
|
||||
@@ -426,8 +446,7 @@ class FacebookBridge extends BridgeAbstract {
|
||||
// Show captcha filling form to the viewer, proxying the captcha image
|
||||
$img = base64_encode(getContents($captcha->find('img', 0)->src));
|
||||
|
||||
http_response_code(500);
|
||||
header('Content-Type: text/html');
|
||||
header('Content-Type: text/html', true, 500);
|
||||
|
||||
$message = <<<EOD
|
||||
<form method="post" action="?{$_SERVER['QUERY_STRING']}">
|
||||
@@ -519,7 +538,7 @@ EOD;
|
||||
|
||||
if(isset($element)) {
|
||||
|
||||
$author = str_replace(' | Facebook', '', $html->find('title#pageTitle', 0)->innertext);
|
||||
$author = str_replace(' - Posts | Facebook', '', $html->find('title#pageTitle', 0)->innertext);
|
||||
|
||||
$profilePic = $html->find('meta[property="og:image"]', 0)->content;
|
||||
|
||||
@@ -558,10 +577,28 @@ EOD;
|
||||
|
||||
$content = $post->find('.userContentWrapper', 0);
|
||||
|
||||
$content = preg_replace(
|
||||
'/(?i)><div class=\"_59tj([^>]+)>(.+?)<\/div><\/div><a/i',
|
||||
'',
|
||||
$content);
|
||||
// This array specifies filters applied to all posts in order of appearance
|
||||
$content_filters = array(
|
||||
'._5mly', // Remove embedded videos (the preview image remains)
|
||||
'._2ezg', // Remove "Views ..."
|
||||
'.hidden_elem', // Remove hidden elements (they are hidden anyway)
|
||||
);
|
||||
|
||||
foreach($content_filters as $filter) {
|
||||
foreach($content->find($filter) as $subject) {
|
||||
$subject->outertext = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Change origin tag for embedded media from div to paragraph
|
||||
foreach($content->find('._59tj') as $subject) {
|
||||
$subject->outertext = '<p>' . $subject->innertext . '</p>';
|
||||
}
|
||||
|
||||
// Change title tag for embedded media from anchor to paragraph
|
||||
foreach($content->find('._3n1k a') as $anchor) {
|
||||
$anchor->outertext = '<p>' . $anchor->innertext . '</p>';
|
||||
}
|
||||
|
||||
$content = preg_replace(
|
||||
'/(?i)><div class=\"_3dp([^>]+)>(.+?)div\ class=\"[^u]+userContent\"/i',
|
||||
@@ -611,6 +648,8 @@ EOD;
|
||||
// Restore links in the content before adding to the item
|
||||
$content = defaultLinkTo($content, self::URI);
|
||||
|
||||
$content = $this->remove_tracking_codes($content);
|
||||
|
||||
// Retrieve date of the post
|
||||
$date = $post->find('abbr')[0];
|
||||
|
||||
|
82
bridges/FindACrewBridge.php
Normal file
82
bridges/FindACrewBridge.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
class FindACrewBridge extends BridgeAbstract {
|
||||
const MAINTAINER = 'couraudt';
|
||||
const NAME = 'Find A Crew Bridge';
|
||||
const URI = 'https://www.findacrew.net';
|
||||
const DESCRIPTION = 'Returns the newest sailing offers.';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'type' => array(
|
||||
'name' => 'Type of search',
|
||||
'title' => 'Choose between finding a boat or a crew',
|
||||
'type' => 'list',
|
||||
'values' => array(
|
||||
'Find a boat' => 'boat',
|
||||
'Find a crew' => 'crew'
|
||||
)
|
||||
),
|
||||
'long' => array(
|
||||
'name' => 'Longitude of the searched location',
|
||||
'title' => 'Center the search at that longitude (e.g: -42.02)'
|
||||
),
|
||||
'lat' => array(
|
||||
'name' => 'Latitude of the searched location',
|
||||
'title' => 'Center the search at that latitude (e.g: 12.42)'
|
||||
),
|
||||
'distance' => array(
|
||||
'name' => 'Limit boundary of search in KM',
|
||||
'title' => 'Boundary of the search in kilometers when using longitude and latitude'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
public function collectData() {
|
||||
$url = $this->getURI();
|
||||
|
||||
if ($this->getInput('type') == 'boat') {
|
||||
$data = array('SrhLstBtAction' => 'Create');
|
||||
} else {
|
||||
$data = array('SrhLstCwAction' => 'Create');
|
||||
}
|
||||
|
||||
if ($this->getInput('long') && $this->getInput('lat')) {
|
||||
$data['real_LocSrh_Lng'] = $this->getInput('long');
|
||||
$data['real_LocSrh_Lat'] = $this->getInput('lat');
|
||||
if ($this->getInput('distance')) {
|
||||
$data['LocDis'] = (int)$this->getInput('distance') * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
$header = array(
|
||||
'Content-Type: application/x-www-form-urlencoded'
|
||||
);
|
||||
|
||||
$opts = array(
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => http_build_query($data) . "\n"
|
||||
);
|
||||
|
||||
$html = getSimpleHTMLDOM($url, $header, $opts) or returnClientError('No results for this query.');
|
||||
|
||||
$annonces = $html->find('.css_SrhRst');
|
||||
foreach ($annonces as $annonce) {
|
||||
$item = array();
|
||||
|
||||
$img = parent::getURI() . $annonce->find('.css_LstPic img', 0)->getAttribute('src');
|
||||
$item['title'] = $annonce->find('.css_LstCtrls span', 0)->plaintext;
|
||||
$item['uri'] = parent::getURI() . $annonce->find('.css_PnlCtrls a', 0)->href;
|
||||
$content = $annonce->find('.css_LstDtl div', 2)->innertext;
|
||||
$item['content'] = "<img src='$img' /><br>$content";
|
||||
$item['enclosures'] = array($img);
|
||||
$item['categories'] = array($annonce->find('.css_AccLocCur', 0)->plaintext);
|
||||
$this->items[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
public function getURI() {
|
||||
$uri = parent::getURI();
|
||||
// Those params must be in the URL
|
||||
$uri .= '/en/' . $this->getInput('type') . '/search?srhtyp=srhrst&mdl=2';
|
||||
return $uri;
|
||||
}
|
||||
}
|
@@ -19,6 +19,12 @@ class InstagramBridge extends BridgeAbstract {
|
||||
'required' => true
|
||||
)
|
||||
),
|
||||
array(
|
||||
'l' => array(
|
||||
'name' => 'location',
|
||||
'required' => true
|
||||
)
|
||||
),
|
||||
'global' => array(
|
||||
'media_type' => array(
|
||||
'name' => 'Media type',
|
||||
@@ -38,16 +44,18 @@ class InstagramBridge extends BridgeAbstract {
|
||||
|
||||
public function collectData(){
|
||||
|
||||
if(!is_null($this->getInput('h')) && $this->getInput('media_type') == 'story') {
|
||||
returnClientError('Stories are not supported for hashtags!');
|
||||
if(is_null($this->getInput('u')) && $this->getInput('media_type') == 'story') {
|
||||
returnClientError('Stories are not supported for hashtags nor locations!');
|
||||
}
|
||||
|
||||
$data = $this->getInstagramJSON($this->getURI());
|
||||
|
||||
if(!is_null($this->getInput('u'))) {
|
||||
$userMedia = $data->entry_data->ProfilePage[0]->graphql->user->edge_owner_to_timeline_media->edges;
|
||||
} else {
|
||||
} elseif(!is_null($this->getInput('h'))) {
|
||||
$userMedia = $data->entry_data->TagPage[0]->graphql->hashtag->edge_hashtag_to_media->edges;
|
||||
} elseif(!is_null($this->getInput('l'))) {
|
||||
$userMedia = $data->entry_data->LocationsPage[0]->graphql->location->edge_location_to_media->edges;
|
||||
}
|
||||
|
||||
foreach($userMedia as $media) {
|
||||
@@ -147,8 +155,9 @@ class InstagramBridge extends BridgeAbstract {
|
||||
return self::URI . urlencode($this->getInput('u')) . '/';
|
||||
} elseif(!is_null($this->getInput('h'))) {
|
||||
return self::URI . 'explore/tags/' . urlencode($this->getInput('h'));
|
||||
} elseif(!is_null($this->getInput('l'))) {
|
||||
return self::URI . 'explore/locations/' . urlencode($this->getInput('l'));
|
||||
}
|
||||
|
||||
return parent::getURI();
|
||||
}
|
||||
}
|
||||
|
130
bridges/OnVaSortirBridge.php
Normal file
130
bridges/OnVaSortirBridge.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
class OnVaSortirBridge extends FeedExpander {
|
||||
const MAINTAINER = 'AntoineTurmel';
|
||||
const NAME = 'OnVaSortir';
|
||||
const URI = 'https://www.onvasortir.com';
|
||||
const DESCRIPTION = 'Returns the newest events from OnVaSortir (full text)';
|
||||
const PARAMETERS = array(
|
||||
array(
|
||||
'city' => array(
|
||||
'name' => 'City',
|
||||
'type' => 'list',
|
||||
'required' => true,
|
||||
'values' => array(
|
||||
'Agen' => 'Agen',
|
||||
'Ajaccio' => 'Ajaccio',
|
||||
'Albi' => 'Albi',
|
||||
'Amiens' => 'Amiens',
|
||||
'Angers' => 'Angers',
|
||||
'Angoulême' => 'Angouleme',
|
||||
'Annecy' => 'annecy',
|
||||
'Aurillac' => 'aurillac',
|
||||
'Auxerre' => 'auxerre',
|
||||
'Avignon' => 'avignon',
|
||||
'Béziers' => 'Beziers',
|
||||
'Bastia' => 'Bastia',
|
||||
'Beauvais' => 'Beauvais',
|
||||
'Belfort' => 'Belfort',
|
||||
'Bergerac' => 'bergerac',
|
||||
'Besançon' => 'Besancon',
|
||||
'Biarritz' => 'Biarritz',
|
||||
'Blois' => 'Blois',
|
||||
'Bordeaux' => 'bordeaux',
|
||||
'Bourg-en-Bresse' => 'bourg-en-bresse',
|
||||
'Bourges' => 'Bourges',
|
||||
'Brest' => 'Brest',
|
||||
'Brive' => 'brive-la-gaillarde',
|
||||
'Bruxelles' => 'bruxelles',
|
||||
'Caen' => 'Caen',
|
||||
'Calais' => 'Calais',
|
||||
'Carcassonne' => 'Carcassonne',
|
||||
'Châteauroux' => 'Chateauroux',
|
||||
'Chalon-sur-saone' => 'chalon-sur-saone',
|
||||
'Chambéry' => 'chambery',
|
||||
'Chantilly' => 'chantilly',
|
||||
'Charleroi' => 'charleroi',
|
||||
'Charleville-Mézières' => 'Charleville-Mezieres',
|
||||
'Chartres' => 'Chartres',
|
||||
'Cherbourg' => 'Cherbourg',
|
||||
'Cholet' => 'cholet',
|
||||
'Clermont-Ferrand' => 'Clermont-Ferrand',
|
||||
'Compiègne' => 'compiegne',
|
||||
'Dieppe' => 'dieppe',
|
||||
'Dijon' => 'Dijon',
|
||||
'Dunkerque' => 'Dunkerque',
|
||||
'Evreux' => 'evreux',
|
||||
'Fréjus' => 'frejus',
|
||||
'Gap' => 'gap',
|
||||
'Genève' => 'geneve',
|
||||
'Grenoble' => 'Grenoble',
|
||||
'La Roche sur Yon' => 'La-Roche-sur-Yon',
|
||||
'La Rochelle' => 'La-Rochelle',
|
||||
'Lausanne' => 'lausanne',
|
||||
'Laval' => 'Laval',
|
||||
'Le Havre' => 'le-havre',
|
||||
'Le Mans' => 'le-mans',
|
||||
'Liège' => 'liege',
|
||||
'Lille' => 'lille',
|
||||
'Limoges' => 'Limoges',
|
||||
'Lorient' => 'Lorient',
|
||||
'Luxembourg' => 'Luxembourg',
|
||||
'Lyon' => 'lyon',
|
||||
'Marseille' => 'marseille',
|
||||
'Metz' => 'Metz',
|
||||
'Mons' => 'Mons',
|
||||
'Mont de Marsan' => 'mont-de-marsan',
|
||||
'Montauban' => 'Montauban',
|
||||
'Montluçon' => 'montlucon',
|
||||
'Montpellier' => 'montpellier',
|
||||
'Mulhouse' => 'Mulhouse',
|
||||
'Nîmes' => 'nimes',
|
||||
'Namur' => 'Namur',
|
||||
'Nancy' => 'Nancy',
|
||||
'Nantes' => 'nantes',
|
||||
'Nevers' => 'nevers',
|
||||
'Nice' => 'nice',
|
||||
'Niort' => 'niort',
|
||||
'Orléans' => 'orleans',
|
||||
'Périgueux' => 'perigueux',
|
||||
'Paris' => 'paris',
|
||||
'Pau' => 'Pau',
|
||||
'Perpignan' => 'Perpignan',
|
||||
'Poitiers' => 'Poitiers',
|
||||
'Quimper' => 'Quimper',
|
||||
'Reims' => 'Reims',
|
||||
'Rennes' => 'Rennes',
|
||||
'Roanne' => 'roanne',
|
||||
'Rodez' => 'rodez',
|
||||
'Rouen' => 'Rouen',
|
||||
'Saint-Brieuc' => 'Saint-Brieuc',
|
||||
'Saint-Etienne' => 'saint-etienne',
|
||||
'Saint-Malo' => 'saint-malo',
|
||||
'Saint-Nazaire' => 'saint-nazaire',
|
||||
'Saint-Quentin' => 'saint-quentin',
|
||||
'Saintes' => 'saintes',
|
||||
'Strasbourg' => 'Strasbourg',
|
||||
'Tarbes' => 'Tarbes',
|
||||
'Toulon' => 'Toulon',
|
||||
'Toulouse' => 'Toulouse',
|
||||
'Tours' => 'Tours',
|
||||
'Troyes' => 'troyes',
|
||||
'Valence' => 'valence',
|
||||
'Vannes' => 'vannes',
|
||||
'Zurich' => 'zurich',
|
||||
),
|
||||
'defaultValue' => ''
|
||||
)
|
||||
)
|
||||
);
|
||||
protected function parseItem($item){
|
||||
$item = parent::parseItem($item);
|
||||
$html = getSimpleHTMLDOMCached($item['uri']);
|
||||
$text = $html->find('div.corpsMax', 0)->innertext;
|
||||
$item['content'] = utf8_encode($text);
|
||||
return $item;
|
||||
}
|
||||
public function collectData(){
|
||||
$this->collectExpandableDatas('https://' .
|
||||
$this->getInput('city') . '.onvasortir.com/rss.php');
|
||||
}
|
||||
}
|
@@ -53,7 +53,7 @@ class PixivBridge extends BridgeAbstract {
|
||||
|
||||
$url = str_replace('_master1200', '', $url);
|
||||
$url = str_replace('c/240x240/img-master/', 'img-original/', $url);
|
||||
$path = CACHE_DIR . '/pixiv_img';
|
||||
$path = PATH_CACHE . '/pixiv_img';
|
||||
|
||||
if(!is_dir($path))
|
||||
mkdir($path, 0755, true);
|
||||
|
@@ -13,8 +13,8 @@ class RainbowSixSiegeBridge extends BridgeAbstract {
|
||||
|
||||
public function collectData(){
|
||||
$dlUrl = 'https://prod-tridionservice.ubisoft.com/live/v1/News/Latest?templateId=tcm%3A152-7677';
|
||||
$dlUrl .= '8-32&pageIndex=0&pageSize=10&language=en-US&detailPageId=tcm%3A152-194572-64';
|
||||
$dlUrl .= '&keywordList=175426&siteId=undefined&useSeoFriendlyUrl=true';
|
||||
$dlUrl .= '8-32&pageIndex=0&pageSize=10&language=en-US&detailPageId=tcm%3A150-194572-64';
|
||||
$dlUrl .= '&keywordList=233416%2C316144%2C233418%2C233417&siteId=undefined&useSeoFriendlyUrl=true';
|
||||
$jsonString = getContents($dlUrl) or returnServerError('Error while downloading the website content');
|
||||
|
||||
$json = json_decode($jsonString, true);
|
||||
|
@@ -1,25 +1,50 @@
|
||||
<?php
|
||||
class Rue89Bridge extends FeedExpander {
|
||||
class Rue89Bridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = 'pit-fgfjiudghdf';
|
||||
const MAINTAINER = 'teromene';
|
||||
const NAME = 'Rue89';
|
||||
const URI = 'http://rue89.nouvelobs.com/';
|
||||
const DESCRIPTION = 'Returns the 5 newest posts from Rue89 (full text)';
|
||||
const URI = 'https://www.nouvelobs.com/rue89/';
|
||||
const DESCRIPTION = 'Returns the newest posts from Rue89';
|
||||
|
||||
protected function parseItem($item){
|
||||
$item = parent::parseItem($item);
|
||||
|
||||
$url = 'http://api.rue89.nouvelobs.com/export/mobile2/node/'
|
||||
. str_replace(' ', '', substr($item['uri'], -8))
|
||||
. '/full';
|
||||
public function collectData() {
|
||||
|
||||
$datas = json_decode(getContents($url), true);
|
||||
$item['content'] = $datas['node']['body'];
|
||||
$jsonArticles = getContents('https://appdata.nouvelobs.com/rue89/feed.json')
|
||||
or die('Unable to query Rue89 !');
|
||||
$articles = json_decode($jsonArticles)->items;
|
||||
foreach($articles as $article) {
|
||||
$this->items[] = $this->getArticle($article);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function getArticle($articleInfo) {
|
||||
|
||||
$articleJson = getContents($articleInfo->json_url) or die('Unable to get article !');
|
||||
$article = json_decode($articleJson);
|
||||
$item = array();
|
||||
$item['title'] = $article->title;
|
||||
$item['uri'] = $article->url;
|
||||
if($article->content_premium !== null) {
|
||||
$item['content'] = $article->content_premium;
|
||||
} else {
|
||||
$item['content'] = $article->content;
|
||||
}
|
||||
$item['timestamp'] = $article->date_publi;
|
||||
$item['author'] = $article->author->show_name;
|
||||
|
||||
$item['enclosures'] = array();
|
||||
foreach($article->images as $image) {
|
||||
$item['enclosures'][] = $image->url;
|
||||
}
|
||||
|
||||
$item['categories'] = array();
|
||||
foreach($article->categories as $category) {
|
||||
$item['categories'][] = $category->title;
|
||||
}
|
||||
|
||||
return $item;
|
||||
|
||||
}
|
||||
|
||||
public function collectData(){
|
||||
$this->collectExpandableDatas('http://api.rue89.nouvelobs.com/feed');
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ class ThePirateBayBridge extends BridgeAbstract {
|
||||
|
||||
const MAINTAINER = 'mitsukarenai';
|
||||
const NAME = 'The Pirate Bay';
|
||||
const URI = 'https://thepiratebay.org/';
|
||||
const URI = 'https://thepiratebay.wf/';
|
||||
const DESCRIPTION = 'Returns results for the keywords. You can put several
|
||||
list of keywords by separating them with a semicolon (e.g. "one show;another
|
||||
show"). Category based search needs the category number as input. User based
|
||||
|
@@ -77,7 +77,7 @@ class WordPressPluginUpdateBridge extends BridgeAbstract {
|
||||
debugMessage('getting pubdate from url ' . $url . '');
|
||||
// Initialize cache
|
||||
$cache = Cache::create('FileCache');
|
||||
$cache->setPath(CACHE_DIR . '/pages');
|
||||
$cache->setPath(PATH_CACHE . '/pages');
|
||||
$params = [$url];
|
||||
$cache->setParameters($params);
|
||||
// Get cachefile timestamp
|
||||
|
@@ -15,7 +15,7 @@ class AtomFormat extends FormatAbstract{
|
||||
|
||||
$extraInfos = $this->getExtraInfos();
|
||||
$title = $this->xml_encode($extraInfos['name']);
|
||||
$uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/RSS-Bridge/rss-bridge';
|
||||
$uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : REPOSITORY;
|
||||
|
||||
$uriparts = parse_url($uri);
|
||||
if(!empty($extraInfos['icon'])) {
|
||||
|
@@ -18,7 +18,7 @@ class MrssFormat extends FormatAbstract {
|
||||
if(!empty($extraInfos['uri'])) {
|
||||
$uri = $this->xml_encode($extraInfos['uri']);
|
||||
} else {
|
||||
$uri = 'https://github.com/RSS-Bridge/rss-bridge';
|
||||
$uri = REPOSITORY;
|
||||
}
|
||||
|
||||
$uriparts = parse_url($uri);
|
||||
|
38
index.php
38
index.php
@@ -28,11 +28,6 @@ if(file_exists('DEBUG')) {
|
||||
|
||||
require_once __DIR__ . '/lib/RssBridge.php';
|
||||
|
||||
define('PHP_VERSION_REQUIRED', '5.6.0');
|
||||
|
||||
// Specify directory for cached files (using FileCache)
|
||||
define('CACHE_DIR', __DIR__ . '/cache');
|
||||
|
||||
// Specify path for whitelist file
|
||||
define('WHITELIST_FILE', __DIR__ . '/whitelist.txt');
|
||||
|
||||
@@ -54,13 +49,15 @@ if (isset($argv)) {
|
||||
$params = $_GET;
|
||||
}
|
||||
|
||||
// FIXME : beta test UA spoofing, please report any blacklisting by PHP-fopen-unfriendly websites
|
||||
define('USER_AGENT',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:30.0) Gecko/20121202 Firefox/30.0(rss-bridge/'
|
||||
. Configuration::$VERSION
|
||||
. ';+'
|
||||
. REPOSITORY
|
||||
. ')'
|
||||
);
|
||||
|
||||
$userAgent = 'Mozilla/5.0(X11; Linux x86_64; rv:30.0)';
|
||||
$userAgent .= ' Gecko/20121202 Firefox/30.0(rss-bridge/0.1;';
|
||||
$userAgent .= '+https://github.com/RSS-Bridge/rss-bridge)';
|
||||
|
||||
ini_set('user_agent', $userAgent);
|
||||
ini_set('user_agent', USER_AGENT);
|
||||
|
||||
// default whitelist
|
||||
$whitelist_default = array(
|
||||
@@ -83,9 +80,9 @@ $whitelist_default = array(
|
||||
|
||||
try {
|
||||
|
||||
Bridge::setDir(__DIR__ . '/bridges/');
|
||||
Format::setDir(__DIR__ . '/formats/');
|
||||
Cache::setDir(__DIR__ . '/caches/');
|
||||
Bridge::setDir(PATH_LIB_BRIDGES);
|
||||
Format::setDir(PATH_LIB_FORMATS);
|
||||
Cache::setDir(PATH_LIB_CACHES);
|
||||
|
||||
if(!file_exists(WHITELIST_FILE)) {
|
||||
$whitelist_selection = $whitelist_default;
|
||||
@@ -221,7 +218,7 @@ try {
|
||||
|
||||
// Initialize cache
|
||||
$cache = Cache::create('FileCache');
|
||||
$cache->setPath(CACHE_DIR);
|
||||
$cache->setPath(PATH_CACHE);
|
||||
$cache->purgeCache(86400); // 24 hours
|
||||
$cache->setParameters($cache_params);
|
||||
|
||||
@@ -239,7 +236,7 @@ try {
|
||||
$stime = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
||||
|
||||
if($mtime <= $stime) { // Cached data is older or same
|
||||
header('HTTP/1.1 304 Not Modified');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s ', $mtime) . 'GMT', true, 304);
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -316,13 +313,11 @@ try {
|
||||
$format->display();
|
||||
} catch(Error $e) {
|
||||
error_log($e);
|
||||
http_response_code($e->getCode());
|
||||
header('Content-Type: text/html');
|
||||
header('Content-Type: text/html', true, $e->getCode());
|
||||
die(buildTransformException($e, $bridge));
|
||||
} catch(Exception $e) {
|
||||
error_log($e);
|
||||
http_response_code($e->getCode());
|
||||
header('Content-Type: text/html');
|
||||
header('Content-Type: text/html', true, $e->getCode());
|
||||
die(buildTransformException($e, $bridge));
|
||||
}
|
||||
} else {
|
||||
@@ -330,8 +325,7 @@ try {
|
||||
}
|
||||
} catch(HttpException $e) {
|
||||
error_log($e);
|
||||
http_response_code($e->getCode());
|
||||
header('Content-Type: text/plain');
|
||||
header('Content-Type: text/plain', true, $e->getCode());
|
||||
die($e->getMessage());
|
||||
} catch(\Exception $e) {
|
||||
error_log($e);
|
||||
|
@@ -5,8 +5,7 @@ class Authentication {
|
||||
|
||||
if(Configuration::getConfig('authentication', 'enable') === true) {
|
||||
if(!Authentication::verifyPrompt()) {
|
||||
header('WWW-Authenticate: Basic realm="RSS-Bridge"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
header('WWW-Authenticate: Basic realm="RSS-Bridge"', true, 401);
|
||||
die('Please authenticate in order to access this instance !');
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/BridgeInterface.php');
|
||||
|
||||
class Bridge {
|
||||
|
||||
static protected $dirBridge;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/BridgeInterface.php');
|
||||
|
||||
abstract class BridgeAbstract implements BridgeInterface {
|
||||
|
||||
const NAME = 'Unnamed bridge';
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/CacheInterface.php');
|
||||
|
||||
class Cache {
|
||||
|
||||
static protected $dirCache;
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
class Configuration {
|
||||
|
||||
public static $VERSION = 'dev.2018-10-15';
|
||||
public static $VERSION = '2018-11-10';
|
||||
|
||||
public static $config = null;
|
||||
|
||||
public static function verifyInstallation() {
|
||||
|
||||
// Check PHP version
|
||||
if(version_compare(PHP_VERSION, PHP_VERSION_REQUIRED) === -1)
|
||||
die('RSS-Bridge requires at least PHP version ' . PHP_VERSION_REQUIRED . '!');
|
||||
if(version_compare(PHP_VERSION, '5.6.0') === -1)
|
||||
die('RSS-Bridge requires at least PHP version 5.6.0!');
|
||||
|
||||
// extensions check
|
||||
if(!extension_loaded('openssl'))
|
||||
@@ -31,8 +31,8 @@ class Configuration {
|
||||
die('"json" extension not loaded. Please check "php.ini"');
|
||||
|
||||
// Check cache folder permissions (write permissions required)
|
||||
if(!is_writable(CACHE_DIR))
|
||||
die('RSS-Bridge does not have write permissions for ' . CACHE_DIR . '!');
|
||||
if(!is_writable(PATH_CACHE))
|
||||
die('RSS-Bridge does not have write permissions for ' . PATH_CACHE . '!');
|
||||
|
||||
// Check whitelist file permissions (only in DEBUG mode)
|
||||
if(!file_exists(WHITELIST_FILE) && !is_writable(dirname(WHITELIST_FILE)))
|
||||
|
@@ -19,7 +19,8 @@ function buildGitHubIssueQuery($title, $body, $labels = null, $maintainer = null
|
||||
}
|
||||
|
||||
// Add title and body
|
||||
$uri = 'https://github.com/rss-bridge/rss-bridge/issues/new?title='
|
||||
$uri = REPOSITORY
|
||||
. 'issues/new?title='
|
||||
. urlencode($title)
|
||||
. '&body='
|
||||
. urlencode($body);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/BridgeInterface.php');
|
||||
|
||||
abstract class FeedExpander extends BridgeAbstract {
|
||||
|
||||
private $name;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/FormatInterface.php');
|
||||
|
||||
class Format {
|
||||
|
||||
static protected $dirFormat;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
require_once(__DIR__ . '/FormatInterface.php');
|
||||
|
||||
abstract class FormatAbstract implements FormatInterface {
|
||||
const DEFAULT_CHARSET = 'UTF-8';
|
||||
|
||||
|
@@ -1,69 +1,37 @@
|
||||
<?php
|
||||
/* rss-bridge library.
|
||||
Foundation functions for rss-bridge project.
|
||||
See https://github.com/sebsauvage/rss-bridge
|
||||
Licence: Public domain.
|
||||
*/
|
||||
|
||||
define('PATH_VENDOR', '/../vendor');
|
||||
define('PATH_LIB', __DIR__ . '/../lib/'); // Path to core library
|
||||
define('PATH_LIB_VENDOR', __DIR__ . '/../vendor/'); // Path to vendor library
|
||||
define('PATH_LIB_BRIDGES', __DIR__ . '/../bridges/'); // Path to bridges library
|
||||
define('PATH_LIB_FORMATS', __DIR__ . '/../formats/'); // Path to formats library
|
||||
define('PATH_LIB_CACHES', __DIR__ . '/../caches/'); // Path to caches library
|
||||
define('PATH_CACHE', __DIR__ . '/../cache'); // Path to cache folder
|
||||
define('REPOSITORY', 'https://github.com/RSS-Bridge/rss-bridge/');
|
||||
|
||||
require __DIR__ . '/Exceptions.php';
|
||||
require __DIR__ . '/Format.php';
|
||||
require __DIR__ . '/FormatAbstract.php';
|
||||
require __DIR__ . '/Bridge.php';
|
||||
require __DIR__ . '/BridgeAbstract.php';
|
||||
require __DIR__ . '/FeedExpander.php';
|
||||
require __DIR__ . '/Cache.php';
|
||||
require __DIR__ . '/Authentication.php';
|
||||
require __DIR__ . '/Configuration.php';
|
||||
require __DIR__ . '/BridgeCard.php';
|
||||
require __DIR__ . '/BridgeList.php';
|
||||
require __DIR__ . '/ParameterValidator.php';
|
||||
// Interfaces
|
||||
require_once PATH_LIB . 'BridgeInterface.php';
|
||||
require_once PATH_LIB . 'CacheInterface.php';
|
||||
require_once PATH_LIB . 'FormatInterface.php';
|
||||
|
||||
require __DIR__ . '/html.php';
|
||||
require __DIR__ . '/error.php';
|
||||
require __DIR__ . '/contents.php';
|
||||
// Classes
|
||||
require_once PATH_LIB . 'Exceptions.php';
|
||||
require_once PATH_LIB . 'Format.php';
|
||||
require_once PATH_LIB . 'FormatAbstract.php';
|
||||
require_once PATH_LIB . 'Bridge.php';
|
||||
require_once PATH_LIB . 'BridgeAbstract.php';
|
||||
require_once PATH_LIB . 'FeedExpander.php';
|
||||
require_once PATH_LIB . 'Cache.php';
|
||||
require_once PATH_LIB . 'Authentication.php';
|
||||
require_once PATH_LIB . 'Configuration.php';
|
||||
require_once PATH_LIB . 'BridgeCard.php';
|
||||
require_once PATH_LIB . 'BridgeList.php';
|
||||
require_once PATH_LIB . 'ParameterValidator.php';
|
||||
|
||||
$vendorLibSimpleHtmlDom = __DIR__ . PATH_VENDOR . '/simplehtmldom/simple_html_dom.php';
|
||||
if(!file_exists($vendorLibSimpleHtmlDom)) {
|
||||
throw new \HttpException('"PHP Simple HTML DOM Parser" library is missing.
|
||||
Get it from http://simplehtmldom.sourceforge.net and place the script "simple_html_dom.php" in '
|
||||
. substr(PATH_VENDOR, 4)
|
||||
. '/simplehtmldom/',
|
||||
500);
|
||||
}
|
||||
require_once $vendorLibSimpleHtmlDom;
|
||||
// Functions
|
||||
require_once PATH_LIB . 'html.php';
|
||||
require_once PATH_LIB . 'error.php';
|
||||
require_once PATH_LIB . 'contents.php';
|
||||
|
||||
$vendorLibPhpUrlJoin = __DIR__ . PATH_VENDOR . '/php-urljoin/src/urljoin.php';
|
||||
if(!file_exists($vendorLibPhpUrlJoin)) {
|
||||
throw new \HttpException('"php-urljoin" library is missing.
|
||||
Get it from https://github.com/fluffy-critter/php-urljoin and place the script "urljoin.php" in '
|
||||
. substr(PATH_VENDOR, 4)
|
||||
. '/php-urljoin/src/',
|
||||
500);
|
||||
}
|
||||
require_once $vendorLibPhpUrlJoin;
|
||||
|
||||
|
||||
/* Example use
|
||||
|
||||
require_once __DIR__ . '/lib/RssBridge.php';
|
||||
|
||||
// Data retrieval
|
||||
Bridge::setDir(__DIR__ . '/bridges/');
|
||||
$bridge = Bridge::create('GoogleSearch');
|
||||
$bridge->collectData($_REQUEST);
|
||||
|
||||
// Data transformation
|
||||
Format::setDir(__DIR__ . '/formats/');
|
||||
$format = Format::create('Atom');
|
||||
$format
|
||||
->setItems($bridge->getItems())
|
||||
->setExtraInfos(array(
|
||||
'name' => $bridge->getName(),
|
||||
'uri' => $bridge->getURI(),
|
||||
'icon' => $bridge->getIcon(),
|
||||
))
|
||||
->display();
|
||||
|
||||
*/
|
||||
// Vendor
|
||||
require_once PATH_LIB_VENDOR . 'simplehtmldom/simple_html_dom.php';
|
||||
require_once PATH_LIB_VENDOR . 'php-urljoin/src/urljoin.php';
|
||||
|
@@ -113,7 +113,7 @@ $defaultSpanText = DEFAULT_SPAN_TEXT){
|
||||
|
||||
// Initialize cache
|
||||
$cache = Cache::create('FileCache');
|
||||
$cache->setPath(CACHE_DIR . '/pages');
|
||||
$cache->setPath(PATH_CACHE . '/pages');
|
||||
$cache->purgeCache(86400); // 24 hours (forced)
|
||||
|
||||
$params = [$url];
|
||||
|
47
phpcompatibility.xml
Normal file
47
phpcompatibility.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ruleset name="RSS-Bridge PHPCompatibility">
|
||||
<description>Defines rules for PHPCompatibility</description>
|
||||
<exclude-pattern>./static</exclude-pattern>
|
||||
<exclude-pattern>./vendor</exclude-pattern>
|
||||
|
||||
<!-- Run against the PHPCompatibility ruleset -->
|
||||
<!--
|
||||
|
||||
-->
|
||||
<config name="testVersion" value="5.6"/>
|
||||
<rule ref="PHPCompatibility">
|
||||
<!--
|
||||
"PHP 7 changes how most errors are reported by PHP. Instead of reporting
|
||||
errors through the traditional error reporting mechanism used by PHP 5,
|
||||
most errors are now reported by throwing Error exceptions."
|
||||
|
||||
from: http://php.net/manual/en/language.errors.php7.php
|
||||
|
||||
Skip this check for PHP 5.6 in order to support PHP 7.x
|
||||
|
||||
Catch Exception and Error separately to support both versions.
|
||||
|
||||
Example:
|
||||
|
||||
<code>
|
||||
try {
|
||||
// Run your code here
|
||||
} catch(Error $e) {
|
||||
// Handle errors (PHP 7.0+)
|
||||
} catch(Exception $e) {
|
||||
// Handle exceptions (PHP 5.6+)
|
||||
}
|
||||
</code>
|
||||
-->
|
||||
<exclude name="PHPCompatibility.Classes.NewClasses.errorFound"/>
|
||||
<!--
|
||||
RSS-Bridge uses parse_ini_file with INI_SCANNER_TYPED to load configuration
|
||||
settings. INI_SCANNER_TYPED was added in PHP 5.6.1. Skip checking for that
|
||||
specific constant.
|
||||
|
||||
References: http://php.net/manual/de/function.parse-ini-file.php
|
||||
-->
|
||||
<exclude name="PHPCompatibility.Constants.NewConstants.ini_scanner_typedFound"/>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
@@ -6,7 +6,7 @@ use PHPUnit\Framework\AssertionFailedError;
|
||||
|
||||
require_once(__DIR__ . '/../lib/RssBridge.php');
|
||||
|
||||
Bridge::setDir(__DIR__ . '/../bridges/');
|
||||
Bridge::setDir(PATH_LIB_BRIDGES);
|
||||
|
||||
/**
|
||||
* This class checks bridges for implementation details:
|
||||
|
Reference in New Issue
Block a user