23
Parsing Tweets with the TwitterString Class
While building a little Twitter aggregator for an upcoming conference, I found myself in need of a set of methods to create hyperlinks from three distinct elements that can be included within a tweet; links, usernames, and hashtags.
I was able to find regular expressions to do all the heavy lifting from various sources on the Web and have created a class which pretty much does all the processing with one method call. Here’s an example of the thing working, followed by example code, and the class itself.
Example SWF
Example MXML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init()" width="300" height="100" backgroundColor="#1E1E1E" preloaderBaseColor="#989898"> <fx:Script> <![CDATA[ import flashx.textLayout.elements.Configuration; import flashx.textLayout.elements.TextFlow; import flashx.textLayout.conversion.TextConverter; import flashx.textLayout.formats.TextLayoutFormat; import com.fracturedvisionmedia.utils.TwitterString; private var myTxt:String = "Everyone should follow @josephlabrecque (http://bit.ly/7NkqrB) - really cool stuff and super-informative insights! #Awesome #Super #LOL"; private function init():void { // Configure styling the TextFlow links to match richTxt var cfg:Configuration = TextFlow.defaultConfiguration; var normalTLF:TextLayoutFormat = new TextLayoutFormat(cfg.defaultLinkNormalFormat); normalTLF.color = 0xDCD9D9; cfg.defaultLinkNormalFormat = normalTLF; TextFlow.defaultConfiguration = cfg; // Import tweet as HTML richTxt.textFlow = TextConverter.importToFlow(TwitterString.instance.parseTweet(myTxt), TextConverter.TEXT_FIELD_HTML_FORMAT); } ]]> </fx:Script> <s:RichEditableText id="richTxt" selectable="false" editable="false" right="10" top="10" bottom="10" color="#DCD9D9" left="10"/> </s:Application> |
TwitterString Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package com.fracturedvisionmedia.utils { /** * The TwitterString class assists with the parsing of a tweet to add hyperlinks * around Links, HashTags, and UserNames in a tweet. * @author Joseph Labrecque * v. 0.1.2 */ public final class TwitterString { private static var _instance:TwitterString = new TwitterString(); public function TwitterString(){ if (_instance != null){ throw new Error("TwitterString can only be accessed through TwitterString.instance"); } } public static function get instance():TwitterString { return _instance; } public function parseTweet(t:String):String { var step1:String = parseHyperlinks(t); var step2:String = parseUsernames(step1) var step3:String = parseHashtags(step2) return step3; } private function parseUsernames(t:String):String { var result:String = t.replace(/(^|\s)#(\w+)/g, "$1#<a href='http://search.twitter.com/search?q=$2' target='_blank'>$2</a>"); return result; } private function parseHashtags(t:String):String { var result:String = t.replace(/(^|\s)@(\w+)/g, "$1@<a href='http://www.twitter.com/$2' target='_blank'>$2</a>"); return result; } private function parseHyperlinks(t:String):String { var urlPattern:RegExp = new RegExp("(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)", "g") var result:String = t.replace(urlPattern, "<a href='$1' target='_blank'>$1</a>"); return result; } } } |
20
YouTube AS3 Example Using Flash Professional
Based on comments received in my previous article I’ve decided to also produce an example using Flash Professional CS4. The approach is different in some ways, but very similar in others.
View the Example:
References:
The ActionScript 3 YouTube Chromeless Player is Now Live
YouTube ActionScript 3.0 Player API Reference
Download the Example:
YouTubeAS3_CS4.zip
View Code for Flash Professional:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | package { import flash.system.Security; import flash.display.MovieClip; import flash.display.Loader; import flash.events.Event; import flash.net.URLRequest; import fl.data.DataProvider; import fl.controls.ComboBox; import fl.controls.TextArea; public class YouTubeAS3 extends MovieClip { public var VidHolder:MovieClip; public var VidSelection:ComboBox; public var traceArea:TextArea; private var player:Object; private var loader:Loader; private var vidCollection:DataProvider; public function YouTubeAS3():void { Security.allowInsecureDomain("*"); Security.allowDomain("*"); vidCollection = new DataProvider(); vidCollection.addItem({data:"KhAplw0Z8zQ", label:"Wreckage"}); vidCollection.addItem({data:"d54AA2YWll0", label:"Window View"}); vidCollection.addItem({data:"Sv83GeuyN8A", label:"The Fearless Man"}); vidCollection.addItem({data:"9t5guYGbuZs", label:"Ephemeral"}); VidSelection.dataProvider = vidCollection; VidSelection.addEventListener(Event.CHANGE, cueVideo); loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit); loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3")); } private function onLoaderInit(event:Event):void { VidHolder.addChild(loader); loader.content.addEventListener("onReady", onPlayerReady); loader.content.addEventListener("onError", onPlayerError); loader.content.addEventListener("onStateChange", onPlayerStateChange); loader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange); } private function onPlayerReady(event:Event):void { traceArea.text += "player ready:" + Object(event).data + "\r"; player = loader.content; player.setSize(VidHolder.width, VidHolder.height); VidSelection.selectedIndex = 0; VidSelection.dispatchEvent(new Event(Event.CHANGE)); } private function cueVideo(event:Event):void { traceArea.text += "switch to:" + event.target.selectedItem.label + "\r"; player.cueVideoById(event.target.selectedItem.data); } private function onPlayerError(event:Event):void { traceArea.text += "player error:" + Object(event).data + "\r"; } private function onPlayerStateChange(event:Event):void { traceArea.text += "player state:" + Object(event).data + "\r"; } private function onVideoPlaybackQualityChange(event:Event):void { traceArea.text += "video quality:" + Object(event).data + "\r"; } } } |
14
Google FINALLY Releases AS3 Player for YouTube
Absolutely wonderful that Google has finally released an AS3 version of their chromeless player for use in Flex/AS3 projects. No more weird proxy hacks!!!
I’ve thrown together a quick example and have posted the code below. Really simple stuff to set up and use. Google seems to be more and more friendly to the Flash world lately. There are at least two major projects I’m going to implement this in as soon as I get the time to do so. Very nice- I’m quite pleased!
View the Example:
References:
The ActionScript 3 YouTube Chromeless Player is Now Live
YouTube ActionScript 3.0 Player API Reference
Download the Example:
YouTubeAS3.fxp
View Code for Flash Builder 4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" applicationComplete="init()" width="480" height="500"> <fx:Script> <![CDATA[ import flash.system.Security; import mx.collections.ArrayCollection; import mx.events.ListEvent; import flash.display.Loader; import flash.events.Event; private var player:Object; private var loader:Loader; [Bindable] private var vidCollection:ArrayCollection; private function init():void { Security.allowInsecureDomain("*"); Security.allowDomain("*"); vidCollection = new ArrayCollection(); vidCollection.addItem({data:"KhAplw0Z8zQ", label:"Wreckage"}); vidCollection.addItem({data:"d54AA2YWll0", label:"Window View"}); vidCollection.addItem({data:"Sv83GeuyN8A", label:"The Fearless Man"}); vidCollection.addItem({data:"9t5guYGbuZs", label:"Ephemeral"}); loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaderInit); loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3")); } private function onLoaderInit(event:Event):void { VidHolder.rawChildren.addChild(loader); loader.content.addEventListener("onReady", onPlayerReady); loader.content.addEventListener("onError", onPlayerError); loader.content.addEventListener("onStateChange", onPlayerStateChange); loader.content.addEventListener("onPlaybackQualityChange", onVideoPlaybackQualityChange); } private function onPlayerReady(event:Event):void { traceArea.text += "player ready:" + Object(event).data + "\r"; player = loader.content; player.setSize(VidHolder.width, VidHolder.height); VidSelection.selectedIndex = 0; VidSelection.dispatchEvent(new ListEvent(ListEvent.CHANGE, true, false)); } private function cueVideo(event:ListEvent):void { traceArea.text += "switch to:" + event.target.selectedItem.label + "\r"; player.cueVideoById(event.target.selectedItem.data); } private function onPlayerError(event:Event):void { traceArea.text += "player error:" + Object(event).data + "\r"; } private function onPlayerStateChange(event:Event):void { traceArea.text += "player state:" + Object(event).data + "\r"; } private function onVideoPlaybackQualityChange(event:Event):void { traceArea.text += "video quality:" + Object(event).data + "\r"; } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> <mx:Canvas id="VidHolder" left="0" right="0" top="0" bottom="140"></mx:Canvas> <mx:ComboBox id="VidSelection" editable="false" dataProvider="{vidCollection}" left="10" right="10" bottom="110" height="22" change="cueVideo(event)"></mx:ComboBox> <s:TextArea left="10" right="10" editable="false" top="398" bottom="10" id="traceArea"/> </s:Application> |
31
ActionScript 3.0 Client Library for Facebook Platform API
Nice. Adobe has apparently been working closely with Facebook and Jason Crist (original API dev.) to get a nice, solid API for Facebook apps ready for the Flash Platform. As a Flash Platform developer and Facebook user, this is nothing but good news. Very timely, too – as my department is looking to expand into the social media space. I look forward to integrating this into my day-to-day work and our overall codebase!
3
Quick Tip: Display Application Version in your AIR App.
Just a quick tip for those looking to somehow display the AIR application version from the descriptor file. I’ve found it very helpful in troubleshooting is users can say EXACTLY what version of the app they are running.

1 2 3 4 5 6 | private function getAppVersion():String { var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor; var ns:Namespace = appXml.namespace(); var appVersion:String = appXml.ns::version[0]; return appVersion; } |










