soundcloud python/php apis, recorder python script so far.

This commit is contained in:
Naomi 2011-03-05 11:53:29 -05:00
parent b3e111b0a0
commit f68a8f67ea
109 changed files with 24297 additions and 10 deletions

View file

@ -0,0 +1,114 @@
# SoundCloud PHP API Wrapper
## Introduction
A wrapper for the SoundCloud API written in PHP with support for authentication using [OAuth 2.0](http://oauth.net/2/).
The wrapper got a real overhaul with version 2.0. The current version was written with [PEAR](http://pear.php.net/) in mind and can easily by distributed as a PEAR package.
## Getting started
Check out the [getting started](https://github.com/mptre/php-soundcloud/wiki/OAuth-2) wiki entry for further reference on how to get started. Also make sure to check out the [demo application](https://github.com/mptre/ci-soundcloud) for some example code.
## Examples
The wrapper includes convenient methods used to perform HTTP requests on behalf of the authenticated user. Below you'll find a few quick examples.
Ofcourse you need to handle the authentication first before being able to request and modify protect resources as demonstrated below. Therefor I refer to the [demo application](https://github.com/mptre/ci-soundcloud) which got some example code on how to handle authentication.
### GET
<pre><code>try {
$response = json_decode($soundcloud->get('me'), true);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}</code></pre>
### POST
<pre><code>$comment = &lt;&lt;&lt;EOH
&lt;comment&gt;
&lt;body&gt;Yeah!&lt;/body&gt;
&lt;/comment&gt;
EOH;
try {
$response = json_decode(
$soundcloud->post(
'tracks/1/comments',
$comment,
array(CURLOPT_HTTPHEADER => array('Content-Type: application/xml'))
),
true
);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}</code></pre>
### PUT
<pre><code>$track = &lt;&lt;&lt;EOH
&lt;track&gt;
&lt;downloadable&gt;true&lt;/downloadable&gt;
&lt;/track&gt;
EOH;
try {
$response = json_decode(
$soundcloud->put(
'tracks/1',
$track,
array(CURLOPT_HTTPHEADER => array('Content-Type: application/xml'))
),
true
);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}</code></pre>
### DELETE
<pre><code>try {
$response = json_decode($soundcloud->delete('tracks/1'), true);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}</code></pre>
### DOWNLOAD TRACK
<pre><code>try {
$track = $soundcloud->download(1337);
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
exit($e->getMessage());
}
// do something clever with $track. Save to file perhaps?</code></pre>
## Feedback and questions
Found a bug or missing a feature? Don't hesitate to create a new issue here on GitHub. Or contact me [directly](https://github.com/mptre).
Also make sure to check out the official [documentation](https://github.com/soundcloud/api/wiki/) and the join [Google Group](https://groups.google.com/group/soundcloudapi?pli=1) in order to stay updated.
## License
Copyright (c) 2011 Anton Lindqvist
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.

View file

@ -0,0 +1,713 @@
<?php
require_once 'Soundcloud/Exception.php';
require_once 'Soundcloud/Version.php';
/**
* SoundCloud API wrapper with support for authentication using OAuth 2.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud {
/**
* Custom cURL option.
*
* @access public
*
* @var integer
*/
const CURLOPT_OAUTH_TOKEN = 173;
/**
* Access token returned by the service provider after a successful authentication.
*
* @access private
*
* @var string
*/
private $_accessToken;
/**
* Version of the API to use.
*
* @access private
*
* @var integer
*/
private static $_apiVersion = 1;
/**
* Supported audio MIME types.
*
* @access private
*
* @var array
*/
private static $_audioMimeTypes = array(
'aac' => 'video/mp4',
'aiff' => 'audio/x-aiff',
'flac' => 'audio/flac',
'mp3' => 'audio/mpeg',
'ogg' => 'audio/ogg',
'wav' => 'audio/x-wav'
);
/**
* OAuth client id.
*
* @access private
*
* @var string
*/
private $_clientId;
/**
* OAuth client secret.
*
* @access private
*
* @var string
*/
private $_clientSecret;
/**
* Development mode.
*
* @access private
*
* @var boolean
*/
private $_development;
/**
* Available API domains.
*
* @access private
*
* @var array
*/
private static $_domains = array(
'development' => 'sandbox-soundcloud.com',
'production' => 'soundcloud.com'
);
/**
* HTTP response body from the last request.
*
* @access private
*
* @var string
*/
private $_lastHttpResponseBody;
/**
* HTTP response code from the last request.
*
* @access private
*
* @var integer
*/
private $_lastHttpResponseCode;
/**
* HTTP response headers from last request.
*
* @access private
*
* @var array
*/
private $_lastHttpResponseHeaders;
/**
* OAuth paths.
*
* @access private
*
* @var array
*/
private static $_paths = array(
'authorize' => 'connect',
'access_token' => 'oauth2/token',
);
/**
* OAuth redirect uri.
*
* @access private
*
* @var string
*/
private $_redirectUri;
/**
* API response format MIME type.
*
* @access private
*
* @var string
*/
private $_requestFormat;
/**
* Available response formats.
*
* @access private
*
* @var array
*/
private static $_responseFormats = array(
'*' => '*/*',
'json' => 'application/json',
'xml' => 'application/xml'
);
/**
* HTTP user agent.
*
* @access private
*
* @var string
*/
private static $_userAgent = 'PHP-SoundCloud';
/**
* Class version.
*
* @var string
*/
public $version;
/**
* Constructor.
*
* @param string $clientId OAuth client id
* @param string $clientSecret OAuth client secret
* @param string $redirectUri OAuth redirect uri
* @param boolean $development Sandbox mode
*
* @throws Services_Soundcloud_Missing_Client_Id_Exception when missing client id
* @return void
*/
function __construct($clientId, $clientSecret, $redirectUri = null, $development = false) {
if (empty($clientId)) {
throw new Services_Soundcloud_Missing_Client_Id_Exception();
}
$this->_clientId = $clientId;
$this->_clientSecret = $clientSecret;
$this->_redirectUri = $redirectUri;
$this->_development = $development;
$this->_responseFormat = self::$_responseFormats['json'];
$this->version = Services_Soundcloud_Version::get();
}
/**
* Get authorization URL.
*
* @param array $params Optional query string parameters
*
* @return string
* @see Soundcloud::_buildUrl()
*/
function getAuthorizeUrl($params = array()) {
$defaultParams = array(
'client_id' => $this->_clientId,
'redirect_uri' => $this->_redirectUri,
'response_type' => 'code'
);
$params = array_merge($defaultParams, $params);
return $this->_buildUrl(self::$_paths['authorize'], $params, false);
}
/**
* Get access token URL.
*
* @param array $params Optional query string parameters
*
* @return string
* @see Soundcloud::_buildUrl()
*/
function getAccessTokenUrl($params = array()) {
return $this->_buildUrl(self::$_paths['access_token'], $params, false);
}
/**
* Retrieve access token.
*
* @param string $code OAuth code returned from the service provider
* @param array $postData Optional post data
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_getAccessToken()
*/
function accessToken($code, $postData = array(), $curlOptions = array()) {
$defaultPostData = array(
'code' => $code,
'client_id' => $this->_clientId,
'client_secret' => $this->_clientSecret,
'redirect_uri' => $this->_redirectUri,
'grant_type' => 'authorization_code'
);
$postData = array_merge($defaultPostData, $postData);
return $this->_getAccessToken($postData, $curlOptions);
}
/**
* Refresh access token.
*
* @param string $refreshToken
* @param array $postData Optional post data
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_getAccessToken()
*/
function accessTokenRefresh($refreshToken, $postData = array(), $curlOptions = array()) {
$defaultPostData = array(
'refresh_token' => $refreshToken,
'client_id' => $this->_clientId,
'client_secret' => $this->_clientSecret,
'redirect_uri' => $this->_redirectUri,
'grant_type' => 'refresh_token'
);
$postData = array_merge($defaultPostData, $postData);
return $this->_getAccessToken($postData, $curlOptions);
}
/**
* Get access token.
*
* @return mixed
*/
function getAccessToken() {
return $this->_accessToken;
}
/**
* Get API version.
*
* @return integer
*/
function getApiVersion() {
return self::$_apiVersion;
}
/**
* Get the corresponding MIME type for a given file extension.
*
* @param string $extension
*
* @return string
* @throws Services_Soundcloud_Unsupported_Audio_Format_Exception if the format is unsupported
*/
function getAudioMimeType($extension) {
if (array_key_exists($extension, self::$_audioMimeTypes)) {
return self::$_audioMimeTypes[$extension];
} else {
throw new Services_Soundcloud_Unsupported_Audio_Format_Exception();
}
}
/**
* Get development mode.
*
* @return boolean
*/
function getDevelopment() {
return $this->_development;
}
/**
* Get HTTP response header.
*
* @param string $header Name of the header
*
* @return mixed
*/
function getHttpHeader($header) {
if (is_array($this->_lastHttpResponseHeaders)
&& array_key_exists($header, $this->_lastHttpResponseHeaders)
) {
return $this->_lastHttpResponseHeaders[$header];
} else {
return false;
}
}
/**
* Get redirect uri.
*
* @return mixed
*/
function getRedirectUri() {
return $this->_redirectUri;
}
/**
* Get response format.
*
* @return string
*/
function getResponseFormat() {
return $this->_responseFormat;
}
/**
* Set access token.
*
* @param string $accessToken
*
* @return object
*/
function setAccessToken($accessToken) {
$this->_accessToken = $accessToken;
return $this;
}
/**
* Set redirect uri.
*
* @param string $redirectUri
*
* @return object
*/
function setRedirectUri($redirectUri) {
$this->_redirectUri = $redirectUri;
return $this;
}
/**
* Set response format.
*
* @param string $format Could either be xml or json
*
* @throws Services_Soundcloud_Unsupported_Response_Format_Exception if the given response format isn't supported
* @return object
*/
function setResponseFormat($format) {
if (array_key_exists($format, self::$_responseFormats)) {
$this->_responseFormat = self::$_responseFormats[$format];
} else {
throw new Services_Soundcloud_Unsupported_Response_Format_Exception();
}
return $this;
}
/**
* Set development mode.
*
* @param boolean $development
*
* @return object
*/
function setDevelopment($development) {
$this->_development = $development;
return $this;
}
/**
* Send a GET HTTP request.
*
* @param string $path URI to request
* @param array $params Optional query string parameters
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_request()
*/
function get($path, $params = array(), $curlOptions = array()) {
$url = $this->_buildUrl($path, $params);
return $this->_request($url, $curlOptions);
}
/**
* Send a POST HTTP request.
*
* @param string $path URI to request
* @param array $postData Optional post data
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_request()
*/
function post($path, $postData = array(), $curlOptions = array()) {
$url = $this->_buildUrl($path);
$options = array(CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postData);
$options += $curlOptions;
return $this->_request($url, $options);
}
/**
* Send a PUT HTTP request.
*
* @param string $path URI to request
* @param array $postData Optional post data
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_request()
*/
function put($path, $postData, $curlOptions = array()) {
$url = $this->_buildUrl($path);
$options = array(
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => $postData
);
$options += $curlOptions;
return $this->_request($url, $options);
}
/**
* Send a DELETE HTTP request.
*
* @param string $path URI to request
* @param array $params Optional query string parameters
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_request()
*/
function delete($path, $params = array(), $curlOptions = array()) {
$url = $this->_buildUrl($path, $params);
$options = array(CURLOPT_CUSTOMREQUEST => 'DELETE');
$options += $curlOptions;
return $this->_request($url, $options);
}
/**
* Download track.
*
* @param integer $trackId
* @param array Optional query string parameters
* @param array $curlOptions Optional cURL options
*
* @return mixed
* @see Soundcloud::_request()
*/
function download($trackId, $params = array(), $curlOptions = array()) {
$lastResponseFormat = array_pop(
preg_split('/\//', $this->getResponseFormat())
);
$defaultParams = array('oauth_token' => $this->getAccessToken());
$defaultCurlOptions = array(
CURLOPT_FOLLOWLOCATION => true,
self::CURLOPT_OAUTH_TOKEN => false
);
$url = $this->_buildUrl(
'tracks/' . $trackId . '/download',
array_merge($defaultParams, $params)
);
$options = $defaultCurlOptions + $curlOptions;
$this->setResponseFormat('*');
$response = $this->_request($url, $options);
// rollback to the previously defined response format.
$this->setResponseFormat($lastResponseFormat);
return $response;
}
/**
* Construct default HTTP headers including response format and authorization.
*
* @param boolean Include access token or not
*
* @return array $headers
*/
protected function _buildDefaultHeaders($includeAccessToken = true) {
$headers = array();
if ($this->_responseFormat) {
array_push($headers, 'Accept: ' . $this->_responseFormat);
}
if ($includeAccessToken && $this->_accessToken) {
array_push($headers, 'Authorization: OAuth ' . $this->_accessToken);
}
return $headers;
}
/**
* Construct a URL.
*
* @param string $path Relative or absolute URI
* @param array $params Optional query string parameters
* @param boolean $includeVersion Include API version
*
* @return string $url
*/
protected function _buildUrl($path, $params = null, $includeVersion = true) {
if (preg_match('/^https?\:\/\//', $path)) {
$url = $path;
} else {
$url = 'https://';
$url .= (!preg_match('/connect/', $path)) ? 'api.' : '';
$url .= ($this->_development)
? self::$_domains['development']
: self::$_domains['production'];
$url .= '/';
$url .= ($includeVersion) ? 'v' . self::$_apiVersion . '/' : '';
$url .= $path;
}
$url .= (count($params)) ? '?' . http_build_query($params) : '';
return $url;
}
/**
* Retrieve access token.
*
* @param array $postData Post data
* @param array $curlOptions Optional cURL options
*
* @return mixed
*/
protected function _getAccessToken($postData, $curlOptions = array()) {
$options = array(CURLOPT_POST => true, CURLOPT_POSTFIELDS => $postData);
$options += $curlOptions;
$response = json_decode(
$this->_request($this->getAccessTokenUrl(), $options),
true
);
if (array_key_exists('access_token', $response)) {
$this->_accessToken = $response['access_token'];
return $response;
} else {
return false;
}
}
/**
* Get HTTP user agent.
*
* @access protected
*
* @return string
*/
protected function _getUserAgent() {
return self::$_userAgent . '/' . $this->version;
}
/**
* Parse HTTP response headers.
*
* @param string $headers
*
* @return array
*/
protected function _parseHttpHeaders($headers) {
$headers = preg_split('/\n/', trim($headers));
$parsedHeaders = array();
foreach ($headers as $header) {
if (!preg_match('/\:\s/', $header)) {
continue;
}
list($key, $val) = preg_split('/\:\s/', $header, 2);
$key = str_replace('-', '_', strtolower($key));
$val = trim($val);
$parsedHeaders[$key] = $val;
}
return $parsedHeaders;
}
/**
* Validates HTTP response code.
*
* @access protected
*
* @return boolean
*/
protected function _validResponseCode($code) {
return (bool)preg_match('/^20[0-9]{1}$/', $code);
}
/**
* Performs the actual HTTP request using curl. Can be overwritten by extending classes.
*
* @access protected
*
* @param string $url
* @param array $curlOptions Optional cURL options
*
* @throws Services_Soundcloud_Invalid_Http_Response_Code_Exception if the response code isn't valid
* @return mixed
*/
protected function _request($url, $curlOptions = array()) {
$ch = curl_init();
$options = array(
CURLOPT_URL => $url,
CURLOPT_HEADER => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => $this->_getUserAgent()
);
$options += $curlOptions;
if (array_key_exists(self::CURLOPT_OAUTH_TOKEN, $options)) {
$includeAccessToken = $options[self::CURLOPT_OAUTH_TOKEN];
unset($options[self::CURLOPT_OAUTH_TOKEN]);
} else {
$includeAccessToken = true;
}
if (array_key_exists(CURLOPT_HTTPHEADER, $options)) {
$options[CURLOPT_HTTPHEADER] = array_merge(
$this->_buildDefaultHeaders(),
$curlOptions[CURLOPT_HTTPHEADER]
);
} else {
$options[CURLOPT_HTTPHEADER] = $this->_buildDefaultHeaders($includeAccessToken);
}
curl_setopt_array($ch, $options);
$data = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$this->_lastHttpResponseHeaders = $this->_parseHttpHeaders(
substr($data, 0, $info['header_size'])
);
$this->_lastHttpResponseBody = substr($data, $info['header_size']);
$this->_lastHttpResponseCode = $info['http_code'];
if ($this->_validResponseCode($this->_lastHttpResponseCode)) {
return $this->_lastHttpResponseBody;
} else {
throw new Services_Soundcloud_Invalid_Http_Response_Code_Exception(
null,
0,
$this->_lastHttpResponseBody,
$this->_lastHttpResponseCode
);
}
}
}

View file

@ -0,0 +1,146 @@
<?php
/**
* Soundcloud missing client id exception.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Missing_Client_Id_Exception extends Exception {
/**
* Default message.
*
* @access protected
*
* @var string
*/
protected $message = 'All requests must include a consumer key. Referred to as client_id in OAuth2.';
}
/**
* Soundcloud invalid HTTP response code exception.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Invalid_Http_Response_Code_Exception extends Exception {
/**
* HTTP response body.
*
* @access protected
*
* @var string
*/
protected $httpBody;
/**
* HTTP response code.
*
* @access protected
*
* @var integer
*/
protected $httpCode;
/**
* Default message.
*
* @access protected
*
* @var string
*/
protected $message = 'The requested URL responded with HTTP code %d.';
/**
* Constructor.
*
* @param string $message
* @param string $code
* @param string $httpBody
* @param integer $httpCode
*
* @return void
*/
function __construct($message = null, $code = 0, $httpBody = null, $httpCode = 0) {
$this->httpBody = $httpBody;
$this->httpCode = $httpCode;
$message = sprintf($this->message, $httpCode);
parent::__construct($message, $code);
}
/**
* Get HTTP response body.
*
* @return mixed
*/
function getHttpBody() {
return $this->httpBody;
}
/**
* Get HTTP response code.
*
* @return mixed
*/
function getHttpCode() {
return $this->httpCode;
}
}
/**
* Soundcloud unsupported response format exception.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Unsupported_Response_Format_Exception extends Exception {
/**
* Default message.
*
* @access protected
*
* @var string
*/
protected $message = 'The given response format is unsupported.';
}
/**
* Soundcloud unsupported audio format exception.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Unsupported_Audio_Format_Exception extends Exception {
/**
* Default message.
*
* @access protected
*
* @var string
*/
protected $message = 'The given audio format is unsupported.';
}

View file

@ -0,0 +1,22 @@
<?php
/**
* Soundcloud package version.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Version {
const MAJOR = 2;
const MINOR = 1;
const PATCH = 1;
public static function get() {
return implode('.', array(self::MAJOR, self::MINOR, self::PATCH));
}
}

View file

@ -0,0 +1,310 @@
<?php
require_once 'Soundcloud_Test_Helper.php';
class Soundcloud_Test extends PHPUnit_Framework_TestCase {
protected $soundcloud;
function setUp() {
$this->soundcloud = new Services_Soundcloud_Expose(
'1337',
'1337',
'http://soundcloud.local/callback'
);
}
function tearDown() {
$this->soundcloud = null;
}
function testVersionFormat() {
$this->assertRegExp(
'/^[0-9]+\.[0-9]+\.[0-9]+$/',
Services_Soundcloud_Version::get()
);
}
function testGetUserAgent() {
$this->assertRegExp(
'/^PHP\-SoundCloud\/[0-9]+\.[0-9]+\.[0-9]+$/',
$this->soundcloud->getUserAgent()
);
}
function testApiVersion() {
$this->assertEquals(1, $this->soundcloud->getApiVersion());
}
function testGetAudioMimeTypes() {
$supportedExtensions = array(
'aac' => 'video/mp4',
'aiff' => 'audio/x-aiff',
'flac' => 'audio/flac',
'mp3' => 'audio/mpeg',
'ogg' => 'audio/ogg',
'wav' => 'audio/x-wav'
);
$unsupportedExtensions = array('gif', 'html', 'jpg', 'mp4', 'xml', 'xspf');
foreach ($supportedExtensions as $extension => $mimeType) {
$this->assertEquals(
$mimeType,
$this->soundcloud->getAudioMimeType($extension)
);
}
foreach ($unsupportedExtensions as $extension => $mimeType) {
$this->setExpectedException('Services_Soundcloud_Unsupported_Audio_Format_Exception');
$this->soundcloud->getAudioMimeType($extension);
}
}
function testGetAuthorizeUrl() {
$this->assertEquals(
'https://soundcloud.com/connect?client_id=1337&redirect_uri=http%3A%2F%2Fsoundcloud.local%2Fcallback&response_type=code',
$this->soundcloud->getAuthorizeUrl()
);
}
function testGetAuthorizeUrlWithCustomQueryParameters() {
$this->assertEquals(
'https://soundcloud.com/connect?client_id=1337&redirect_uri=http%3A%2F%2Fsoundcloud.local%2Fcallback&response_type=code&foo=bar',
$this->soundcloud->getAuthorizeUrl(array('foo' => 'bar'))
);
$this->assertEquals(
'https://soundcloud.com/connect?client_id=1337&redirect_uri=http%3A%2F%2Fsoundcloud.local%2Fcallback&response_type=code&foo=bar&bar=foo',
$this->soundcloud->getAuthorizeUrl(array('foo' => 'bar', 'bar' => 'foo'))
);
}
function testGetAccessTokenUrl() {
$this->assertEquals(
'https://api.soundcloud.com/oauth2/token',
$this->soundcloud->getAccessTokenUrl()
);
}
function testSetAccessToken() {
$this->soundcloud->setAccessToken('1337');
$this->assertEquals('1337', $this->soundcloud->getAccessToken());
}
function testSetDevelopment() {
$this->soundcloud->setDevelopment(true);
$this->assertTrue($this->soundcloud->getDevelopment());
}
function testSetRedirectUri() {
$this->soundcloud->setRedirectUri('http://soundcloud.local/callback');
$this->assertEquals(
'http://soundcloud.local/callback',
$this->soundcloud->getRedirectUri()
);
}
function testDefaultResponseFormat() {
$this->assertEquals(
'application/json',
$this->soundcloud->getResponseFormat()
);
}
function testSetResponseFormatHtml() {
$this->setExpectedException('Services_Soundcloud_Unsupported_Response_Format_Exception');
$this->soundcloud->setResponseFormat('html');
}
function testSetResponseFormatAll() {
$this->soundcloud->setResponseFormat('*');
$this->assertEquals(
'*/*',
$this->soundcloud->getResponseFormat()
);
}
function testSetResponseFormatJson() {
$this->soundcloud->setResponseFormat('json');
$this->assertEquals(
'application/json',
$this->soundcloud->getResponseFormat()
);
}
function testSetResponseFormatXml() {
$this->soundcloud->setResponseFormat('xml');
$this->assertEquals(
'application/xml',
$this->soundcloud->getResponseFormat()
);
}
function testResponseCodeSuccess() {
$this->assertTrue($this->soundcloud->validResponseCode(200));
}
function testResponseCodeRedirect() {
$this->assertFalse($this->soundcloud->validResponseCode(301));
}
function testResponseCodeClientError() {
$this->assertFalse($this->soundcloud->validResponseCode(400));
}
function testResponseCodeServerError() {
$this->assertFalse($this->soundcloud->validResponseCode(500));
}
function testBuildDefaultHeaders() {
$this->assertEquals(
array('Accept: application/json'),
$this->soundcloud->buildDefaultHeaders()
);
}
function testBuildDefaultHeadersWithAccessToken() {
$this->soundcloud->setAccessToken('1337');
$this->assertEquals(
array('Accept: application/json', 'Authorization: OAuth 1337'),
$this->soundcloud->buildDefaultHeaders()
);
}
function testBuildUrl() {
$this->assertEquals(
'https://api.soundcloud.com/v1/me',
$this->soundcloud->buildUrl('me')
);
}
function testBuildUrlWithQueryParameters() {
$this->assertEquals(
'https://api.soundcloud.com/v1/tracks?q=rofl+dubstep',
$this->soundcloud->buildUrl(
'tracks',
array('q' => 'rofl dubstep')
)
);
$this->assertEquals(
'https://api.soundcloud.com/v1/tracks?q=rofl+dubstep&filter=public',
$this->soundcloud->buildUrl(
'tracks',
array('q' => 'rofl dubstep', 'filter' => 'public')
)
);
}
function testBuildUrlWithDevelopmentDomain() {
$this->soundcloud->setDevelopment(true);
$this->assertEquals(
'https://api.sandbox-soundcloud.com/v1/me',
$this->soundcloud->buildUrl('me')
);
}
function testBuildUrlWithoutApiVersion() {
$this->assertEquals(
'https://api.soundcloud.com/me',
$this->soundcloud->buildUrl('me', null, false)
);
}
function testBuildUrlWithAbsoluteUrl() {
$this->assertEquals(
'https://api.soundcloud.com/me',
$this->soundcloud->buildUrl('https://api.soundcloud.com/me')
);
}
/**
* @dataProvider dataProviderHttpHeaders
*/
function testParseHttpHeaders($rawHeaders, $expectedHeaders) {
$parsedHeaders = $this->soundcloud->parseHttpHeaders($rawHeaders);
foreach ($parsedHeaders as $key => $val) {
$this->assertEquals($val, $expectedHeaders[$key]);
}
}
function testSoundcloudMissingConsumerKeyException() {
$this->setExpectedException('Services_Soundcloud_Missing_Client_Id_Exception');
$soundcloud = new Services_Soundcloud('', '');
}
function testSoundcloudInvalidHttpResponseCodeException() {
$this->setExpectedException('Services_Soundcloud_Invalid_Http_Response_Code_Exception');
$this->soundcloud->get('me');
}
/**
* @dataProvider dataProviderSoundcloudInvalidHttpResponseCode
*/
function testSoundcloudInvalidHttpResponseCode($expectedHeaders) {
try {
$this->soundcloud->get('me');
} catch (Services_Soundcloud_Invalid_Http_Response_Code_Exception $e) {
$this->assertEquals(
'{"error":"401 - Unauthorized"}',
$e->getHttpBody()
);
$this->assertEquals(401, $e->getHttpCode());
foreach ($expectedHeaders as $key => $val) {
$this->assertEquals(
$val,
$this->soundcloud->getHttpHeader($key)
);
}
}
}
static function dataProviderHttpHeaders() {
$rawHeaders = <<<HEADERS
HTTP/1.1 200 OK
Date: Wed, 17 Nov 2010 15:39:52 GMT
Cache-Control: public
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Server: foobar
Content-Length: 1337
HEADERS;
$expectedHeaders = array(
'date' => 'Wed, 17 Nov 2010 15:39:52 GMT',
'cache_control' => 'public',
'content_type' => 'text/html; charset=utf-8',
'content_encoding' => 'gzip',
'server' => 'foobar',
'content_length' => '1337'
);
return array(array($rawHeaders, $expectedHeaders));
}
static function dataProviderSoundcloudInvalidHttpResponseCode() {
$expectedHeaders = array(
'server' => 'nginx',
'content_type' => 'application/json; charset=utf-8',
'connection' => 'keep-alive',
'cache_control' => 'no-cache',
'content_length' => '30'
);
return array(array($expectedHeaders));
}
}

View file

@ -0,0 +1,94 @@
<?php
set_include_path(
get_include_path()
. PATH_SEPARATOR
. realpath(dirname(__FILE__) . '/../')
);
require_once 'Services/Soundcloud.php';
/**
* Extended class of the Soundcloud class in order to expose protected methods
* for testing.
*
* @category Services
* @package Services_Soundcloud
* @author Anton Lindqvist <anton@qvister.se>
* @copyright 2010 Anton Lindqvist <anton@qvister.se>
* @license http://www.opensource.org/licenses/mit-license.php MIT
* @link http://github.com/mptre/php-soundcloud
*/
class Services_Soundcloud_Expose extends Services_Soundcloud {
/**
* Class constructor. See parent constructor for further reference.
*
* @param string $clientId Application client id
* @param string $clientSecret Application client secret
* @param string $redirectUri Application redirect uri
* @param boolean $development Sandbox mode
*
* @return void
* @see Soundcloud
*/
function __construct($clientId, $clientSecret, $redirectUri = null, $development = false) {
parent::__construct($clientId, $clientSecret, $redirectUri, $development);
}
/**
* Construct default http headers including response format and authorization.
*
* @return array
* @see Soundcloud::_buildDefaultHeaders()
*/
function buildDefaultHeaders() {
return $this->_buildDefaultHeaders();
}
/**
* Construct a url.
*
* @param string $path Relative or absolute uri
* @param array $params Optional query string parameters
* @param boolean $includeVersion Include the api version
*
* @return string
* @see Soundcloud::_buildUrl()
*/
function buildUrl($path, $params = null, $includeVersion = true) {
return $this->_buildUrl($path, $params, $includeVersion);
}
/**
* Get http user agent.
*
* @return string
* @see Soundcloud::_getUserAgent()
*/
function getUserAgent() {
return $this->_getUserAgent();
}
/**
* Parse HTTP response headers.
*
* @param string $headers
*
* @return array
* @see Soundcloud::_parseHttpHeaders()
*/
function parseHttpHeaders($headers) {
return $this->_parseHttpHeaders($headers);
}
/**
* Validates http response code.
*
* @return boolean
* @see Soundcloud::_validResponseCode()
*/
function validResponseCode($code) {
return $this->_validResponseCode($code);
}
}