Skip to content

Instantly share code, notes, and snippets.

@bknarendra
Created September 12, 2016 20:39
Show Gist options
  • Save bknarendra/949d6dab8d83ba0fc82e5aa0445d52c7 to your computer and use it in GitHub Desktop.
Save bknarendra/949d6dab8d83ba0fc82e5aa0445d52c7 to your computer and use it in GitHub Desktop.
Download images from shared Flickr album 1 by 1. It has the ability to resume downloads if it is interrupted. Also you can download images in different size options
require 'mechanize'
require 'json'
ALBUM_URL = ARGV[0]
ALBUM_NAME = ARGV[1]
SIZE_TO_DOWNLOAD = ARGV[2]
if !ALBUM_URL || !ALBUM_NAME
puts "Usage: ruby #{__FILE__} <album_url> <album_name> [size_to_download_image]"
puts "size_to_download_image default 'o' which is original. Other available options in descending order of size k, h, l, c, m etc."
exit!
end
SIZE_TO_DOWNLOAD = 'o'
class FlickrDownloader
def initialize
@client = Mechanize.new{|u| u.user_agent_alias="Mac Safari"}
home_page = @client.get(ALBUM_URL)
@photoset_id = home_page.uri.to_s.match(/sets\/(\d+)/)[1]
@api_key = home_page.content.match(/root\.YUI_config\.flickr\.api\.site_key.*?"(.*)".*$/)[1]
@per_page = 50
@album = {"title" => ALBUM_NAME, "photo_urls" => []}
@json_file = ALBUM_NAME + '.json'
end
def reset_token
@api_key = @client.get(ALBUM_URL).content.match(/root\.YUI_config\.flickr\.api\.site_key.*?"(.*)".*$/)[1]
end
def fetch_photo_links
links_file = JSON.parse(File.read(@json_file)) rescue nil
return if links_file
page = 1
loop do
puts "fetching links on page #{page}"
photo_list_url = "https://api.flickr.com/services/rest?extras=can_addmeta%2Ccan_comment%2Ccan_download%2Ccan_share%2Ccontact%2Ccount_comments%2Ccount_faves%2Ccount_views%2Cdate_taken%2Cdate_upload%2Cdescription%2Cicon_urls_deep%2Cisfavorite%2Cispro%2Clicense%2Cmedia%2Cneeds_interstitial%2Cowner_name%2Cowner_datecreate%2Cpath_alias%2Crealname%2Crotation%2Csafety_level%2Csecret_k%2Csecret_h%2Curl_c%2Curl_f%2Curl_h%2Curl_k%2Curl_l%2Curl_m%2Curl_n%2Curl_o%2Curl_q%2Curl_s%2Curl_sq%2Curl_t%2Curl_z%2Cvisibility%2Cvisibility_source%2Co_dims%2Cis_marketplace_printable%2Cis_marketplace_licensable%2Cpubliceditability&per_page=#{@per_page}&page=#{page}&get_user_info=1&primary_photo_extras=url_c%2C%20url_h%2C%20url_k%2C%20url_l%2C%20url_m%2C%20url_n%2C%20url_o%2C%20url_q%2C%20url_s%2C%20url_sq%2C%20url_t%2C%20url_z%2C%20needs_interstitial%2C%20can_share&jump_to=&photoset_id=#{@photoset_id}&viewerNSID=&method=flickr.photosets.getPhotos&csrf=&api_key=#{@api_key}&format=json&hermes=1&hermesClient=1&reqId=53857556&nojsoncallback=1"
photos = JSON.parse(@client.get(photo_list_url).content)
if photos["stat"] != "ok"
if photos["message"]['Invalid API Key']
reset_token()
else
break
end
end
photos['photoset']['photo'].each do |photo|
@album["photo_urls"].push(photo["url_#{SIZE_TO_DOWNLOAD}_cdn"])
end
puts "fetched #{photos['photoset']['photo'].length} links from page"
page += 1
end
puts "dumping links to #{@json_file}"
File.open(@json_file, 'w') { |file| file.write @album.to_json }
end
def download_photos_from_links
puts "reading links from #{@json_file}"
links = JSON.parse(File.read(@json_file)) rescue nil
fetch_photo_links if !links
if !Dir.exists?(links["title"])
puts "creating dir '#{links["title"]}'"
Dir.mkdir(links["title"])
end
links["photo_urls"].each do |photo|
file_path = links["title"] + "/" + File.basename(photo)
puts "downloading #{photo}"
@client.get(photo).save(file_path) if !File.exists?(file_path)
end
end
end
flickr_downloader = FlickrDownloader.new()
flickr_downloader.fetch_photo_links
flickr_downloader.download_photos_from_links
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment