core: Automatically select a bridge based on a URL (#928)
* core: Add bridge parameter auto detection This adds a new 'detect' action which accepts a URL from which an appropriate bridge is selected and relevant parameters are extracted. The user is then automatically redirected to the selected bridge. For example to get a feed from: https://twitter.com/search?q=%23rss-bridge we could send a request to: '/?action=detect&format=Atom&url=twitter.com/search%3Fq%3D%2523rss-bridge' which would redirect to: '/?action=display&q=%23rss-bridge&bridge=Twitter&format=Atom'. This auto detection happens on a per-bridge basis, so a new function 'detectParameters' is added to BridgeInterface which bridges may implement. It takes a URL for an argument and returns a list of parameters that were extracted, or null if the URL isn't relevant for the bridge. * [TwitterBridge] Add parameter auto detection * [BridgeAbstract] Add generic parameter detection This adds generic "paramater detection" for bridges that don't have any parameters defined. If the queried URL matches the URI defined in the bridge (ignoring https://, www. and trailing /) an emtpy list of parameters is returned.
This commit is contained in:
parent
b4dbd191d0
commit
49da67cb33
4 changed files with 92 additions and 0 deletions
|
@ -66,6 +66,41 @@ class TwitterBridge extends BridgeAbstract {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public function detectParameters($url){
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
// By keyword or hashtag (search)
|
||||||
|
$regex = '/^(https?:\/\/)?(www\.)?twitter\.com\/search.*(\?|&)q=([^\/&?\n]+)/';
|
||||||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||||||
|
$params['q'] = urldecode($matches[4]);
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By hashtag
|
||||||
|
$regex = '/^(https?:\/\/)?(www\.)?twitter\.com\/hashtag\/([^\/?\n]+)/';
|
||||||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||||||
|
$params['q'] = urldecode($matches[3]);
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By list
|
||||||
|
$regex = '/^(https?:\/\/)?(www\.)?twitter\.com\/([^\/?\n]+)\/lists\/([^\/?\n]+)/';
|
||||||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||||||
|
$params['user'] = urldecode($matches[3]);
|
||||||
|
$params['list'] = urldecode($matches[4]);
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By username
|
||||||
|
$regex = '/^(https?:\/\/)?(www\.)?twitter\.com\/([^\/?\n]+)/';
|
||||||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||||||
|
$params['u'] = urldecode($matches[3]);
|
||||||
|
return $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function getName(){
|
public function getName(){
|
||||||
switch($this->queriedContext) {
|
switch($this->queriedContext) {
|
||||||
case 'By keyword or hashtag':
|
case 'By keyword or hashtag':
|
||||||
|
|
36
index.php
36
index.php
|
@ -96,6 +96,42 @@ try {
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
echo json_encode($list, JSON_PRETTY_PRINT);
|
echo json_encode($list, JSON_PRETTY_PRINT);
|
||||||
|
|
||||||
|
} elseif($action === 'detect') {
|
||||||
|
|
||||||
|
$targetURL = $params['url']
|
||||||
|
or returnClientError('You must specify a url!');
|
||||||
|
|
||||||
|
$format = $params['format']
|
||||||
|
or returnClientError('You must specify a format!');
|
||||||
|
|
||||||
|
foreach(Bridge::listBridges() as $bridgeName) {
|
||||||
|
|
||||||
|
if(!Bridge::isWhitelisted($bridgeName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bridge = Bridge::create($bridgeName);
|
||||||
|
|
||||||
|
if($bridge === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bridgeParams = $bridge->detectParameters($targetURL);
|
||||||
|
|
||||||
|
if(is_null($bridgeParams)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bridgeParams['bridge'] = $bridgeName;
|
||||||
|
$bridgeParams['format'] = $format;
|
||||||
|
|
||||||
|
header('Location: ?action=display&' . http_build_query($bridgeParams), true, 301);
|
||||||
|
die();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
returnClientError('No bridge found for given URL: ' . $targetURL);
|
||||||
|
|
||||||
} elseif($action === 'display' && !empty($bridge)) {
|
} elseif($action === 'display' && !empty($bridge)) {
|
||||||
|
|
||||||
$format = $params['format']
|
$format = $params['format']
|
||||||
|
|
|
@ -278,4 +278,17 @@ abstract class BridgeAbstract implements BridgeInterface {
|
||||||
return static::CACHE_TIMEOUT;
|
return static::CACHE_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** {@inheritdoc} */
|
||||||
|
public function detectParameters($url){
|
||||||
|
$regex = '/^(https?:\/\/)?(www\.)?(.+?)(\/)?$/';
|
||||||
|
if(empty(static::PARAMETERS)
|
||||||
|
&& preg_match($regex, $url, $urlMatches) > 0
|
||||||
|
&& preg_match($regex, static::URI, $bridgeUriMatches) > 0
|
||||||
|
&& $urlMatches[3] === $bridgeUriMatches[3]) {
|
||||||
|
return array();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,4 +114,12 @@ interface BridgeInterface {
|
||||||
* @return int Cache timeout
|
* @return int Cache timeout
|
||||||
*/
|
*/
|
||||||
public function getCacheTimeout();
|
public function getCacheTimeout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns parameters from given URL or null if URL is not applicable
|
||||||
|
*
|
||||||
|
* @param string $url URL to extract parameters from
|
||||||
|
* @return array|null List of bridge parameters or null if detection failed.
|
||||||
|
*/
|
||||||
|
public function detectParameters($url);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue