kelvinluck.com

a stroke of luck

Flashr Auth demo


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:

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

Update:

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

I’ve just stuck together a simple demo which shows how to authenticate against flickr.com using Flashr and the new authentication API.

This seems to be one of the more confusing aspects of the Flickr API (it definitely was to me until I implemented it the first time). This demo basically shows the process of authenticating and also shows how you can store the authentication token in a SharedObject so that a returning user doesn’t need to log in again.

Note: you don’t need to authenticate against flickr.com to use most methods of the API. You only need to do it if you want to access a user’s private photos or to add / update information. The api docs tell you when authenication is necessary (I didn’t necessarily port all this information across into the flashr docs).

Right, here is the demo in action:

And here is the source code. To use the source code just download it and unzip it. Edit the file to put your API Key and secret in. Make sure you have the core of Flashr in your class path and compile the class with these MTASC flags (on top of your normal ones for -cp and -swf):


-header 400:250:25 -main com/kelvinluck/flickr/example/FlashrAuthDemo.as

If you have any problems with the demo then please ask questions on the Flashr mailing list.



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.



Flashr demo


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 Flashr and see the data structures 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.

Update – I have made a standalone version of this demo which connects to SOS for improved logging performance (quicker output, horizontal scrollbar and you can copy and paste the logged text). Download it here.

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



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.



krl_flickr_photoset released


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.

A little while ago I added some code to display my Flickr photosets on my photos page. I got an email requesting the code so I just released it in my projects section. It takes the form of a Textpattern plugin but I’ve also released the raw PHP code for people without Textpattern. Enjoy!



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…



A new way to browse Flickr


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.

Felix Turner of Airtight Interactive has been playing with the Flickr API and has come up with a cool new way to browse flickr.

Great work and great use of the API… It really inspires me to actually get around to making something :)



Simulating access to the Flickr API offline


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.

As I recently mentioned on the Flickr API mailing list, I’m just about to head off on a road trip where I will have my laptop and maybe a little spare time but no Internet connection. And I was thinking it would be good to carry on putting together my Flickr API library for AS2. But – to test my methods requires an internet connection to connect to the Flickr servers… Or does it?

I wrote the script below to use as a proxy between Flash and Flickr. You will need to use a proxy of some kind anyway as you cannot connect directly from a Flash movie on one domain to servers on another domain (due to the cross domain security sandbox in the Flash Player). This proxy saves all the XML it receives from Flickr as files on your file system. Then if it can’t reach the Flickr servers (e.g. when you are offline) it will serve up the contents of these files instead. Well – it will if you make a call to the API which is identical to one which has been cached. Otherwise it will serve up a custom error document which is similar to the standard Flickr error document except it contains a unique error code so you can deal with it in your application.

Without further ado, here is the code:

// CONFIGURATION
define("_SAVE_PATH", dirname(__FILE__)."/downloaded/");
define("_ERROR_MESSAGE", "< ?xml version=\"1.0\" encoding=\"utf-8\" ?><rsp stat=\"fail\"><err code=\"999\" msg=\"No access to flickr.com and no cached result for this request\" /></rsp>");
define("REST_ENDPOINT", "http://www.flickr.com/services/rest/");

if ($fp = @fopen("http://flickr.com", "r")) {
    // we are online and can see flickr.com - cache any requests that come in
    fclose($fp);
    define("_ONLINE", 1);
} else {
    // we can't see flickr.com - try an serve up cached pages instead...
    define("_ONLINE", 0);
}

$querystring = array_pop(explode("?", $_SERVER["REQUEST_URI"]));
$query_parts = array();
parse_str($querystring, $query_parts);
ksort($query_parts);

$filename = "";
foreach($query_parts as $key=>$value) {
    $filename .= $key."|".$value."||";
}

$filename = urlencode($filename);

if (_ONLINE) { // we are online - go get the info and save it!
    $fp = fopen(_SAVE_PATH.$filename, "w");
    $content = file_get_contents(REST_ENDPOINT."?".$querystring);
    fwrite($fp, $content);
    fclose($fp);
} else { // we are offline - serve up the saved file if it exists or the error message if you can't find a file
    if (file_exists(_SAVE_PATH.$filename)) {
        $content = file_get_contents(_SAVE_PATH.$filename);
    } else {
        $content = _ERROR_MESSAGE;
    }
}
header("Content-Type: text/xml");
echo $content;

As you can see, it’s pretty simple really. It’s not tested all that comprehensively yet but it should work. The next thing to do is to write a script which automatically calls this script once for each possible outcome of each call to the Flickr API so that you have a complete library of the possible returns on your machine.

One side note… I wouldn’t recommend running this script on a public webserver. It doesn’t feel too secure to me to be writing files which are named based on the querystring to your webserver. At least change the _SAVE_PATH so that people don’t know where to look for the files. Probably a bit paranoid but better safe than sorry, ey? And anyway – you should be running the it on your laptop anyway so this shouldn’t be an issue :)

If you want to download the complete script with commenting etc then please do: flickr_cache.phps. Any comments, ways to improve it or ideas on how to easily implement the “call every method once” script please use the form below…