Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@tatey
Created October 18, 2008 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatey/17576 to your computer and use it in GitHub Desktop.
Save tatey/17576 to your computer and use it in GitHub Desktop.
require "ftools"
require "net/http"
require "rexml/document"
require "timeout"
require "uri"
# Methods for retrieving social data from services including Flickr, Last.fm and Twitter.
module SocialServices
def get_recently_uploaded_from_flickr(limit)
recently_uploaded = []
response = get_response_from_remote("<FLICKR FEED URL>", 2, 5)
if response
REXML::Document.new(response.body).elements.to_a("feed/entry").each_with_index do |uploaded, count|
if count < limit
uploaded_elements = {}
uploaded_elements[:title] = uploaded.elements["title"].text
uploaded_elements[:url] = uploaded.elements["link"].attributes["href"]
uploaded_elements[:image_path] = get_image_from_remote_and_crop("/flickr", 60, uploaded.elements["content"].text.match(/img.*(jpg|jpeg|png)/).to_s.match(/http.*/).to_s, 1, 5)
recently_uploaded << uploaded_elements
else
break
end
end
end
return recently_uploaded
end
# http://www.last.fm/api/show?service=278
def get_recently_listened_to_from_lastfm(limit)
recently_listened_to = []
response = get_response_from_remote("http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=< USER >&api_key=< API_KEY >&limit=#{ limit }", 2, 5)
if response
xml_document = REXML::Document.new(response.body)
if xml_document.elements["lfm[@status = 'ok']"]
xml_document.each_element("lfm/recenttracks/track") do |track|
track_elements = {}
%w(artist name album url date).each do |tag|
if track.elements[tag]
track_elements[tag.intern] = track.elements[tag].text
end
end
image_path = get_image_from_remote_and_crop("/lastfm", 60, track.elements["image[@size = 'large']"].text, 1, 5)
if image_path
track_elements[:image_path] = image_path
else
track_elements[:image_path] = "/images/defaults/lastfm.png"
end
recently_listened_to << track_elements
end
end
end
return recently_listened_to
end
# http://apiwiki.twitter.com/REST+API+Documentation#usertimeline
def get_recent_statuses_from_twitter(limit)
recent_statuses = []
response = get_response_from_remote("http://twitter.com/statuses/user_timeline/< USERNAME >.xml?count=#{ limit }", 2, 5)
if response
xml_document = REXML::Document.new(response.body)
if xml_document.elements["statuses[@type = 'array']"]
xml_document.each_element("statuses/status") do |status|
status_elements = {}
%w(created_at text in_reply_to_status_id in_reply_to_user_id).each { |tag| status_elements[tag.intern] = status.elements[tag].text }
recent_statuses << status_elements
end
end
end
return recent_statuses
end
private
def get_response_from_remote(url, retry_count, timeout_in_seconds)
begin
url = URI.parse(url)
timeout(timeout_in_seconds) do
Net::HTTP.start(url.host) do |session|
if url.query
response = session.get(url.path + "?" + url.query, { "User-Agent" => "Ruby/#{ VERSION } (#{ RUBY_PLATFORM })" })
else
response = session.get(url.path)
end
if response.is_a? Net::HTTPSuccess
return response
else
RAILS_DEFAULT_LOGGER.error("ERROR #{ response.class } in SocialServices.get_xml_from_remote, URL: #{ url }")
return nil
end
end
end
rescue Exception => exception
if retry_count > 0
retry_count -= 1
retry
else
RAILS_DEFAULT_LOGGER.error("ERROR #{ exception.class } in SocialServices.get_xml_from_remote, URL: #{ url }, Message: #{ exception.message }")
return nil
end
end
end
def get_image_from_remote_and_crop(directory, size, url, retry_count, timeout_in_seconds)
if url
file_name = "/" + URI.parse(url).path.gsub("/", "")
public_directory = "/images/social_services" + directory
absolute_directory = Rails.root + "/public" + public_directory
if File.file? absolute_directory + file_name
return public_directory + file_name
else
response = get_response_from_remote(url, retry_count, timeout_in_seconds)
if response
begin
File.open(absolute_directory + file_name, "w") { |image| image.write(response.body) }
ImageScience.with_image(absolute_directory + file_name) do |image|
image.cropped_thumbnail(size) { |cropped_image| cropped_image.save(absolute_directory + file_name) }
end
return public_directory + file_name
rescue Exception => exception
if exception.is_a? Errno::ENOENT
RAILS_DEFAULT_LOGGER.info("INFO Errno::ENOENT in SocialServices.get_image_from_remote_and_crop. Message: #{ exception.message }. Attempting to create directory and retry")
File.makedirs(absolute_directory)
retry
else
RAILS_DEFAULT_LOGGER.error("ERROR #{ exception.class } in SocialServices.get_image_from_remote_and_crop. Message: #{ exception.message }")
end
end
end
end
end
return nil
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment