-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Bob Corsaro
committed
Feb 11, 2011
0 parents
commit 99bd674
Showing
6 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
<?php | ||
define('VERSION', '0.1.0'); | ||
|
||
class Embedly_API { | ||
private $hostname = 'api.embed.ly'; | ||
private $key = null; | ||
private $_api_version = array( | ||
'oembed' => 1, | ||
'objectify' => 1, | ||
'preview' => 1 | ||
); | ||
private $user_agent = 'Mozilla/5.0 (compatible; embedly-php/${VERSION})'; | ||
|
||
public function __construct($user_agent=null, $key=null, $hostname=null, $_api_version=array()) | ||
{ | ||
if ($user_agent) { | ||
$this->user_agent = $user_agent; | ||
} | ||
if ($key) { | ||
$this->key = $key; | ||
$this->_api_version['objectify'] = 2; | ||
} | ||
if ($hostname) { | ||
$this->hostname = $hostname; | ||
} else if ($key) { | ||
$this->hostname = 'pro.embed.ly'; | ||
} | ||
if ($_api_version) { | ||
$this->_api_version = array_merge($this->_api_version, $_api_version); | ||
} | ||
} | ||
/* Flexibly parse host strings. | ||
* | ||
* Returns an array of | ||
* { protocol: | ||
* , host: | ||
* , port: | ||
* , url: | ||
* } | ||
*/ | ||
private function parse_host($host) { | ||
$port = 80; | ||
$protocol = 'http'; | ||
|
||
preg_match('/^(https?:\/\/)?([^\/]+)(:\d+)?\/?$/', $host, $matches); | ||
|
||
if (!$matches) { | ||
throw new Error(sprintf('invalid host %s', host)); | ||
} | ||
|
||
$hostname = $matches[2]; | ||
|
||
if ($matches[1] == 'https://') { | ||
$protocol = 'https'; | ||
} | ||
|
||
if (array_key_exists(3, $matches) && $matches[3]) { | ||
$port = intval($matches[3]); | ||
} else if ($matches[1] == 'https://') { | ||
$port = 443; | ||
} | ||
|
||
$portpart = ""; | ||
if (array_key_exists(3, $matches) && $matches[3]) { | ||
$portpart = sprintf(":%s", $matches[3]); | ||
} | ||
|
||
$url = sprintf("%s://%s%s/", $protocol, $hostname, $portpart); | ||
|
||
return array( | ||
'url' => $url, | ||
'scheme' => $protocol, | ||
'hostname' => $hostname, | ||
'port' => $port | ||
); | ||
} | ||
|
||
public function oembed($params) | ||
{ | ||
return $this->apicall($this->_api_version['oembed'], 'oembed', $params); | ||
} | ||
|
||
public function preview($params) | ||
{ | ||
return $this->apicall($this->_api_version['preview'], 'preview', $params); | ||
} | ||
|
||
public function objectify($params) | ||
{ | ||
return $this->apicall($this->_api_version['objectify'], 'objectify', $params); | ||
} | ||
|
||
public function api_version() | ||
{ | ||
return $this->_api_version; | ||
} | ||
|
||
public function apicall($version, $action, $params) | ||
{ | ||
if (!array_key_exists('urls', $params)) { | ||
$params['urls'] = array(); | ||
} | ||
if (array_key_exists('url', $params) && $params['url']) { | ||
array_push($params['urls'], $params['url']); | ||
delete($params['url']); | ||
} | ||
|
||
if ($this->key) { | ||
$params['key'] = $this->key; | ||
} | ||
|
||
$path = sprintf("%s/%s", $version, $action); | ||
$url_parts = $this->parse_host($this->hostname); | ||
$apiUrl = sprintf("%s%s?%s", $url_parts['url'], $path, $this->q($params)); | ||
//print("\ncalling $apiUrl\n"); | ||
|
||
$ch = curl_init($apiUrl); | ||
$this->setCurlOptions($ch, array( | ||
sprintf('Host: %s', $url_parts['hostname']), | ||
sprintf('User-Agent: %s', $this->user_agent) | ||
)); | ||
$res = $this->curlExec($ch); | ||
$result = json_decode($res); | ||
return $result; | ||
} | ||
|
||
private function q($params) { | ||
$pairs = array_map(function($key, $value) { | ||
$key = urlencode($key); | ||
if (is_array($value)) { | ||
$value = implode(',', array_map(function($i){ | ||
return urlencode($i); | ||
}, $value)); | ||
} else { | ||
$value = urlencode($value); | ||
} | ||
return sprintf("%s=%s", $key, $value); | ||
}, array_keys($params), array_values($params)); | ||
return implode('&', $pairs); | ||
} | ||
|
||
private function setCurlOptions(&$ch, $headers = array()) | ||
{ | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
curl_setopt($ch, CURLOPT_HEADER, false); | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | ||
curl_setopt($ch, CURLOPT_BUFFERSIZE, 4096); | ||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 25); | ||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | ||
} | ||
|
||
private function curlExec(&$ch) | ||
{ | ||
$res = curl_exec($ch); | ||
if (false === $res) { | ||
throw new Exception(curl_error($ch), curl_errno($ch)); | ||
} | ||
return $res; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2011 Embed.ly, Inc. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Feature: Objectify | ||
|
||
As an embedly user | ||
I want to call the the embedly api | ||
Because I want to objectify a url | ||
|
||
Scenario Outline: Get the meta description | ||
Given an embedly api | ||
When objectify is called with the <url> URL | ||
Then the meta.description should start with <metadesc> | ||
And objectify api_version is 1 | ||
|
||
Examples: | ||
| url | metadesc | | ||
| http://tweetphoto.com/14784358 | Plixi allows user to ins | | ||
|
||
Scenario Outline: Get the meta description with pro | ||
Given an embedly api with key | ||
When objectify is called with the <url> URL | ||
Then the meta.description should start with <metadesc> | ||
And objectify api_version is 2 | ||
|
||
Examples: | ||
| url | metadesc | | ||
| http://tweetphoto.com/14784358 | Plixi allows user to ins | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
Feature: OEmbed | ||
|
||
As an embedly user | ||
I want to call the the embedly api | ||
Because I want and oembed for a specific url | ||
|
||
Scenario Outline: Get the provider_url | ||
Given an embedly api | ||
When oembed is called with the <url> URL | ||
Then the provider_url should be <provider_url> | ||
|
||
Examples: | ||
| url | provider_url | | ||
| http://www.scribd.com/doc/13994900/Easter | http://www.scribd.com/ | | ||
| http://www.scribd.com/doc/28452730/Easter-Cards | http://www.scribd.com/ | | ||
| http://www.youtube.com/watch?v=Zk7dDekYej0 | http://www.youtube.com/ | | ||
| http://tweetphoto.com/14784358 | http://plixi.com | | ||
|
||
|
||
Scenario Outline: Get the types | ||
Given an embedly api | ||
When oembed is called with the <url> URL | ||
Then the type should be <type> | ||
|
||
Examples: | ||
| url | type | | ||
| http://www.scribd.com/doc/13994900/Easter | rich | | ||
| http://www.scribd.com/doc/28452730/Easter-Cards | rich | | ||
| http://www.youtube.com/watch?v=Zk7dDekYej0 | video | | ||
| http://tweetphoto.com/14784358 | photo | | ||
|
||
|
||
Scenario Outline: Get the provider_url with force flag | ||
Given an embedly api | ||
When oembed is called with the <url> URL and force flag | ||
Then the provider_url should be <provider_url> | ||
|
||
Examples: | ||
| url | provider_url | | ||
| http://www.youtube.com/watch?v=Zk7dDekYej0 | http://www.youtube.com/ | | ||
|
||
|
||
Scenario Outline: Get multiple provider_urls | ||
Given an embedly api | ||
When oembed is called with the <urls> URLs | ||
Then provider_url should be <provider_urls> | ||
|
||
Examples: | ||
| urls | provider_urls | | ||
| http://www.scribd.com/doc/13994900/Easter,http://www.scribd.com/doc/28452730/Easter-Cards | http://www.scribd.com/,http://www.scribd.com/ | | ||
| http://www.youtube.com/watch?v=Zk7dDekYej0,http://plixi.com/p/16044847 | http://www.youtube.com/,http://plixi.com | | ||
|
||
|
||
Scenario Outline: Get the provider_url with pro | ||
Given an embedly api with key | ||
When oembed is called with the <url> URL | ||
Then the provider_url should be <provider_url> | ||
|
||
Examples: | ||
| url | provider_url | | ||
| http://blog.embed.ly/bob | http://posterous.com | | ||
| http://blog.doki-pen.org/cassandra-rules | http://posterous.com | | ||
| http://www.guardian.co.uk/media/2011/jan/21/andy-coulson-phone-hacking-statement | http://www.guardian.co.uk/ | | ||
|
||
|
||
Scenario Outline: Attempt to get 404 URL | ||
Given an embedly api | ||
When oembed is called with the <url> URL | ||
Then type should be error | ||
And error_code should be 404 | ||
And type should be error | ||
|
||
Examples: | ||
| url | | ||
| http://www.youtube.com/watch/is/a/bad/url | | ||
| http://www.scribd.com/doc/zfldsf/asdfkljlas/klajsdlfkasdf | | ||
| http://tweetphoto.com/alsdfldsf/asdfkljlas/klajsdlfkasdf | | ||
|
||
|
||
Scenario Outline: Attempt multi get 404 URLs | ||
Given an embedly api | ||
When oembed is called with the <urls> URLs | ||
Then error_code should be <errcode> | ||
And type should be <types> | ||
|
||
Examples: | ||
| urls | errcode | types | | ||
| http://www.youtube.com/watch/a/bassd/url,http://www.youtube.com/watch/ldf/asdlfj | 404,404 | error,error | | ||
| http://www.scribd.com/doc/lsbsdlfldsf/kl,http://www.scribd.com/doc/zasdf/asdfl | 404,404 | error,error | | ||
| http://www.youtube.com/watch/zzzzasdf/kl,http://tweetphoto.com/14784358 | 404, | error,photo | | ||
| http://tweetphoto.com/14784358,http://www.scribd.com/doc/asdfasdfasdf | ,404 | photo,error | | ||
|
||
Scenario Outline: Attempt at non-api service without key | ||
Given an embedly api | ||
When oembed is called with the <url> URL | ||
Then error_code should be 401 | ||
And error_message should be This service requires an Embedly Pro account | ||
And type should be error | ||
|
||
Examples: | ||
| url | | ||
| http://hn.embed.ly/ | | ||
| http://bit.ly/enZRxO | | ||
| http://techcrunch.com/2011/02/03/linkedins-next-data-dive-professional-skills/ | | ||
| http://teachertube.com/rssPhoto.php | | ||
| http://goo.gl/y1i9p | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php | ||
require_once('Embedly.php'); | ||
|
||
|
||
$steps->Given('/an embedly api$/', function($world) { | ||
$world->embedlyapi = new Embedly_API(); | ||
$world->api = $world->embedlyapi; | ||
}); | ||
|
||
$steps->Given('/an embedly api with key/', function($world) { | ||
if (getenv('EMBEDLY_KEY') === null) { | ||
throw new Exception('Please set env variable $EMBEDLY_KEY'); | ||
} | ||
$world->embedlypro = new Embedly_API(array( | ||
'key' => getenv('EMBEDLY_KEY') | ||
)); | ||
$world->api = $world->embedlypro; | ||
}); | ||
|
||
$steps->When('/(\w+) is called with the (.*) URLs?( and ([^\s]+) flag)?$/', function($world, $method, $urls, $_=null, $flag=null) { | ||
$world->result = null; | ||
try { | ||
$urls = explode(',', $urls); | ||
$opts = array( | ||
'urls' => $urls | ||
); | ||
if ($flag != null) { | ||
$opts[$flag] = TRUE; | ||
} | ||
$world->result = $world->api->$method($opts); | ||
} catch(Exception $e) { | ||
print("\nAn error occurred: "); | ||
print($e->getMessage()); | ||
print("\n "); | ||
print($e->getFile()); | ||
print(":"); | ||
print($e->getLine()); | ||
$world->error = $e; | ||
} | ||
}); | ||
|
||
$steps->Then('/an? (\w+) error should get thrown/', function($world, $error) { | ||
//$world->error.class.to_s.should == error | ||
assertEquals(1,1); | ||
}); | ||
|
||
$steps->Then('/objectify api_version is (\d+)$/', function($world, $version) { | ||
$api_version = $world->api->api_version(); | ||
assertEquals($api_version['objectify'], $version); | ||
}); | ||
|
||
$steps->Then('/([^\s]+) should be (.+)$/', function($world, $key, $value) { | ||
if ($world->error) { | ||
throw $world->error; | ||
} | ||
|
||
$results = array_map(function($o) use ($key){ | ||
return $o->$key; | ||
}, $world->result); | ||
assertEquals(implode(',', $results), $value); | ||
}); | ||
|
||
$steps->Then('/([^\s]+) should start with ([^\s]+)/', function($world, $key, $value) { | ||
if ($world->error) { | ||
throw $world->error; | ||
} | ||
//$v = array_reduce(key.split('.').inject(@result[0]){|o,c| o.send(c)}.to_s | ||
//assertEquals(v_s.should match(/^#{value}/) | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?php | ||
|
||
require_once 'PHPUnit/Autoload.php'; | ||
require_once 'PHPUnit/Framework/Assert/Functions.php'; | ||
|
||
require_once __DIR__ . '/../../Embedly.php'; |