Mobile Zone is brought to you in partnership with:

Den is a DZone Zone Leader and has posted 460 posts at DZone. You can read more from them at their website. View Full User Profile

Flickr API for Windows Phone 7 – Part 9 – Favorites

10.06.2010
| 7616 views |
  • submit to reddit

Favorites are everywhere – in your web browser, in your multitude of accounts all over the web – Twitter, Foursquare and even Flickr. Favorite pictures – the ones you probably liked most for some reason. Here I am going to show you how to find out what exactly are your favorites via Flickr API and eventually integrate this functionality in the Windows Phone 7 application I am working on.

First of all, there are four methods that work with favorites in Flickr:

•    add – adds a photo to the favorites.
•    getList – gets the list of favorites for a specific user.
•    getPublicList – as the title says, it gets the public list of favorites for the user identified by the passed ID.
•    remove – removes a picture from the favorites.

As I mentioned before, I am going to omit the getPublicList method, since I will not be directly invoking other users’ favorites content – the application is to show some core Flickr functionality rather than develop a full client (which will take much longer).

So to start, there is the same familiar class skeleton. I decided to make it easier for you and I created a CS file called base_structure.cs – you can download it here. It is the base structure for a lot of classes that will be used from now on. All you have to do is add it to your solution (the Core folder) and rename it to use proper class naming. From now on, I will not write the class over and over again, but will rather refer to it as the skeleton class.

In my case, I renamed the class to Favorites and set the return property name to LastFavoritesResult, since it will represent the result of the last query (API call).

The add method is called by having a POST HTTP request that contains the photo ID.

NOTE: You cannot favorite your own photos. If you try doing it, the response will be this:

jsonFlickrApi({"stat":"fail", "code":2, "message":"Photo is owned by you"})

My C# implementation for the add method looks like this:

public void AddFavorite(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate)
{
    helperDelegateInstance = helperDelegate;
    string URL = string.Format(
        "http://www.flickr.com/services/rest/?method=flickr.favorites.add&api_key={0}&api_sig={1}&auth_token={2}&photo_id={3}&format=json",
        apiKey,signature,authToken,photoID);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
    request.Method = "POST";

    request.BeginGetResponse(asyncCallback =>
    {
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncCallback);
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            LastFavoritesResult = reader.ReadToEnd();
        }
        helperDelegate();
    }, null);
}

It executes a simple HTTP request that later on reads the response asynchronously – all you have to do is specify a correct photo ID that belongs to someone other than yourself. A successful response looks like this:

jsonFlickrApi({"stat":"ok"})

If you check through the web interface, you can indeed see that the picture was added as a favorite.

To remove the photo from favorites, logically you would think that you would have to do the same – a POST HTTP request with the only difference being the URL. And this is indeed true:

public void RemoveFavorite(string apiKey, string authToken, string signature, string photoID, HelperDelegate helperDelegate)
{
    helperDelegateInstance = helperDelegate;
    string URL = string.Format(
        "http://www.flickr.com/services/rest/?method=flickr.favorites.remove&api_key={0}&api_sig={1}&auth_token={2}&photo_id={3}&format=json",
        apiKey, signature, authToken, photoID);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
    request.Method = "POST";

    request.BeginGetResponse(asyncCallback =>
    {
        HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncCallback);
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            LastFavoritesResult = reader.ReadToEnd();
        }
        helperDelegate();
    }, null);
}

Getting a list of favorites doesn’t require you to work directly with HTTP requests – you can use a WebClient:

public void GetList(string apiKey, string authToken, string signature, string[] extras,
    HelperDelegate helperDelegate, string userID = "",  string minFaveDate = "", string maxFaveDate = "", string page = "",
    string perPage = "")
{
    helperDelegateInstance = helperDelegate;

    WebClient client = new WebClient();
    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
    string URL = string.Format("http://www.flickr.com/services/rest/?method=flickr.favorites.getList&api_key={0}&api_sig={1}&auth_token={2}&format=json",
            apiKey, signature, authToken);

    if (extras != null)
    {
        string toAdd = "&extras=";
        for (int i =0; i< extras.Length; i++)
        {
            if (i != extras.Length - 1)
                toAdd += extras[i] + ",";
            else
                toAdd += extras[i];
        }
        URL += toAdd;
    }

    if (userID != "")
        URL += "&user_id=" + userID;
    if (minFaveDate != "")
        URL += "&min_fave_date=" + minFaveDate;
    if (maxFaveDate != "")
        URL += "&max_fave_date=" + maxFaveDate;
    if (page != "")
        URL += "&page=" + page;
    if (perPage != "")
        URL += "&per_page=" + perPage;

    client.DownloadStringAsync(new Uri(URL));
}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    LastFavoritesResult = e.Result;
    helperDelegateInstance();
}

userID is the optional parameter that represents the user identifier for the user whose favorites you want to retrieve. minFaveDate and maxFaveDate represent the time limits that you can put on the favorites to be retrieved. These should be specified in the UNIX timestamp format.

You can see an interesting parameter here – extras. In fact, it is a parameter that accepts a set of parameters. Basically, you can specify what additional data you want to see about the favorite pictures by sending a text array of the attribute names.

Possible attributes are:

•    description
•    license
•    date_upload
•    date_taken
•    owner_name
•    icon_server
•    original_format
•    last_update
•    geo
•    tags
•    machine_tags
•    o_dims
•    views
•    media
•    path_alias
•    url_sq
•    url_t
•    url_s
•    url_m
•    url_o

What I’m doing here is separating all these additional attributes with a comma in one single extras parameter – it is not optional, but you can pass a null value to it and it won’t be processed. So, for example, if I would like to get the number of views and the license type, I would pass the parameter like this:

&extras=views,license

A simple positive result looks like this:

jsonFlickrApi({"photos":{"page":1, "pages":1, "perpage":100, "total":"1", "photo":[{"id":"3337624498", "owner":"36045374@N03", "secret":"3c3bfc5baf", "server":"3567", "farm":4, "title":"summer streets 1", "ispublic":1, "isfriend":0, "isfamily":0, "datetaken":"2008-09-06 21:42:33", "datetakengranularity":"0", "views":"21", "date_faved":"1286338318"}]}, "stat":"ok"})

You can download Favorites.cs here.