activity_feed 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +4 -0
- data/README.markdown +16 -15
- data/lib/activity_feed/feed.rb +34 -9
- data/lib/activity_feed/version.rb +1 -1
- data/spec/activity_feed/feed_spec.rb +31 -7
- data/spec/version_spec.rb +1 -1
- metadata +4 -4
data/CHANGELOG.markdown
CHANGED
data/README.markdown
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# ActivityFeed
|
2
2
|
|
3
|
-
Activity feeds backed by Redis. Activity feeds may also be referred to as timelines or
|
3
|
+
Activity feeds backed by Redis. Activity feeds may also be referred to as timelines or
|
4
4
|
news feeds.
|
5
5
|
|
6
6
|
## Compatibility
|
@@ -15,7 +15,7 @@ or:
|
|
15
15
|
|
16
16
|
`gem 'activity_feed'`
|
17
17
|
|
18
|
-
Make sure your redis server is running! Redis configuration is outside the scope of this README, but
|
18
|
+
Make sure your redis server is running! Redis configuration is outside the scope of this README, but
|
19
19
|
check out the [Redis documentation](http://redis.io/documentation).
|
20
20
|
|
21
21
|
## Configuration
|
@@ -54,7 +54,7 @@ require 'mongoid'
|
|
54
54
|
module ActivityFeed
|
55
55
|
module Mongoid
|
56
56
|
class Item
|
57
|
-
include ::Mongoid::Document
|
57
|
+
include ::Mongoid::Document
|
58
58
|
include ::Mongoid::Timestamps
|
59
59
|
|
60
60
|
field :user_id, type: String
|
@@ -70,7 +70,7 @@ module ActivityFeed
|
|
70
70
|
|
71
71
|
index :user_id
|
72
72
|
|
73
|
-
after_save :update_item_in_activity_feed
|
73
|
+
after_save :update_item_in_activity_feed
|
74
74
|
|
75
75
|
private
|
76
76
|
|
@@ -95,8 +95,8 @@ If you need to handle any exceptions when loading activity feed items, please do
|
|
95
95
|
### Developing an Activity Feed for an Individual
|
96
96
|
|
97
97
|
Below is a complete example using Mongoid as our persistent storage for activity feed items.
|
98
|
-
The example uses callbacks to update and remove items from the activity feed. As this example
|
99
|
-
uses the `updated_at` time of the item, updated items will "bubble up" to the top of the
|
98
|
+
The example uses callbacks to update and remove items from the activity feed. As this example
|
99
|
+
uses the `updated_at` time of the item, updated items will "bubble up" to the top of the
|
100
100
|
activity feed.
|
101
101
|
|
102
102
|
```ruby
|
@@ -111,7 +111,7 @@ end
|
|
111
111
|
module ActivityFeed
|
112
112
|
module Mongoid
|
113
113
|
class Item
|
114
|
-
include ::Mongoid::Document
|
114
|
+
include ::Mongoid::Document
|
115
115
|
include ::Mongoid::Timestamps
|
116
116
|
|
117
117
|
field :user_id, type: String
|
@@ -157,7 +157,7 @@ end
|
|
157
157
|
|
158
158
|
# Create a couple of activity feed items
|
159
159
|
activity_item_1 = ActivityFeed::Mongoid::Item.create(
|
160
|
-
:user_id => 'david',
|
160
|
+
:user_id => 'david',
|
161
161
|
:nickname => 'David Czarnecki',
|
162
162
|
:type => 'some_activity',
|
163
163
|
:title => 'Great activity',
|
@@ -166,7 +166,7 @@ activity_item_1 = ActivityFeed::Mongoid::Item.create(
|
|
166
166
|
)
|
167
167
|
|
168
168
|
activity_item_2 = ActivityFeed::Mongoid::Item.create(
|
169
|
-
:user_id => 'david',
|
169
|
+
:user_id => 'david',
|
170
170
|
:nickname => 'David Czarnecki',
|
171
171
|
:type => 'some_activity',
|
172
172
|
:title => 'Another great activity',
|
@@ -176,7 +176,7 @@ activity_item_2 = ActivityFeed::Mongoid::Item.create(
|
|
176
176
|
|
177
177
|
# Pull up the activity feed
|
178
178
|
feed = ActivityFeed.feed('david', 1)
|
179
|
-
=> [#<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000004, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Another great activity", text: "This is some other text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>, #<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000003, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Great activity", text: "This is text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>]
|
179
|
+
=> [#<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000004, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Another great activity", text: "This is some other text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>, #<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000003, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Great activity", text: "This is text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>]
|
180
180
|
|
181
181
|
# Update an actitivity feed item
|
182
182
|
activity_item_1.text = 'Updated some text for the activity feed item'
|
@@ -184,7 +184,7 @@ activity_item_1.save
|
|
184
184
|
|
185
185
|
# Pull up the activity feed item and notice that the item you updated has "bubbled up" to the top of the feed
|
186
186
|
feed = ActivityFeed.feed('david', 1)
|
187
|
-
=> [#<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000003, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:11:27 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Great activity", text: "Updated some text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>, #<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000004, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Another great activity", text: "This is some other text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>]
|
187
|
+
=> [#<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000003, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:11:27 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Great activity", text: "Updated some text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>, #<ActivityFeed::Mongoid::Item _id: 4fe0ce26421aa91fc2000004, _type: nil, created_at: 2012-06-19 19:08:22 UTC, updated_at: 2012-06-19 19:08:22 UTC, user_id: "david", nickname: "David Czarnecki", type: "some_activity", title: "Another great activity", text: "This is some other text for the activity feed item", url: "http://url.com", icon: nil, sticky: nil>]
|
188
188
|
```
|
189
189
|
|
190
190
|
### Developing an Aggregate Activity Feed for an Individual
|
@@ -201,7 +201,7 @@ end
|
|
201
201
|
module ActivityFeed
|
202
202
|
module Mongoid
|
203
203
|
class Item
|
204
|
-
include ::Mongoid::Document
|
204
|
+
include ::Mongoid::Document
|
205
205
|
include ::Mongoid::Timestamps
|
206
206
|
|
207
207
|
field :user_id, type: String
|
@@ -251,7 +251,7 @@ end
|
|
251
251
|
:text => "This is from unknown's activity feed"
|
252
252
|
)
|
253
253
|
|
254
|
-
sleep(1)
|
254
|
+
sleep(1)
|
255
255
|
|
256
256
|
ActivityFeed.aggregate_item('david', another_item.id, another_item.updated_at.to_i)
|
257
257
|
end
|
@@ -272,8 +272,8 @@ pp feed = ActivityFeed.feed('david', 1, true)
|
|
272
272
|
|
273
273
|
## ActivityFeed Caveats
|
274
274
|
|
275
|
-
`ActivityFeed.remove_item` can ONLY remove items from a single user's activity feed. If you allow activity feed
|
276
|
-
items to be deleted from a user's activity feed, you will need to propagate that delete out to all the other
|
275
|
+
`ActivityFeed.remove_item` can ONLY remove items from a single user's activity feed. If you allow activity feed
|
276
|
+
items to be deleted from a user's activity feed, you will need to propagate that delete out to all the other
|
277
277
|
feeds in which that activity feed item may have been aggregated.
|
278
278
|
|
279
279
|
## ActivityFeed method summary
|
@@ -288,6 +288,7 @@ ActivityFeed.remove_item(user_id, item_id)
|
|
288
288
|
# Feed-related
|
289
289
|
|
290
290
|
ActivityFeed.feed(user_id, page, aggregate = ActivityFeed.aggregate)
|
291
|
+
ActivityFeed.full_feed(user_id, aggregate = ActivityFeed.aggregate)
|
291
292
|
ActivityFeed.feed_between_timestamps(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
292
293
|
ActivityFeed.total_pages_in_feed(user_id, aggregate = ActivityFeed.aggregate, page_size = ActivityFeed.page_size)
|
293
294
|
ActivityFeed.total_items_in_feed(user_id, aggregate = ActivityFeed.aggregate)
|
data/lib/activity_feed/feed.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActivityFeed
|
2
2
|
module Feed
|
3
|
-
# Retrieve a page from the activity feed for a given +user_id+. You can configure
|
4
|
-
# +ActivityFeed.item_loader+ with a Proc to retrieve an item from, for example,
|
5
|
-
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the page
|
3
|
+
# Retrieve a page from the activity feed for a given +user_id+. You can configure
|
4
|
+
# +ActivityFeed.item_loader+ with a Proc to retrieve an item from, for example,
|
5
|
+
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the page
|
6
6
|
# returned with loaded items rather than item IDs.
|
7
7
|
#
|
8
8
|
# @param user_id [String] User ID.
|
9
9
|
# @param page [int] Page in the feed to be retrieved.
|
10
10
|
# @param aggregate [boolean, false] Whether to retrieve the aggregate feed for +user_id+.
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# @return page from the activity feed for a given +user_id+.
|
13
13
|
def feed(user_id, page, aggregate = ActivityFeed.aggregate)
|
14
14
|
feederboard = ActivityFeed.feederboard_for(user_id, aggregate)
|
@@ -26,17 +26,42 @@ module ActivityFeed
|
|
26
26
|
feed.nil? ? [] : feed
|
27
27
|
end
|
28
28
|
|
29
|
-
# Retrieve
|
30
|
-
# +
|
31
|
-
#
|
32
|
-
#
|
29
|
+
# Retrieve the entire activity feed for a given +user_id+. You can configure
|
30
|
+
# +ActivityFeed.item_loader+ with a Proc to retrieve an item from, for example,
|
31
|
+
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the page
|
32
|
+
# returned with loaded items rather than item IDs.
|
33
|
+
#
|
34
|
+
# @param user_id [String] User ID.
|
35
|
+
# @param aggregate [boolean, false] Whether to retrieve the aggregate feed for +user_id+.
|
36
|
+
#
|
37
|
+
# @return the full activity feed for a given +user_id+.
|
38
|
+
def full_feed(user_id, aggregate = ActivityFeed.aggregate)
|
39
|
+
feederboard = ActivityFeed.feederboard_for(user_id, aggregate)
|
40
|
+
feed = feederboard.leaders(1, :page_size => feederboard.total_members).inject([]) do |feed_items, feed_item|
|
41
|
+
item = if ActivityFeed.item_loader
|
42
|
+
ActivityFeed.item_loader.call(feed_item[:member])
|
43
|
+
else
|
44
|
+
feed_item[:member]
|
45
|
+
end
|
46
|
+
|
47
|
+
feed_items << item unless item.nil?
|
48
|
+
feed_items
|
49
|
+
end
|
50
|
+
|
51
|
+
feed.nil? ? [] : feed
|
52
|
+
end
|
53
|
+
|
54
|
+
# Retrieve a page from the activity feed for a given +user_id+ between a
|
55
|
+
# +starting_timestamp+ and an +ending_timestamp+. You can configure
|
56
|
+
# +ActivityFeed.item_loader+ with a Proc to retrieve an item from, for example,
|
57
|
+
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the feed data
|
33
58
|
# returned with loaded items rather than item IDs.
|
34
59
|
#
|
35
60
|
# @param user_id [String] User ID.
|
36
61
|
# @param starting_timestamp [int] Starting timestamp between which items in the feed are to be retrieved.
|
37
62
|
# @param ending_timestamp [int] Ending timestamp between which items in the feed are to be retrieved.
|
38
63
|
# @param aggregate [boolean, false] Whether to retrieve items from the aggregate feed for +user_id+.
|
39
|
-
#
|
64
|
+
#
|
40
65
|
# @return feed items from the activity feed for a given +user_id+ between the +starting_timestamp+ and +ending_timestamp+.
|
41
66
|
def feed_between_timestamps(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
42
67
|
feederboard = ActivityFeed.feederboard_for(user_id, aggregate)
|
@@ -25,6 +25,30 @@ describe ActivityFeed::Feed do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
describe '#full_feed' do
|
29
|
+
describe 'without aggregation' do
|
30
|
+
it 'should return the full activity feed' do
|
31
|
+
add_items_to_feed('david', 30)
|
32
|
+
|
33
|
+
feed = ActivityFeed.full_feed('david', false)
|
34
|
+
feed.length.should == 30
|
35
|
+
feed[0].to_i.should == 30
|
36
|
+
feed[29].to_i.should == 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'with aggregation' do
|
41
|
+
it 'should return the full activity feed' do
|
42
|
+
add_items_to_feed('david', 30, true)
|
43
|
+
|
44
|
+
feed = ActivityFeed.full_feed('david', true)
|
45
|
+
feed.length.should == 30
|
46
|
+
feed[0].to_i.should == 30
|
47
|
+
feed[29].to_i.should == 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
28
52
|
describe '#feed_between_timestamps' do
|
29
53
|
describe 'without aggregation' do
|
30
54
|
it 'should return activity feed items between the starting and ending timestamps' do
|
@@ -176,15 +200,15 @@ describe ActivityFeed::Feed do
|
|
176
200
|
describe 'ORM or ODM loading' do
|
177
201
|
describe 'ActiveRecord' do
|
178
202
|
it 'should be able to load an item via ActiveRecord when requesting a feed' do
|
179
|
-
ActivityFeed.item_loader = Proc.new do |id|
|
203
|
+
ActivityFeed.item_loader = Proc.new do |id|
|
180
204
|
ActivityFeed::ActiveRecord::Item.find(id)
|
181
205
|
end
|
182
|
-
|
206
|
+
|
183
207
|
feed = ActivityFeed.feed('david', 1)
|
184
208
|
feed.length.should == 0
|
185
209
|
|
186
210
|
item = ActivityFeed::ActiveRecord::Item.create(
|
187
|
-
:user_id => 'david',
|
211
|
+
:user_id => 'david',
|
188
212
|
:nickname => 'David Czarnecki',
|
189
213
|
:type => 'some_activity',
|
190
214
|
:title => 'Great activity',
|
@@ -200,12 +224,12 @@ describe ActivityFeed::Feed do
|
|
200
224
|
describe 'Mongoid' do
|
201
225
|
it 'should be able to load an item via Mongoid when requesting a feed' do
|
202
226
|
ActivityFeed.item_loader = Proc.new { |id| ActivityFeed::Mongoid::Item.find(id) }
|
203
|
-
|
227
|
+
|
204
228
|
feed = ActivityFeed.feed('david', 1)
|
205
229
|
feed.length.should == 0
|
206
230
|
|
207
231
|
item = ActivityFeed::Mongoid::Item.create(
|
208
|
-
:user_id => 'david',
|
232
|
+
:user_id => 'david',
|
209
233
|
:nickname => 'David Czarnecki',
|
210
234
|
:type => 'some_activity',
|
211
235
|
:title => 'Great activity',
|
@@ -242,7 +266,7 @@ describe ActivityFeed::Feed do
|
|
242
266
|
end
|
243
267
|
|
244
268
|
item = ActivityFeed::Mongoid::Item.create(
|
245
|
-
:user_id => 'david',
|
269
|
+
:user_id => 'david',
|
246
270
|
:nickname => 'David Czarnecki',
|
247
271
|
:type => 'some_activity',
|
248
272
|
:title => 'Great activity',
|
@@ -253,7 +277,7 @@ describe ActivityFeed::Feed do
|
|
253
277
|
ActivityFeed.update_item('david', '4fe4c5f3421aa9b89c000001', DateTime.now.to_i)
|
254
278
|
|
255
279
|
another_item = ActivityFeed::Mongoid::Item.create(
|
256
|
-
:user_id => 'david',
|
280
|
+
:user_id => 'david',
|
257
281
|
:nickname => 'David Czarnecki',
|
258
282
|
:type => 'some_activity',
|
259
283
|
:title => 'Great activity',
|
data/spec/version_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activity_feed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-08-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -215,7 +215,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
215
215
|
version: '0'
|
216
216
|
segments:
|
217
217
|
- 0
|
218
|
-
hash:
|
218
|
+
hash: -2201344879016856649
|
219
219
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
220
|
none: false
|
221
221
|
requirements:
|
@@ -224,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
224
224
|
version: '0'
|
225
225
|
segments:
|
226
226
|
- 0
|
227
|
-
hash:
|
227
|
+
hash: -2201344879016856649
|
228
228
|
requirements: []
|
229
229
|
rubyforge_project: activity_feed
|
230
230
|
rubygems_version: 1.8.24
|