Kodak Gallery is holding our photos hostage. But me and Open Source are here to bust them out! (Ruby source code included)

I used kodakgallery.com in 2004 for some photos. I was younger then. I didn't know that I shouldn't bother storing photos on one of the worst photo hosts on the Internet. I thought Kodak was a brand I could trust.

"WE DON'T WANT TO DELETE YOUR PHOTOS" says the email I got today. Fine, delete them. But only after I download them. And I'm not going to pay you $20 to get an Archive CD either.


They're well within their rights to do so (heck, everyone needs to make some money) -- but they also make it quite difficult to download these photos. If you had 200 photos, you would have to click the "Download Full Resolution" button 200 times individually. If these photos are mine, then shouldn't it be a little easier? Sorry, a product manager in some stovepiped organization said no.

A quick google search returned basically no super-easy way to download and archive these things in one fell swoop.

I thought I'd whip up this simple ruby script to download them to your local directory. It requires the 'mechanize' and Ruby 1.8.6+. Save this code to a file, e.g. "kodak_easyshare.rb",  edit your username and password in the script below, then run 'ruby kodak_easyshare.rb' -- and watch the magic happen.

You own those photos. Get them. Download them. Don't let Kodak hold you hostage.

This is hereby released under MIT license.

 
require 'rubygems' 
require 'mechanize' 
require 'fileutils' 
 
agent = WWW::Mechanize.new 
signin_page = agent.get('http://www.kodakgallery.com/Signin.jsp') 
signin_page.forms[0].email = 'yourlogin_at_gmail.com' 
signin_page.forms[0].password = 'your_password_here' 
signin_page.forms[0].submit 
 
album_page = agent.get('http://www.kodakgallery.com/AlbumMenu.jsp?Upost_signin=Welcome.jsp') 
albums = album_page.links.map{|l| (l.href.match(/BrowsePhotos.jsp/) && l.text && l.text.match(/[A-Za-z0-9]/)) ? {:href => l.href, :name => l.text} : nil}.compact 
 
albums.each do |album_hash| 
  puts "\n\n\n" 
  puts "-----------------------------------------" 
  puts "'#{album_hash[:name]}'" 
  puts "#{album_hash[:href]}" 
 
  gallery_page = agent.get("http://www.kodakgallery.com/#{album_hash[:href]}") 
  photos = gallery_page.links.map{|l| (l.href.match(/PhotoView.jsp/) && !l.href.match(/javascript/)) ? l.href : nil}.compact.uniq 
 
  album_dirname = album_hash[:name].gsub(/[\n\t\?\:[[posterous_whitelist_block_0]]gt;[[posterous_whitelist_block_0]]lt;\\/|]/, '_') 
 
  unless File.exists?(album_dirname) 
   puts "creating album #{album_dirname}" 
   FileUtils.mkdir(album_dirname) 
  end 
 
  FileUtils.cd(album_dirname, :verbose => true) do 
 
   photos.each do |p| 
    photo_page = agent.get("http://www.kodakgallery.com/#{p}") 
    fullres = photo_page.links.map{|l| (l.href.match(/FullResDownload/) && !l.href.match(/javascript/)) ? l.href : nil}.compact.uniq.first 
 
    file_to_dl = "http://www.kodakgallery.com#{fullres}" 
    result = agent.get(file_to_dl) 
    if result.class == WWW::Mechanize::File 
     result.save 
     puts "Saved #{file_to_dl}" 
    else 
     puts "FAIL on #{file_to_dl}" 
    end 
 
   end 
 
  end 
 
  puts "-----------------------------------------" 
  puts "-----------------------------------------" 
  puts "-----------------------------------------" 
end 
 

Posted

37 comments

May 22, 2009
data box said...
perfct! lol! hope they read that (one day).
May 22, 2009
Tom Davis said...
if result.class == WWW::Mechanize::File

Type-checking in a duck-typed language? For serious?

May 23, 2009
Garry Tan said...
Haha, well, what are you gonna do? If the fetch method returns other kinds of objects and you know success is only defined by a File, then you do what you gotta do. ;-)
May 23, 2009
Ivan Kirigin said...
Checking if you have the right type is a fine way to do error checking. You more often do this when you're checking if something is None in python. That's essentially a type comparison.
May 23, 2009
turbodingo said...
Thanks! for those of us with more than 16 albums, change this line to get all of them.
FROM THIS:
album_page = agent.get('http://www.kodakgallery.com/AlbumMenu.jsp?Upost_signin=Welcome.jsp')
TO THIS:
album_page = agent.get('http://www.kodakgallery.com/AlbumMenu.jsp?Upost_signin=Welcome.jsp&albumsperpage=9999')
May 23, 2009
data box said...
you guys are really great. i am stting at my pc here and smiling.
May 23, 2009
Bem Jones-Bey said...
@garry: They did what? How do they port a Perl lib to Ruby and change the API in such a way that you now need to do type checking? *sigh* (The perl one returns a response object that you can ask if it's a success or fail and get the body/etc)
May 23, 2009
zanshin said...
Excellent script. Saved me from having to individually download 125+ images.
May 23, 2009
Tom Davis said...
"If the fetch method returns other kinds of objects and you know success is only defined by a File..."

I'm not blaming you, I'm just saying it is pretty sick if the best way to check for a successful grab is by checking the returned class. Why wouldn't it always return the same class? Or in absence of that sensibility, None (or nil, or w/e)?

May 23, 2009
Garry Tan said...
It's just that a fetch can return "Page" or "Meta" and other types, not just "File"
May 23, 2009
turbodingo said...
One more suggestion: If you let it, mechanize will keep a copy of previously loaded pages in memory. This script doesn't need that, and it's a big waste of system resources, especially when downloading hundreds of pictures. To avoid it, change this line:

agent = WWW::Mechanize.new

to be this:

agent = WWW::Mechanize.new{ |agent|
agent.history.max_size=0
}

(learned from http://my.opera.com/dduenker/blog/2008/09/03/ruby-prevent-www-mechanize-from-stealing-your-memory )

May 24, 2009
robert carter said...
can anyone host this easily? would be great to offer it as a service available to more than those that with a local ruby instance...

p.s., luv that posterous displays this code so well.

Jul 13, 2009
Chris Sparno said...
Garry, this is awesome. We must have signed up the same time of year as I just got the message that I jad 13 days to make a $4.99 purchased or lose my photos. The script is running in the background right now and I am so glad I saw this post.
Aug 12, 2009
deepakjain said...
I've been using Kodakgallery since 2003 (when there weren't many options and I figured Kodak was a good enough name to stay around). I didn't even mind buying stuff form them until photographs became passe.

I even tried to buy their Archive CD except their system can't process > 40,000 images via Archive CD.

They keep canceling my order without comment.

(Current photo storage: 62.532 GB Used,
219 galleries,
Your Archive CD Pricing:
Number of Photos: 42666
Cost of your CD: $667.85

FYI).

Works like a champ. Send me an address and I'll send you some beer or money or something.

Aug 18, 2009
greacen said...
nice. you could probably write something to use their XMI interface if you ran easyshare desktop app through something like Charles. Might even be a little (only slightly) cleaner.
Aug 29, 2009
mnicw said...
Okay... This news is great, and I am very thankful that someone has giving me a chance to get back all my daughters baby pictures I haved stored on Ofoto. But, I have a massive problem that needs attention !!!

For the last 2 hours, I have tried to figure out how to run the script posted above using Ruby. It says you need Mechanize, which has no exe to launch, so how the hell does it work.I have it downloaded, but there's no setup or exe or launch method, very F@*#@$g frustrating...Does it run with IE, or Firefox, or in the Run cmd line...What is the order to launch...Mechanize, then Ruby than the script. How do I tell that Mechanize is running. I type in the script posted above with the mono settings as mentioned ( usually default ) and it does nothing... Where does it download to, does it show a file percentage downloaded... Is Mechanize suppose to be running without notification...Forgive me as I am not a computer idiot, just have no clue how this works whatsoever !!!

I've read the articles on Ruby, Mechanize and still have no clue how or where or what should be happening on my screen or how this can work...I am in hell, please help this idiot,,,I beg you... lol : )

Aug 30, 2009
Garry Tan said...
Hi mnicw -- Sorry this doesn't work very well at all using Windows. This script is most easily run on OS X or on Linux. You can probably run it on Windows if you install this: http://rubyforge.org/projects/rubyinstaller/ (I haven't used this but it seems like this would help)

You would need to install the mechanize gem by first running gem install mechanize. Then you would run ruby myscript.rb.

Aug 30, 2009
mnicw said...
You would need to install the mechanize gem by first running gem install mechanize -

Where and how using what program, where do I input this command... Do i have to open a program ??? Where does this go ??? Sorry, but I'm still lost !

Aug 30, 2009
Garry Tan said...
mcnicw -- They're command line programs (no GUI, no program that is clickable)I.

If you still have problems, I suggest trying http://www.picwing.com/blog/?p=1457 -- there's no setup involved, and we know those guys and they're awesome!

Aug 30, 2009
robert carter said...
picwing does do a great job importing but they do downres your photos; if you're a windows user you can download the kodak easyshare software (http://www.kodak.com/eknec/PageQuerier.jhtml?pq-path=130&pq-locale=en_US&_requestid=7662) and download all your images that way; should be your hi-res originals...
Aug 31, 2009
picwing said...
We'd be happy to import your pictures at Picwing. Let me know if you need any help. We actually don't downres the photos anymore, as we keep a hires version for printing purposes.
Sep 07, 2009
mnicw said...
Hey guys...Thanks for all your help. Unfortunately, I installed the Picwing program and none of my pictures are there when I entered my Kodak Username and password. It just displayed and empty folder... I'm considering wiping out my wfie's computer and installing Linux so I can try the scripting suggested...Is it too late??? I have no photos at all, very saddened... I wil supply my username and pass if somebody trustworthy could try the scripting for me to see if the 500 pictures are there...

Help please : (

Sep 08, 2009
picwing said...
Hi mnicw,

Its Edward from Picwing. I just tested our kodak gallery import program and didn't see any problems. It's possible that Kodak already deleted your photos so we couldn't find anything to import =(. Send me an email and i'll try to help you out.

Sep 25, 2009
tanstaafl said...
Thanks, out Boy Scout troop had almost 6 Gigs of photos. Now we can xfer them to our own server. The script works great!
Sep 25, 2009
tanstaafl said...
Looks like a limitation in the script. I had one folder with 246 photos and the script kept aborting at 223 pictures. I moved some photos around and put the album at 220 and it works fine now.
Oct 07, 2009
dgtlrift said...
Ack... I think they pages have changed and this script no longer works. Oh well...
Oct 17, 2009
armyofbobs said...
Kodak strikes again. I think they're site rebuild broke the picwing program. Picwing gave me this error "We're sorry, but something went wrong." Well, you're a hero for building this, wish I found it before the new kodak launched.
Nov 04, 2009
picwing said...
Picwing strikes back again! Kodak broke our import tool when they launched their new site, but we've since modified the script so that Kodak import is up and working once again.
Nov 06, 2009
brink668 said...
Hi Garry, is it possible that you can update your code a bit? I tried to tweaking to get the sign-in page to work, but that isn't working out..

That would be awesome if you could.

Nov 06, 2009
brink668 said...
Adding to that, the sign-in page didn't work, so I ended up finding an old page that did work!

Below:
http://classic.kodakgallery.com/Signin.jsp?

I got past the login but still having troubles, hope this helps if you don't mind updating your script.

Nov 06, 2009
brink668 said...
Gosh I got it Working!!

I'll report back, later with the new code. Just want to see if it works well!

Nov 06, 2009
Garry Tan said...
Very cool -- if you want to email me garry@posterous.com I can update the code and provide a link to you / your blog / whatever.
Nov 08, 2009
juamps said...
Thx, Garry and all for the comments.

I updated your code and got it to work. Here's what I did:

1. updated the agent code to avoid memory problems (thx @turbodingo)
agent = WWW::Mechanize.new{ |agent|
agent.history.max_size=0
}

2. updated albums per page (thx @turbodingo's) since i have more than 16 albums
album_page = agent.get('http://www.kodakgallery.com/AlbumMenu.jsp?Upost_signin=Welcome.jsp&albumsperpage=999

3. updated the kodakgallery urls from www.kodakgallery.com to classic.kodaygallery.com

Nov 08, 2009
juamps said...
what I haven't been able to figure out is how to skip photos that already exist in the folder - there was some trial and error going on so i had to restart the process a couple of times.
Nov 09, 2009
brink668 said...
@juamps thats awesome, I just sent him those exact fixes on Nov 5th!! Wierd.

Even posted a tutorial how to do it on a windows machine.

http://www.computerrich.com/news/kodak-gallery-download-ruby-script-windows-automation-tool/

Mar 03, 2010
jlueck said...
Nice stuff. Worked really well. Liberation from Kodak!
Jun 30, 2010
alexmb said...
i am not to good with computers, is there a simple way to do this?
thanks

Leave a comment...