768x90 Getting Online Shouldn't be Tough- $7.49 .com Domains at Go Daddy

Create Game in Air or Flex Easily

I am the admirer of bored.com website, this site will help you with its games to reduce your stressing in office or work. But How you can create your own game in Flex or Adobe air with painless ? I have found a great library to help developer in making 2D game easily, it is called FlashPunk by Paul Sztajer. Thanks dude.

FlashPunk is a free ActionScript 3 library designed for developing 2D Flash games. It provides you with a fast, clean framework to prototype and develop your games in. This means that most of the dirty work (timestep, animation, input, and collision to name a few) is already coded for you and ready to go, giving you more time and energy to concentrate on the design and testing of your game.

This framework is designed for use with the free Flex framework, used for building Flash applications; by combining this with a code editor such as FlashDevelop or Flash Builder, you can import the FlashPunk library and develop games without the need of the official Flash IDE.

You can feel the delicious of features:
  • Framerate-independent and fixed-framerate timestep support.
  • Fast & manageable rectangle, pixel, and grid collision system.
  • Helper classes for animations, tilemaps, text, backdrops, and more.
  • Debug console for real-time debugging and information tracking.
  • Sound effect support with volume, panning, and fading/crossfading.
  • Powerful motion tweening for linear, curved, and path-based movement.
  • Z-sorted render lists for easy depth management.
  • Simple keyboard and mouse input state checking.
  • Quick & efficent particle effects and emitters.
Click here to see flashPunk sample game which is not for flex or flash but it is already used for android.

Download Youtube Video Using ActionScript or Air

Youtube is my favorite website and very entertaining, not only in video but also making money. How you can download youtube video to flv format? A week ago, i have little experiment to make Air application for downloading Youtube. The important thing you have to get is the video id http://www.youtube.com/watch?v=yGTg5116dCM, the action script is very simple, even you can make multiple download as many as you want, here is the script:

private function configureListeners(stream:URLStream):void {
    var _date:Date = new Date();
    var _fileName:String = String(_date.milliseconds)+".flv";
    stream.addEventListener(Event.COMPLETE, function(event:Event):void {
      var fileData:ByteArray = new ByteArray();
      stream.readBytes(fileData,0,stream.bytesAvailable);
      var file:File = File.documentsDirectory.resolvePath(_fileName);
      var fileStream:FileStream = new FileStream();
      fileStream.open(file, FileMode.WRITE);
      fileStream.writeBytes(fileData,0,fileData.length);
      fileStream.close();
     });
    downloadProgress.source = stream; //downloadProgress is ProgressBar id    
  }
  
  public static const GET_VIDEO_INFO :String = "http://youtube.com/get_video_info.php";
            
  public function downloadVideo(_youtubeId:String):void{
    var service :HTTPService = new HTTPService();
    service.url = GET_VIDEO_INFO + "?video_id=" + _youtubeId;
    service.resultFormat = 'object';  

    service.addEventListener(ResultEvent.RESULT, function(evt:ResultEvent):void{
      var request:URLRequest = new URLRequest(unescape(evt.result.toString()).split("|")[1]);
      var stream:URLStream = new URLStream;
      configureListeners(stream);
       try {
         stream.load(request);
       } catch (error:Error) {
         trace("Unable to load requested URL.");
       }
     });
     service.send();
    }

Yeah, that is a short codes, for advance application you can use as3youtubelib to search, subscribe and comment the video. I have used oauth google and youtube API for multiple uploads to youtube. And once again no webservice unless google data protocol. i use pinless oauth. Please read the previous article. Thank you.

Sort Collection Rss By PubDate in ActionScript

XML can be friendly and some times can be nightmare for me. A few days ago, i have task to sort rss results from multiple sites by the pubDate. If you see the source xml of rss, each websites has common format pubDate : Wed, 03 Nov 2010 22:31:34 +0000 . As my experience, converting string date to datetime in actionScript using DateField.stringToDate not always give you actual result and my client want get the results are sorted up to milliseconds. There are some suggestion to use XSLT to sort xml by pubDate, but my application is desktop Air, how to do that without connect to webservice and parsing the rss result to XSLT ?

ActionScript is very fast to recursive big of data. So I decide to sort rss results in XMLListCollection, here is my codes:

//_result are composite of total rss results from a number of websites.
    // _results += new XMLList(XML(event.result)..item);
    public function sortRss(_results:XMLList, sortedResults:XMLListCollection):void{
      var sort:Sort = new Sort();
      sortedResults = new XMLListCollection(_results);
          
      var sortField:SortField = new SortField();
      sortField.compareFunction = sortRssByDate;
      sortField.descending = true;
     sort.fields = [sortField]
           
      sortedResults.sort = sort;
      sortedResults.refresh();
    }
    
    public var months:Array = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

    private function convertPubDate(_pubDate:String):Date{
      var arrDate:Array = _pubDate.split(/\s/gi);
      var _strDate:String = arrDate[0]+" "+arrDate[1]+" "+arrDate[2]+" "+arrDate[3];
      var arrTime:Array = arrDate.length > 5 ? String(arrDate[4]).split(/\:/gi) : [];        
      var _hour:Number = arrTime.length == 3 ? Number(arrTime[0]) : 0;
      var _minute:Number = arrTime.length == 3 ? Number(arrTime[1]) : 0;
      var _second:Number = arrTime.length == 3 ? Number(arrTime[2]) : 0;
      var _dateTime:Date = new Date(Number(arrDate[3]), months.indexOf(arrDate[2]),Number(arrDate[1]),_hour,_minute,_second);
      return _dateTime;
    }
      
    private function sortRssByDate(itemA:Object,itemB:Object,fields:Array = null):int{
    var dateA:Date = convertPubDate(itemA.pubDate);
      var dateB:Date = convertPubDate(itemB.pubDate);
      return ObjectUtil.dateCompare(dateA,dateB);
  }

Finally, it works without crash the application. I have tested from 10 websites with 25 items for each rss per 1 box, and i have 10 boxes. Total 100 websites rss that have to be sorted together by pubdate and grand total item is 2500 items.

BBAuth, Y!Oauth with pinless authentication in Air

I developed Air application which requires yahoo profile data. I think the application is little bit extraordinary since it doesn't need webservice, because my client won't it. I found Yahoo SDK for AS3 to build simple Yahoo Social Applications. It is quite satisfied to introduce me how to use Browser-Based Authentication (BBAuth) or Yahoo! Oauth, but how to make it not to open external browser and automatically get access token without invoking webservice and get verification pin? I got inspiration from twitter pinless . Fortunately, it works, you can see my screencast below:



When you click "Login To Yahoo" button, the authorize() method is executed, below is the codes.

private function authorize():void{
        YSession = new YahooSession(StormModel.YCONSUMER_KEY, StormModel.YSECRET_KEY, StormModel.YAPPLICATION_ID);
        YSession.clearSession();
        YSession.auth.addEventListener(YahooResultEvent.GET_REQUEST_TOKEN_SUCCESS, handleRequestTokenSuccess);
        YSession.auth.addEventListener(YahooResultEvent.GET_ACCESS_TOKEN_SUCCESS, handleAccessTokenSuccess);
        YSession.auth.pinlessAuth = true;
        
        var rect:Rectangle = new Rectangle(50,50, 780, 500);
        var browser:CustomHtmlHost = new CustomHtmlHost;
        var newHTMLOptoions:HTMLWindowCreateOptions = new HTMLWindowCreateOptions;
        newHTMLOptoions.x = 50;
        newHTMLOptoions.y = 50;
        newHTMLOptoions.scrollBarsVisible = true;   
        htmlBox = browser.createWindow(newHTMLOptoions);
        YSession.auth.htmlLoader = htmlBox;
       YSession.auth.getRequestToken("http://www.google.com");
      }
      
      private function handleRequestTokenSuccess(event:YahooResultEvent):void{
       YSession.auth.sendToAuthorization(event.data as OAuthToken);
      }
      
      private function handleAccessTokenSuccess(event:YahooResultEvent):void{
        YSession.auth.token = event.data as OAuthToken;
        htmlBox.stage.nativeWindow.close();
        YSession.setAccessToken(event.data as OAuthToken);
        gridProviders.addItem({token: YSession.auth.token.key, secret: YSession.auth.token.secret});
      }

The screencast seems little fool, because i use callback to www.google.com, but you can use any redirect url, eg: to your webservice, your domain or yahoo.com. Aside issues, to make my pinless authentication work sexier, I should hacks some line codes in YahooSession.as and AuthorizationRequest.as . (You can copy paste from these links). After i get the accessToken and accessSecret, i store them in sharedObject, and then re-validate any time you want extend the expired token. So what is CustomHtmlHost? Adobe has changed the policy for HTML where HTMLLoader is no available if you create directly new HTMLLoader, it is little hack solution from me:

package com.yahooStorm.utilities
{
    import flash.display.NativeWindowInitOptions;
    import flash.events.Event;
    import flash.geom.Rectangle;
    import flash.html.*;

    public class CustomHtmlHost extends HTMLHost
    {
        import flash.html.*;
        
        public function CustomHtmlHost():void{}
        
        override public function 
            createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader
        {
            var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
            var bounds:Rectangle = new Rectangle(windowCreateOptions.x,
                                                 windowCreateOptions.y, 
                                                 1000,
                                                 650);
            var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions,
                                        windowCreateOptions.scrollBarsVisible,bounds);

            htmlControl.addEventListener(Event.COMPLETE, onCompleteWindowHandler); 
            return htmlControl;
        }
        
        public function makeWindow(options:HTMLWindowCreateOptions):HTMLLoader{
          return createWindow(options)
        }
        
        public function onCompleteWindowHandler(event:Event):void{
        }
        
        override public function windowClose():void
        {
            htmlLoader.stage.nativeWindow.close();
        }
        
        override public function updateTitle(title:String):void
        {
          htmlLoader.stage.nativeWindow.title = "Placepoint Browser: " + title;
        }
    }
}

I am very interested to make BBauth pinless version work too in Flex and Flash As3 and then build the package scripts to swc, but i still have no time to do that, ASAP i will post the swc and documentation here.

If there's any question or suggestion please post in the comment box. Thank you.

ArrayCollection Mapping From Multiple Object Types

 private function listToString(element:*, index:int, arr:Array):String {
   var _return:String = "";
   if(element is FeedInfo){ 
     _return = element.address;
   }else if(element is UserFeed){
     _return = element.name;
   }else{
     _return = element.id;
   }
    return _return;
 }
    
 private function prepareSaveFeeds(_list:RxCollection):void{
   var _tmpUserFeed:UserFeed = new UserFeed;
   _tmpUserFeed.feedAccount = _account;
   _tmpUserFeed.user = userModel.currentUser;
   _tmpUserFeed.keywords = _list.toArray().map(listToString).join("::");
 }

The output will be

 "yacobus::reinhart::blog"

BackUp PostgreSQL in CommandLine

pg_dump -h db_host -U user_name db_name > dump_file.sql

And Restore by:

psql -h db_host -U user_name -d db_name -f dumpfilename.sql

HTML5 For Client Architectures and Virtualization Loom

Such trends as cloud computing, service oriented architecture (SOA), social media, software as a service (SaaS), and virtualization are combining and overlapping to upset the client landscape. If more of what more users are doing with their clients involves services, then shouldn't the client be more services ready? Should we expect one client to do it all very well, or do we need to think more about specialized clients that might be configured on the fly?

Today's clients are more tied to the past than the future, where one size fits all. Most clients consist of a handful of entrenched PC platforms, a handful of established web browsers, and a handful of PC-like smartphones. But, what has become popular on the server, virtualization, is taken to its full potential on these edge devices. New types of dynamic and task specific client types might emerge.

Imagine that you have your own personal Windows OS, that maybe you have signed up for Microsoft’s new Intune service to manage that from the cloud standpoint. Then, you have another Google OS that comes down with applications that are specific from that Google service, and that desktop is running in parallel with Windows, because it’s fully controlled from a cloud provider like Google. Something like Chrome OS is truly a cloud-based OS, where everything is supposed to be stored up in the cloud.

Those kinds of services, in turn, can converge into the PC, and virtualization can take that to the next level on the endpoint, so that those two things don’t overlap with each other, and a level of service, which is important for the cloud, certainly for service level agreements (SLAs), can truly be attained. There will be a lot of flexibility there.

Virtualization is a key enabler into that, and is going to open up PC architectures to a whole brave new world of management and security. And, at a platform level, there will be things that we're not even seeing yet, things that developers can think of, because they have options to now run applications and agents and not be bound to just Windows itself. I think it’s going to be very interesting.

 When we talk about the client, we're mostly thinking about the web-browser based client as opposed to the client as an entire virtualized OS. When you're using a business process management system (BPMS) and you involve people, at some point somebody is going to need to pull work off of a work list and work on it and then eventually complete it and go and get the next piece of work.

That’s done in a web-based environment, which isn’t particularly unusual. It's a fairly rich environment, which is something that a lot of applications are going to. Web-based applications are going to a rich Internet application (RIA) style.

We have tried to take it even a step further and have taken advantage of the fact that by moving to some of these real infrastructures, you can do not just some of the presentation tier of an application on the client. You can do the entire presentation tier on the web browser client and have its communication to the server, instead of being traditional HTML, have the entire presentation on the browser. Its communication uses more of a web-service approach and going directly into the services tier on the server. That server can be in a private cloud or, potentially, a public cloud.

What's interesting is that by not having to install anything on the client, as with any of these discussions we are talking about, that's an advantage, but also on the server, not having to have a different presentation tier that's separate from your services tier.

You go directly from your browser client into the services tier on the server, and it just decreases the overall complexity of the entire system. That's possible, because we base it on Ajax, with JavaScript that uses a library that's becoming a de-facto standard called jQuery. jQuery has the power to communicate with the server and then do all of the presentation logic locally.

Next Rich Internet Application of Web Base will be more interactive using HTML5, let's wait up to HTML5 finish the Virtualization on the next release.

Dont Add your Gmail Inbox To Public Bookmark

If you have added the web address (URL) of your Gmail inbox to your browser bookmarks, make sure that the bookmarks are not getting synched with a public service like Delicious or Google Bookmarks.

Gmail Inbox

That’s because when you bookmark your Inbox or any other folder in Gmail, your email address is added to the title of the bookmark. When this bookmark becomes public, your email address automatically gets exposed to spam bots.

This may sound like an obvious thing but just search for “mail.google.com” or “Gmail Inbox” on Delicous, Xmarks or even Google Bookmarks and you’ll tons of “working” email addresses in the title of the bookmarks.

Forget iPhone 4, Buy new Mac Mini



iphone4Today's WWDC speech by Steve Jobs was in some ways, surprising. Despite a veritable armful of rumors, Steve mainly talked about a handful of tech, with emphasis on the new iPhone 4. So what did he leave out, and when may it come true anyway?

New Mac Minis

mac-mini-hdmiThe Mac Mini is a much-beloved little computer, widely use as a home theater device and even as a server workhorse (due to its petite size and reasonable pricing). So why didn't Apple lavish any WWDC love on their smallest Mac? Strong rumors hinted at a big refresh with HDMI connectivity, after all.
Because the Mini is not a high profile world-beating device, like the iPhone or iPad, it's not high on Apple's priority list and simply isn't going to garner many headlines online or in the traditional press. Apple probably didn't want to water down the excitement about the iPhone 4 by announcing other new hardware. (Leaks have already muffled a bit of the thunder around the new iPhone as it is.)
When will we hear this news? Soon. We think it'll happen, and Apple will just slip out a special press release with some Jobs quotes and a splashy new Web page to advertise it.

HTML5, in the shadows
Jobs did mention HTML5 briefly during his address. But it was literally a mention in passing, and he didn't even play up the new promotional HTML5-ready Apple demo page. Instead Jobs noted HTML5 is one "platform" the company supports, an "open, uncontrolled platform that is forged and defined by standards alone." Apple is "fully behind" it, and its browsers are "in the lead" in supporting it. Apple's second platform is the "curated" iPhone OS (now iOS) for comparison.
Will Apple hit the news with HTML5? Possibly not in a special event, unless you're talking about a dedicated Jobs blog. Apple thinks its support for HTML5 is now self-sustaining in terms of news and media coverage, and probably didn't want to bring any hint of the Apple versus Adobe "war" into the Apple WWDC event.

iTunes in the cloud
Not a peep about iTunes during Steve's speech, which may be a surprise to some who were expecting news about a move to cloud-based storage and content streaming (possibly using tech from Lala, the streaming music platform that Apple recently acquired). The only mention of iTunes is in the new iPhone's specs page on Apple.com, where it's noted the device needs "iTunes 9.2" whereas the current version is 9.1.1.
Will iTunes 9.2 have cloud elements? We don't know. It'll have to ship before the new iPhone 4 goes on sale on June 24th, so it has to happen soon. We suspect a cloud-based iTunes would be a big enough revelation that Jobs would mention it in a big event so it won't appear in June. But it may merit a special "Come Feel Music's Future in the Air" Apple-style special event later this year.

MacBook Air revisions
Intel's got new silicon on the way that'll give Mac's slenderest model a big boost, and it's a premium piece of tech for Apple--they'll definitely support it through a basic spec upgrade.
When will the Air laptop get some love? Soon. Probably on a Tuesday, Apple's traditional new hardware launch day, as a minor mention in a press release.

External trackpad, the "Magic Slate"?
Many folk will have been saddened to not see this announced today--it's a device that'll surely sell by the boatload, thanks to Apple's marketing and impressive lead in multitouch technology. But the rumors about it today did reveal the "leaked" hardware had a copyright sign from 2009, so they may have been of a prototype, rather than shipping hardware.
When will the Slate go on sale? Sometime this year, we hope. If it does, we're guessing around October, a year after the Magic Mouse came out, as the two peripherals are kinda complementary.

Safari 5, OS X 10.6.4
Kinda surprising that these two "flagship" pieces of code didn't get much of a mention at Apple's developer conference. But maybe Apple's already supremely confident in its software offerings and doesn't feel the need to advertise single-point code updates. And don't forget Apple will be revealing more stuff to developers throughout this week's WWDC sessions.
Maybe Safari 5 and the new OS X tweak will get a proper "private" reveal to devs this week and a quiet launch soon.

UPDATE: In an email sent hours after the keynote, Apple announced the release of Safari 5 today.
Free MobileMe
Hmmm. We're scratching our heads on this one, as a free user level in MobileMe would be such a powerful boost to the iPhone's already prodigious powers. Maybe Apple's not got all its code in order yet, as they've been too busy messing with iPhone 4s, iPads and new versions of OS X and Safari.
Will we see this? Yes, we think so. But possibly as a big mention during another hardware/software release later in the year.

iPhone 4's HD video output powers
So here's something you probably didn't know, as it's not surfaced yet online: One thing Steve didn't mention is that the new iPhone outputs 720p-resolution video over a 30-pin to VGA connector cable, meaning it can drive your HDTV with HD-quality video. That beats the existing standard-def resolution, and almost rivals the existing Apple TV's powers.
Does this hint at a 1080p-capable Apple TV revamp? Very possibly, if you apply some twisty logic about why Apple didn't highlight this power.

Source: fastcompany.com

Is Apple TV 16GB with OS iPhone 4 released?


Alleged details on a forthcoming update to the Apple TV set top box were revealed on Friday, with the device reportedly based on iPhone OS 4, powered by Apple's custom-built A4 processor, and offering 1080P cloud-based streaming content -- all starting at just $99.

Engadget editor Joshua Topolsky said the information came from a tip and was confirmed by a source "very close to Apple." The new hardware will reportedly have just 16GB of storage, but will be capable of full 1080P HD video with 99$ only.

"Not only will this be priced to sell (like hotcakes), it seems that Apple is moving away from the model of local storage and will be focusing the new ATV on cloud-based storage (not unlike Amazon's streaming scheme, though we're talking instant-on 1080P, a la Microsoft)," the report said. "For those still interested in keeping their content close, there will be an option to utilize a Time Capsule as an external storage component, but the main course will be about streaming."

The new hardware, said to be small with only a power plug and video out, was described as "an iPhone without a screen." Sources could not say whether or not the new hardware would be compatible with software from the App Store, though Topolsky noted "it makes sense given the shared platform."

Engadget reported that Apple will not announce the new hardware at the forthcoming Worldwide Developers Conference, but the development is currently "full steam ahead."

The project has allegedly been in development since long before the Google TV was introduced last week. Google's offering will run on the Android operating system, and will be integrated in set top boxes as well as on HDTV hardware itself from major manufacturers. Google TV, which will run applications from the Android Market and stream Internet video, is scheduled to be released this fall.

Currently, the Apple TV costs $229 and comes with 160GB of storage. Last September, Apple discontinued the low-end 40GB Apple TV.

The set top box software was updated last October to Apple TV 3.0. The update added a redesigned main menu that aimed to make navigating content simpler and faster. It also allowed useres to watch iTunes Extras and iTunes LP content in full screen on their TV.

However, the software update failed to boost sales for the device, and Apple executives maintained their position that the Apple TV is simply a "hobby" for the Cupertino, Calif., company. In February, Chief Operating Officer Tim Cook said the set top box market does not compare with the other categories in which Apple competes, particularly media players, smartphones and computers.

Engadget's rumors would suggest that Apple would continue to sell the product as a set top box, while Google TV will be integrated with some HDTVs starting this fall. But analyst Gene Munster with Piper Jaffray has long believed that Apple could release its own connected HDTV, with Apple TV functionality built in to the device, in the next 2 to 4 years.

DateTime Range Helper In Rails View

There's some secret that you should know before you make time scaling in ruby on rails specially to the view. I have little smile when seeing helper from a developer that make time helper like in twitter or facebook, example a moment ago, or 3 minutes ago, or 1 hour ago. Why you hurt your brain if Rails already supports it. I think that he doesnt know the secret, now let me tell you the secret:

distance_of_time_in_words_to_now
Reports the approximate distance in time between from Time to time now. Set include_seconds to true if you want more detailed approximations when distance less than 1 min.  example :

<%=  distance_of_time_in_words_to_now(from_time, include_seconds =  false) %> 

distance_of_time_in_words
This is the same like above, but you can get range of time from 2 dateTimes, example :
<%=  distance_of_time_in_words_to_now(from_time, to_time = 0, include_seconds = false, options = {}) %>

below is table list from date range in many conditions:
0  - 29 secs # => less than a minute
30 secs to 1 min, 29 secs # => 1 minute
1 min, 30 secs to; 44 mins, 29 secs # => [2..44] minutes
44 mins, 30 secs to 89 mins, 29 secs # => about 1 hour
89 mins, 29 secs to 23 hrs, 59 mins, 29 secs # => about [2..24] hours
23 hrs, 59 mins, 29 secs to 47 hrs, 59 mins, 29 secs # => 1 day
47 hrs, 59 mins, 29 secs to 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days
29 days, 23 hrs, 59 mins, 30 secs to 59 days, 23 hrs, 59 mins, 29 secs # => about 1 month
59 days, 23 hrs, 59 mins, 30 secs to 1 yr minus 1 sec # => [2..12] months
1 yr to 1 yr, 3 months # => about 1 year
1 yr, 3 months to 1 yr, 9 months # => over 1 year
1 yr, 9 months to 2 yr minus 1 sec # => almost 2 years
2 yrs to max time or date # => (same rules as 1 yr)

Rainbow for Slow Rack Application

Rainbows! is an HTTP server for sleepy Rack applications. It is based on Unicorn, but designed to handle applications that expect long request/response times and/or slow clients. For Rack applications not heavily bound by slow external network dependencies, consider Unicorn instead as it simpler and easier to debug.

Rainbows is mainly designed for the odd things Unicorn sucks at:

  • Web Sockets (via Sunshowers)
  • 3rd-party APIs (to services outside your control/LAN)
  • OpenID consumers (to providers outside your control/LAN)
  • Reverse proxy implementations with editing/censoring (to upstreams outside your control/LAN)
  • Comet
  • BOSH (with slow clients)
  • HTTP server push
  • Long polling
  • Reverse AJAX
  • real-time upload processing (via upr)
    Rainbows can also be used to service slow clients directly even with fast applications. 

 You may also install it via RubyGems on RubyGems.org
gem install rainbows

for Rack applications

In APP_ROOT, run:
rainbows
 
PS: For more information about tunning you can read here  

How To Create List & Add User Twitter in Flex and Air

A moment ago i have a problem about how to get Home Line or status from a group users list in my Air Application and sort them by date ascending. My analyst is if an account has 20 tweets but the group has 10 users, it means that i have to sort 200 list. Why don't use SortOn for Array? If you try myArray.SortOn("date",[Array.CASE_SENSITIVE, Array.UNIQUE ]), it can't sort date (string type in twitter) very well, we have to convert them from string to millisecond, and it will take time, maybe crashed.

My idea is, unite them in a list in customer twitter account then get the list status, make sense, no ? For this case i use library from Sandro (Thanks Dude) , which is named tweetr, badly no more example about create list like my case. When i read the documentation, it seems simple, but the process is not like that. The list status, only can pull status of users which are public, so if it is protected you can't pull them.

Here is the sample of my work, you can try by clicking the demo link below (this sample not stores your twitter login ^_^), the demo is in flex version, but you can convert it to Air easily.

DEMO
SOURCE (Flex)

Develop SmartPhone Using RhoHub

RhoMobile is a first Development as a Service for Mobile, RhoHub or RhoMobile lets you quickly create native apps in Ruby and HTML for all major smartphones using the award-winning Rhodes framework. RhoHub provides a hosted RhoSync server to synchronize backend data with your users' smartphones.Writing an app on RhoHub consists of generating a set of objects, editing the client side (Rhodes framework) code, the server side (RhoSync) source adapter and building for your target smartphones. Below is an overview of RhoHub's rich IDE and other services.



  1. Debugging Console : Use the collapsible console to quickly view output from your RhoSync source adapters.
  2. File Manager : Navigate and modify your app's files in a simple view.
  3. Rich Editor : Use the powerful Ruby/HTML/CSS/Javascript editor right from your browser, or work locally and upload your app.
  4. Text Search :  Search for text in all files of your app.
  5. Toolbar & Quick Links :  Access all of RhoHub's productivity tools right from the editor.




What you can do in RhoHub ?

RhoHub provides you 3 packages, Free, Basic and Premium. You can start with free 50MB Disk Space.

List and read files and directories in a zip file

First of all you should download library here

And then short play with script below
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">


<mx:Script>
<![CDATA[
import mx.controls.Alert;
import nochump.util.zip.ZipEntry;
import mx.events.ListEvent;
import nochump.util.zip.ZipFile;
[Bindable]private var _zipFile:ZipFile;
[Bindable]private var _file:File;

private function browseFile():void{
var _file:File = new File();
_file.browseForOpen("Open.", getTypes());
_file.addEventListener(Event.SELECT, fileSelected);
}

private function getTypes():Array {
var allTypes:Array = new Array(getImageTypeFilter());
return allTypes;
}

private function getImageTypeFilter():FileFilter {
return new FileFilter("ZIP File", "*.zip");
}

private function setFileInfo(name:String, size:uint):void {
zipFileLabel.text = "Archive: " + name + " (" + sizeFormatter.format(size) + " bytes)";
}

private function fileSelected(event:Event):void {
_file = event.currentTarget as File;
var urlStream:URLStream = new URLStream();
urlStream.addEventListener(Event.COMPLETE, completeHandler);
urlStream.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
urlStream.load(new URLRequest(_file.nativePath));
}

private function completeHandler(event:Event):void {
var data:URLStream = URLStream(event.target);
setFileInfo(_file.name, data.bytesAvailable);
_zipFile = new ZipFile(data);
}

private function errorHandler(event:ErrorEvent):void {
Alert.show(event.text);
}

private function itemClickEvent(event:ListEvent):void {
var entry:ZipEntry = event.currentTarget.selectedItem as ZipEntry;
if(entry) taEntryData.text = String(_zipFile.getInput(entry));
}

private function labelSize(item:Object, column:DataGridColumn):String {
return sizeFormatter.format(item[column.dataField]);
}

private function labelModified(item:Object, column:DataGridColumn):String {
return dateFormatter.format(new Date(item.time));
}

private function labelCrc(item:Object, column:DataGridColumn):String {
return item.crc.toString(16).toUpperCase();
}

]]>
</mx:Script>

<mx:NumberFormatter id="sizeFormatter" useThousandsSeparator="true" />
<mx:DateFormatter id="dateFormatter" formatString="MM/DD/YYYY L:NN A" />

<mx:Panel title="Zip Demo" height="100%" width="100%">
<mx:Label id="zipFileLabel" />
<mx:VDividedBox width="100%" height="100%">
<mx:DataGrid id="dgEntries" width="100%" height="100%" dataProvider="{_zipFile.entries}" itemClick="itemClickEvent(event);">
<mx:columns>
<mx:DataGridColumn headerText="Name" dataField="name" width="300" />
<mx:DataGridColumn headerText="Size" dataField="size" labelFunction="labelSize" />
<mx:DataGridColumn headerText="Packed" dataField="compressedSize" labelFunction="labelSize" />
<mx:DataGridColumn headerText="Modified" labelFunction="labelModified" width="150" />
<mx:DataGridColumn headerText="CRC32" labelFunction="labelCrc" />
</mx:columns>
</mx:DataGrid>
<mx:TextArea id="taEntryData" width="100%" height="100%">
</mx:TextArea>
</mx:VDividedBox>
<mx:ControlBar>
<mx:Spacer width="100%"/>
<mx:HBox>
<mx:Form>
<mx:FormItem label="Open Zip File:" width="100%" styleName="lblForm" required="true">
<mx:Button id="btnBrowse" label="Browse" click="{browseFile()}"/>
</mx:FormItem>
</mx:Form>
</mx:HBox>
</mx:ControlBar>
</mx:Panel>



</mx:WindowedApplication>

Anti Distorted resolution picture when resizing

If you resize picture by defining new width or height from normal size, you will get the picture resolution's distorted or broken quality. There's a method how to make the picture keeps soft and smooth.

Create a utility class


package com.jackBite.utils
{
import mx.controls.Image;
import flash.display.Bitmap;

public class CleanImage extends Image
{
/*public function CleanImage()
{
}*/

override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if(content is Bitmap)
{
var bmp:Bitmap = Bitmap(content);
if(bmp && bmp.smoothing == false)
bmp.smoothing = true;
}
}

}
}



In MXML Component, You Put this

<utils:CleanImage id="feedLogo" height="30" source="{_imageRss}"/>

How To add image into any Textinput

You maybe want to add image or icon like magnifiying icon in textInput of your flex, Here i have some method how you can do that :

Create AS Component



package nebula.utils
{
import mx.controls.Image;
import mx.controls.TextInput;

public class SearchTextInput extends TextInput
{
public function SearchTextInput()
{
}

override protected function createChildren():void
{
super.createChildren();
var searchImg:Image = new Image();
searchImg.source = Images.search_icon;
searchImg.width=12;
searchImg.height=12;
searchImg.x = 2;
searchImg.y = 3;
setStyle("paddingLeft",searchImg.width+2);
addChild(searchImg);
}

}
}



in mxml component you put this:


<utils:SearchTextInput text="enter professional name ..." id="searchPro" click="{searchPro.text = ''}" width="200"/>




Another Alternative (sometime not work)


<mx:HBox>
<mx:TextInput id="myTextInput" />
<mx:Images source="{your_image_url}" paddingLeft="6" />
</mx:HBox>

Hacking Zindus (ThunderBird Add-On)

Zindus is a thunderbird add-on to import your google contact to thunderbird. The problem of zindus is not shown the first_name and last_name, address and organization if you use google data V.3

Let's see how it works:

1. Download Zindus from your ThunderBird.


2. Open the xpi file using winRar/7zip and extract the file.

3. Go to folder 'chrome' and then extract zindus.jar using WinRar/7zip

4. After you extract the JAR, go to folder content/zindus/

5. Open const.js and find 'const GD_API_VERSION ' and then change the value tobe "3"

6. Open contactgoogle.js and after that replace all with my script from this url: http://pastie.org/879955

7. archive the changes file to zindus.jar and archive back zindus.jar to xpi using 7zip or WinRar(drag and drop the xpi root folder to opened xpi in winRar)

8. Install it into your thunderbird and start import the google document

9. Binggo ^o^ address now display well and also organization and your first & last name.

Import contact information in Google Spreadsheet To Google Contact Using Rake

This March, I had a sexy task to import all employees and departments contacts information which were stored in Google Spreadsheet into Google contact.

A dummy people will think to pay data entry for entering them through google contact form. Whoa.. if i were a data entry, i would have had broken fingers after entering all data. Any way, I found a shortcut to import all data in only seconds or minutes, that is; make a robot to enter all data when we have a lunch.

Now, let's prepare the tools :

1. Installed Ruby on Rails Application
2. gem install gdata
3. gem install google-spreadsheet-ruby
4. open any text editor

Create Basic Rake Frame


namespace :db do

desc "GS2C: Google spreadsheet to Google contact"
task :gs2c => :environment do
require 'gdata'
require 'google_spreadsheet'

#Here will be some sexy scripts

end

end



Here it is, The Robot

namespace :db do

desc "GS2C: Google spreadsheet to Google contact"
task :gs2c => :environment do
require 'fastercsv'
require 'gdata'
require 'google_spreadsheet'

#sample spreadsheet URL
#https://spreadsheets.google.com/a/kiranatama.com/ccc?key=0AlQZq7IIjE6UdF92SkhRazlYaVFUWFNYZGxxLWpoT0E&hl=en

#settings
@spreadsheet_key = "0AlQZq7IIjE6UdF92SkhRazlYaVFUWFNYZGxxLWpoT0E"
login_config = YAML.load_file("#{RAILS_ROOT}/config/google_login.yml")[RAILS_ENV]
login_config["google"].each { |key, value| instance_variable_set("@#{key}", value) }

def create_spreadsheet_connector
@google_spreadsheet = GoogleSpreadsheet.login(@email_contact, @password_contact)
create_contact_connector
end

def create_contact_connector
@google_contact = GData::Client::Contacts.new({
:authsub_scope => 'http://www.google.com/m8/feeds/',
:source => 'google-DocListManager-v1.1',
:version => '3.0'})
@google_contact.clientlogin(@email_contact, @password_contact)
create_contact_entry
end

def create_contact_entry
@contact_entry = <<-EOF
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/contact/2008#contact' />
EOF
start_load_csv
end

def start_load_csv
@spreadsheet = @google_spreadsheet.spreadsheet_by_key(@spreadsheet_key)
#Sample Row Header / First Row
#First Name | Last Name | Email | Work Phone | Home Phone | Address | City | State | Country | ZIP
#You have to skip first row and blank row
i = 0
@spreadsheet.worksheets do |row|
if i < 1
i++
return
end
@google_contact.post( 'http://www.google.com/m8/feeds/' + 'contacts/default/base?v=3', create_google_contact(row,i))
i++
end
end

def create_address(address,city,state,country,zip)
address = <<-EOF
<gd:postalAddress rel='http://schemas.google.com/g/2005#home' primary='true'>
#{address}
#{city}
#{state}, #{zip}
#{country}
</gd:postalAddress>
EOF
return address
end

def create_google_contact(row,i)
first_name = row[i, 1].blank? ? "---" : row[i, 1]
last_name = row[i, 1].blank? ? "---" : row[i, 2]
email = row[i, 3].blank? ? "---" : row[i, 3]
work_phone = row[i, 4].blank? ? "---" : row[i, 4]
home_phone = row[i, 5].blank? ? "---" : row[i, 5]
address = row[i, 6].blank? ? "---" : row[i, 6]
city = row[i, 7].blank? ? "---" : row[i, 7]
state = row[i, 8].blank? ? "---" : row[i, 8]
country = row[i, 9].blank? ? "---" : row[i, 9]
zip = row[i, 10].blank? ? "---" : row[i, 10]
full_name = first_name + last_name

data = <<-EOF
#{@contact_entry}
<title>#{full_name}</title>
<atom:content type='text'>#{contact.note}</atom:content>
<gd:name>
<gd:fullName>#{full_name}</gd:fullName>
<gd:givenName>#{first_name}</gd:givenName>
<gd:familyName>#{last_name}</gd:familyName>
</gd:name>

<gd:email primary='true' rel='http://schemas.google.com/g/2005#home' address='#{email}'/>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'>#{home_phone}</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work'>#{work_phone}</gd:phoneNumber>

#{create_address(address,city,state,country,zip)}

</atom:entry>
EOF
return data
end

create_spreadsheet_connector

end

end


Command Line : rake db:gs2c or rake -T

Create and Update Google Contact from Ruby without Batch

There's less information about ruby on rails method in google contact. I would like to share you about how to export new google contact / create new google contact from our table contacts through Ruby.

in my contacts_controller.rb, i wrote this script


class ContactsController < ApplicationController
require 'yaml'
require 'cgi'
before_filter :prepare_google_contact, :expect => [:create, :update]
CONTACTS_SCOPE = 'http://www.google.com/m8/feeds/'

def create
@contact = Contact.new(params[:contact])

respond_to do |format|
if @contact.save
feed = @google_contact.post( CONTACTS_SCOPE + 'contacts/default/base', google_contact(@contact)).to_xml
@contact.update_attribute(:google_contact_id, feed.elements['id'].text)
flash[:notice] = 'Contact was successfully created.'
format.html { redirect_to(@contact) }
format.xml { render :xml => @contact, :status => :created, :location => @contact }
format.fxml { render :fxml => @contact }
else
format.html { render :action => "new" }
format.xml { render :xml => @contact.errors, :status => :unprocessable_entity }
format.fxml { render :fxml => @contact.errors }
end
end
end

# PUT /contacts/1
# PUT /contacts/1.xml
# PUT /contacts/1.fxml
def update
@contact = Contact.find(params[:id])
@saved = @contact.update_attributes(params[:contact])

respond_to do |format|
if @saved
@google_contact.headers = {'If-Match'=>'*'}
feed = @google_contact.put(@contact.google_contact_id,
create_google_contact(@contact.reload())).to_xml
flash[:notice] = 'Contact was successfully updated.'
format.html { redirect_to(@contact) }
format.xml { head :ok }
format.fxml { render :fxml => @contact }
else
format.html { render :action => "edit" }
format.xml { render :xml => @contact.errors, :status => :unprocessable_entity }
format.fxml { render :fxml => @contact.errors }
end
end
end

private

def prepare_google_contact
contact_setup = YAML.load_file("#{RAILS_ROOT}/config/contact.yml")
contact_setup["google"].each { |key, value| instance_variable_set("@#{key}", value) }
@google_contact = GData::Client::Contacts.new({
:authsub_scope => 'http://www.google.com/m8/feeds/',
:source => 'google-DocListManager-v1.1',
:version => '3.0'})
session[:token_contact] = @google_contact.clientlogin(@email_contact, @password_contact)
@contact_entry = <<-EOF
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:contact="http://schemas.google.com/contact/2008"
xmlns:gd="http://schemas.google.com/g/2005">

<category term='http://schemas.google.com/contact/2008#contact'
scheme='http://schemas.google.com/g/2005#kind'/>
EOF

session[:token_contact] = @google_contact.clientlogin(@email_contact, @password_contact)
end

def google_contact(contact)
data = <<-EOF
#{@contact_entry}
<title>#{contact.first_name}</title>
<content>#{contact.note}</content>
<gd:name>
<gd:fullName>#{contact.first_name}</gd:fullName>
</gd:name>
<gContact:birthday when='#{contact.birth_day}'/>
<gd:email primary='true' rel='http://schemas.google.com/g/2005#home' address='#{contact.email}'/>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>#{contact.mobile}</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work'>#{contact.phone}</gd:phoneNumber>
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#home'>
<gd:formattedAddress>#{contact.street}
#{contact.city}
#{contact.province}, #{contact.zipcode}
#{contact.country}
</gd:formattedAddress>
</gd:structuredPostalAddress>
</entry>
EOF
return data
end

end


in this study case I put my login google information in config/contact.yml file like this :


google:
email_contact: yacobus.r@kiranatama.com
password_contact: dec.07.1982


and here is my contact migration script lines :

class CreateContacts < ActiveRecord::Migration
def self.up
create_table :contacts do |t|
t.string :first_name
t.string :middle_name
t.string :last_name
t.string :phone
t.string :mobile
t.string :email
t.string :street
t.string :province
t.string :zipcode
t.string :city
t.string :country
t.string :note
t.string :type
t.string :google_contact_id
t.timestamps
end
end

def self.down
drop_table :contacts
end
end


and of course you have to install gem install gdata

Do not confuse about "format.fxml" this is respond data type for Restfulx (Flex/Air Framework).

Simple right !! but when this written's published, google still not release how to create and update trough ruby on rails. And many developer stucked because google provided create and update contact trough Batch method.

Basic Authentication in Flex or Air

After discussing about AuthSub and ClientLogin in Google in Flex or Air, now I would like to step forward about Basic authentication in Flex or Air. To know more about Basic Authentication please browse to this link https://mail.google.com/mail/feed/atom/all , you will be asked by pop up window to enter your login information right? now let we see how to handle it :



<mx:VBox
xmlns:mx = "http://www.adobe.com/2006/mxml"
width = "100%"
height = "100%"
verticalAlign = "middle"
horizontalAlign = "center"
backgroundColor = "#364a59"
creationComplete= "{creationHandler()}"
>

<mx:Script>
<![CDATA[

import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;
import mx.utils.*;

private function creationHandler():void{
gmailService.headers = {Authorization:"Basic " + basicAuth()};
gmailService.url = "https://mail.google.com/mail/feed/atom/all"
gmailService.contentType = "application/x-www-form-urlencoded"
gmailService.resultFormat = "e4x"
gmailService.addEventListener(ResultEvent.RESULT, feedSuccess);
gmailService.addEventListener(FaultEvent.FAULT, faultHandler);
gmailService.send(); //Update Here
}

private function basicAuth():String{
var encoder:Base64Encoder = new Base64Encoder();
encoder.insertNewLines = false;
encoder.encode("yacobus.r@kiranatama.com:Dec.07.1082"));
return String(encoder);
}

private function feedSuccess(event:ResultEvent):void{
//Do any logic for feed result here
trace(XML(event.result))
}


private function faultHandler(event:FaultEvent):void{

}

]]>
</mx:Script>

<mx:HTTPService id="gmailService" showBusyCursor="true"/>

</mx:VBox>


Perfect right!!

AuthSub Authentication on Flex or Air

There are 3 types of authentication on when you are accessing website nowdays, they are :

  1. AuthSub / ClientLogin authentication, this authentication uses credential login information and give back to you authentication token that will be used on header as security login token to make you available login in 24 hours.
  2. OAuth authentication, this authentication is using secret key and customer key, more secure than AuthSub, this kind authentication will use your token and secret token in header Authentication information to identify you are the valid user when accessing secure data or page.
  3. Basic Authentication, if you see pop up alert that ask you to enter username or password, that is Basic Authentication.
Now i would like to share you about how to make those authentication become autologin without you face on their login page. First let discuss AuthSub or ClientLogin :

Now, try access this page : http://docs.google.com/feeds/documents/private/full

You will see error like this Authorization required, Error 401. These scripts all you need to pass the authentication easily :

you can use or just a class of HTTPService.


<mx:VBox
xmlns:mx = "http://www.adobe.com/2006/mxml"
width = "100%"
height = "100%"
verticalAlign = "middle"
horizontalAlign = "center"
backgroundColor = "#364a59"
creationComplete= "{creationHandler()}"
>

<mx:Script>
<![CDATA[

import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;
import mx.utils.*;

private function creationHandler():void{
var data:Object = new Object;
data.Email = "yacobus.r@kiranatama.com";
data.Passwd = "Dec.07.1082"
data.accountType = "GOOGLE";
data.service = "writely";
//ClientLogin Url : https://www.google.com/accounts/ClientLogin
//AuthSub Url : https://www.google.com/accounts/AuthSubRequest
gmailService.url = "https://www.google.com/accounts/ClientLogin";
gmailService.contentType = "application/x-www-form-urlencoded";
gmailService.method = "POST";
gmailService.request = data;
gmailService.addEventListener(ResultEvent.RESULT, successHandler);
gmailService.addEventListener(FaultEvent.FAULT, faultHandler);
gmailService.send();
}

private function successHandler(event:ResultEvent):void{
gmailService.removeEventListener(ResultEvent.RESULT, new Function);
var txtAuth:String = String(event.result);
var authPosition:int = txtAuth.search("Auth");
txtAuth = txtAuth.substring(authPosition);
txtAuth = txtAuth.replace("Auth=","");
authPosition = txtAuth.length;
authPosition = authPosition - 1;
txtAuth = txtAuth.substring(0,authPosition);

accessProtectedUrl(txtAuth);
}

private function accessProtectedUrl(txtAuth:String):void{

gmailService.headers = {Authorization:"GoogleLogin auth="+txtAuth};
gmailService.url = "http://docs.google.com/feeds/documents/private/full";
gmailService.method = "GET";
gmailService.addEventListener(ResultEvent.RESULT, feedSuccess);
gmailService.addEventListener(FaultEvent.FAULT, faultHandler);
}

private function feedSuccess(event:ResultEvent):void{
//Do any logic for feed result here
trace(XML(event.result))
}


private function faultHandler(event:FaulttEvent):void{

}


]]>
</mx:Script>

<mx:HTTPService id="gmailService" showBusyCursor="true"/>

</mx:VBox>


List of Google Apps Service : http://code.google.com/apis/base/faq_gdata.html#clientlogin

How to make Air Application become iPhone SDK

Adobe air is great and smooth desktop application, many developers of Air dream their application can be installed into iPhone SDK. Now that dream come true. Thanks to my friend auraAnar for this great information :

First thing you do is downloading editor Eclips (like Flex Builder) from openplug.com, once you have successfully download it, create new project, in this show case i would to create sample parking searcher based on google Map for iPhone SDK.


Preview builder application

  1. Create WindowedApplication example project name is parkingApp.mxml
  2. Design indexView for iPhone application, let's called it as indexView.mxml (click the link)
  3. For component you can use mx:xxx like Flex or Air, but for control you should use mob:xxx from openPlug. Take a look my textinput Here
  4. Here is the screenshot of iPhone Emulator :


Preview Emulator


Once you success compiling your script without error, you need XCode of Apple to compile your script to iPhone SDK, i am using this way to compile my script in XCode. Happy iPhoning.

PS: I've tried commiting my script to google codes but it seems the google SVN is under maintenance, once it works i will upload the sample codes. Here is the address:

svn checkout http://airiphone.googlecode.com/svn/trunk/

AutoLogin to google account in Air without Oauth

i believe a part number of you there want their application allow the user to enter google account credential information to access the page, right? It's like i were faced off in my project. So how we will do it ?

If you use webservice, here's the information you should send to air application :
Google Account Credential Information and CallBack Url (the next url you want go after login)
I believe to access protected google page it will asked thridparty login, right? Note: OAuth, AuthSub and ClientLogin will not allow you to remote interface specially page after login google. In this case i create a component which is called GoogleBrowser.mxml and here the codes:

 <?xml version="1.0" encoding="utf-8"?>
  

     <mx:Window xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" 
                   width="600" height="600" backgroundColor="#242424"
                   creationComplete="init()"  >

     <mx:Script>
      <![CDATA[
         private var googleUserName:String = "yacobus.r@kiranatama.com";
         private var googlePassword:String = "i_love_u";
         private var nextUrl:String = "http://docs.google.com/a/kiranatama.com/Doc?docid=0AWbobJ8BSfPlZGcyaGtiYmJfMjlkajlwc3hncw&hl=en";  

         private function init():void{
           browserStack.selectedIndex = 1;
           gdocHtml.addEventListener(Event.COMPLETE, onCompleteHandler);
           gdocHtml.location = nextUrl;
         }

   
         private function onCompleteHandler(event:Event):void{
           gdocHtml.removeEventListener(Event.COMPLETE, removeListenerHandler);
           var additionalScript:String = '<script type="text/javascript">\n'+
                                   "gaia_setFocus();\n" + 
                                   "document.gaia_loginform.submit();\n"+
                                   "</script>";
           var username:String = googleUserName.split("@")[0];
           var body:String = String(event.target.htmlLoader.window.document.body.innerHTML);
           body = body.replace('id="Passwd"','id="Passwd" value="'+googlePassword+'" ');
           body = body.replace('value="" class','value="'+username+'" class"');
           body = body + addScript;
           gdocHtml.htmlLoader.window.document.body.innerHTML = body;
           browserStack.selectedIndex = 0;
          }

           private function removeListenerHandler(event:Event):void{
              event.stopPropagation();
           }

        ]]>
      </mx:Script>

      <mx:ViewStack id="browserStack" width="100%" height="100%">
        <mx:Canvas width="100%" height="100%">
          <mx:HTML width="100%" height="100%" id="gdocHtml" />    
        </mx:Canvas>
        <mx:Text id="loadingText" text="Loading ..." />
      </mx:ViewStack>  
</mx:Window>

Autocomplete from arrayCollection data in Flex and Air

Autocomplete is still high traffic in search engine for flex or action script, although it has plugin or component now (FLEX 4 is available). But now i would like to share you my script about how find documents, which is stored in arrayCollection and reflect with autocomplete textInput. here the sample code :

CASE:
In a form there's Multiple selection List the List can be clicked multiply or can be selected using auto complete in text input. the List dataProvider is from arrayCollection. The arrayCollection is filled by data from database.

  <mx:VBox
     xmlns:mx = "http://www.adobe.com/2006/mxml"
     width = "100%"
     height = "100%"
     creationComplete = "{onComplete()}" >

  <mx:Script>
      <![CDATA[

   private var docDummyData:ArrayCollection = new ArrayCollection(
                              [{id:234, title:"qwerty data"}], 
                              [{id:1020, title:"employee data"}],
                              [{id:1033, title:"salary data"}],
                              [{id:643, title:"tomorrow presentation"}],
                              [{id:721, title:"kiranatama human resource"}],
                              [{id:162, title:"flex and air outsource"}],
                              [{id:905, title:"ruby on rails docs"}],
                              [{id:453, title:"and many more"}]);

    private var copyData:ArrayCollection = new ArrayCollection;

    private function onComplete():void{
      copyData = docDummyData;
      docDummyData.sort = sortDoc();
      docDummyData.refresh();
      listDocuments.dataProvider = docDummyData;
    }

    private function sortDoc():Sort{
       var mySort:Sort = new Sort();
       var sortLevel:SortField = new SortField("title");
       sortLevel.numeric = false;
       sortLevel.descending = false;
       mySort.fields = [sortLevel];
       return mySort;
    }

    private function filterTitle(item:Object):Boolean
    {
      var arrTxtDocs:Array = txtGDocs.text.split(", ");
      var keyWord:String = String(arrTxtDocs[arrTxtDocs.length-1]);
      listDocuments.scrollToIndex(0); // scrolled the top item
      i++;
      return item['title'].match(new RegExp(keyWord,"i")); 
    }

    private function onTyping():void{
      if(listDocuments.dataProvider != null){
        docDummyData.filterFunction = filterTitle;
        docDummyData.refresh();
       }
    }

    private function detectEnter(event:KeyboardEvent):void{

       if(event.charCode == 13){
         listDocuments.selectedIndex = i;
        if(docDummyData.length < 1){
         Alert.show("This Document is not exist or invalid");   
        }else{
         var arrInputDoc:Array = txtGDoc.text.split(",");
         arrInputDoc[arrInputDoc.length-1] = String(listDocuments.selectedItem.title)+ ", ";
         txtGDoc.text = arrInputDoc.join(", ");
         docDummyData = copyData;
         docDummyData.refresh();
         listDocuments.invalidateDisplayList();
        }
      }
    }

    private function onSelectDocs(event:ListEvent):void{
       var arrDocTitles:Array = listDocuments.selectedItems;
       var strText:String = txtGDocs.text;

       for(var i:int = 0; i < arrDocTitles.length;i++){
         var nameTitle:String = arrDocTitles[i].title.toString();
         txtGDocs.text += nameTitle+ ', ';
       }
     }
   ]]>
  </mx:Script>

  <mx:Text  text="Please enter your document title" width="100%"/>
  <mx:TextInput width="100%"
           id="txtGDocs"
           change="{onTyping()}"
           keyDown="detectEnter(event)"/>

   <mx:List id="listDocuments"
      labelField="title"
      rowCount="5"
      itemClick="{onSelectDocs(event)}"
      width="100%" 
     allowMultipleSelection="true"/>         
  </mx:VBox>        



That's all :), any body know how to make code sniped like wordpress in blogspot ?

Servicing Restful CakePHP in Flex/Air

I have found a great framework of Dima Berastau which is called Restfulx, this framework is helping you to abstract your application from repetitive CRUD code and switch/synchronize between various data providers with minimal effort, very suitable for Ruby on rails and Phyton(Django) Developers. What about PHP?

Honestly Restfulx is suitable for php developer like CakePHP, CodeIgniter or any MVC and Restful framework as their webservice in flex or Air. But now I would like to share about simple Restful webservice utility for php framework, my handmade, if i get wrong please send me feedback correction.

The main idea of using is :
//http://localhost/baking_cake/users/?first_name=yacobus

RestfulPhp.index(User,{first_name: "yacobus"}, onIndexSuccess, onIndexFailure);


//http://localhost/baking_cake/users
  var params:Object = new Object;
  params.first_name = "yacobus";
  params.last_name = "reinhart";
  params.current_company = "kiranatama.com";
  RestfulPhp.add(User,params, onCreateSuccess, onCreateFailure);



  //http://localhost/baking_cake/users/7.xml
  var params:Object = new Object;
  params.id = "7";
  params.first_name = "yacobus";
  params.last_name = "reinhart";
  params.current_company = "www.wgs.co.id";
  RestfulPhp.edit(User,params, onEditSuccess, onEditFailure);


  //http://localhost/baking_cake/users/7.xml
  RestfulPhp.show(User,{id: "7"}, onShowSuccess, onShowFailure);

  //http://localhost/baking_cake/users/7.xml
  RestfulPhp.delete(User,{id: "7"}, onDeleteSuccess, onDeleteFailure);

First step and the last are :

you should create utility class or any class name that will have function as webservice, for example : I create RestfulPhp in com.reinhartlab.share


package com.teapoci.share
{
  import flash.utils.getQualifiedClassName;
  import mx.messaging.messages.HTTPRequestMessage;
  import mx.rpc.events.FaultEvent;
  import mx.rpc.events.ResultEvent;
  import mx.rpc.http.HTTPService;

  public class RestfulPhp {

    private static var restful:RestfulPhp;
    private static var baseURL:String = "http://localhost/baking_cake/";
    public static function getInstance():RestfulPhp {
      (restful == null) ? restful = new RestfulPhp();
      return restful;
    }

    public function index(model:Class, params:Object = null, successFunction:Function = null, faultFunction: Function = null, resultFormat:String = "e4x"):void
    {
      var sendData:XML = ;
      var httpService : HTTPService = new HTTPService();
      httpService.contentType = "text/xml";
      httpService.method = HTTPRequestMessage.GET_METHOD;
      doHttpService(model, httpService, "GET", resultFormat, params, successFunction,  faultFunction);
     }

     public function add(model:Class, resultFormat:String = "e4x"):void{
       var sendData:XML = ;
       var httpService : HTTPService = new HTTPService();
       httpService.contentType = "text/xml";
       httpService.method = HTTPRequestMessage.POST_METHOD;
       doHttpService(model, httpService, "POST", resultFormat, params, successFunction, faultFunction);
     }

     public function edit(model:Class, params:Object = null, successFunction:Function = null, faultFunction: Function = null, resultFormat:String = "e4x"):void
     {
        var sendData:XML = ;
        var httpService : HTTPService = new HTTPService();
        httpService.contentType = "text/xml";
        httpService.method = HTTPRequestMessage.PUT_METHOD;
        doHttpService(model, httpService, "PUT", resultFormat, params, successFunction, faultFunction);
     }

     public function delete(model:Class, params:Object = null, successFunction:Function = null, faultFunction: Function = null, resultFormat:String = "e4x"):void
     {
         var httpService : HTTPService = new HTTPService();
         httpService.contentType = "text/xml";
         httpService.method = HTTPRequestMessage.DELETE_METHOD;
         doHttpService(model, httpService, "DELETE", resultFormat, params, successFunction, faultFunction);
     }

     public function show(model:Class, params:Object = null, successFunction:Function = null, faultFunction: Function = null, resultFormat:String = "e4x"):void
     {
         var httpService : HTTPService = new HTTPService();
         httpService.contentType = "text/xml";
         httpService.method = HTTPRequestMessage.GET_METHOD;
         doHttpService(model, httpService, "GET", resultFormat, params, successFunction, faultFunction);
     }

     private function doHttpService(_model:Class, _service:HTTPService, _method:String, _format:String, _params:Object,_onSuccess:Function, _onFailure:Function):void
     {         
         var sendData:XML = ;
         (_params!= null) ? sendData.appendChild(_params);
         var controllerUrl:String = flash.utils.getQualifiedClassName(_model)+"s";
         _service.url =  baseURL + controllerUrl;
        if(_method != "POST" && _params.id != null){
        _service.url = _service.url + "/" + String(_params.id)+".xml";
      }
             

     _service.headers = {"REQUEST_METHOD": _method,
                         "X_HTTP_METHOD_OVERRIDE": _method};
     _service.resultFormat = _format;
     _service.addEventListener( ResultEvent.RESULT, _onSuccess);

     if(_onFailure != null )
       _service.addEventListener( FaultEvent.FAULT, _onFailure );

     _service.send( sendData ); 

   }
  }
}             

 
powered by Blogger