PageRenderTime 58ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/empika/SoundCloudWrapper.as

https://github.com/empika/SoundCloudWrapper_Flex_AS3
ActionScript | 489 lines | 343 code | 63 blank | 83 comment | 25 complexity | e993e94c7d58de7a1bdb83ddaffaa737 MD5 | raw file
  1. package com.empika
  2. {
  3. // flash and flex imports
  4. import flash.data.*;
  5. import flash.display.Sprite;
  6. import flash.errors.*;
  7. import flash.events.*;
  8. import flash.filesystem.File;
  9. import flash.net.*;
  10. import org.iotashan.oauth.*;
  11. import org.iotashan.utils.*;
  12. public class SoundCloudWrapper extends Sprite
  13. {
  14. // public variables
  15. // ----------------
  16. // consumer key and secret
  17. private var consumerKey: String;
  18. private var consumerSecret: String;
  19. // private variables
  20. // -----------------
  21. // Soundcloud specific variables
  22. // These are the end points used to get data from SC
  23. private var soundCloudLiveURL:String = "http://api.soundcloud.com/";
  24. private var soundCloudSandboxURL:String = "http://api.sandbox-soundcloud.com/";
  25. private var soundCloudURL:String;
  26. private var requestTokenURL:String = "oauth/request_token";
  27. private var userAuthorizationURL:String = "oauth/authorize";
  28. private var accessTokenURL:String = "oauth/access_token";
  29. private var usingSandbox:Boolean = false;
  30. // Some OAuth bits
  31. private var tokenSecret:String;
  32. private var oauth_timestamp:String;
  33. private var oauth_nonce:String;
  34. private var oauth_signature:String;
  35. private var signatureMethod:String = "HMAC-SHA1";
  36. private var oaConsumerToken: OAuthConsumer = new OAuthConsumer( consumerKey, consumerSecret );
  37. private var oaAuthToken: OAuthToken = new OAuthToken();
  38. private var oaAccessToken: OAuthToken = new OAuthToken();
  39. private var oaSignatureMethod: OAuthSignatureMethod_HMAC_SHA1 = new OAuthSignatureMethod_HMAC_SHA1();
  40. private var strResult: String = "header";
  41. private var strHeader: String = "";
  42. private var hasAccess: Boolean = false;
  43. // Some misc bits
  44. private var conn: SQLConnection = new SQLConnection;
  45. private var sqlStatement:SQLStatement = new SQLStatement();
  46. private var sqliteFile: File = File.applicationStorageDirectory.resolvePath( "soundcloud_access.db" );
  47. public function SoundCloudWrapper( consumerKey: String = "", consumerSecret: String = "", useSandbox: Boolean = false )
  48. {
  49. this.oaConsumerToken.key = consumerKey;
  50. this.oaConsumerToken.secret = consumerSecret;
  51. if( !useSandbox ){
  52. soundCloudURL = soundCloudLiveURL;
  53. }
  54. else{
  55. soundCloudURL = soundCloudSandboxURL;
  56. }
  57. this.usingSandbox = useSandbox;
  58. // localsave is on! lets try and create our SQLite DB
  59. //conn.addEventListener(SQLEvent.OPEN, connOpenHandler);
  60. sqlStatement.sqlConnection = conn;
  61. try{
  62. trace ( sqliteFile.nativePath );
  63. conn.open( sqliteFile );
  64. trace( "opened SQLite database" );
  65. }
  66. catch( error: SQLError ){
  67. trace( "error opening SQLite database" );
  68. trace( "error: " + error.message );
  69. trace( "details: " + error.details );
  70. return;
  71. }
  72. // lets see if we have our access token
  73. // have a look at this.has_access to see if we have it or not
  74. this.checkAccessToken();
  75. }
  76. /*
  77. * Send request to get our AUTH token
  78. */
  79. private function requestAuthToken():void {
  80. // set up our auth request
  81. var oaAuthRequest: OAuthRequest = new OAuthRequest( "get",
  82. this.soundCloudURL + this.requestTokenURL,
  83. null,
  84. this.oaConsumerToken,
  85. this.oaAuthToken );
  86. // generate our url
  87. var strRequsetURL:String = oaAuthRequest.buildRequest( this.oaSignatureMethod, "url", this.strHeader );
  88. trace( "strRequsetURL: " + strRequsetURL );
  89. // create our url request
  90. var authURLRequest: URLRequest = new URLRequest( strRequsetURL );
  91. authURLRequest.method = URLRequestMethod.GET;
  92. // create our url loader
  93. var authURLLoader: URLLoader = new URLLoader();
  94. // set up our event listeners for the url loader
  95. authURLLoader.addEventListener( HTTPStatusEvent.HTTP_RESPONSE_STATUS, trcHTTP );
  96. authURLLoader.addEventListener( Event.COMPLETE, this.authorizeUser );
  97. authURLLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
  98. // try to load our request
  99. try{
  100. authURLLoader.load( authURLRequest );
  101. }
  102. catch( error:Error ){
  103. trace("requestAuthToken() : Unable to load requested document.");
  104. }
  105. }
  106. /*
  107. * We get our AUTH token and then send the use to Soundcloud to authenticate
  108. */
  109. private function authorizeUser( event: Event ):void {
  110. trace( "authorizeUser() : Got the AUTH token" );
  111. var recievedData:URLLoader = event.target as URLLoader;
  112. this.oaAuthToken.key = recievedData.data['oauth_token'];
  113. this.oaAuthToken.secret = recievedData.data['oauth_token_secret'];
  114. trace( "authorizeUser() : oaAuthToken.key : " + this.oaAuthToken.key );
  115. trace( "authorizeUser() : oaAuthToken.secret : " + this.oaAuthToken.secret );
  116. var strUserAuthorizationURL: String = this.soundCloudURL + this.userAuthorizationURL + "?oauth_token=" + oaAuthToken.key
  117. var userAuthReq: URLRequest = new URLRequest( strUserAuthorizationURL );
  118. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.AUTHORIZED);
  119. navigateToURL( userAuthReq );
  120. trace("navigated");
  121. dispatchEvent(scwEvent);
  122. }
  123. /*
  124. * Check to see if we have an access token.
  125. * Called during the instantiation of the class
  126. */
  127. private function checkAccessToken():void {
  128. trace("requestAccessToken() : retrieving local access token");
  129. // lets try and get our access token if it is already saved
  130. sqlStatement.addEventListener(SQLEvent.RESULT, checkAccessTokenResult);
  131. sqlStatement.text = "SELECT * FROM access_tokens WHERE using_sandbox = " + this.usingSandbox;
  132. try{
  133. sqlStatement.execute();
  134. }
  135. catch( error: SQLError )
  136. {
  137. trace( "requestAccessToken() : error executing : " + sqlStatement.text );
  138. trace( "error: " + error.message );
  139. trace( "details: " + error.details );
  140. return;
  141. }
  142. }
  143. /*
  144. * handler for our SQLite statement in checkAccessToken
  145. */
  146. private function checkAccessTokenResult( event:SQLEvent ):void{
  147. this.sqlStatement.removeEventListener(SQLEvent.RESULT, this.requestAccessToken);
  148. // get our result
  149. var sqlResult:SQLResult = this.sqlStatement.getResult();
  150. if (sqlResult.data == null){
  151. trace("checkAccessTokenResult() : did not retrieve local access token");
  152. this.hasAccess = false;
  153. }
  154. else{
  155. this.oaAccessToken.key = sqlResult.data[0].accessKey;
  156. this.oaAccessToken.secret = sqlResult.data[0].accessSecret;
  157. trace( "checkAccessTokenResult() : w00t, got our token from 'access_tokens'" );
  158. trace( "checkAccessTokenResult() : oaAccessToken.key : " + this.oaAccessToken.key);
  159. trace( "checkAccessTokenResult() : oaAccessToken.secret : " + this.oaAccessToken.secret);
  160. this.hasAccess = true;
  161. }
  162. }
  163. /*
  164. * if you dont have an access token already, run this to get one
  165. */
  166. private function requestAccessToken( ):void{
  167. trace("requestAccessToken() : requesting access token");
  168. var oaAccessRequest: OAuthRequest = new OAuthRequest( "get",
  169. this.soundCloudURL + this.accessTokenURL,
  170. null,
  171. this.oaConsumerToken,
  172. this.oaAuthToken );
  173. var strRequestURL:String = oaAccessRequest.buildRequest(this.oaSignatureMethod, "post", this.strHeader);
  174. var accessURLRequest: URLRequest = new URLRequest(this.soundCloudURL + this.accessTokenURL + "?" + strRequestURL );
  175. trace( "requestAccessToken() : strRequestURL : " + strRequestURL );
  176. accessURLRequest.method = URLRequestMethod.GET;
  177. var accessURLLoader: URLLoader = new URLLoader( accessURLRequest );
  178. accessURLLoader.dataFormat = URLLoaderDataFormat.TEXT;
  179. accessURLLoader.addEventListener(IOErrorEvent.IO_ERROR, requestAccessTokenError);
  180. accessURLLoader.addEventListener(Event.COMPLETE, requestAccessTokenComplete);
  181. accessURLLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, trcHTTP);
  182. try{
  183. accessURLLoader.load( accessURLRequest);
  184. }
  185. catch( error:Error ){
  186. trace("requestAccessToken() : Unable to load requested document.");
  187. }
  188. }
  189. private function requestAccessTokenError( event: Event ):void{
  190. trace("BING!");
  191. }
  192. private function requestAccessTokenComplete( event: Event ):void{
  193. // get our tokens from our returned data
  194. var urlLoadData:URLLoader = event.target as URLLoader;
  195. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.ERROR);
  196. scwEvent.error = "Request Access Token Complete - #226 : Sorry, failure in getting the access token. Please report this error to the application creator.";
  197. var response:String = urlLoadData.data;
  198. var scwEventAccess: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.ACCESS);
  199. //scwEvent.error = "Request Access Token Complete - #226 : Sorry, failure in getting the access token. Please report this error to the application creator.";
  200. trace( "response: " + response );
  201. // see if we acctually got somthing back
  202. if( response != "" && response != " " ){
  203. var re:RegExp = /(?P<prop>[^&=]+)=(?P<val>[^&]*)/g;
  204. var result:Object;
  205. var resultOBJ:Object = { };
  206. var dataDecode: Boolean = true;
  207. // loop through our returned data
  208. do
  209. {
  210. result = re.exec(response);
  211. if (!result){
  212. // gah, couldnt parse the response, lets bail!
  213. dataDecode = false;
  214. }
  215. else{
  216. resultOBJ[result.prop] = result.val;
  217. }
  218. }
  219. while (dataDecode);
  220. this.oaAccessToken.key = resultOBJ.oauth_token;
  221. this.oaAccessToken.secret = resultOBJ.oauth_token_secret;
  222. if( this.oaAccessToken.key != null && this.oaAccessToken.secret != null ){
  223. this.sqlStatement.text =
  224. "CREATE TABLE IF NOT EXISTS access_tokens (" +
  225. " accessId INTEGER PRIMARY KEY AUTOINCREMENT, " +
  226. " accessKey TEXT, " +
  227. " accessSecret TEXT, " +
  228. " using_sandbox BOOL " +
  229. " ) ";
  230. try{
  231. this.sqlStatement.execute();
  232. trace( "requestAccessTokenComplete() : created SQLite table 'access_tokens'" );
  233. }
  234. catch( error: SQLError )
  235. {
  236. trace( "requestAccessTokenComplete() : error creating table" );
  237. trace( "error: " + error.message );
  238. trace( "details: " + error.details );
  239. return;
  240. }
  241. this.sqlStatement.text = "DELETE FROM access_tokens WHERE using_sandbox = " + this.usingSandbox;
  242. try{
  243. this.sqlStatement.execute();
  244. trace( "requestAccessTokenComplete() : deleted existing access token" );
  245. }
  246. catch( error: SQLError )
  247. {
  248. trace( "error deleting data" );
  249. trace( "error: " + error.message );
  250. trace( "details: " + error.details );
  251. return;
  252. }
  253. this.sqlStatement.text = "INSERT INTO access_tokens (accessKey, accessSecret, using_sandbox)" +
  254. " VALUES ( '" + this.oaAccessToken.key + "', '" + this.oaAccessToken.secret + "'," + this.usingSandbox + ") ";
  255. try{
  256. this.sqlStatement.execute();
  257. trace( "requestAccessTokenComplete() : inserted access_token" );
  258. }
  259. catch( error: SQLError )
  260. {
  261. trace( "requestAccessTokenComplete() : error inserting access_token" );
  262. trace( "error: " + error.message );
  263. trace( "details: " + error.details );
  264. return;
  265. }
  266. }
  267. dispatchEvent( scwEventAccess );
  268. }
  269. else{
  270. dispatchEvent(scwEvent);
  271. }
  272. }
  273. /*
  274. * Helper function to check our access token exists
  275. * returns:
  276. * true - if we do have an access token
  277. * false - if we dont have an access token
  278. */
  279. public function has_access():Boolean{
  280. return this.hasAccess;
  281. }
  282. public function getResource( strResource: String = "", type: String = "xml" ):void{
  283. if( !this.oaAccessToken.isEmpty && strResource != "" ){
  284. trace("getResource() : " + strResource);
  285. if( type == "xml" || type == "json" ){
  286. var strRes:String;
  287. var strPattern: RegExp = /\//;
  288. strRes = this.soundCloudURL + strResource.replace(strPattern, "") + "." + type;
  289. var resourceRequest: OAuthRequest = new OAuthRequest( "get",
  290. strRes,
  291. null,
  292. this.oaConsumerToken,
  293. this.oaAccessToken );
  294. var resourceURL:String = resourceRequest.buildRequest(this.oaSignatureMethod, "url", this.strHeader);
  295. trace( resourceURL );
  296. var resourceURLRequest: URLRequest = new URLRequest( resourceURL );
  297. var resourceURLLoader: URLLoader = new URLLoader( resourceURLRequest );
  298. resourceURLLoader.addEventListener(Event.COMPLETE, gotResource);
  299. resourceURLLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, trcHTTP);
  300. resourceURLLoader.load( resourceURLRequest );
  301. }
  302. else{
  303. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.ERROR);
  304. scwEvent.error = "*ERROR* - SoundCloudWrapper.getResource() : Type was not 'xml' or 'json'";
  305. dispatchEvent(scwEvent);
  306. }
  307. }
  308. }
  309. private function gotResource( event: Event):void{
  310. trace("gotResource() : got given resource");
  311. var theLoader: URLLoader = event.currentTarget as URLLoader;
  312. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.LOADED);
  313. scwEvent.data = theLoader.data;
  314. dispatchEvent(scwEvent);
  315. }
  316. public function postResource( strResource: String = "", strGetData: String = "", fileReference: FileReference = null):void{
  317. trace("got some auth");
  318. var strRes:String;
  319. strRes = this.soundCloudURL + strResource;
  320. var theRequest: OAuthRequest = new OAuthRequest( "post",
  321. strRes,
  322. null,
  323. this.oaConsumerToken,
  324. this.oaAccessToken );
  325. var resourceURL: String = theRequest.buildRequest(this.oaSignatureMethod, "url", this.strHeader);
  326. //var urlVars: URLVariables = new URLVariables( );
  327. //var header: URLRequestHeader = new URLRequestHeader();
  328. var resourceURLRequest: URLRequest = new URLRequest( resourceURL );
  329. /*
  330. * track[title], string, the title of the track
  331. * track[asset_data], file, the original asset file
  332. * track[description], string, a description
  333. * track[downloadable], true|false
  334. * track[sharing], public|private
  335. * track[bpm], float, beats per minute
  336. */
  337. var params:URLVariables = new URLVariables();
  338. var paramArray:Array = new Array();
  339. resourceURLRequest.method = URLRequestMethod.POST;
  340. // convert our string of params to AS3 happy params
  341. params.decode( strGetData );
  342. resourceURLRequest.data = params;
  343. // gwaarn, send that track and data!
  344. if( fileReference ){
  345. //fileReference.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, trcHTTPUpload );
  346. //fileReference.addEventListener(ProgressEvent.PROGRESS, progressHandler);
  347. fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, postedFile);
  348. //fileReference.addEventListener(Event.COMPLETE, eventComplete);
  349. fileReference.upload( resourceURLRequest, "track[asset_data]" );
  350. }
  351. else{
  352. var resourceURLLoader: URLLoader = new URLLoader( resourceURLRequest );
  353. resourceURLLoader.addEventListener(Event.COMPLETE, postedResource);
  354. resourceURLLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, trcHTTP);
  355. resourceURLLoader.load( resourceURLRequest );
  356. }
  357. }
  358. private function postedResource( event: Event):void{
  359. var loader:URLLoader = URLLoader(event.target) as URLLoader;
  360. //trace("completeHandler: " + loader.data);
  361. trace("postedResource() : posted given resource");
  362. //var theLoader: URLLoader = event.currentTarget as URLLoader;
  363. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.LOADED);
  364. scwEvent.data = loader.data;
  365. dispatchEvent(scwEvent);
  366. }
  367. private function postedFile( event: DataEvent):void{
  368. var fileRef: FileReference = event.target as FileReference;
  369. //trace("completeHandler: " + loader.data);
  370. trace("postedResource() : posted given resource");
  371. //var theLoader: URLLoader = event.currentTarget as URLLoader;
  372. var scwEvent: SoundCloudWrapperDataEvent = new SoundCloudWrapperDataEvent(SoundCloudWrapperDataEvent.LOADED);
  373. scwEvent.fileRef = fileRef;
  374. dispatchEvent(scwEvent);
  375. }
  376. private function eventComplete( event: DataEvent):void{
  377. trace("hallo");
  378. }
  379. public function progressHandler( event:ProgressEvent ):void
  380. {
  381. // bloop bloop bloop BLOOP!
  382. trace( event.bytesLoaded + " / " + event.bytesTotal );
  383. }
  384. /*
  385. * Wrapper function to kick off the authentication process
  386. * using the functions in this class
  387. */
  388. public function getRequest():void{
  389. this.requestAuthToken();
  390. }
  391. public function getAccess():void{
  392. this.requestAccessToken();
  393. }
  394. public function getMe():void{
  395. this.getResource();
  396. }
  397. /*
  398. * Helper function to trace out some data about our HTTP upload
  399. */
  400. public function trcHTTPUpload( event:HTTPStatusEvent ):void
  401. {
  402. //trace( event.responseHeaders );
  403. for each( var ar: URLRequestHeader in event.responseHeaders )
  404. {
  405. trace( ar.name + " : " + ar.value );
  406. if( ar.name == "Location" )
  407. {
  408. var arrayT: Array = ar.value.split( /.*\// );
  409. trace( arrayT[1] );
  410. //postTrackAsset( arrayT[1] );
  411. }
  412. }
  413. }
  414. /*
  415. * Helper function to trace out some data about our HTTP request
  416. */
  417. public function trcHTTP( event:HTTPStatusEvent ):void
  418. {
  419. //trace( event.responseHeaders );
  420. for each( var ar: URLRequestHeader in event.responseHeaders ){
  421. trace( ar.name + " : " + ar.value );
  422. }
  423. }
  424. }
  425. }