activity_feed 2.3.0 → 3.0.0
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/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
|