Skip to content

Instantly share code, notes, and snippets.

@romuloceccon
Last active December 15, 2015 00:39
Show Gist options
  • Select an option

  • Save romuloceccon/5174707 to your computer and use it in GitHub Desktop.

Select an option

Save romuloceccon/5174707 to your computer and use it in GitHub Desktop.
Downloads photos from a facebook album and builds a simple html page for browsing them.
#!/usr/bin/env bash
TOKEN=$1
ruby fb_album_tool.rb -t $TOKEN -l | while IFS="\|" read -ra LINE; do
mkdir "${LINE[1]}"
cd "${LINE[1]}"
ruby ../fb_album_tool.rb -t $TOKEN -d ${LINE[0]}
cd ..
done
# coding: utf-8
require 'cgi'
require 'fb_graph'
require 'net/http'
require 'uri'
require 'optparse'
require 'fileutils'
options = {}
optparse = OptionParser.new do |opts|
opts.banner = "Usage: #{$0} [options]"
opts.on("-t", "--access-token", "=TOKEN", "Access token generated by Graph Explorer") do |v|
options[:access_token] = v
end
opts.on("-l", "--list", "List albums for current user") do
options[:list] = true
end
opts.on("-d", "--download", "=ALBUM_ID", "Downloads an album given an ALBUM_ID (returned by --list)") do |v|
options[:download] = v
end
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit(0)
end
end
optparse.parse!
def save_image(source, dest)
uri = URI.parse(source)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme = 'https'
res = http.start do
res = http.get([uri.path, uri.query].compact.join('?'))
unless Net::HTTPSuccess === res
STDERR.print "Error: #{res.code} #{res.message}\n"
exit(1)
end
res
end
File.open(dest, 'wb+') { |g| g << res.body }
end
# Get an access token at http://developers.facebook.com/tools/explorer/
me = FbGraph::User.me(options[:access_token])
if options[:list]
me.albums.each do |x|
puts "#{x.identifier}|#{x.name}|(#{x.count.to_i} photo#{ x.count.to_i >= 2 ? 's' : '' })"
end
exit(0)
end
if album_id = options[:download]
album = me.albums.find { |x| x.identifier == album_id }
i = 1
offset = 0
limit = 25
FileUtils.mkdir_p(album_id)
File.open("#{album_id}.html", 'w+') do |f|
STDERR.puts "Downloading album #{album.identifier} (#{album.name})..."
f << "<!DOCTYPE html>\n"
f << "<head>\n"
f << "<meta charset=\"utf-8\" />\n"
f << "<title>#{CGI::escapeHTML(album.name)}</title>\n"
f << "</head>\n"
f << "<html>\n"
f << "<body>\n"
f << "<p>\n"
f << "#{CGI::escapeHTML(album.description).gsub("\n", "<br />")}\n" if album.description
f << "</p>\n"
begin
photos = album.photos(offset: offset, limit: limit)
offset += limit
photos.each do |p|
STDERR.print "\r#{i}/#{album.count}"
dt = p.raw_attributes["backdated_time"] || p.raw_attributes["created_time"]
dt_str = DateTime.parse(dt).strftime("%d %b %Y %H:%M:%S %Z")
large_url = !p.images.empty? &&
p.images.sort { |a, b| a.width <=> b.width }.last.source
f << "<div>\n"
filename = "#{album_id}/#{i}.jpg"
save_image(p.source, filename)
f << " <div>\n"
if large_url
large_filename = "#{album_id}/#{i}-large.jpg"
save_image(large_url, large_filename)
f << " <a href=\"#{large_filename}\"><image src=\"#{filename}\" /></a>\n"
else
f << " <image src=\"#{filename}\" />\n"
end
f << " </div>\n"
f << " <p>\n"
f << " #{CGI::escapeHTML(p.name).gsub("\n", "<br />")}\n" if p.name
f << " &#x2014; at #{CGI::escapeHTML(p.place.name)}\n" if p.place
f << " </p>\n"
f << " <p>#{dt_str}</p>\n"
f << "</div>\n"
i += 1
STDERR.flush
end
end while !photos.empty?
f << "</body>\n"
f << "</html>\n"
STDERR.print "\n"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment