Flickr ‘Justified’ Layout in JQuery

Update: I’ve done a updated version, with scrolling, and various input boxes for changing the tags to search for here: http://jsbin.com/upinek/15. Enjoy.

Someone posted recently on Stackoverflow asking how the new Flickr Justified photo pages had been created. i.e. how to create multiple rows of evenly spaced images without cropping the images to fit. It was something I had been wondering about for a while, so I did a bit of investigation.

A similar question had been answered to do with the Google+ photo page, but that uses cropped thumbnails to create the effect, something I thought it would be better to avoid.

I’m not 100% sure that this is indeed how Flickr do it, but it produces such nice results that I thought I would show you what I came up with.

The key to this method is to make the height of the row variable.

The first thing I did was pick an arbitrary height, the maximum you want each row to be. Then get the width of the parent div, in this case a div with class “picrow”. Then keep a copy of all the widths of the photos, scaled to match this height. I also set an margin to be included later at 5 px.

Then I counted the number of photos that are going to appear in the row, along with their accumulated width until I reach the width of the parent div.

Then you can calculate the ratio of the actual width of the div to the accumulated width of the photos to include in the row.

Finally, take the images, one at a time, and resize and add to the div. Again, keep track of the actual accumulated width.

That is the basics. In the full code I have added multiple rows, and support for refreshing on resizing of the window, and making it easy to change the tag searched for.

 

You can view the full code on JSBin here: http://jsbin.com/upinek/3/edit#javascript,html and you can see it running here: http://jsbin.com/upinek/3

There is certainly room for scope for adding other features, such as dynamically creating new rows where there is more content, and adding overlays to show photo titles etc., but hopefully this gives you a place to start. There is also an issue if one of the images it especially wide which I haven’t tracked down yet, so its not perfect by any means.

Weekly Tweet Update 22-03-2012

Weekly Tweet Update 16-02-2012

Silverlight and the Authorization Header – OAuth

I discovered the other day that there are issues when using Silverlight and setting the Authorization header, the preferred method for sending the oauth parameters to a service.

http://oauth.net/core/1.0a/#consumer_req_param

Silverlight 3.0 does not however let you set the Authorization header.

Silverlight 4 and 5 will let you set the header, but will produce a rather generic exception “System.Security.SecurityException: Security error” if the endpoint does not have a clientaccesspolicy.xml – the cross domain policy defined by Microsoft for use with Silverlight. This file allows for more specific control over the access, and must explicitly allow the use of the Authorization header. Currently services such as Flickr and Twitter do not support the clientaccesspolicy file, only the Adobe crossdomain.xml file.

Silverlight will fall back on to using the crossdomain.xml file, so calls can be made. However it appears the same issue exists with this file too:

http://kb2.adobe.com/cps/403/kb403184.html

Tim Heuer has an article covering how Silverlight and the Client Access Policy file works.

http://timheuer.com/blog/archive/2010/04/23/silverlight-authorization-header-access.aspx

It isn’t clear whether Silverlight would work with a modified crossdomain.xml file that allowed the Authorization header, as Silverlight only supports a subset of the crossdomain.xml file specification (but I can’t find details on which subset).

Flickr announces end date for old authentication

Don't go!Flickr have announced the end date for the old authentication method.

After the 31st July you will no longer be able to use the old authentication methods, and will have to use the new OAuth 1.0a authentication flow in your applications.

http://code.flickr.com/blog/2012/01/13/farewell-flickrauth/

I’m glad to say that Flickr.Net library already fully supports OAuth, and the old methods are deprecated. I will be deleting these methods from the library nearer the time in an effort to get everyone to move forward with the new OAuth flow.

OAuth and Flickr – Part 2

Continuing on from Part 1.

Update: I got the order of the parameters wrong below so my example signature was incorrect. I have now fixed that.

Update2: Flickr have updated to only using HTTPS endpoints. I won’t change the code below as then the signature generation would not match the output values, but bare this in mind.

Authenticating with Flickr

The process of authenticating with Flickr is a 3 stage process.

First you call the request token url and get back a request token and a request token secret.

Second you redirect the user to the authorize url and they approve your authentication request. Then they are either presented with a verification code on the screen, or the verification code is appended to your callback url.

Thirdly, once you have the verifier code you call the access token url to get your final access token.

Step 1 – Request a Request Token?

I have created an API key and shared secret especially for this tutorial which I will use below. Feel free to use this API key for testing, but do not use it for development – go get your own. The reason I provide this functionality here is so that you can test your signature generation function – if you use my api key and shared secret you should get exactly the same signature.

Signature Generation

This is the bit that catches most people out, and so I will go through this step by step.

First, you need to get your oauth parameters set.

Timestamp= “1316657628”
Nonce = “C2F26CD5C075BA9050AD8EE90644CF29”
Consumer Key = “768fe946d252b119746fda82e1599980”
Version = “1.0”
Signature Method =  “HMAC-SHA1”
Callback URL = “http://www.wackylabs.net/oauth/test”

Consumer Secret = “1a3c208e172d3edc”

To generate a SHA1 signature you require two things. First a key. For OAuth the signature key is made up of two parts, your consumer secret, and your token secret (for whichever token you are using at the time). As this is the first stage you have neither, so your token secret is simply an empty string.

Key = Consumer Secret + “&” + Token Secret
= “1a3c208e172d3edc&”

The second part of the SHA1 signature generation is the base string. For OAuth the base string is made up of three parts, the HTTP method, the URL endpoint you are using, and the parameters you are sending.

OAuth Parameter Encoding – Not your normal encoding

However the key to this part is the encoding. OAuth uses an encoding which is very similar to URL encoding (i.e. replacing parts of a URL string with %NN where NN is the hex number for that character). However it is different, in that more things are encoded when using OAuth encoding (e.g. spaces can be encoded as a “+” symbol in URL encoding, but in OAuth must be encoded as “%20”.

OAuth encoding only allows letters, numbers and the following 4 punctuation marks: “_”, “-“, “.” and “~”. All other characters must be encoded.

You will likely not notice the difference until you come to call methods that include things like title etc, as most parameters will not contain data that is encoded differently with the above compared to standard url encoding.

A little post I found covering some of the differences is here: http://www.marcworrell.com/article-2943-en.html

Bringing the Base String Together

For the first part of the base string then encoding doesn’t matter, as it will be either “GET” or “POST”. This is the same once encoded :)

For the second part your request url endpoint will get encoded to something like this:

“http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token”

For the final part of the base string you need to concatenate the encoded parameters and values as if you were generating a URL (except you are using oauth encoding), and then encode the whole lot again. The parameters must also be sorted in alphabetical order. Note, technically you are encoding both the parameter name and value, but as letters and the “_” character do not change after encoding the parameter names look the same after encoding.

So first you generate the following string (ignore carriage returns):

“oauth_callback=http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest&
oauth_consumer_key=768fe946d252b119746fda82e1599980&
oauth_nonce=C2F26CD5C075BA9050AD8EE90644CF29&
oauth_signature_method=HMAC-SHA1&oauth_timestamp=1316657628&
oauth_version=1.0”

And then you encode it again (again, ignore carriage returns):

“oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252Foauth%252Ftest%26
oauth_consumer_key%3D768fe946d252b119746fda82e1599980%26
oauth_nonce%3DC2F26CD5C075BA9050AD8EE90644CF29%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1316657628%26
oauth_version%3D1.0”

Before finally adding it all together as part1 + “&” + part2 + “&” + part3 to give a final base string like so:

Base String = “GET&http%3A%2F%2Fwww.flickr.com%2Fservices%2Foauth%2Frequest_token&
oauth_callback%3Dhttp%253A%252F%252Fwww.wackylabs.net%252F
oauth%252Ftest%26oauth_consumer_key%3D768fe946d252b119746fda82e1599980%26
oauth_nonce%3DC2F26CD5C075BA9050AD8EE90644CF29%26
oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1316657628%26
oauth_version%3D1.0”

Finally you are ready to use whatever SHA1 code your programming language provides to generate the signature.

In .Net this might look like this:

byte[] keyBytes = System.Text.Encoding.UTF8.GetBytes(key); System.Security.Cryptography.HMACSHA1 sha1 = new System.Security.Cryptography.HMACSHA1(keyBytes); byte[] signatureBytes = sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(baseString)); string signature = Convert.ToBase64String(signatureBytes);

In PHP this might look like this:

$signature = base64_encode(hash_hmac(‘sha1’, $baseString, $key, true));

The important thing to notice with both of these examples is that you are returning binary data from the signature method, and then base 64 encoding this data. The hash_hmac() method in php can also return string data, but this will not work, so the fourth parameter is required to be set to true to return the raw binary data instead.

Using the above methods, and the above sample parameters the final signature is as follows:

Signature = “0fhNGlzpFNAsTme/hDfUb5HPB5U=”

Finally Request your Token

Now you have your signature you can create the url to actually request your request token with.

Note, when generating your URL you must again encode everything (including the new oauth_signature parameter) but you do not need to use the strict OAuth encoding, but can return to normal url encoding.

URL = “http://www.flickr.com/services/oauth/request_token?oauth_callback=http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest&oauth_consumer_key=768fe946d252b119746fda82e1599980&oauth_nonce=C2F26CD5C075BA9050AD8EE90644CF29&oauth_timestamp=1316657628&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=0fhNGlzpFNAsTme%2FhDfUb5HPB5U%3D”

 Authorization Header

It is possible, rather than putting everything in the query string as above to put all of your oauth parameters in a special HTTP header instead.

OAuth parameter put into the Authorization header should be encoded using oauth encoding as for the generation of the base string. However the parameter values are enclosed in double quotes (“) and each parameter is separated by a comma.

All OAuth parameters then need removing from the request URL, in this case as they are ALL oauth parameter you are just left with the request_token endpoint.

So the header would look like this (line breaks and other white space are optional between the parameters in the header):

OAuth oauth_consumer_key=”768fe946d252b119746fda82e1599980″, oauth_timestamp=”1316657628″, oauth_nonce=”C2F26CD5C075BA9050AD8EE90644CF29″, oauth_signature_method=”HMAC-SHA1″, oauth_signature=”0fhNGlzpFNAsTme%2FhDfUb5HPB5U%3D”, oauth_callback_url=”http%3A%2F%2Fwww.wackylabs.net%2Foauth%2Ftest”, oauth_version=”1.0″

Note: DO NOT send oauth parameters in both the Authoriszation header and the query string (or body) as Flickr thinks you are sending each parameter twice and will generate a different signature from you (unless you include all the parameters twice when you generate the signature, but that’s just silly).

In the next part I will look at error handling.

OAuth and Flickr – Part 1

Flickr recently announced (well OK, it was back in June) that they would be supporting OAuth 1.0a as the future authentication method for accessing the Flickr API. They say that sometime in 2012 the old authentication token scheme will be phased out.

http://code.flickr.com/blog/2011/06/21/flickr-now-supports-oauth-1-0a/

Now on the surface the authentication method that Flickr had been using was very OAuth ‘like’, but as I soon came to realise they are really very different beasts, mostly because unless you get OAuth exactly right it can be very confusing where you are going wrong.

So I thought I would write these posts to take you through, step-by-step how to get OAuth working with Flickr, and then finally how to use the new functionality in the FlickrNet library.

Flickr OAuth Documentation

The first thing you will probably want to do is have a quick read through the Flickr OAuth documentation. I don’t consider it to be an exhaustive document, hence why I am writing this, but it is a good place to start.

http://www.flickr.com/services/api/auth.oauth.html

Right, are you back? Good.

If you want a more in-depth look of the whole OAuth specification then I recommend this:

http://oauth.net/core/1.0a/

Converting from Old to New?

First, if you are converting from old to new here is a run-down of the new oauth parameters, and what they used to be called:

oauth_consumer_key: This is your API Key. You will still need this key, but you will not need to pass the “api_key” parameter any more as it is now called oauth_consumer_key. If you are not doing authenticated calls then you can still use OAuth to send your API Key to Flickr inside the oauth_consumer_key parameter.

consumer secret: This is your Shared Secret. As with the old mechnanism you never send this value to Flickr, but use it to generate the signature. If you are not doing any authentication then this is not really needed.

http://www.flickr.com/services/oauth/request_token: This is the URL endpoint for requesting a temporary token for performing OAuth authentication. This replaces effectively the “frob” or the “flickr.auth.getFrob” method. Note, previously the frob was a single value, but now the request_token is made up of both a token and a secret.

http://www.flickr.com/services/oauth/authorize: This is the web page you redirect the user to to perform the authorization.

http://www.flickr.com/services/oauth/access_token: And finally this is the URL endpoint that you request your permanent access token and access token secret from.

oauth_token: There are two ‘tokens’ used during the authentication process. The request token is the first one, and is only used during authentication. The access token is returned at the final step of authentication and is used for calling normal Flickr methods.

oauth_token_secret: Both tokens used above have a corresponding secret (so there is a request token secret, and an access token secret). Which token secret you use to sign a call depends on which token you are using. During authentication this will be the request token secret, and afterwards the access token secret.

oauth_timestamp: This is the number of seconds since 1/1/1970, sometimes called the unix epoch. Note, this time should always be calculated using GMT (or UTC) times, not local times. If your timestamp is not a current time (i.e. is more than an hour out) then Flickr will reject your call to the Flickr API.

oauth_nonce: A random series of characters unique to this call to Flickr. If you have two users using the same web page that both make calls to Flickr at the same time then the timestamp will be the same, but the oauth_nonce must be different.

oauth_callback: The callback URL in the Flickr API Keys settings is now ignored, and you sent the callback url every time you call the request_token endpoint. This does mean you can include anything you want in the url, and you can also use the same consumer key for multiple web sites if you so desired. Your 1 query per second limit is on a per key basis though, not on a per website basis, so probably better get different keys for different web sites. If you are not using a callback url then you can use “oob” as your callback url. This will present the user with a web page once they have authenticated and they will have to cut and paste the oauth verifier string into your application. There are ways around this that I will go into in a later part.

oauth_version and oauth_signature_method: The version is always “1.0” and signature method for Flickr is always HMAC-SHA1 (although others are supported by the OAuth spec).

In Part 2 I will take you through a sample authentication process.