activity_feed 2.3.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +10 -0
- data/README.markdown +16 -12
- data/lib/activity_feed/configuration.rb +7 -4
- data/lib/activity_feed/feed.rb +28 -39
- data/lib/activity_feed/version.rb +1 -1
- data/spec/activity_feed/feed_spec.rb +17 -5
- data/spec/spec_helper.rb +1 -1
- data/spec/version_spec.rb +2 -2
- metadata +4 -4
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.0.0 (2013-07-12)
|
4
|
+
|
5
|
+
* Allow for bulk-loading of feed items. The `ActivityFeed.item_loader`
|
6
|
+
has been renamed to `ActivityFeed.items_loader`. The only difference
|
7
|
+
is that the proc is now passed an array of IDs, rather than an
|
8
|
+
individual ID.
|
9
|
+
* Updated `item_loader` references to `items_loader` throughout internal
|
10
|
+
documentation and README.
|
11
|
+
* Added `expire_feed_in` method alias for `expire_feed`.
|
12
|
+
|
3
13
|
## 2.3.0 (2013-05-03)
|
4
14
|
|
5
15
|
* Added `check_item?(user_id, item_id, aggregate = ActivityFeed.aggregate)` to see if an item is in an activity feed.
|
data/README.markdown
CHANGED
@@ -42,7 +42,9 @@ end
|
|
42
42
|
|
43
43
|
### Advanced configuration options
|
44
44
|
|
45
|
-
* `
|
45
|
+
* `items_loader`: ActivityFeed supports loading items from your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid) when a page for a user's activity feed is requested. This option should be set to a Proc that will be called passing the item IDs as its only argument.
|
46
|
+
|
47
|
+
NOTE: The following examples developing an activity feed with Mongoid using Mongoid 3.x.
|
46
48
|
|
47
49
|
For example:
|
48
50
|
|
@@ -68,15 +70,20 @@ module ActivityFeed
|
|
68
70
|
field :icon, type: String
|
69
71
|
field :sticky, type: Boolean
|
70
72
|
|
71
|
-
index :
|
73
|
+
index({ user_id: 1 }
|
72
74
|
|
73
75
|
after_save :update_item_in_activity_feed
|
76
|
+
after_destroy :remove_item_from_activity_feed
|
74
77
|
|
75
78
|
private
|
76
79
|
|
77
80
|
def update_item_in_activity_feed
|
78
81
|
ActivityFeed.update_item(self.user_id, self.id, self.updated_at.to_i)
|
79
82
|
end
|
83
|
+
|
84
|
+
def remove_item_from_activity_feed
|
85
|
+
ActivityFeed.remove_item(self.user_id, self.id)
|
86
|
+
end
|
80
87
|
end
|
81
88
|
end
|
82
89
|
end
|
@@ -85,7 +92,7 @@ end
|
|
85
92
|
You would add the following option where you are configuring ActivityFeed as follows:
|
86
93
|
|
87
94
|
```ruby
|
88
|
-
ActivityFeed.
|
95
|
+
ActivityFeed.items_loader = Proc.new { |ids| ActivityFeed::Mongoid::Item.where(:id.in => ids).order_by(updated_at: :desc).to_a }
|
89
96
|
```
|
90
97
|
|
91
98
|
If you need to handle any exceptions when loading activity feed items, please do this in the Proc.
|
@@ -103,9 +110,7 @@ activity feed.
|
|
103
110
|
# Configure Mongoid
|
104
111
|
require 'mongoid'
|
105
112
|
|
106
|
-
Mongoid.
|
107
|
-
config.master = Mongo::Connection.new.db("activity_feed_gem_test")
|
108
|
-
end
|
113
|
+
Mongoid.load!("/path/to/your/mongoid.yml", :production)
|
109
114
|
|
110
115
|
# Create a class for activity feed items
|
111
116
|
module ActivityFeed
|
@@ -125,7 +130,7 @@ module ActivityFeed
|
|
125
130
|
field :icon, type: String
|
126
131
|
field :sticky, type: Boolean
|
127
132
|
|
128
|
-
index :
|
133
|
+
index({ user_id: 1 }
|
129
134
|
|
130
135
|
after_save :update_item_in_activity_feed
|
131
136
|
after_destroy :remove_item_from_activity_feed
|
@@ -152,7 +157,7 @@ ActivityFeed.configure do |configuration|
|
|
152
157
|
configuration.aggregate = false
|
153
158
|
configuration.aggregate_key = 'aggregate'
|
154
159
|
configuration.page_size = 25
|
155
|
-
configuration.
|
160
|
+
configuration.items_loader = Proc.new { |ids| ActivityFeed::Mongoid::Item.where(:id.in => ids).order_by(updated_at: :desc).to_a }
|
156
161
|
end
|
157
162
|
|
158
163
|
# Create a couple of activity feed items
|
@@ -193,9 +198,7 @@ feed = ActivityFeed.feed('david', 1)
|
|
193
198
|
# Configure Mongoid
|
194
199
|
require 'mongoid'
|
195
200
|
|
196
|
-
Mongoid.
|
197
|
-
config.master = Mongo::Connection.new.db("activity_feed_gem_test")
|
198
|
-
end
|
201
|
+
Mongoid.load!("/path/to/your/mongoid.yml", :production)
|
199
202
|
|
200
203
|
# Create a class for activity feed items
|
201
204
|
module ActivityFeed
|
@@ -234,7 +237,7 @@ ActivityFeed.configure do |configuration|
|
|
234
237
|
configuration.aggregate = true
|
235
238
|
configuration.aggregate_key = 'aggregate'
|
236
239
|
configuration.page_size = 25
|
237
|
-
configuration.
|
240
|
+
configuration.items_loader = Proc.new { |ids| ActivityFeed::Mongoid::Item.where(:id.in => ids).order_by(updated_at: :desc).to_a }
|
238
241
|
end
|
239
242
|
|
240
243
|
# Create activity feed items for a couple of users and aggregate the activity feed items from the second user in the first user's activity feed
|
@@ -300,6 +303,7 @@ ActivityFeed.total_items_in_feed(user_id, aggregate = ActivityFeed.aggregate)
|
|
300
303
|
ActivityFeed.total_items(user_id, aggregate = ActivityFeed.aggregate)
|
301
304
|
ActivityFeed.trim_feed(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
302
305
|
ActivityFeed.expire_feed(user_id, seconds, aggregate = ActivityFeed.aggregate)
|
306
|
+
ActivityFeed.expire_feed_in(user_id, seconds, aggregate = ActivityFeed.aggregate)
|
303
307
|
ActivityFeed.expire_feed_at(user_id, timestamp, aggregate = ActivityFeed.aggregate)
|
304
308
|
ActivityFeed.remove_feeds(user_id)
|
305
309
|
```
|
@@ -4,8 +4,10 @@ module ActivityFeed
|
|
4
4
|
# Redis instance.
|
5
5
|
attr_accessor :redis
|
6
6
|
|
7
|
-
# Proc that will be called for loading
|
8
|
-
|
7
|
+
# Proc that will be called for loading items from an
|
8
|
+
# ORM (e.g. ActiveRecord) or ODM (e.g. Mongoid). Proc
|
9
|
+
# will be called with the IDs of the items from the feed.
|
10
|
+
attr_accessor :items_loader
|
9
11
|
|
10
12
|
# ActivityFeed namespace for Redis.
|
11
13
|
attr_writer :namespace
|
@@ -19,7 +21,8 @@ module ActivityFeed
|
|
19
21
|
# Page size to be used when paging through the activity feed.
|
20
22
|
attr_writer :page_size
|
21
23
|
|
22
|
-
# Yield self to be able to configure ActivityFeed with
|
24
|
+
# Yield self to be able to configure ActivityFeed with
|
25
|
+
# block-style configuration.
|
23
26
|
#
|
24
27
|
# Example:
|
25
28
|
#
|
@@ -56,7 +59,7 @@ module ActivityFeed
|
|
56
59
|
end
|
57
60
|
|
58
61
|
# Default page size.
|
59
|
-
#
|
62
|
+
#
|
60
63
|
# @return the page size or the default of 25 if not set.
|
61
64
|
def page_size
|
62
65
|
@page_size ||= 25
|
data/lib/activity_feed/feed.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActivityFeed
|
2
2
|
module Feed
|
3
3
|
# Retrieve a page from the activity feed for a given +user_id+. You can configure
|
4
|
-
# +ActivityFeed.
|
4
|
+
# +ActivityFeed.items_loader+ with a Proc to retrieve items from, for example,
|
5
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
|
#
|
@@ -12,22 +12,12 @@ module ActivityFeed
|
|
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)
|
15
|
-
|
16
|
-
|
17
|
-
ActivityFeed.item_loader.call(feed_item[:member])
|
18
|
-
else
|
19
|
-
feed_item[:member]
|
20
|
-
end
|
21
|
-
|
22
|
-
feed_items << item unless item.nil?
|
23
|
-
feed_items
|
24
|
-
end
|
25
|
-
|
26
|
-
feed.nil? ? [] : feed
|
15
|
+
feed_items = feederboard.leaders(page, :page_size => ActivityFeed.page_size)
|
16
|
+
load_feed_items(feed_items)
|
27
17
|
end
|
28
18
|
|
29
19
|
# Retrieve the entire activity feed for a given +user_id+. You can configure
|
30
|
-
# +ActivityFeed.
|
20
|
+
# +ActivityFeed.items_loader+ with a Proc to retrieve items from, for example,
|
31
21
|
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the page
|
32
22
|
# returned with loaded items rather than item IDs.
|
33
23
|
#
|
@@ -37,23 +27,13 @@ module ActivityFeed
|
|
37
27
|
# @return the full activity feed for a given +user_id+.
|
38
28
|
def full_feed(user_id, aggregate = ActivityFeed.aggregate)
|
39
29
|
feederboard = ActivityFeed.feederboard_for(user_id, aggregate)
|
40
|
-
|
41
|
-
|
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
|
30
|
+
feed_items = feederboard.leaders(1, :page_size => feederboard.total_members)
|
31
|
+
load_feed_items(feed_items)
|
52
32
|
end
|
53
33
|
|
54
34
|
# Retrieve a page from the activity feed for a given +user_id+ between a
|
55
35
|
# +starting_timestamp+ and an +ending_timestamp+. You can configure
|
56
|
-
# +ActivityFeed.
|
36
|
+
# +ActivityFeed.items_loader+ with a Proc to retrieve items from, for example,
|
57
37
|
# your ORM (e.g. ActiveRecord) or your ODM (e.g. Mongoid), and have the feed data
|
58
38
|
# returned with loaded items rather than item IDs.
|
59
39
|
#
|
@@ -65,18 +45,8 @@ module ActivityFeed
|
|
65
45
|
# @return feed items from the activity feed for a given +user_id+ between the +starting_timestamp+ and +ending_timestamp+.
|
66
46
|
def feed_between_timestamps(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
67
47
|
feederboard = ActivityFeed.feederboard_for(user_id, aggregate)
|
68
|
-
|
69
|
-
|
70
|
-
ActivityFeed.item_loader.call(feed_item[:member])
|
71
|
-
else
|
72
|
-
feed_item[:member]
|
73
|
-
end
|
74
|
-
|
75
|
-
feed_items << item unless item.nil?
|
76
|
-
feed_items
|
77
|
-
end
|
78
|
-
|
79
|
-
feed.nil? ? [] : feed
|
48
|
+
feed_items = feederboard.members_from_score_range(starting_timestamp, ending_timestamp)
|
49
|
+
load_feed_items(feed_items)
|
80
50
|
end
|
81
51
|
|
82
52
|
# Return the total number of pages in the activity feed.
|
@@ -133,6 +103,8 @@ module ActivityFeed
|
|
133
103
|
ActivityFeed.redis.expire(ActivityFeed.feed_key(user_id, aggregate), seconds)
|
134
104
|
end
|
135
105
|
|
106
|
+
alias_method :expire_feed_in, :expire_feed
|
107
|
+
|
136
108
|
# Expire an activity feed at a given timestamp.
|
137
109
|
#
|
138
110
|
# @param user_id [String] User ID.
|
@@ -141,5 +113,22 @@ module ActivityFeed
|
|
141
113
|
def expire_feed_at(user_id, timestamp, aggregate = ActivityFeed.aggregate)
|
142
114
|
ActivityFeed.redis.expireat(ActivityFeed.feed_key(user_id, aggregate), timestamp)
|
143
115
|
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Load feed items from the `ActivityFeed.items_loader` if available,
|
120
|
+
# otherwise return the individual members from the feed items.
|
121
|
+
#
|
122
|
+
# @param feed_items [Array] Array of hash feed items as `[{:member=>"5", :rank=>1, :score=>1373564960.0}, ...]`
|
123
|
+
#
|
124
|
+
# @return Array of feed items
|
125
|
+
def load_feed_items(feed_items)
|
126
|
+
feed_item_ids = feed_items.collect { |feed_item| feed_item[:member] }
|
127
|
+
if ActivityFeed.items_loader
|
128
|
+
ActivityFeed.items_loader.call(feed_item_ids)
|
129
|
+
else
|
130
|
+
feed_item_ids
|
131
|
+
end
|
132
|
+
end
|
144
133
|
end
|
145
134
|
end
|
@@ -205,8 +205,8 @@ describe ActivityFeed::Feed do
|
|
205
205
|
describe 'ORM or ODM loading' do
|
206
206
|
describe 'ActiveRecord' do
|
207
207
|
it 'should be able to load an item via ActiveRecord when requesting a feed' do
|
208
|
-
ActivityFeed.
|
209
|
-
ActivityFeed::ActiveRecord::Item.find(
|
208
|
+
ActivityFeed.items_loader = Proc.new do |ids|
|
209
|
+
ActivityFeed::ActiveRecord::Item.find(ids)
|
210
210
|
end
|
211
211
|
|
212
212
|
feed = ActivityFeed.feed('david', 1)
|
@@ -228,7 +228,9 @@ describe ActivityFeed::Feed do
|
|
228
228
|
|
229
229
|
describe 'Mongoid' do
|
230
230
|
it 'should be able to load an item via Mongoid when requesting a feed' do
|
231
|
-
ActivityFeed.
|
231
|
+
ActivityFeed.items_loader = Proc.new do |ids|
|
232
|
+
ActivityFeed::Mongoid::Item.find(ids)
|
233
|
+
end
|
232
234
|
|
233
235
|
feed = ActivityFeed.feed('david', 1)
|
234
236
|
feed.length.should eql(0)
|
@@ -249,8 +251,8 @@ describe ActivityFeed::Feed do
|
|
249
251
|
end
|
250
252
|
end
|
251
253
|
|
252
|
-
describe '#expire_feed' do
|
253
|
-
it 'should set an expiration on an activity feed' do
|
254
|
+
describe '#expire_feed and #expire_feed_in' do
|
255
|
+
it 'should set an expiration on an activity feed using #expire_feed' do
|
254
256
|
add_items_to_feed('david', Leaderboard::DEFAULT_PAGE_SIZE)
|
255
257
|
|
256
258
|
ActivityFeed.expire_feed('david', 10)
|
@@ -259,6 +261,16 @@ describe ActivityFeed::Feed do
|
|
259
261
|
ttl.should be <= 10
|
260
262
|
end
|
261
263
|
end
|
264
|
+
|
265
|
+
it 'should set an expiration on an activity feed using #expire_feed_in' do
|
266
|
+
add_items_to_feed('david', Leaderboard::DEFAULT_PAGE_SIZE)
|
267
|
+
|
268
|
+
ActivityFeed.expire_feed_in('david', 10)
|
269
|
+
ActivityFeed.redis.ttl(ActivityFeed.feed_key('david')).tap do |ttl|
|
270
|
+
ttl.should be > 1
|
271
|
+
ttl.should be <= 10
|
272
|
+
end
|
273
|
+
end
|
262
274
|
end
|
263
275
|
|
264
276
|
describe '#expire_feed_at' do
|
data/spec/spec_helper.rb
CHANGED
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:
|
4
|
+
version: 3.0.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: 2013-
|
12
|
+
date: 2013-07-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -216,7 +216,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
216
216
|
version: '0'
|
217
217
|
segments:
|
218
218
|
- 0
|
219
|
-
hash:
|
219
|
+
hash: 3361752817333604694
|
220
220
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
221
221
|
none: false
|
222
222
|
requirements:
|
@@ -225,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
225
225
|
version: '0'
|
226
226
|
segments:
|
227
227
|
- 0
|
228
|
-
hash:
|
228
|
+
hash: 3361752817333604694
|
229
229
|
requirements: []
|
230
230
|
rubyforge_project: activity_feed
|
231
231
|
rubygems_version: 1.8.25
|