Skip to content

Instantly share code, notes, and snippets.

@o-sam-o
Created February 8, 2015 22:52
Show Gist options
  • Save o-sam-o/a3093fc1caf0e1c9954b to your computer and use it in GitHub Desktop.
Save o-sam-o/a3093fc1caf0e1c9954b to your computer and use it in GitHub Desktop.
flickr_to_untappd.rb
require 'mechanize'
require 'json'
require 'awesome_print'
require 'base58'
require 'net/http'
require 'uri'
require 'untappd'
require 'logger'
FLICKR_API_KEY = "3fffd0917fa897e24bd5a442018df29a"
FLICKR_PHOTOSET = "72157625277593652"
ALREADY_POSTED_FILE = "/home/sam/Programming/Ruby/flick_untappd/already_posted.txt"
FAILED_TO_POST = "/home/sam/Programming/Ruby/flick_untappd/failed_to_post.txt"
UNTAPPD_CLIENT_ID = "..."
UNTAPPD_SECRET = "..."
UNTAPPD_USERNAME = '...'
UNTAPPD_PASSWORD = '...'
Untappd.configure do |config|
config.client_id = UNTAPPD_CLIENT_ID
config.client_secret = UNTAPPD_SECRET
config.redirect_url = 'http://example.com'
config.gmt_offset = -8
end
def post_photo_to_untappd(photo)
p "Attempting to post photo '#{photo}'"
beer = Untappd::Beer.search(photo.beer_name).beers.items.find do |b|
p "Search found #{b.brewery.brewery_name} - #{b.beer.beer_name}"
photo.brewery_name.nil? || b.brewery.brewery_name.start_with?(photo.brewery_name)
end
beer = Untappd::Beer.search(photo.title).beers.items.find do |b|
p "Search found #{b.brewery.brewery_name} - #{b.beer.beer_name}"
photo.brewery_name.nil? || b.brewery.brewery_name.start_with?(photo.brewery_name)
end if beer.nil?
raise "Unable to find beer for #{photo}" unless beer
ap beer
# Untappd API doesnt support image upload so needs to be done via website API
a = Mechanize.new
a.log = Logger.new('mech.txt')
a.get('https://untappd.com/login') do |login_page|
home_page = login_page.form_with(:action => 'https://untappd.com/login') do |form|
form.username = UNTAPPD_USERNAME
form.password = UNTAPPD_PASSWORD
end.submit
check_in = Untappd::Checkin.create(auth_token, beer.beer.bid, {"shout" => photo.flickr_url})
p "Untappd checkin #{check_in.checkin_id}"
p "Downloading photo"
`wget #{photo.image_url}`
file_name = URI(photo.image_url).path.split('/').last
image_file = File.new(file_name)
#photo_post = a.post('https://untappd.com/apireqs/photo/add', {
# "checkin_id" => check_in.checkin_id,
# "file" => image_file
#},
#{'Content-Type' => 'image/jpeg'})
# Mechanize doesnt set the mime_type correctly and untappd rejects the call if its not set. Need to use hacky private method technique
node = {}
# Create a fake form
class << node
def search(*args); []; end
end
node['method'] = 'POST'
node['enctype'] = 'application/x-www-form-urlencoded'
form = Mechanize::Form.new(node)
form.enctype = 'multipart/form-data'
ul = Mechanize::Form::FileUpload.new({'name' => 'file'},::File.basename(image_file.path))
ul.file_data = image_file.read
ul.mime_type = "image/jpeg"
form.file_uploads << ul
form.fields << Mechanize::Form::Field.new({'name' => "checkin_id"}, check_in.checkin_id.to_s)
photo_post = a.send(:post_form, 'https://untappd.com/apireqs/photo/add', form, {})
p photo_post
# TODO post photo
File.delete(file_name)
end
p "Done"
end
def auth_token
#TODO automate get auth token
#auth_url = Untappd::OAuth.authenticate_url
#response = Net::HTTP.get_response(URI.parse(auth_url))
#ap response
#ap response.methods
#ap response.body
return '...'
end
class FlickrPhoto
attr_reader :brewery_name, :beer_name
def initialize(photo_json)
@json = photo_json
@brewery_name, @beer_name = title.include?('-') ? title.split('-') : [nil, title]
end
def photo_id
@json['id']
end
def title
@json['title']
end
def flickr_url
"https://flic.kr/p/#{Base58.encode photo_id.to_i}"
end
def image_url
@json['url_m']
end
def to_s
"#{title} (#{photo_id})"
end
end
def random_flickr_photos(photo_count)
p "Fletching flickr photos for photoset #{FLICKR_PHOTOSET}"
agent = Mechanize.new
photos = []
page_count = 1
json_results = {}
begin
p "Fetch page #{page_count}"
page = agent.get "https://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos&page=#{page_count}&api_key=#{FLICKR_API_KEY}&photoset_id=#{FLICKR_PHOTOSET}&format=json&nojsoncallback=1&extras=url_m"
json_results = JSON.parse(page.body)
photos = photos + json_results['photoset']['photo'].collect {|j| FlickrPhoto.new(j)}
page_count = page_count + 1
break #FIXME remove this
end while json_results['photoset']['total'].to_i > photos.size
p "Fetched #{photos.size} photos"
already_posted = IO.read(ALREADY_POSTED_FILE).split("\n").collect { |s| s.strip }.uniq rescue []
already_posted = already_posted + (IO.read(FAILED_TO_POST).split("\n").collect { |s| s.strip }.uniq rescue [])
photos.reject! { |p| already_posted.include? p.photo_id }
raise "No photos to post!" if photos.empty?
p "Unposted photos #{photos.size}"
return photos.sample(photo_count)
end
random_flickr_photos(5).each do |photo|
p "Posting photo #{photo}"
begin
post_photo_to_untappd photo
open(ALREADY_POSTED_FILE, 'a') { |f| f << "#{photo.photo_id}\n" }
rescue
p "Failed to post photo #{photo.photo_id}"
open(FAILED_TO_POST, 'a') { |f| f << "#{photo.photo_id}\n" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment