Merging Flickr Accounts
How to Use the FlickrNet API to Merge Flickr Accounts
A few months ago, my wife finally convinced me that it doesn't make any sense to manage two separate pro Flickr accounts, and that we should transfer all the photos to one account and drop the other.So, I looked online for tools that merge Flickr accounts, and couldn't find any. Not even on CodePlex. Don't get me wrong, I found a gazzillion mass downloaders, and uploaders and a bunch of other very cool stuff. But not a merge tool. I even contacted Flickr support, but they were totally useless.
What I really wanted was a way to download the photos from the source account, and keep all the metadata I have meticulously added to the photos over the years - titles, descriptions, sets, tags, geo tags, etc. Then, upload to the target account without disrupting the flow on my photostream. I didn't want a bunch of old photos clogging it up.
Being a developer, I decided to write my own Flickr app using the FlickrNet API library, which turned out to be fun and quite enjoyable.
I don't want to bore you with all the details of my implementation. I'd just like to point out some interesting aspects and potential pitfalls.
Getting an API Key
To get started, you'll need an API key from Flickr. Go to the Services page and click on the "Apply for an API Key" link.
The FlickrNet Library
Download the FlickrNet library from CodePlex. You can download the binaries and reference the DLL from your code. I opted for the more geeky option, and downloaded the source code, and added the FlickrNet project to my solution. This way I could step through the code and better understand how it works.
Authorizing
If you want your app to do more than merely download public photos, your users will need to authorize it. The process is quite simple, but not that obvious. You need to launch a web browser and navigate to a Url. Here's what you do to get the Url.
FlickrNet.Flickr flickr = new FlickrNet.Flickr(ApiKey, SharedSecret);
string frob = flickr.AuthGetFrob();
string url = flickr.AuthCalcUrl(frob, FlickrNet.AuthLevel.Write);
AuthLevel can be one of the following values:
- Read
- Write
- Delete
- None
Once you have the Url, launch the default web browser.
System.Diagnostics.Process.Start(url);
At this point, the user needs to login to her account and authorize the application. Now you can retrieve the authorization token from Flickr.
FlickrNet.Flickr flickr = new FlickrNet.Flickr(ApiKey, SharedSecret);
FlickrNet.Auth auth = flickr.AuthGetToken(frob);
string token = auth.Token;
string userName = auth.User.Username;
Downloading Photos Metadata
This is a relatively simple process. Use the PhotoSearchOptions object to define the photos you are interested in (this could be based on a user, tag, etc.). The PhotosSearch method doesn't return all the photos it finds in one call, rather it returns "pages" of photos. You use the same PhotoSearchOptions to move to the next page and bring the next batch of results.
// Get the user Id based on the user name
FlickrNet.Flickr flickr = new FlickrNet.Flickr(ApiKey, SharedSecret);
FlickrNet.FoundUser user = flickr.PeopleFindByUsername(UserName);
string userId = user.UserId;
// Create a PhotoSearchOptions object
FlickrNet.PhotoSearchOptions options = new FlickrNet.PhotoSearchOptions();
options.UserId = userId;
// Retrieve the user's photos
FlickrNet.Photos photos = flickr.PhotosSearch(options);
Downloading Sets Metadata
// Get all the photosets for the user
FlickrNet.Photosets sets = flickr.PhotosetsGetList(userId);
Linking Photos to Photosets
This is where it gets a little tricky. See, Flickr allows photos to belong to 0-n sets. So, in theory I had to account for photos that are not part of any set, photos that belong to a single set, and for photos that belong to multiple sets. Since almost all of my photos belong to just one set, I've decided to cut myself some slack, and only deal with 0-1 sets per photo.
foreach (FlickrNet.Photoset set in sets.PhotosetCollection)
{
...
... //Save photoset metadata
...
// Get the photoset's photos
FlickrNet.Photoset set1 = flickr.PhotosetsGetPhotos(set.PhotosetId);
FlickrNet.Photo[] setPhotos = set1.PhotoCollection;
foreach (FlickrNet.Photo photo in setPhotos)
{
...
... // Link photo to photoset
...
}
}
Downloading Photos
The one thing to keep in mind here is that Flickr stores multiple versions of each photo (with different resolutions), so you want to make sure you download the largest one.
FlickrNet.Sizes sizes = flickr.PhotosGetSizes(photo.PhotoId);
FlickrNet.Size size = sizes.SizeCollection[sizes.SizeCollection.Length - 1];
string sourceUrl = size.Source;
string fileName = size.Source.Substring(size.Source.LastIndexOf("/") + 1);
WebClient client = new WebClient();
client.DownloadFile(sourceUrl, fileName);
Uploading Photos
Uploading the photos is easy. I just had to change the dates on the photo after the upload to make sure it shows up in the correct place in my photostream based on the upload date, and add the GEO tags, if they existed in the original metadata.
FlickrNet.Flickr flickr = new FlickrNet.Flickr(ApiKey, SharedSecret, AuthToken);
string photoId = flickr.UploadPicture(fileName, title, description, tags, true, false, false);
flickr.PhotosSetDates(photoId, datePosted, dateTaken, FlickrNet.DateGranularity.FullDate);
flickr.PhotosGeoSetLocation(photoId, latitude, longitude);
Creating Photosets
Creating a Photoset is a breeze. Just remember to assign a primary photo to the set, and make sure the photo id is the new photo id (from the target account) not the old one.
FlickrNet.Flickr flickr = new FlickrNet.Flickr(ApiKey, SharedSecret, AuthToken);
FlickrNet.Photoset set = flickr.PhotosetsCreate(title, description, primaryPhotoId);
Now you can add the photos (already uploaded) to the newly created set.
flickr.PhotosetsAddPhoto(photosetId, photoId);
Conclusion
Working with the FlickrNet API is both easy and fun. I'm personally happy I've decided to write my own app, I think I've learned a lot from it. If you are like me, and believe that reading code makes you a better developer, I recommend downloading the source code version and using is in your solution.
Related Links
Coding4Fun
Flickr Explorer
Flickr API
13 comments:
Is there any way for us laymen to merge flickr accounts?
I would pay you for this app if you still have it! Really need it and I'm far from a developer.
Ron,
I'd give it to you for free, but it's in such raw form I don't know if it'll work. I need a couple of weeks to work it over. When it's ready I'll post it for free.
I'm very interested in this as well, looking forward to your post ...
Hi Uri. If you don't have the time to work on this, I'd really appreciate if you just post the code "as is" (with an appropriate YMMV disclaimer) ...
Great idea for an app. I'm sure many would find it useful if you manage to get it up and out there, me included!
I was on the verge of building an app like yours and was wondering if you try to get 'everything' in, say, one batch or rather wanted to store the intermediate data (I have different sets, not just one) in a few tables? Just to make the process more flexible and controllable.
My name is Sherry Calaway I was browsing internet and found your blog. The author did a great job. I will subscribe to your RSS feeds. Thank you for your contribution. I am a web designer myself. And here some examples of the websites that I designed for bad credit loans payday loans canada company.
Hello Uri, Me too, I am eager to have a merge tool like you coded. Did you have a chance to finish it? Greetings from germany, River Beach
I need this too! Any updates...?
To all of you who asked for the app, you can now get it form this location: http://dl.dropbox.com/u/165911/FlickrMerge.zip
Keep in mind though that you are doing it on your own risk. I am in no way liable for the consequences.
Please let me know if you would like the source code as well.
Thanks,
Uri
Dear Uri,
I just downloaded the Seamless Flickr Tool - but unfortunately I don't understand a thing how to use it. Can you give some instructions? Whenever I start it, it says it couldn't be initialized correctly.
Thank you so much!
River
How to use the tool:
Enter the user name of the source account in the text box on the right.
Sign in to the target account.
Once you authorize the application, go back to the tool and click Continue Authentication.
Then just follow the items in the Actions menu top to bottom.
Hope this helps.
Post a Comment