paritytimeline 0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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