{"id":1177,"date":"2010-01-30T19:05:40","date_gmt":"2010-01-31T00:05:40","guid":{"rendered":"http:\/\/UnhinderedByTalent.com\/Phi\/?p=1177"},"modified":"2010-01-30T19:05:40","modified_gmt":"2010-01-31T00:05:40","slug":"flickr-uploadr-is-a-pain-but-flickraw-saved-the-day","status":"publish","type":"post","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2010\/01\/30\/flickr-uploadr-is-a-pain-but-flickraw-saved-the-day\/","title":{"rendered":"Flickr Uploadr is a pain, but Flickraw saved the day"},"content":{"rendered":"<p><figure style=\"width: 500px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.flickr.com\/photos\/nics_events\/4313355604\/in\/set-72157623180822901\"><img decoding=\"async\" loading=\"lazy\" alt=\"Thomas McPhee as Arnold in the MAHS 2010 production of &quot;The boys next door&quot; as a one-act\" src=\"https:\/\/i0.wp.com\/farm5.static.flickr.com\/4017\/4313355604_e68f0979bd.jpg?resize=500%2C333\" title=\"Thomas McPhee as Arnold in the MAHS 2010 production of &quot;The boys next door&quot; as a one-act\" width=\"500\" height=\"333\" data-recalc-dims=\"1\" \/><\/a><figcaption class=\"wp-caption-text\">Tom as Arnold in &quot;The boys next door&quot;<\/figcaption><\/figure><br \/>\nFlickr&#8217;s Uploadr is fine for small uploads, but tends to die consistently and unpleasantly when I have several hundred photos to upload, like those from Thursday&#8217;s opening of &#8220;The boys next door&#8221;, this year&#8217;s Morris Area High School one-act.  It almost always takes me several tries to get a large pool of photos uploaded, which is a pain, but not fatal.  This time, however, it chose to upload them in a semi-random order, so then it died I had 80-ish photos scattered all across the show, which meant I couldn&#8217;t just delete the first <em>K<\/em> from the list and restart the upload.  Ugh.<\/p>\n<p>Because it was late and I was in a hurry, I ended up just uploading the whole set (over several attempts), but marked them as private so people wouldn&#8217;t end up seeing two copies of that first group of images, figuring I&#8217;d sort things out in the morning.<\/p>\n<p>The morning came, and it turned out that I really didn&#8217;t have a workable plan.  All the pictures were on Flickr, but there was no good (i.e., automated) way to figure out which were the duplicates.  If I could identify them, then deleting the duplicates and making the rest visible would be easy, but I didn&#8217;t have a clue how to find the duplicates using Flickr&#8217;s tools.<\/p>\n<p>Sigh.<\/p>\n<p>This would, however, be pretty straight forward in a script if I had all the data I needed, and this is where Flickr redeemed itself.  They have a very rich API for accessing (and modifying) photos and their associated information (like tags), so if I could figure out how to use that I&#8217;d be golden.  I&#8217;d poked a <em>little<\/em> with some Ruby Flickr libraries in the past, but none of them ever seemed very complete and they were always struggling to stay on top of Flickr&#8217;s changes and extensions to the API.  A little searching this time, however, turned up <a href=\"http:\/\/github.com\/hanklords\/flickraw\">Flickraw<\/a>, which uses some really nifty <a href=\"http:\/\/pragprog.com\/titles\/ppmetr\/metaprogramming-ruby\">Ruby metaprogramming<\/a> to essentially build the Ruby part of the API &#8220;on the fly&#8221;, ensuring that it will be complete and up-to-date all automagically!<\/p>\n<p>It turns out that Flickraw was indeed powerful, flexible, and easy to use.  After authenticating (following the example on the Flickraw web site), I was able to use it to pull down a list of all the photos from &#8220;The boys next door&#8221;<\/p>\n<pre class=\"brush: ruby; title: ; notranslate\" title=\"\">\r\nmy_owner_id = &quot;68457656@N00&quot;\r\nplay_title = &quot;The boys next door&quot;\r\nmy_stream = flickr.photos.search(\r\n              :user_id =&gt; my_owner_id, \r\n              :text =&gt; play_title, \r\n              :per_page =&gt; 500)\r\n<\/pre>\n<p>I then split that list into the initial set of publicly visible photos, and the photos I&#8217;d uploaded after things got screwy and kept private (i.e., visible only to me):<\/p>\n<pre class=\"brush: ruby; title: ; notranslate\" title=\"\">\r\npublic_photos = my_stream.find_all {|photo| photo.ispublic == 1}\r\nprivate_photos = my_stream.find_all {|photo| photo.ispublic == 0}\r\n<\/pre>\n<p>My next task was to determine which of the private photos were duplicates of one of the public photos people were already looking at.  All I <em>really<\/em> needed was the list of duplicates, but I decided to create lists of both the duplicates and the non-duplicates.  I had to compare titles here because the Flickr IDs would be different; as far as Flickr knew they were all different photos.  Happily, I had named them in a way that they each had a unique title, so if two photos had the same title, I knew they were the same shot uploaded twice.<\/p>\n<pre class=\"brush: ruby; title: ; notranslate\" title=\"\">\r\ndups = []\r\nnon_dups = []\r\nprivate_photos.each do |photo|\r\n  public_duplicate = public_photos.find { |pub| photo.title == pub.title }\r\n  if public_duplicate\r\n    dups.push(photo)\r\n  else\r\n    non_dups.push(photo)\r\n  end\r\nend\r\n<\/pre>\n<p>At this point, I could apply tags to all the photos in the two groups, and all the rest of the fiddling could be done through Flickr&#8217;s web tools:<\/p>\n<pre class=\"brush: ruby; title: ; notranslate\" title=\"\">\r\nnon_dups.each do |photo|\r\n  flickr.photos.addTags(:photo_id =&gt; photo.id, \r\n                        :tags =&gt; &quot;to_keep&quot;)\r\nend\r\n\r\ndups.each do |photo|\r\n  flickr.photos.addTags(:photo_id =&gt; photo.id, \r\n                        :tags =&gt; &quot;to_delete&quot;)\r\nend\r\n<\/pre>\n<p>I could have actually done everything with the Ruby script (delete the duplicates, change the remaining images to publicly visible, and add them to the appropriate set), but wanted to do that via Flickr so I could see what was happening as I went.  And once the tags were in place, the work in Flickr was quite straightforward.  The result: <a href=\"http:\/\/www.flickr.com\/photos\/nics_events\/sets\/72157623180822901\/\">A set of 339 images<\/a> that contains all the photos I uploaded, with no duplicates, all accomplished without deleting any of the original uploads.<\/p>\n<p>Big thanks to <a href=\"http:\/\/github.com\/hanklords\">Ma\u00ebl Cl\u00e9rambault<\/a>, the author of Flickraw, for his excellent little library, and thanks to Flickr for providing this very nice set of API calls.  (Now go fix Flickr Uploadr, damnit!)<\/p>\n<p>As for the play &#8211; I just heard that they took second at today&#8217;s sub-sections competiton, which means they move on to sections next week, and <a href=\"http:\/\/ThomasMcPhee.com\/\">Tom<\/a> got a star performance award!  Congratulations all!<\/p>\n\n\t<div class=\"st-post-tags \">\n\tTags: <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/api\/\" title=\"API\">API<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/automation\/\" title=\"automation\">automation<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/family\/\" title=\"Family\">Family<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/flickr\/\" title=\"Flickr\">Flickr<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/flickraw\/\" title=\"Flickraw\">Flickraw<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/my-photography\/\" title=\"my photography\">my photography<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/performance\/\" title=\"performance\">performance<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/photography\/\" title=\"Photography\">Photography<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/programming\/\" title=\"programming\">programming<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/ruby\/\" title=\"Ruby\">Ruby<\/a>, <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/tag\/scripting\/\" title=\"scripting\">scripting<\/a><br \/><\/div>\n\n\n\t<h4>Related posts<\/h4>\n\t<ul class=\"st-related-posts\">\n\t<li><a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2008\/01\/20\/new-ways-to-bore-you-with-our-holiday-photos\/\" title=\"New ways to bore you with our holiday photos (20 Jan 08)\">New ways to bore you with our holiday photos<\/a> (1)<\/li>\n\t<li><a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/11\/18\/hey-dee-ho-spiffy-new-version-of-wordpress-all-around\/\" title=\"Hey-dee-ho!  Spiffy new version of WordPress all around (18 Nov 07)\">Hey-dee-ho!  Spiffy new version of WordPress all around<\/a> (0)<\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>Flickr&#8217;s Uploadr is fine for small uploads, but tends to die consistently and unpleasantly when I have several hundred photos to upload, like those from Thursday&#8217;s opening of &#8220;The boys next door&#8221;, this year&#8217;s Morris Area High School one-act. It almost always takes me several tries to get a large pool of photos uploaded, which &hellip; <a href=\"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2010\/01\/30\/flickr-uploadr-is-a-pain-but-flickraw-saved-the-day\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Flickr Uploadr is a pain, but Flickraw saved the day&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_newsletter_tier_id":0},"categories":[4,11,25,20],"tags":[505,507,873,105,504,65,89,869,82,503,506],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p90sy-iZ","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"jetpack-related-posts":[{"id":1263,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2010\/05\/06\/mom-loves-me\/","url_meta":{"origin":1177,"position":0},"title":"Mom Loves Me","author":"Nic McPhee","date":"6 May 10","format":false,"excerpt":"Mom Loves Me, originally uploaded by nailbender. I don't get enough time to look at the wonderful photos that other people are posting on Flickr, but every now and then I carve out a few minutes. This morning over breakfast I discovered this gem and had to share. There is\u2026","rel":"","context":"In &quot;Art&quot;","block_context":{"text":"Art","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/art\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":534,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/04\/10\/feathers-braids-and-beads\/","url_meta":{"origin":1177,"position":1},"title":"Feathers, braids, and beads","author":"Nic McPhee","date":"10 Apr 07","format":false,"excerpt":"Feathers, braids, and beads, originally uploaded by Unhindered by Talent. On of my favorite shots from the powwow (or here) a few weeks ago. I'm still moving very slowly through those (and other photos), but now and then I find time to handle a few.","rel":"","context":"In &quot;Art&quot;","block_context":{"text":"Art","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/art\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":503,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/03\/03\/signs-of-winter-finally\/","url_meta":{"origin":1177,"position":2},"title":"Signs of winter (finally!)","author":"Nic McPhee","date":"3 Mar 07","format":false,"excerpt":"Signs of winter (finally!), originally uploaded by Unhindered by Talent. After a warm and extremely dry (as in drought sort of dry) winter, we've had two major winter storms across Minnesota and Wisconsin in the last week. So a week or so ago the ground was bare, and now we've\u2026","rel":"","context":"In &quot;Environment&quot;","block_context":{"text":"Environment","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/science\/environment\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":423,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/01\/06\/giving-me-the-evil-eye\/","url_meta":{"origin":1177,"position":3},"title":"Giving me the evil eye","author":"Nic McPhee","date":"6 Jan 07","format":false,"excerpt":"Giving me the evil eye, originally uploaded by Unhindered by Talent. This is one of a pair of photos for my sister (the other is here). This is her parrot, Julian, a bright and most cantankerous bird, with a tendency to lunge out and remove bits of your flesh with\u2026","rel":"","context":"In &quot;Family&quot;","block_context":{"text":"Family","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/family\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":435,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/01\/30\/fuzzy-leaves\/","url_meta":{"origin":1177,"position":4},"title":"Fuzzy leaves","author":"Nic McPhee","date":"30 Jan 07","format":false,"excerpt":"Fuzzy leaves, originally uploaded by Unhindered by Talent. I hear tell that's it's probably a mullien plant. It (and several like it) were growing in the fields at Pea Ridge National Miliary Park, which isn't too far from my parents' house in NW Arkansas. Pea Ridge was a major battle\u2026","rel":"","context":"In &quot;Events&quot;","block_context":{"text":"Events","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/events\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":551,"url":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/2007\/05\/05\/24-hours-of-flickr\/","url_meta":{"origin":1177,"position":5},"title":"24 Hours of Flickr","author":"Nic McPhee","date":"5 May 07","format":false,"excerpt":"Popu, originally uploaded by fraud_art. The Flickr folks are finally getting around to doing a \"Day in the life of Flickr\" sort of event called \"24 Hours of Flickr\". (It seems like such an obvious idea, I'm really surprised they haven't done it earlier.) Today (5 May) is the big\u2026","rel":"","context":"In &quot;Books&quot;","block_context":{"text":"Books","link":"https:\/\/UnhinderedByTalent.com\/Phi\/archives\/category\/writing\/books\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/posts\/1177"}],"collection":[{"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/comments?post=1177"}],"version-history":[{"count":14,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/posts\/1177\/revisions"}],"predecessor-version":[{"id":1191,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/posts\/1177\/revisions\/1191"}],"wp:attachment":[{"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/media?parent=1177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/categories?post=1177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/UnhinderedByTalent.com\/Phi\/wp-json\/wp\/v2\/tags?post=1177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}