Skip to content

Instantly share code, notes, and snippets.

@ryanbriones
Created April 3, 2011 04:10
Show Gist options
  • Save ryanbriones/900169 to your computer and use it in GitHub Desktop.
Save ryanbriones/900169 to your computer and use it in GitHub Desktop.
more crap I had on my desktop. Messing with graphs to implement twitter timelines that don't include retweets from people you've blocked. End goal was to store it in a key-value store like redis and see how painful it was to implement a graph on top of re
require 'set'
class Vertex
attr_reader :out, :in
def initialize(properties = {})
@properties = properties
@out = Set.new
@in = Set.new
end
def in(edge)
@in << edge
end
def out(vertex, type = :edge, properties = {})
@out << Edge.new(type, self, vertex, properties)
end
end
class Edge
attr_reader :type, :out_v, :in_v
def initialize(type, out_v, in_v, properties = {})
@type = type
@out_v = out_v
@in_v = in_v
@properties = properties
in_v.in(self)
end
end
class User < Vertex
def initialize(username)
super({:username => username})
end
def follow(other_user)
@out << Follows.new(self, other_user)
end
def following
follows_edges = @out.select { |e| Follows === e }
follows_edges.map { |relationship| relationship.followee }
end
def followers
follower_edges = @in.select { |e| Follows === e }
follower_edges.map { |relationship| relationship.follower }
end
def blocked
block_edged = @out.select { |e| Block === e }
block_edged.map { |relationship| relationship.blockee }
end
def tweets
tweets = @out.select { |e| Created === e }
tweets.map { |e| e.tweet }
end
def retweets
tweets = @out.select { |e| Retweeted === e }
tweets.map { |e| e.tweet }
end
def friends_tweets
following.inject([]) do |tweets, user|
tweets += user.tweets
end
end
def friends_retweets
following.inject([]) do |tweets, user|
users_retweets = user.retweets
users_retweets.each do |tweet|
next if blocked?(tweet.user)
tweets << tweet
end
tweets
end
end
def not_mutual_following
following.reject { |user| followers.include?(user) }
end
def friends
following.select { |user| followers.include?(user) }
end
def tweet(content)
tweet = Tweet.new(content)
@out << Created.new(self, tweet)
tweet
end
def retweet(tweet)
@out << Retweeted.new(self, tweet)
end
def block(user)
@out << Block.new(self, user)
end
def blocked?(user)
blocked.include?(user)
end
end
class Follows < Edge
def initialize(follower, followee)
super(:follows, follower, followee)
end
def follower
@out_v
end
def followee
@in_v
end
end
class Tweet < Vertex
def initialize(content)
super({:content => content})
end
def user
@in.detect { |e| Created === e }.user
end
end
class Created < Edge
def initialize(user, tweet)
super(:created, user, tweet)
end
def user
@out_v
end
def tweet
@in_v
end
end
class Retweeted < Edge
def initialize(user, tweet)
super(:retweeted, user, tweet)
end
def user
@out_v
end
def tweet
@in_v
end
end
class Block < Edge
def initialize(blocker, blockee)
super(:blocked, blocker, blockee)
end
def blocker
@out_v
end
def blockee
@in_v
end
end
ryan = User.new("ryanbriones")
ethan = User.new("ethangunderson")
kent = User.new("kentbeck")
haml = User.new("haml")
sass = User.new("sass")
ryan.follow(ethan)
ryan.follow(kent)
ryan.block(haml)
ethan.follow(ryan)
ethan.follow(kent)
ethan.follow(haml)
ethan.follow(sass)
ethan.tweet("i'm a douche")
ethan.tweet("look at me. i like haml.")
kent.tweet("watch my tdd videos")
haml_tweet = haml.tweet("haml rox0rs")
sass_tweet = sass.tweet("sass 3 has changes you might like")
ethan.retweet(haml_tweet)
ethan.retweet(sass_tweet)
puts "ryan's friends: " + ryan.friends.map { |user| user.instance_eval { @properties[:username] } }.inspect
puts "ryan following (not mutual) :" + ryan.not_mutual_following.map { |user| user.instance_eval { @properties[:username] } }.inspect
puts "ryan's blocked users: " + ryan.blocked.map { |user| user.instance_eval { @properties[:username] } }.inspect
puts "ethan's tweets: " + ethan.tweets.map { |tweet| tweet.instance_eval { @properties[:content] } }.inspect
puts "ryan's following's tweets: " + ryan.friends_tweets.map { |tweet| "(#{tweet.user.instance_eval { @properties[:username] }}) #{tweet.instance_eval { @properties[:content] }}" }.inspect
# give me all the RT from my followers except for where the original tweet came from someone i've blocked
puts "ryan's following's retweets: " + ryan.friends_retweets.map { |tweet| "(#{tweet.user.instance_eval { @properties[:username] }}) #{tweet.instance_eval { @properties[:content] }}" }.inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment