Skip to content

Commit

Permalink
Separated the code interfacing with del.ici.ous API in different classes
Browse files Browse the repository at this point in the history
  • Loading branch information
dlt committed Jul 6, 2009
1 parent 8ae6cc4 commit 521dd78
Showing 1 changed file with 103 additions and 77 deletions.
180 changes: 103 additions & 77 deletions delicious.rb
Expand Up @@ -4,76 +4,53 @@
require 'recommendations.rb'

class DeliciousRecommender
include HTTParty
base_uri 'http://feeds.delicious.com/v2/xml'
format :xml

def initialize
@recommender = Recommendations.new
@api = DeliciousAPI.new
set_handlers
end

def get_tagurls(*tags)
count = 10
hash = self.class.get("/tag/#{tags.join('+')}?count=#{count}")
handle_response hash
end

def get_urlinfo(url)
json_format("/urlinfo/#{Digest::MD5.hexdigest(url)}").first #will always return one result
end

def get_popular(tag = nil, count = 5)
hash = self.class.get("/popular#{query_string(tag, count)}")
handle_response hash
end

def get_userposts(user, tag = nil, count = 15)
hash = get("/#{user}/#{query_string(tag, count)}")
handle_response hash
end

def get_urlposts(url)
hash = get("/url/#{Digest::MD5.hexdigest(url)}")
handle_response hash
end

def get_recommendations(tag, user = nil, search_for = :user, similarity = :sim_distance)
if search_for == :user
Raise 'Have to provide user param.' unless user
user_recommendations(user, tag, similarity)
elsif search_for == :tag
tag_recommendations(tag, similarity)
end
end

private
def user_recommendations(user, tag, similarity)
def user_recommendations(user, tag, similarity, count = 10)
user_hash = initialize_user_hash(user, tag)
fill_items(user_hash) {|user| get_userposts(user, tag, 10) }
fill_items(user_hash) {|user| @api.get_userposts(user, tag, count) }
@recommender.get_recommendations(user_hash, user, similarity)
end

def tag_recommendations(tag, similarity, count = 10)
tag_hash = init_tag_hash(tag, count)
tag_hash = init_tag_hash(tag, count)
fill_tag_items(tag_hash)
@recommender.get_recommendations(tag_hash, tag, :sim_distance)
@recommender.get_recommendations(tag_hash, tag, similarity)
end

private
def set_handlers
@api.xml_client.response_handler = Proc.new do |response|
response = response['rss']['channel']['item']
# if returned 1 or 0 items in the response, makes it look like an array
response = [response] if response.is_a? Hash
response ||= []
response
end
end

def init_tag_hash(tag, count = 10)
categories = [tag]
get_popular(tag, count).each do |post|

@api.get_popular(tag, count).each do |post|
categs = post['category']
categs = [categs] unless categs.is_a? Array
categories += categs
end

init_hash_with_keys(categories)
end

def initialize_user_hash(user, tag, count = 5)
creators = [user]
get_popular(tag, count).each do |post|
@api.get_popular(tag, count).each do |post|
Thread.new do
get_urlposts(post['link']).each do |post2|
@api.get_urlposts(post['link']).each do |post2|
creator = post2['dc:creator']
creators << creator
end
Expand All @@ -86,13 +63,18 @@ def initialize_user_hash(user, tag, count = 5)
def fill_tag_items(hash)
copy = hash.dup
copy.each_key do |tag|
popular_posts = get_popular(tag)
popular_posts.each do |post|
url = post['link']
top_tags = get_urlinfo(url)['top_tags']
hash[url] = top_tags
Thread.new do
popular_posts = @api.get_popular(tag)
popular_posts.each do |post|
url = post['link']
Thread.new do
top_tags = @api.get_urlinfo(url)['top_tags']
hash[url] = top_tags
end
end
end
end
join_all
hash
end

Expand All @@ -117,6 +99,39 @@ def fill_items(hash, extract = 'link')
end
end

def init_hash_with_keys(keys)
hash = {}
keys.uniq.each { |k| hash[k] = {} }
hash
end

def join_all
Thread.list.each {|t| t.join unless t == Thread.current || t == Thread.main }
end
end


class DeliciousAPI
attr_reader :xml_client, :json_client

def initialize
@xml_client = XMLClient.new
@json_client = JSONClient.new
end

alias old_method_missing method_missing

def method_missing(meth, *args)
return @xml_client.send(meth, *args) if @xml_client.respond_to? meth
return @json_client.send(meth, *args) if @json_client.respond_to? meth

old_method_missing meth, *args
end
end

class Client
attr_accessor :response_handler

def get(*params)
self.class.get(*params)
end
Expand All @@ -128,36 +143,47 @@ def query_string(tag, count)
query
end

def init_hash_with_keys(keys)
hash = {}
keys.uniq.each { |k| hash[k] = {} }
hash
def handle_response(response)
if @response_handler
response = @response_handler.call(response)
end
response
end
end

def json_format(url)
self.class.format :json
self.class.base_uri 'http://feeds.delicious.com/v2/'

prefix = '/json'
prefix += '/' if url.each_char.first != '/'

response = self.class.get(prefix + url)
self.class.format :xml
self.class.base_uri 'http://feeds.delicious.com/v2/xml'
return response
class XMLClient < Client
include HTTParty
base_uri 'http://feeds.delicious.com/v2/xml'
format :xml

def get_tagurls(*tags)
count = 10
hash = get("/tag/#{tags.join('+')}?count=#{count}")
handle_response hash
end

def handle_response(response_hash)
response = response_hash['rss']['channel']['item']

# if returned 1 or 0 items in the response, makes it look like an array
response = [response] if response.is_a? Hash
response ||= []
response

def get_popular(tag = nil, count = 5)
hash = get("/popular#{query_string(tag, count)}")
handle_response hash
end

def get_userposts(user, tag = nil, count = 15)
hash = get("/#{user}/#{query_string(tag, count)}")
handle_response hash
end

def get_urlposts(url)
hash = get("/url/#{Digest::MD5.hexdigest(url)}")
handle_response hash
end

def join_all
Thread.list.each {|t| t.join unless t == Thread.current || t == Thread.main }
end
end

class JSONClient < Client
include HTTParty
base_uri 'http://feeds.delicious.com/v2/json'
format :json

def get_urlinfo(url)
get("/urlinfo/#{Digest::MD5.hexdigest(url)}").first #will always return one result
end
end

0 comments on commit 521dd78

Please sign in to comment.