Flickr API: getting a photo's description?

Jan 22, 2011 at 5:03 PM

Has anyone managed to retrieve a photo's description using the Flickr API?

Flickr puts the description into flickr.photos.getInfo so it seems to require a separate api call to get the actual description for a photo (if one exists).

 

Just wondering if anyone has already done this before I go ahead and try to patch this together myself. Just seems more pertinent to me to have the description under the title rather than when the photo was taken...

Jan 26, 2011 at 6:58 PM

...Bump...

 

Anyone?

Jan 26, 2011 at 11:05 PM

Okay, I just figured out that I can get at the description by using the "extras" parameter along with the flickr.photosets.getPhotos method call and specifying "description". Well, I did it using the API explorer, so now I just need to suss it out in C#. I'll post back here with the code, assuming someone else doesn't beat me to it.  :)

Jan 27, 2011 at 10:27 PM
Edited Jan 27, 2011 at 10:28 PM

SOLVED!

Okay, I noticed that the "extras" argument of the flickr.photossets.getPhotos method is already being called in the OnPhotosetsRequestCompleted method where key/value pairs are being assigned to the "extras" parameters, so first thing to do is add "description" (which isn't included in the Flickr API documentation for the flickr.photossets.getPhotos method, by the way, but it is actually there) to be included in the key/value pair, as so:

 

            foreach (Photoset set in sets)
{
CallFlickrMethod(MethodGetPhotos, OnPhotosRequestCompleted,
new KeyValuePair<string, string>("photoset_id", set.Id),
new KeyValuePair<string, string>("extras", "icon_server,date_taken,description"));
}

 

 

Then, in your OnPhotosRequestCompleted method where the photo attributes are being assigned, you'll want to add a string for the description (I called mine "PhotoDesc"; note also that I got rid of the "DateTaken" variable in my code here since I didn't want it--you can leave it in if you wish); in my case I also pulled the variables out of the "photos.Add" statement since I wasn't able to figure out how to move down to the "description" node while inside it, so I declared some local variables above it to hold the data, and added MoveToContent and ReadToDescendent statements to move out of the "photo" node's attributes and down to the nested "description" node, as so:

 

		private void OnPhotosRequestCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string setId = string.Empty;
List<Photo> photos = new List<Photo>();

using (XmlReader reader = XmlReader.Create(new StringReader(e.Result)))
{
if (reader.ReadToFollowing("photoset"))
{
setId = reader.GetAttribute("id");

while (reader.Read())
{
if (reader.IsStartElement() && reader.Name == "photo")
{

string Id1 = reader.GetAttribute("id");
string Secret1 = reader.GetAttribute("secret");
string Server1 = reader.GetAttribute("server");
string Farm1 = reader.GetAttribute("farm");
string Title1 = reader.GetAttribute("title");


reader.MoveToContent();
reader.ReadToDescendant("description");

string PhotoDesc1 = reader.ReadInnerXml();

photos.Add(new Photo()
{
Id = Id1,
Secret = Secret1,
Server = Server1,
Farm = Farm1,
Title = Title1,
PhotoDesc = PhotoDesc1
});

}

}
}
}

Photoset set = (from p in photosets
where p.Id == setId
select p).ElementAt(0);

if (set != null)
{
set.Photos = photos.ToArray();
}

if (photosets.All(p => p.Photos != null))
{
LoadData();
}
}

 

Then, in the "LoadData" method, you'll want to add a reference for the "description" in the the slide data, as so:

 

		private void LoadData()
{
List<Album> albums = new List<Album>();

foreach (Photoset set in photosets)
{
List<Slide> slides = new List<Slide>();

foreach (Photo photo in set.Photos)
{
slides.Add(new Slide()
{
Title = photo.Title,
Description = photo.PhotoDesc,
Thumbnail = new Uri(
string.Format(CultureInfo.InvariantCulture, ThumbnailFormat,
photo.Farm,
photo.Server,
photo.Id,
photo.Secret),
UriKind.Absolute),
Preview = new Uri(
string.Format(CultureInfo.InvariantCulture, PreviewFormat,
photo.Farm,
photo.Server,
photo.Id,
photo.Secret),
UriKind.Absolute),
Source = new Uri(
string.Format(CultureInfo.InvariantCulture, SourceFormat,
photo.Farm,
photo.Server,
photo.Id,
photo.Secret),
UriKind.Absolute),
Link = new Uri(
string.Format(CultureInfo.InvariantCulture, LinkFormat,
userId,
photo.Id),
UriKind.Absolute)
});
}

albums.Add(new Album()
{
Title = set.Title,
Description = set.Description,
Thumbnail = null,
Slides = slides.ToArray()
});
}

Data.Albums = albums.ToArray();

OnDataFinishedLoading();
}

 

 

Finally, in your "Photo" class, you'll want to add the reference for your description variable (in this case, "PhotoDesc"):

 

public class Photo
{
/// <summary>
/// Gets or sets the id.
/// </summary>
/// <value>The id.</value>
public string Id { get; set; }

/// <summary>
/// Gets or sets the secret.
/// </summary>
/// <value>The secret.</value>
public string Secret { get; set; }

/// <summary>
/// Gets or sets the server.
/// </summary>
/// <value>The server.</value>
public string Server { get; set; }

/// <summary>
/// Gets or sets the farm.
/// </summary>
/// <value>The farm.</value>
public string Farm { get; set; }

/// <summary>
/// Gets or sets the title.
/// </summary>
/// <value>The title.</value>
public string Title { get; set; }

/// <summary>
/// Gets or sets the description.
/// </summary>
/// <value>The description.</value>
public string PhotoDesc { get; set; }

/// <summary>
/// Gets or sets the date taken.
/// </summary>
/// <value>The date taken.</value>
public string DateTaken { get; set; }
}
}


Save, rebuild and run, and you should be pulling in the picture descriptions!

I hope this helps someone. You don't want to know how long it took me to figure this all out (I'm not a "programmer", lol).