redis-timeline 0.1.5 → 0.1.6

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.
data/README.md CHANGED
@@ -33,6 +33,7 @@ You can specify these options explicity...
33
33
  on: :update,
34
34
  actor: :author,
35
35
  target: :post,
36
+ object: [:body]
36
37
  followers: :post_participants
37
38
 
38
39
  delegate :participants, to: :post, prefix: true
@@ -23,6 +23,8 @@ module Timeline::Actor
23
23
  defaults.merge!(list_name: "global:activity")
24
24
  when :posts
25
25
  defaults.merge!(list_name: "user:id:#{self.id}:posts")
26
+ when :mentions
27
+ defaults.merge!(list_name: "user:id:#{self.id}:mentions")
26
28
  end
27
29
  end
28
30
  end
@@ -12,10 +12,10 @@ module Timeline::Track
12
12
  @target = options.delete :target
13
13
  @followers = options.delete :followers
14
14
  @followers ||= :followers
15
- @extra_fields = options.delete :extra_fields
15
+ @mentionable = options.delete :mentionable
16
16
 
17
17
  method_name = "track_#{@name}_after_#{@callback}".to_sym
18
- define_activity_method method_name, actor: @actor, object: @object, target: @target, followers: @followers, verb: name, extra_fields: @extra_fields
18
+ define_activity_method method_name, actor: @actor, object: @object, target: @target, followers: @followers, verb: name, mentionable: @mentionable
19
19
 
20
20
  send "after_#{@callback}".to_sym, method_name, if: options.delete(:if)
21
21
  end
@@ -23,11 +23,14 @@ module Timeline::Track
23
23
  private
24
24
  def define_activity_method(method_name, options={})
25
25
  define_method method_name do
26
- actor = send(options[:actor])
27
- object = !options[:object].nil? ? send(options[:object].to_sym) : self
28
- target = !options[:target].nil? ? send(options[:target].to_sym) : nil
29
- followers = actor.send(options[:followers].to_sym)
30
- add_activity activity(verb: options[:verb], actor: actor, object: object, target: target, extra_fields: options[:extra_fields]), followers
26
+ @actor = send(options[:actor])
27
+ @fields_for = {}
28
+ @object = set_object(options[:object])
29
+ @target = !options[:target].nil? ? send(options[:target].to_sym) : nil
30
+ @extra_fields ||= nil
31
+ @followers = @actor.send(options[:followers].to_sym)
32
+ @mentionable = options[:mentionable]
33
+ add_activity activity(verb: options[:verb])
31
34
  end
32
35
  end
33
36
  end
@@ -36,46 +39,52 @@ module Timeline::Track
36
39
  def activity(options={})
37
40
  {
38
41
  verb: options[:verb],
39
- actor: options_for(options[:actor]),
40
- object: options_for(options[:object]),
41
- target: options_for(options[:target]),
42
+ actor: options_for(@actor),
43
+ object: options_for(@object),
44
+ target: options_for(@target),
42
45
  created_at: Time.now
43
- }.merge(add_extra_fields(options[:extra_fields]))
46
+ }
44
47
  end
45
48
 
46
- def add_activity(activity_item, followers)
49
+ def add_activity(activity_item)
47
50
  redis_add "global:activity", activity_item
48
51
  add_activity_to_user(activity_item[:actor][:id], activity_item)
49
52
  add_activity_by_user(activity_item[:actor][:id], activity_item)
50
- add_activity_to_followers(followers, activity_item) if followers.any?
51
- end
52
-
53
- def add_activity_to_user(user_id, activity_item)
54
- redis_add "user:id:#{user_id}:activity", activity_item
53
+ add_mentions(activity_item)
54
+ add_activity_to_followers(activity_item) if @followers.any?
55
55
  end
56
56
 
57
57
  def add_activity_by_user(user_id, activity_item)
58
58
  redis_add "user:id:#{user_id}:posts", activity_item
59
59
  end
60
60
 
61
- def add_activity_to_followers(followers, activity_item)
62
- followers.each { |follower| add_activity_to_user(follower.id, activity_item) }
61
+ def add_activity_to_user(user_id, activity_item)
62
+ redis_add "user:id:#{user_id}:activity", activity_item
63
+ end
64
+
65
+ def add_activity_to_followers(activity_item)
66
+ @followers.each { |follower| add_activity_to_user(follower.id, activity_item) }
63
67
  end
64
68
 
65
- def add_extra_fields(extra_fields)
66
- if !extra_fields.nil? and extra_fields.any?
67
- extras = {}
68
- extra_fields.each do |value|
69
- extras[value] = send(value)
69
+ def add_mentions(activity_item)
70
+ return unless @mentionable and @object.send(@mentionable)
71
+ @object.send(@mentionable).scan(/@\w+/).each do |mention|
72
+ if user = @actor.class.find_by_username(mention[1..-1])
73
+ add_mention_to_user(user.id, activity_item)
70
74
  end
71
- extras
72
- else
73
- {}
74
75
  end
75
76
  end
76
77
 
77
- def redis_add(list, activity_item)
78
- Timeline.redis.lpush list, Timeline.encode(activity_item)
78
+ def add_mention_to_user(user_id, activity_item)
79
+ redis_add "user:id:#{user_id}:mentions", activity_item
80
+ end
81
+
82
+ def extra_fields_for(object)
83
+ return {} unless @fields_for.has_key?(object.class.to_s.downcase.to_sym)
84
+ @fields_for[object.class.to_s.downcase.to_sym].inject({}) do |sum, method|
85
+ sum[method.to_sym] = @object.send(method.to_sym)
86
+ sum
87
+ end
79
88
  end
80
89
 
81
90
  def options_for(target)
@@ -84,9 +93,26 @@ module Timeline::Track
84
93
  id: target.id,
85
94
  class: target.class.to_s,
86
95
  display_name: target.to_s
87
- }
96
+ }.merge(extra_fields_for(target))
88
97
  else
89
98
  nil
90
99
  end
91
100
  end
101
+
102
+ def redis_add(list, activity_item)
103
+ Timeline.redis.lpush list, Timeline.encode(activity_item)
104
+ end
105
+
106
+ def set_object(object)
107
+ case
108
+ when object.is_a?(Symbol)
109
+ send(object)
110
+ when object.is_a?(Array)
111
+ @fields_for[self.class.to_s.downcase.to_sym] = object
112
+ self
113
+ else
114
+ self
115
+ end
116
+ end
117
+
92
118
  end
@@ -1,3 +1,3 @@
1
1
  module Timeline
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
Binary file
@@ -1,4 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib timeline]))
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib redis-timeline]))
2
2
  dir = File.dirname(File.expand_path(__FILE__))
3
3
 
4
4
  RSpec.configure do |config|
@@ -34,14 +34,15 @@ class Comment
34
34
  extend ActiveModel::Callbacks
35
35
 
36
36
  define_model_callbacks :create
37
- attr_accessor :id, :creator_id
37
+ attr_accessor :id, :creator_id, :body
38
38
 
39
39
  include Timeline::Track
40
40
 
41
- track :new_comment, extra_fields: [:post_name, :post_id]
41
+ track :new_comment, object: [:post_name, :post_id, :body], mentionable: :body
42
42
 
43
43
  def initialize(options={})
44
44
  @creator_id = options.delete :creator_id
45
+ @body = options.delete :body
45
46
  end
46
47
 
47
48
  def save
@@ -68,22 +69,28 @@ end
68
69
 
69
70
  class User
70
71
  include Timeline::Actor
71
- attr_accessor :id, :to_param
72
+ attr_accessor :id, :to_param, :username
72
73
 
73
74
  def initialize(options={})
74
75
  @id = options.delete :id
76
+ @username = options.delete :username
75
77
  end
76
78
 
77
79
  class << self
78
80
  def find user_id
79
81
  User.new(id: user_id)
80
82
  end
83
+
84
+ def find_by_username username
85
+ User.new(username: username)
86
+ end
81
87
  end
82
88
  end
83
89
 
84
90
  describe Timeline::Track do
85
- let(:creator) { User.new(id: 1) }
91
+ let(:creator) { User.new(id: 1, username: "first_user") }
86
92
  let(:post) { Post.new(creator_id: creator.id, name: "New post") }
93
+ let(:comment) { Comment.new(creator_id: creator.id, id: 1) }
87
94
 
88
95
  describe "included in an ActiveModel-compliant class" do
89
96
  it "tracks on create by default" do
@@ -116,11 +123,17 @@ describe Timeline::Track do
116
123
  end
117
124
 
118
125
  describe "with extra_fields" do
119
- let(:comment) { Comment.new(creator_id: creator.id, id: 1) }
120
-
121
126
  it "stores the extra fields in the timeline" do
122
127
  comment.save
123
- creator.timeline.first.should respond_to :post_id
128
+ creator.timeline.first.object.should respond_to :post_id
129
+ end
130
+ end
131
+
132
+ describe "tracking mentions" do
133
+ it "adds to a user's mentions timeline" do
134
+ User.stub(:find_by_username).and_return(creator)
135
+ Comment.new(creator_id: creator.id, body: "@first_user should see this").save
136
+ creator.timeline(:mentions).first.object.body.should == "@first_user should see this"
124
137
  end
125
138
  end
126
139
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-timeline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-02-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70281942026620 !ruby/object:Gem::Requirement
16
+ requirement: &70163773026900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.2'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70281942026620
24
+ version_requirements: *70163773026900
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activemodel
27
- requirement: &70281942025820 !ruby/object:Gem::Requirement
27
+ requirement: &70163773026140 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.2'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70281942025820
35
+ version_requirements: *70163773026140
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: multi_json
38
- requirement: &70281942025360 !ruby/object:Gem::Requirement
38
+ requirement: &70163773053400 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70281942025360
46
+ version_requirements: *70163773053400
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: redis
49
- requirement: &70281942024900 !ruby/object:Gem::Requirement
49
+ requirement: &70163773052920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70281942024900
57
+ version_requirements: *70163773052920
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: hashie
60
- requirement: &70281942024480 !ruby/object:Gem::Requirement
60
+ requirement: &70163773052300 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70281942024480
68
+ version_requirements: *70163773052300
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sqlite3
71
- requirement: &70281942024040 !ruby/object:Gem::Requirement
71
+ requirement: &70163773051640 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70281942024040
79
+ version_requirements: *70163773051640
80
80
  description: ''
81
81
  email:
82
82
  - felixclack@gmail.com