Skip to content

Instantly share code, notes, and snippets.

@o-sam-o
Last active October 23, 2017 04:42
Show Gist options
  • Save o-sam-o/f139fc81a1d622d86689 to your computer and use it in GitHub Desktop.
Save o-sam-o/f139fc81a1d622d86689 to your computer and use it in GitHub Desktop.
Flickr to Pinterest
require 'mechanize'
require 'cgi'
require 'json'
PINTERST_EMAIL = "...."
PINTERST_PASSWORD = "...."
PINTERST_BOARD_ID = "264375509314468871"
FLICKR_API_KEY = "3fffd0917fa897e24bd5a442018df29a"
FLICKR_PHOTOSET = "72157625277593652"
ALREADY_POSTED_FILE = "already_posted.txt"
def csrf_token(agent)
csrftoken = agent.cookies.find { |c| c.name == "csrftoken" }.value
raise "Unable to find CSRF token" if csrftoken.nil?
return csrftoken
end
def post_photo_to_pinterst(flickr_url, description, image_url)
p "Attempting to post photo '#{description}' #{flickr_url} #{image_url}"
agent = Mechanize.new
agent.user_agent_alias = 'Mac Safari'
#Login
p "Logging in"
page = agent.get "https://www.pinterest.com/login"
result = agent.post('https://www.pinterest.com/resource/UserSessionResource/create/', {
source_url: '/login/',
data: '{"options":{"username_or_email":"' + PINTERST_EMAIL + '","password":"' + PINTERST_PASSWORD + '"},"context":{}}',
module_path: 'App()>LoginPage()>Login()>Button(class_name=primary, text=Log In, type=submit, size=large)'
}, {
'X-Requested-With' => 'XMLHttpRequest',
'X-CSRFToken' => csrf_token(agent),
})
raise "Login failed:\n#{result}" unless result.code != 200
p "Logged in"
#Pin photo
p "Pinning"
page = agent.get "http://www.pinterest.com/pin/create/button/?url=#{CGI::escape flickr_url}&media=#{CGI::escape image_url}&description=#{CGI::escape description}"
result = agent.post('https://www.pinterest.com/resource/PinResource/create/', {
"source_url" => "/pin/find/?url=#{CGI::escape(flickr_url)}",
"data" => %|{"options":{"board_id":"#{PINTERST_BOARD_ID}","description":"#{description}","link":"#{flickr_url}","share_twitter":false,"image_url":"#{image_url}","method":"button"},"context":{}}|,
"module_path" => "App()>ImagesFeedPage(resource=FindPinImagesResource(url=#{flickr_url}))>Grid()>GridItems()>Pinnable()>ShowModalButton(module=PinCreate)#Modal(module=PinCreate())"
}, {
"X-CSRFToken" => csrf_token(agent),
"X-Requested-With" => "XMLHttpRequest",
})
json_result = JSON.parse(result.body)
raise "Pin failed:\n#{json_result}" unless result.code != 200
p "Pinned. Pin id: #{json_result["resource_response"]["data"]["id"]}"
p "Done"
end
class FlickrPhoto
def initialize(photo_json)
@json = photo_json
end
def photo_id
@json['id']
end
def title
@json['title']
end
def flickr_url
"https://www.flickr.com/photos/cavenagh/#{photo_id}"
end
def image_url
@json['url_m']
end
def to_s
"#{title} (#{photo_id})"
end
end
def random_flickr_photo
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
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
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
end
photo = random_flickr_photo
p "Posting photo #{photo}"
post_photo_to_pinterst photo.flickr_url, photo.title, photo.image_url
open(ALREADY_POSTED_FILE, 'a') { |f| f << "#{photo.photo_id}\n" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment