Dealing with Twitter API 1.1 update_with_media ActionScript 3 - actionscript-3

i'm using as3 for my current project, login, post status to twitter is already done.. but i have problem with update_with_media. Here's the flow of my program. On other screen call it CaptureWebcam, user can capture pic from webcam but can't save it to user computer. And if user open share to twitter screen, there's popup to login and image from CaptureWebcam screen passed to twitter screen, and ready to upload and it failed to post... i don't know whats wrong with my code
here's my code, i'm using iotashan library
private function uploadImage(Image()):void {
var myEncoder:JPGEncoder = new JPGEncoder(80);
var urlLoader:URLLoader = new URLLoader();
var urlRequest:URLRequest;
var multipartLoader:MultipartURLLoader = new MultipartURLLoader();
var urlHeader:URLRequestHeader = new URLRequestHeader();
var oAuth:OAuthRequest;
var consumer:OAuthConsumer;
var twitterRequestUrl:String;
var headerValue:String = "";
var auth_header:URLRequestHeader;
var param:Object;
var vid:Video;
//var bmp:Bitmap = new Bitmap();
var bitmapData:BitmapData = new BitmapData(CaptureWebcam.vid.width, CaptureWebcam.vid.height, true, 0xFFFFFF);
//var byteArray:ByteArray = myEncoder.encode(new Bitmap(new Turtle()).bitmapData);
var byteArray:ByteArray = myEncoder.encode(bitmapData);
var drawRect:Rectangle = new Rectangle(0,0,image.width, image.height);
bitmapData.draw(image, new Matrix(), null, null, drawRect, true);
trace("upload test");
//header create
twitterRequestUrl = "https://api.twitter.com/1.1/statuses/update_with_media.json";
consumer = new OAuthConsumer(consumerKey, consumerSecret);
oAuth = new OAuthRequest(OAuthRequest.HTTP_MEHTOD_POST, twitterRequestUrl, null, consumer, null);
urlRequest = new URLRequest(oAuth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1()));
//
/*
urlRequest = twitterRequestUrl;
urlRequest.contentType = 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary();
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = UploadPostHelper.getPostData(file, byteArray);
urlRequest.requestHeaders.push( new URLRequestHeader( 'Cache-Control', 'no-cache' ) );
urlLoader.dataFormat = URLLoaderDataFormat.BINARY
urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, onStatusDelivered);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_STATUS, onStatusChanged);
urlLoader.addEventListener(Event.COMPLETE, handleUploadComplete);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError);
urlLoader.load(urlRequest);
*/
/*
multipartLoader.addEventListener(Event.COMPLETE, handleUploadComplete);
multipartLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
multipartLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSequrityError);
multipartLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, onStatusDelivered);
*/
/*
headerValue = createHeaderValue(oAuth);
auth_header = new URLRequestHeader("Authorization", headerValue);
multipartLoader.requestHeaders.push(auth_header);
multipartLoader.addVariable("status" , "test");
multipartLoader.addFile(byteArray, 'image.jpg', 'media[]');
multipartLoader.load("https://api.twitter.com/1.1/statuses/update_with_media.json");
*/
var signedData:String = oauth.getSignedRequest( URLRequestMethod.POST, "https://upload.twitter.com/1/statuses/update_with_media.json", null );
var authHeaderValue:String = createAuthorizationHeader( new URLVariables( signedData ) );
// create multipart loader
var multipartLoader : MultipartURLLoader = new MultipartURLLoader();
multipartLoader.addEventListener( Event.COMPLETE, handleUploadComplete );
multipartLoader.addEventListener( IOErrorEvent.IO_ERROR, onError );
multipartLoader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onError );
// add headers
var auth_header : URLRequestHeader = new URLRequestHeader( "Authorization", authHeaderValue );
multipartLoader.requestHeaders.push( auth_header );
// add requeried data
multipartLoader.addVariable( "status" , twitter_msg );
multipartLoader.addFile( byteArray, 'image.jpg', 'media[]');
// load
multipartLoader.load( "https://upload.twitter.com/1/statuses/update_with_media.json" );
}
private function createAuthorizationHeader( _requestParams : Object, headerRealm : String = "" ) : String
{
var data:String = "";
data += "OAuth "
if ( headerRealm.length > 0)
data += "realm=\"" + headerRealm + "\", ";
for (var param : Object in _requestParams ) {
// if this is an oauth param, include it
if ( param.toString().indexOf("oauth") == 0){
data += param + "=\"" + encodeURIComponent( _requestParams[param]) + "\", ";
}
}
return data.substr( 0, data.length - 2);
}

Related

New array for music symbols

I have background musics from the library, any ideas how to solve this code by clicking the button to change it?
var BeachBall: CrashBash_BeachBall = new CrashBash_BeachBall();
var BrickDive: LEGOIsland2_BrickDive = new LEGOIsland2_BrickDive();
var BloocheepOcean: MarioHoops_BloocheepOcean = new MarioHoops_BloocheepOcean();
var Underwater: MarioTeachesTyping2_Underwater = new MarioTeachesTyping2_Underwater();
var UnderPressure: CrashBandicootNST_UnderPressure = new CrashBandicootNST_UnderPressure();
var CalmWaters: DireDireDocks_CalmWaters = new DireDireDocks_CalmWaters();
var Level1: TreasureCove_Level1 = new TreasureCove_Level1();
var Level2: TreasureCove_Level2 = new TreasureCove_Level2();
var Level3: TreasureCove_Level3 = new TreasureCove_Level3();
var music: Array = new Array(CalmWaters, BloocheepOcean, UnderPressure, Underwater, BeachBall, BrickDive, Level1, Level2, Level3);
// Changing the Background Music
music_btn.addEventListener(MouseEvent.CLICK, on_pressMusic);
music[Math.floor(Math.random()*music.length)].play();
if(!sound)
{
sound_channel = CalmWaters.play(0, int.MAX_VALUE);
sound_channel.soundTransform = new SoundTransform(0.4);
}
function on_pressMusic(event: MouseEvent): void
{
/*
var random: int = int(Math.random() * sounds[0].length);
play_music(sounds[0][random]);
var sMusic:Button = new Button();
sMusic.play();
*/
if (is_Playing == true) //# if music is already playing
{
music_player.stop();
}
musicNum = Math.floor(Math.random() * (musicList.length-1));
music_object = new (musicList[musicNum]);
audioTime = 0; //# seconds to start from within track
music_player = music_object.play(audioTime);
is_Playing = true;
}
Error:
TypeError: Error #1007: Instantiation attempted on a non-constructor.
at BlowfishPong_fla::MainTimeline/on_pressMusic()[BlowfishPong_fla.MainTimeline::frame27:205]
All of the codes are updated. any ideas how to solve and fix this for their future coding.
Try something like this:
var BeachBall: CrashBash_BeachBall = new CrashBash_BeachBall();
var BrickDive: LEGOIsland2_BrickDive = new LEGOIsland2_BrickDive();
var BloocheepOcean: MarioHoops_BloocheepOcean = new MarioHoops_BloocheepOcean();
var CalmWaters: DireDireDocks_CalmWaters = new DireDireDocks_CalmWaters();
var Level1: TreasureCove_Level1 = new TreasureCove_Level1();
var Level2: TreasureCove_Level2 = new TreasureCove_Level2();
var Level3: TreasureCove_Level3 = new TreasureCove_Level3();
var Underwater: MarioTeachesTyping2_Underwater = new MarioTeachesTyping2_Underwater();
var UnderPressure: CrashBandicootNST_UnderPressure = new CrashBandicootNST_UnderPressure();
var myNum :uint = 0;
var audioTime :uint = 0;
var music_object :Sound;
var music_player :SoundChannel = new SoundChannel();
var is_Playing :Boolean = false;
var music_list :Array = new Array();
music_list = [ BeachBall, BrickDive, BloocheepOcean, CalmWaters,
Level1, Level2, Level3, Underwater, UnderPressure
];
//# Changing the Background Music
music_btn.addEventListener(MouseEvent.CLICK, on_pressMusic);
function on_pressMusic (event:MouseEvent) : void
{
if ( is_Playing == true ) //# if music is already playing
{ music_player.stop(); }
myNum = Math.floor( Math.random() * (music_list.length-1) );
music_object = new ( music_list[ myNum ] );
audioTime = 0; //# seconds to start from within track
music_player = music_object.play( audioTime );
is_Playing = true;
}

How to separate URL response data in ActionScripts3

I'm working on a site that response to GET request in simple text format, I want to save data and title in separate variables.
Code:
function URLRequest_method():void
{
var url:String = "http://sms-reg.ru/index.php";
var getbalance:String = "mode=api&apikey=*=getbalance";
var postParams:URLVariables = new URLVariables(getbalance);
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
request.data = postParams;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onLoaderComplete);
urlLoader.load(request);
}
function onLoaderComplete( event:Event ):void
{
var urlLoader2:URLLoader = event.target as URLLoader;
txt_BALANCE1.text = urlLoader2.data;
trace( urlLoader2.data);
//var json:Object = JSON.parse( urlLoader2.data );
// trace( "json.response = ", json.response );
}
URLRequest_method();
Update:
function onLoaderComplete( event:Event ):void
{
var urlLoader2:URLLoader = event.target as URLLoader;
trace( urlLoader2.data );
//var json:Object = JSON.parse( urlLoader2.data );
// trace( "json.response = ", json.response );
var response:String = urlLoader2.data;
var pattern:RegExp = new RegExp("BALANCE:([0-9.-]+)");
var data:Object = pattern.exec(response);
if (data != null && data[1] != null)
{
var value:Number = parseFloat(data[1]);
trace(value);
}
}
Outputs:
BALANCE:123.00
ID23:3(Telegram);ID28:4(Viber);ID29:6(Whatsapp);ID30:5(Instagram);
I need to separate title and data: "BALANCE" "123" OR "ID23" "3" | each one in separate variable.
You can extract the value using a regular expression for example, something like this
var response:String = "BALANCE:123.00"
var pattern:RegExp = new RegExp("BALANCE:([0-9.-]+)");
var data:Object = pattern.exec(response);
if (data != null && data[1] != null) {
var value:Number = parseFloat(data[1]);
trace(value);
}
The one i provided is fairly simple, to extract data from a known data format but, as long as there's a pattern in the string, you can extract the pieces of information you need.
Check out the guide on how to use RegExp in actionscript

Upload a picture to cloudinary using the REST API

We are developing an App using AIR/AS3 and would like to upload a picture to cloudinary via the REST API from the client, instead of using Node.js.
Reading the Documentation of cloudinary, we have found that it should be done via a HTTP/S POST request (http://cloudinary.com/documentation/upload_images#remote_upload).
We've tried using a URLLoader and URLRequest passing the parameters as URLVariables.
Using this as a URL:
'https://api.cloudinary.com/v1_1/'+ CLOUD_NAME +'/raw/upload'
The code looks like this:
public function uploadImage(imageVO:CameraUIImageVO):void {
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler, false, 0, true);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler, false, 0, true);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler, false, 0, true);
var request:URLRequest = new URLRequest(_url);
request.data = getVariables(imageVO);
request.method = URLRequestMethod.POST;
loader.load(request);
}
private function getVariables(imageVO:CameraUIImageVO):URLVariables {
var variables:URLVariables = new URLVariables();
variables.timestamp = _timestamp;
var bitmapData:BitmapData = imageVO.image.bitmapData;
var rawBytes:ByteArray = bitmapData.encode(bitmapData.rect, new JPEGEncoderOptions(50));
variables.file = rawBytes;
variables.resource_type = 'raw';
variables.signature = getSignature("anyPublicId");
variables.api_key = API_KEY;
return variables;
}
private function getSignature(publicId:String):String {
var toHash:String =
"public_id="+ publicId
+ "&timestamp=" + timestamp
+ API_SECRET;
var src:ByteArray = Hex.toArray(Hex.fromString(toHash));
var sha1:SHA1 = new SHA1();
var hashedString:String = Hex.fromArray(sha1.hash( src ));
return hashedString;
}
private function get timestamp():String {
return _timestamp = Number(new Date().time).toString();
}
The result of this is a http error 401
It seems you're signing the public_id, however the public_id isn't passed in options of the upload itself. i.e., there's no:
variables.public_id = "anyPublicId";
inside the getVariables method.

AS3/AIR: IOStream Error when trying to upload files

I'm making an AIR app in which the user drags and drops image files onto the stage, the app then uploads those dropped images to the site imgur.com, and then returns with links to the images (in XML format).
I am having two issues:
the program works successfully with a very small file, however anything larger (1mb or more), I get an IOStream error 2023. Imgur supports uploads of up to 10mb so I know it must be something on my end.
I would like to be able to drop multiple image files at once into the program, and have it upload all of them (either synchronously or asynchronously, it does not matter). Right now the program gives errors when I attempt to do this (something along the lines of the byteArray having to be greater than 0).
Below is the code in question which is giving me issues. (thank you for your help in advanced)
private function doDragDrop(e:NativeDragEvent):void
{
trace("doDragDrop() called.");
var dropFiles:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
for each (var file:File in dropFiles)
{
switch (file.extension.toLowerCase())
{
case "jpg" :
case "jpeg" :
case "gif" :
case "png" :
case "apng" :
case "tiff" :
case "bmp" :
case "pdf" :
case "xcf" :
trace("file Extension Check = passed");
addImage(file.nativePath);
break;
//error handling for non-supported filetypes
default :
trace("ERROR: Unsupported File Type Detected!");
}
}
}
private function addImage(nativePath:String):void
{
trace("addImage() called.");
trace("NativePath is: " + nativePath);
//var file:File = new File(nativePath);
var file:File = File.desktopDirectory.resolvePath(nativePath);
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fileLoaded);
loader.loadBytes(ba);
}
private function fileLoaded(e:Event):void
{
trace("fileLoaded() called.");
var bitmap:Bitmap = Bitmap(e.target.content);
var bitmapData:BitmapData = bitmap.bitmapData;
var png:ByteArray = PNGEncoder.encode(bitmapData);
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
var vars:String = "?key=" + API_KEY + "&name=name&title=title";
var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
request.data = png;
urlLoader.load(request);
}
private function onCookieSent(e:Event):void
{
trace("onCookieSent() called.");
var res:XML = new XML(unescape(urlLoader.data));
var resultsList:XMLList = res.links;
trace(resultsList);
}
private function onIOError(e:IOErrorEvent):void
{
trace("ioErrorHandler: " + e);
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
// Handle error
}
private function onSecurityError(e:SecurityErrorEvent):void
{
trace("securityErrorHandler: " + e);
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
// handle error
}
//When the dragged object leaves the drop point, do this
private function doDragExit(e:NativeDragEvent):void
{
trace("doDragExit() called.");
TweenLite.to(tv_mc, 2, {alpha:0.5, scaleX:1.0, scaleY:1.0, ease:Elastic.easeOut});
}
after doing this:
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
you already have a ByteArray of the file/image. can't you just send this one...
private function addImage(nativePath:String):void
{
trace("addImage() called.");
trace("NativePath is: " + nativePath);
//var file:File = new File(nativePath);
var file:File = File.desktopDirectory.resolvePath(nativePath);
var ba:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
stream.readBytes(ba);
stream.close();
urlLoader = new URLLoader();
urlLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
urlLoader.addEventListener(Event.COMPLETE, onCookieSent);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
var vars:String = "?key=" + API_KEY + "&name=name&title=title";
var request:URLRequest = new URLRequest(UPLOAD_URL + vars);
request.contentType = "application/octet-stream";
request.method = URLRequestMethod.POST;
request.data = ba;
urlLoader.load(request);
}

AS3 - positon advertisment that is dynamically loaded

I'm using the code below to place an ad inside a mobile game that I'm building. My problem is that the ad appears in the top left corner of the stage and I need to be able to move it centered near the bottom. I got this code from a book and I understand about 70% of what it's doing. Thanks for any direction you can offer.
Rich
// Smaato Advertising Code for Start Screen
var request:URLRequest = new URLRequest("http://soma.smaato.com/oapi/reqAd.jsp");
var variables:URLVariables = new URLVariables();
variables.adspace = "0";
variables.pub = "0";
variables.devip = "127.0.0.1";
variables.format = "IMG";
variables.adcount = "1";
variables.response = "XML";
request.data = variables;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);
function onComplete(e:Event):void
{
var data:XML = new XML(loader.data as String);
var status:String = data.*::status.toString();
if(status == "success")
{
var ad:XMLList = data.*::ads.*::ad;
var link:String = ad.*::link.toString();
var l:Loader = new Loader();
l.load(new URLRequest(link));
addChild(l);
var clickurl:String = ad.*::action.#target.toString();
l.addEventListener(MouseEvent.CLICK, onAdClick);
function onAdClick(e:MouseEvent):void
{
var request:URLRequest = new URLRequest(clickurl);
navigateToURL(request);
}
}
}
The problem is that you are never actually positioning the image, so the default is [0,0], the top-left corner of the screen.
var request:URLRequest = new URLRequest("http://soma.smaato.com/oapi/reqAd.jsp");
var variables:URLVariables = new URLVariables();
variables.adspace = "0";
variables.pub = "0";
variables.devip = "127.0.0.1";
variables.format = "IMG";
variables.adcount = "1";
variables.response = "XML";
request.data = variables;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);
function onComplete(e:Event):void
{
var data:XML = new XML(loader.data as String);
var status:String = data.*::status.toString();
if(status == "success")
{
var ad:XMLList = data.*::ads.*::ad;
var link:String = ad.*::link.toString();
var l:Loader = new Loader();
l.load(new URLRequest(link));
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onAdLoaded);
function onAdLoaded(e:Event):void
{
var ad:DisplayObject = e.target.content;
addChild(ad);
ad.x = (ad.stage.stageWidth - ad.width) / 2;
ad.y = (ad.stage.stageHeight - ad.height) / 2 + 50;
}
var clickurl:String = ad.*::action.#target.toString();
l.addEventListener(MouseEvent.CLICK, onAdClick);
function onAdClick(e:MouseEvent):void
{
var request:URLRequest = new URLRequest(clickurl);
navigateToURL(request);
}
}
}
That will center the loaded file. The 50 number is because if you don't want it to be in the exact center, you can use the number to adjust the y-value accordingly.
By the way, I recommend you to grab another book, becase the code you are using seems a bit old and have poor performance.
If you have any other issue regarding this, comment it and I can expand my answer.