paritytimeline 0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,116 @@
1
+ module Timeline::Track
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def track(name, options={})
6
+ @name = name
7
+ @actor = options.delete :actor
8
+ @actor ||= :creator
9
+ @object = options.delete :object
10
+ @target = options.delete :target
11
+ @followers = options.delete :followers
12
+ @followers ||= :followers
13
+ @mentionable = options.delete :mentionable
14
+
15
+ method_name = "track_#{@name}_after_#{@callback}".to_sym
16
+ define_activity_method method_name, actor: @actor, object: @object, target: @target, followers: @followers, verb: name, mentionable: @mentionable
17
+
18
+ send "after_#{@callback}".to_sym, method_name, if: options.delete(:if)
19
+ end
20
+
21
+ private
22
+ def define_activity_method(method_name, options={})
23
+ define_method method_name do
24
+ @actor = send(options[:actor])
25
+ @fields_for = {}
26
+ @object = set_object(options[:object])
27
+ @target = !options[:target].nil? ? send(options[:target].to_sym) : nil
28
+ @extra_fields ||= nil
29
+ @followers = @actor.send(options[:followers].to_sym)
30
+ @mentionable = options[:mentionable]
31
+ add_activity activity(verb: options[:verb])
32
+ end
33
+ end
34
+ end
35
+
36
+ protected
37
+ def activity(options={})
38
+ {
39
+ verb: options[:verb],
40
+ actor: options_for(@actor),
41
+ object: options_for(@object),
42
+ target: options_for(@target),
43
+ created_at: Time.now
44
+ }
45
+ end
46
+
47
+ def add_activity(activity_item)
48
+ redis_add "global:activity", activity_item
49
+ add_activity_to_user(activity_item[:actor][:id], activity_item)
50
+ add_activity_by_user(activity_item[:actor][:id], activity_item)
51
+ add_mentions(activity_item)
52
+ add_activity_to_followers(activity_item) if @followers.any?
53
+ end
54
+
55
+ def add_activity_by_user(user_id, activity_item)
56
+ redis_add "user:id:#{user_id}:posts", activity_item
57
+ end
58
+
59
+ def add_activity_to_user(user_id, activity_item)
60
+ redis_add "user:id:#{user_id}:activity", activity_item
61
+ end
62
+
63
+ def add_activity_to_followers(activity_item)
64
+ @followers.each { |follower| add_activity_to_user(follower.id, activity_item) }
65
+ end
66
+
67
+ def add_mentions(activity_item)
68
+ return unless @mentionable and @object.send(@mentionable)
69
+ @object.send(@mentionable).scan(/@\w+/).each do |mention|
70
+ if user = @actor.class.find_by_username(mention[1..-1])
71
+ add_mention_to_user(user.id, activity_item)
72
+ end
73
+ end
74
+ end
75
+
76
+ def add_mention_to_user(user_id, activity_item)
77
+ redis_add "user:id:#{user_id}:mentions", activity_item
78
+ end
79
+
80
+ def extra_fields_for(object)
81
+ return {} unless @fields_for.has_key?(object.class.to_s.downcase.to_sym)
82
+ @fields_for[object.class.to_s.downcase.to_sym].inject({}) do |sum, method|
83
+ sum[method.to_sym] = @object.send(method.to_sym)
84
+ sum
85
+ end
86
+ end
87
+
88
+ def options_for(target)
89
+ if !target.nil?
90
+ {
91
+ id: target.id,
92
+ class: target.class.to_s,
93
+ display_name: target.to_s
94
+ }.merge(extra_fields_for(target))
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def redis_add(list, activity_item)
101
+ Timeline.redis.lpush list, Timeline.encode(activity_item)
102
+ end
103
+
104
+ def set_object(object)
105
+ case
106
+ when object.is_a?(Symbol)
107
+ send(object)
108
+ when object.is_a?(Array)
109
+ @fields_for[self.class.to_s.downcase.to_sym] = object
110
+ self
111
+ else
112
+ self
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,9 @@
1
+ 1.upto(User.last.id).each do |u|
2
+ list = "user:id:#{u}:notification"
3
+ Timeline.redis.ltrim list, 0, 30
4
+ list = "user:id:#{u}:posts"
5
+ Timeline.redis.ltrim list, 0, 30
6
+ list = "user:id:#{u}:activity"
7
+ Timeline.redis.ltrim list, 0, 30
8
+ Timeline.redis.ltrim "global:activity:new_premium_deal", 0, 200
9
+ end
@@ -0,0 +1,3 @@
1
+ module Timeline
2
+ VERSION = "0.4"
3
+ end
@@ -0,0 +1,12 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe Timeline::Activity do
4
+ describe "initialized with json" do
5
+ let(:json) { { id: "1", verb: "new_post" } }
6
+
7
+ it "returns a Hashie-fied object" do
8
+ Timeline::Activity.new(json).id.should == "1"
9
+ Timeline::Activity.new(json).verb.should == "new_post"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ class User
4
+ include Timeline::Actor
5
+
6
+ attr_accessor :id
7
+ end
8
+
9
+ describe Timeline::Actor do
10
+ describe "when included" do
11
+ before { @user = User.new }
12
+
13
+ it "defines a timeline association" do
14
+ @user.should respond_to :timeline
15
+ end
16
+
17
+ describe ".timeline" do
18
+ subject { @user.timeline }
19
+
20
+ it { should == [] }
21
+ end
22
+ end
23
+ end