Skip to content

Commit

Permalink
core: Automatically select a bridge based on a URL (#928)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Roliga authored and logmanoriginal committed Nov 26, 2018
1 parent b4dbd19 commit 49da67c
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
35 changes: 35 additions & 0 deletions bridges/TwitterBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(){
switch($this->queriedContext) {
case 'By keyword or hashtag':
Expand Down
36 changes: 36 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,42 @@
header('Content-Type: application/json');
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)) {

$format = $params['format']
Expand Down
13 changes: 13 additions & 0 deletions lib/BridgeAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,17 @@ public function getCacheTimeout(){
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;
}
}

}
8 changes: 8 additions & 0 deletions lib/BridgeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,12 @@ public function getURI();
* @return int Cache timeout
*/
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);
}

0 comments on commit 49da67c

Please sign in to comment.