kelvinluck.com

a stroke of luck

Flashr released on OSFlash


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update:

For the latest up to date information about Flashr please check out the new Flashr microsite

Flashr has just been released on the OSFlash site. Not only does this make it more visible to more people but it also means there is a shiny new svn repository and a mailing list…

The mailing list is now the preferred place to ask questions about using Flashr and to suggest ways to improve it. Sign up now! You can also check the archives although there isn’t much there at the moment!

There is also a Subversion repository which is where you will find the latest version of Flashr. I’ll still provide the zip files for release versions but may just fix a few bugs on the subversion version in between releases.

Another benefit of the subversion is that there will be detailed changelogs available if you browse it via the Trac system.



Flashr 0.3 released


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update:

For the latest up to date information about Flashr please check out the new Flashr microsite

I have just uploaded a new version of Flashr to the site. Quite a few changes in this version – here are the details:

  • Added flickr.photosets.* methods
  • Added flickr.groups.pools.* methods
  • Cleaned up the code a little so that it compiles with MTASC

And other fixes / improvements which these changes involved (see the full changelog).

I’ve updated the Flashr demo to include support for the new methods. I also added a standalone downloadable version of the demo which uses my SOS wrapper for output. This has a number of advantages. Firstly it is quick (which matters when you are returning lists of hundreds of photos). Secondly you can copy and paste from it (so if you get a list of a user’s photos you can then copy a photo id and use it to call another method in the demo). The zip contains a config.xml file that you can edit to control where it looks for the SOS server.

As well as all of that I also released some example sourcecode which shows how to use Flashr.

And I’ve been working on a little app of my own that uses Flashr – got to get it polished up and then I’ll release it here :)



Flashr code example


Update 3:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update 2:

For the latest up to date information about Flashr please check out the new Flashr microsite

Update:

This example will no longer work as-is – you will need to update your Flashr files as described here.

I’ve put together a very simple example which demonstrates how easy it is to talk to the flickr API using Flashr.

First up, here is the finished product. It basically connects to flickr.com and gets a list of the 16 most recent photos for a given user (me in this case) and displays them all in a nice little grid.

The code to create this simple movie is extremely simple… Here it is in it’s entirety:

/**
* Class: UserRecentPhotos
*
* Author:
* Kelvin Luck
*
* See Also:
* http ://www.kelvinluck.com/projects/flashr-a-flickr-api-wrapper-for-flash
*/


import com.kelvinluck.flickr.Flickr;
import com.kelvinluck.flickr.FlickrResponseListener;
import com.kelvinluck.flickr.Person;
import com.kelvinluck.flickr.Photo;
import com.kelvinluck.util.LogWrapper;
import com.dynamicflash.utils.Delegate;

class com.kelvinluck.flickr.example.UserRecentPhotos
{
   
   /**
   * Variable: apiKey
   * Your API Key.
   *
   * See Also:
   * http ://www.flickr.com/services/api/misc.api_keys.html
   **/

   var apiKey:String = "REPLACE_ME";
   /**
   * Variable: userNsid
   * The NSID of the user whose photos you want to get
   **/

   var userNsid:String = "51035610516@N01";
   /**
   * Variable: _target
   * The MovieClip to attach the photo thumbnails to
   **/

   var _target:MovieClip;
   
   /**
   * Function: UserRecentPhotos
   * Constructor
   **/

   function UserRecentPhotos(target:MovieClip)
   {
      Stage.scaleMode = "noScale";
     
      // initalise logging to Flash's output window
      LogWrapper.getInstance().init();
      LogWrapper.getInstance().addTracePublisher();
     
      _target= target;
      var _flickr:Flickr = Flickr.getFlickr();
      _flickr.apiKey = apiKey;
      var _flickrResponseListener:FlickrResponseListener = new FlickrResponseListener();
      _flickrResponseListener.setSuppressOutput(true);
      _flickrResponseListener.onPeopleGetPublicPhotos = Delegate.create(this, onPeopleGetPublicPhotos);
      _flickr.peopleGetPublicPhotos(userNsid, null, 16,1);
   }
   /**
   * Function: onPeopleGetPublicPhotos
   * Called when the _flickrResponseListener hears a response to flikr.people.getPublicPhotos
   *
   * Parameters:
   * p               -  The person whose photos you just got.
   **/

   function onPeopleGetPublicPhotos(p:Person):Void
   {
      var photosArray:Array = p.getPhotos();
      var userNsid:String = p.nsid;
      for (var i:Number=0; i< photosarray .length; i++) {
         var thisPhoto:Photo = Photo(photosArray[i]);
         
         // create a movieclip to load the photo into
         var mc:MovieClip = _target.createEmptyMovieClip("photo"+i, i);
         
         // position the clips so they form a nice grid
         mc._x = 1 + (i%4) * 76;
         mc._y = 1 + Math.floor(i/4) * 76;
         // create a nested movieclip so that our onPress isn't overwritten by the jpg as it loads
         mc.createEmptyMovieClip("jpgHolder", 1);
         // and load the jpeg into it
         mc.jpgHolder.loadMovie(thisPhoto.thumbnailUrl);
         
         mc.photo = thisPhoto;
         
         // add the onPress to this movieclip to link to the relevant photo on flickr.com
         mc.onPress = function()
         {
            getURL(this["photo"].photoPageUrl, "_blank");
         };
      }
   }
   /**
   * Function: main
   * Entrypoint to the application.
   **/

   public static function main():Void
   {
      var u:UserRecentPhotos = new UserRecentPhotos(_root);
   }
   /**
   * Function: toString
   **/

   public function toString():String
   {
      return "[com.kelvinluck.flickr.example.UserRecentPhotos]";
   }
}

As you can see, an instance of Flickr and an instance of FlickrResponseListener are created. Then _flickr.peopleGetPublicPhotos is called. When a response is returned by flickr.com, _flickrResponseListener.onPeopleGetPublicPhotos is triggered. This function is passed a Person object. We can get this person’s photos with a simple call to Person.getPhotos. We then loop over those photos loading them into movieclips.

And that’s how easy it is! You can download the files used in this demo from here – there is instructions for building with MTASC or the Flash IDE. The file that you will be interested in looking at is com.kelvinluck.flickr.example.UserRecentPhotos.as.

Update 2:

Petit as written a step by step tutorial showing how to use this code as a basis for a copy of the flickr badge.



Logging from FAME


Update:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

I’ve recently started playing with FAME (or more properly FME - FDT, MTASC and Eclipse) and found it frustrating not having a trace window in Eclipse which I could use to debug my code…

Then I discovered Powerflasher SOS which is a handy standalone console which you can connect to via an XMLSocket from Flash. SOS has some incredible handy features for use along with FME. For example you can set it to “Console > Bring to Front > During Connection”. This means that the logging console will stay at the front of your screen while there is a socket connection open to it. I found it fiddly with other logging solutions which had a console opening within a panel in Eclipse (maybe because of the lack of screen real estate on my laptop). So I like this feature a lot. You could even run the SOS console on a different machine to make maximum use of screen space!

I thought what if I could combine the power of SOS with the convenient object introspection of the LuminicBox logger and colour coding etc.. And while I was at it I decided to also add support for the MTASC TRACE directive. So I did. Building on the TracePublisher from LuminicBox and adjusting a little code I came up with something which turns this:

/**
* example code for using a com.kelvinluck.util.SOSLogPublisher
**/


import com.kelvinluck.util.SOSLogPublisher;
import com.kelvinluck.util.LogWrapper;

LogWrapper.getInstance().init();
LogWrapper.getLog().addPublisher(new SOSLogPublisher("myAppsName"));
// log messages at different levels
LogWrapper.getLog().fatal("This is a fatal error :'(");
LogWrapper.getLog().error("This is an error :(");
LogWrapper.getLog().warn("This is a warning, warning, warning");
LogWrapper.getLog().info("This is information");
LogWrapper.getLog().debug("This is debugging info");
// an Array (folded by default in SOS)
LogWrapper.getLog().debug([1,2,3,{a:"Part A", b:"Part B"}, "Some text", 99]);
// an anoynomous object (also folded by default)
LogWrapper.getLog().error({a:"this is a", b:"and this is b"});
// an object with a toString method (folded by default with the name from the toString method shown)...
var testObj:Foo = new Foo("bar", 2000, ["A", "B", "C", "DDDDDD"]);
LogWrapper.getLog().warn(testObj);
// and using TRACE - add "-trace com.kelvinluck.util.LogWrapper.mtascTrace" to the commandline and compile using MTASC
trace("Check out the class and line number info above!");
trace({error:"something is wrong"}, LogWrapper.ERROR);

Into this (showing the horizontal scrollbar and four objects – three in their default folded states and one which I have “unfolded”):

SOS in action

Download:
If you want to play with this code please feel free to download it here.

The zip file includes an example class with a static main method that can be used to test the installation.

Requirements:
To use these classes successfully you will need a couple of things:

Powerflasher SOS – install it and run it. Select “Console > Bring to Front > During Connection” from the menu.

LuminicBox logger – install the extension. I have also included the LuminicBox classes in my zip just because I had to make a few tiny changes to get them to play nice with MTASC which is stricter than the MMC.

Unfortunately SOS only runs on windows so at least the machine that you view the logs on must be a windows machine.

Usage:
You can use it pretty much as demonstrated by the code above… Also check in the comments to the SOSLogPublisher code to see the arguments you can pass to the constructor etc… Just make sure that the relevant files are in your classpath.

If you are using these files along with MTASC’s trace functionality then you will need to add the following argument to your command line to MTASC:

-trace com.kelvinluck.util.LogWrapper.mtascTrace

Also note that you can do the following to toggle the display of line numbers:

LogWrapper.logCallingFile = false; // stops class / file / line number information from being logged
LogWrapper.logCallingFile = true; // starts class / file / line number information getting logged.

If you are using in with FDT then I found it really useful to create 4 Templates (“Window > Preferences > FDT > Templates > Templates”) to speed up entering debug code. For example, I have the “ze” (without the quotes) mapped to:

LogWrapper.getLog().error(${cursor});

or if you are using MTASC and trace you may find this more useful:

trace(${cursor}, LogWrapper.ERROR);

And similarly for the other log levels.

When you publish your finished file for production you can simply comment out the relevant addPublisher line to you don’t need to worry about the innards of your program being visible to others. Or if you use MTASC and trace then even better – just change the trace argument to be “-trace no” and the traces won’t even be compiled into your final swf!

History:
2005-08-30: First release
2005-08-31: Added folding so that Objects, Arrays etc which are logged are folded by default and can be opened inside SOS if you desire.
2005-09-01: Bug fix so XML and other objects containing < and > can be debugged.
2005-09-01: Added support for MTASC’s TRACE command
2005-09-10: Wrapped traced data in CDATA block so that ampersands, < ‘sand >’s can be successfully debugged.
2005-09-14: Added Natural Docs to the download zip.

Feedback:
If you find this useful or can think of a way that it can be more useful then please let me know below by leaving a comment below or via the OSFlash mailing list.



Flashr 0.2 released


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update

For the latest up to date information about Flashr please check out the new Flashr microsite

Flashr is the shiny new name for my Flash AS2 wrapper for the Flickr API. Version 0.2 of it has just been released, including support for the new auth scheme and much more.

Prompted by the update of the user authentication system and by getting back from 3 months holiday I have just updated Flashr. The main changes are where authentication is involved but I also made a number of other changes to the code. Certain things became a lot easier with the new system as you now know who the logged in user is.

Unfortunately some of the changes I made will require people using the library to change some of their code. For example, a lot of API functions which return a list of photos now support the “extras” parameter and I have placed this at the start of the parameters list. This is where it falls in the API documentation on flickr.com and I thought that it was more useful to stick with this than to retain backwards compatibility with old code.

However, at this time the code moves out of alpha and into beta so it should be the last time such radical and unbackwardscompatible changes are made to the library. The Flickr API itself is also maturing now and so should become relatively stable.

Go and check out the new library here or if you want to see it in action then jump straight into a demo.



New flickr API demo


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update:

For the latest up to date information about Flashr please check out the new Flashr microsite

This is a small test file which allows you to call different methods of the flickr API through my flash wrapper class and see the objects that are returned.

You can view the debug information returned from each call in the panel below which is a Luminic Box Flash Inspector. Select the method you want to call from the drop down and then fill in any arguments that are required. Then click the submit button to connect to flickr.com and get the results. Use my documentation to make more sense of the required arguments and returned values.

Warning – I’ve noticed that the Flash Inspector doesn’t work if more than one instance is open at once – make sure you only have one instance of it running while doing this test… If you just see a blank space below check there is no other Flash Inspector running (in another browser or as a panel in the IDE for example) then refresh.

Note – In order to directly connect to flickr.com from a flash file on your domain as I do you will have to speak to the nice people at flickr.com about getting your domain added to their crossdomain.xml file (due to flash’s inbuilt security restrictions).




A couple more notes…

  • When Pablo has done the changes I suggested to the Luminic Flash Inspector then hopefully the output above will be a little more useful.
  • The Flash Inspector is set to a maximum display depth of 4 so when you drill down into objects it may sometimes seem that you have found an empty object within them but this is just because that depth isn’t being displayed…

As always, comments and feedback appreciated below or via email…



Excellent Flash debugging tool


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

much more up to date article on debugging from Flash.

The other day I came across the excellent luminicbox.log API for logging from Flash (english machine translation).

This is an API and debugger which will make your life as a Flash developer many many times easier. Rather than using the trace command you can Log messages to a LuminicBox.Log.Logger which will then use an “IPublisher” to output the logged message.

It comes with an IPublisher which outputs to the trace window in the Flash IDE (but pretty prints objects and arrays) as well as the really impressive “Flash Inspector” which allows you to view what the debug messages in a seperate swf. This swf communicates with your swf through a LocalConnection which means that you will be able to debug your application even after it is sitting on the live server. Yay :)

There is one little change that I wanted to make to it though. Whenever I write custom classes I override the default .toString method so that it returns a sensible name for each instance of that class. I wanted to have that displayed for each object that I logged when debugging… This would allow me to see at a glance what was going on in my application. While I’m at it, it would be nice to know how big an array was without having to specifically look at it’s .length.

First I set about adding this functionality to the TracePublisher class. This was easy enough – just change the following line:

txt += "(" + typeOf + ")";
 

to this:

txt += "(";
if (typeOf == "object") txt += o; // o.toString is implicitly called.
else if (typeOf == "array") txt += "array[" + o.length + "]";
else txt += typeOf;
txt += ") ";

Now when I Log my debug messages I see something like this:

*DEBUG*:(array[2]) {
   1:([Object com.kelvinluck.flickr.Photo - 6895531]) {
      contextThumbUrl:"http://photos7.flickr.com/6895531_23190e6e72_s.jpg"
      contextUrl:"/photos/lifeinpixels/6895531/in/photostream/"
      title:"Almost there"
      secret:"23190e6e72"
      id:"6895531"
   }
   0:([Object com.kelvinluck.flickr.Photo - 6895548]) {
      contextThumbUrl:"http://photos8.flickr.com/6895548_7993732d17_s.jpg"
      contextUrl:"/photos/lifeinpixels/6895548/in/photostream/"
      title:"Drop"
      secret:"7993732d17"
      id:"6895548"
   }
}

Now I want to add this functionality to the “Flash Inspector”. In fact, this is where it would be more useful. Because when you trace an Object or Array it is by default callopsed so it would be good to get a bit more information about the item without having to open it out.

Unfortunately I had a look and it looks like to add this functionality would require some editing in the “Flash Inspector” file which isn’t released with the source code. I suggested this improvement to Pablo (the author of this great tool) and he agreed it would be a good idea and is going to look into implementing it… Yay! In my opinion it would make something that is already really cool into something even more useful!

Anyway – props out to Pablo for writing this cool tool and I’ll update here if he makes the changes I suggested…



Another interface between Flash and Flickr


Update 2:

This is a very old page imported from my previous blog. If there is missing content below or anything that doesn’t make sense then please check the page on my old blog.

Update:

Check out Flashr – that’s what this idea grew into…

This page provides an introduction to an interface I am writing between Flash and the Flickr API. It’s something I’ve been thinking about for a while but which got stuck on the back burner. Seeing inspiring stuff like Flickr graph from Marcos Weskamp has made me decide that I should try and get this out there.
After writing this page I’ve realised that it has ended up much longer than anyone probably wants to read… If you aren’t interested in my motivation then skip down to the example and if it looks like something you might be interested in then you can check out the documentation as well – although that’s maybe even longer.

WHY????
But there are already (at least 2) Flash interfaces to the Flickr API! Why would we need another one?
I started out using flickr api and found it useful. Then I came across a method on the Flickr API which hadn’t yet been implemented in “flickr api”. So I implemented it myself. But doing this I became frustrated and decided there must be an easier way…
I wanted an API which could give me variable type checking on all the things I was passing to Flickr and which would do any necessary XML parsing for me without me having to think about it.
I also wanted it to run in the Flash Player 6 (mamata’s “flickr api” could be fairly easily adjusted for this). And ideally to have things in place like a queue so I didn’t need to worry about waiting for one request to complete before sending the next one.
Another aim was to have good documentation so that someone could sit down with this system and by writing minimal AS2 code could have an application that interfaced with Flickr. The long term aim of all this is to be able to sit down and write some cool applications using the Flickr API… But first things first.

HOW?
So how does my interface work? See the documentation for the gory details. [sidenote - I did the docs with Natural Docs - pretty cool actually!]
Basically there are two core classes: com.kelvinluck.flickr.Flickr and com.kelvinluck.flickr.FlickrResponseListener. The idea is that you create a Flickr object which you can then call methods on. This ensures that type checking can be done when making API calls to Flickr to catch author time errors. You then have an instance of FlickrResponseListener which listens for the responses from the Flickr API. By itself that isn’t much good for you – it just logs some messages (thanks to Colin Moock’s Logger application). But the idea is that you would either subclass FlickrResponseListener or would create an instance and override the methods that you are interested in.
I assume that this approach to this type of problem has been used before and has a name but I’m afraid I don’t know it. It’s kind of like an Java style interface in that I am describing what I expect the function you will write to accept as arguments although the compiler obviously won’t enforce this. You will, however, have the documentation and an argument list for your function so it should make it fairly easy to write the code…

EXAMPLE!
Here is an example of my interface (damn – I need to come up with a more catchy name!) in action. Basically the drop down lets you pick from the functions of the API I have programmed (so far flickr.contacts.*, flickr.people.*, flickr.tags.* and flickr.test.*). Then the two text fields are the two (optional) arguments to the function you are calling. Your call and response are logged to the big TextArea. You can change the severity of the messages logged with the ComboBox at the top of the screen.

The relevant code in this example application is very simple:

// on the first frame
import com.kelvinluck.flickr.Flickr;
import com.kelvinluck.flickr.FlickrResponseListener;
var _flickr:Flickr = Flickr.getFlickr();
_flickrResponseListener = new FlickrResponseListener();
_flickr.apiKey = "YOUR_API_KEY";

// and on the event handler for the "Go" button
_flickr[command_cb.selectedItem.label](arg1.text, arg2.text);
 

You can see that the application takes a lot of the legwork out of talking to Flickr. When you see stuff like “[Object com.kelvinluck.flickr.Person - 51035610516@N01]” in the output that is because the Person.toString method is being called. As you will see if you switch the log level to DEBUG, there is more data stored along with that person…

DOWNLOAD
But where is the code? I’m going to release it when it is a little bit more finished. I wanted to show the docs and example at this stage to try and gather some feedback on the general approach.
Do people think my approach is useful – would you be more likely to use this library than one of the existing ones? What do you think is good/bad about this way of approaching the problem? Have you got any suggestions for a better way of structuring the code given the requirements?
If someone can convince me that another approach to the problem is better then they will save me the time I’ll spend adding the rest of the API calls to the library. If people like the approach it might give me the kick up the arse I need to get round to completing this… So – feedback of any sort appreciated! Use the comments form below or email me – kelvin at kelvinluck dot com :)