activity_feed 1.4.0 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/README.markdown +212 -174
- data/Rakefile +5 -1
- data/activity_feed.gemspec +8 -14
- data/lib/activity_feed/configuration.rb +65 -0
- data/lib/activity_feed/feed.rb +89 -20
- data/lib/activity_feed/item.rb +44 -0
- data/lib/activity_feed/utility.rb +25 -0
- data/lib/activity_feed/version.rb +1 -1
- data/lib/activity_feed.rb +10 -109
- data/spec/activity_feed/configuration_spec.rb +14 -0
- data/spec/activity_feed/feed_spec.rb +270 -0
- data/spec/activity_feed/item_spec.rb +65 -0
- data/spec/activity_feed/utility_spec.rb +24 -0
- data/spec/spec_helper.rb +28 -66
- data/spec/support/active_record.rb +38 -0
- data/spec/support/mongoid.rb +38 -0
- data/spec/version_spec.rb +2 -2
- metadata +24 -155
- data/lib/activity_feed/active_record/item.rb +0 -17
- data/lib/activity_feed/memory/item.rb +0 -36
- data/lib/activity_feed/mongo_mapper/item.rb +0 -30
- data/lib/activity_feed/mongoid/item.rb +0 -31
- data/lib/activity_feed/ohm/item.rb +0 -41
- data/spec/activity_feed/custom/item.rb +0 -36
- data/spec/activity_feed_spec.rb +0 -295
- data/spec/fabricators/item_fabricator.rb +0 -43
- data/spec/feed_spec.rb +0 -106
- data/spec/item_spec.rb +0 -55
data/.rvmrc
CHANGED
data/README.markdown
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# ActivityFeed
|
2
2
|
|
3
|
-
Activity feeds backed by Redis
|
3
|
+
Activity feeds backed by Redis. Activity feeds may also be referred to as timelines or
|
4
|
+
news feeds.
|
4
5
|
|
5
6
|
## Compatibility
|
6
7
|
|
7
|
-
The gem has been built and tested under Ruby 1.
|
8
|
+
The gem has been built and tested under Ruby 1.8.7 and Ruby 1.9.3.
|
8
9
|
|
9
10
|
## Installation
|
10
11
|
|
@@ -19,244 +20,282 @@ check out the [Redis documentation](http://redis.io/documentation).
|
|
19
20
|
|
20
21
|
## Configuration
|
21
22
|
|
23
|
+
### Basic configuration options
|
24
|
+
|
22
25
|
```ruby
|
23
|
-
|
24
|
-
|
25
|
-
ActivityFeed.
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
require 'activity_feed'
|
27
|
+
|
28
|
+
ActivityFeed.configure do |configuration|
|
29
|
+
configuration.redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
30
|
+
configuration.namespace = 'activity_feed'
|
31
|
+
configuration.aggregate = false
|
32
|
+
configuration.aggregate_key = 'aggregate'
|
33
|
+
configuration.page_size = 25
|
34
|
+
end
|
29
35
|
```
|
30
36
|
|
31
|
-
|
37
|
+
* `redis`: The Redis connection instance to be used.
|
38
|
+
* `namespace`: Namespace to isolate ActivityFeed data in Redis.
|
39
|
+
* `aggregate`: Determines whether or not, by default, various calls will pull from the aggregate activity feed for a user.
|
40
|
+
* `aggregate_key`: Further isolates the aggregate ActivityFeed data.
|
41
|
+
* `page_size`: Number of activity feed items to be retrieved per-page.
|
32
42
|
|
33
|
-
|
43
|
+
### Advanced configuration options
|
34
44
|
|
35
|
-
|
36
|
-
$redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
37
|
-
ActivityFeed.redis = $redis
|
38
|
-
```
|
45
|
+
* `item_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 ID as its only argument.
|
39
46
|
|
40
|
-
|
47
|
+
For example:
|
41
48
|
|
42
|
-
|
49
|
+
Assume you have defined a class for storing your activity feed items in Mongoid as follows:
|
43
50
|
|
44
51
|
```ruby
|
45
|
-
require '
|
46
|
-
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
47
|
-
require 'activity_feed'
|
48
|
-
ActivityFeed.redis = $redis
|
49
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'Text')
|
50
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'More text')
|
51
|
-
feed = ActivityFeed::Feed.new(1)
|
52
|
-
feed.page(1)
|
53
|
-
```
|
52
|
+
require 'mongoid'
|
54
53
|
|
55
|
-
|
54
|
+
module ActivityFeed
|
55
|
+
module Mongoid
|
56
|
+
class Item
|
57
|
+
include ::Mongoid::Document
|
58
|
+
include ::Mongoid::Timestamps
|
56
59
|
|
57
|
-
|
58
|
-
|
60
|
+
field :user_id, type: String
|
61
|
+
validates_presence_of :user_id
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
+
field :nickname, type: String
|
64
|
+
field :type, type: String
|
65
|
+
field :title, type: String
|
66
|
+
field :text, type: String
|
67
|
+
field :url, type: String
|
68
|
+
field :icon, type: String
|
69
|
+
field :sticky, type: Boolean
|
63
70
|
|
64
|
-
|
71
|
+
index :user_id
|
65
72
|
|
66
|
-
|
67
|
-
require 'active_record'
|
73
|
+
after_save :update_item_in_activity_feed
|
68
74
|
|
69
|
-
|
70
|
-
:adapter => "sqlite3",
|
71
|
-
:database => ":memory:"
|
72
|
-
)
|
75
|
+
private
|
73
76
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
t.integer :user_id
|
79
|
-
t.string :nickname
|
80
|
-
t.string :type
|
81
|
-
t.string :title
|
82
|
-
t.text :text
|
83
|
-
t.string :url
|
84
|
-
t.string :icon
|
85
|
-
t.boolean :sticky
|
86
|
-
|
87
|
-
t.timestamps
|
77
|
+
def update_item_in_activity_feed
|
78
|
+
ActivityFeed.update_item(self.user_id, self.id, self.updated_at.to_i)
|
79
|
+
end
|
80
|
+
end
|
88
81
|
end
|
89
|
-
|
90
|
-
add_index :activity_feed_items, :user_id
|
91
82
|
end
|
92
|
-
|
93
|
-
require 'redis'
|
94
|
-
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
95
|
-
require 'activity_feed'
|
96
|
-
ActivityFeed.redis = $redis
|
97
|
-
ActivityFeed.persistence = :active_record
|
98
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'Text')
|
99
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'More text')
|
100
|
-
feed = ActivityFeed::Feed.new(1)
|
101
|
-
feed.page(1)
|
102
83
|
```
|
103
84
|
|
104
|
-
|
105
|
-
|
106
|
-
ActivityFeed can also use MongoMapper to persist the items to more durable storage while
|
107
|
-
keeping the IDs for the activity feed items in Redis. You can set this using:
|
85
|
+
You would add the following option where you are configuring ActivityFeed as follows:
|
108
86
|
|
109
87
|
```ruby
|
110
|
-
ActivityFeed.
|
88
|
+
ActivityFeed.item_loader = Proc.new { |id| ActivityFeed::Mongoid::Item.find(id) }
|
111
89
|
```
|
112
90
|
|
113
|
-
|
114
|
-
If using Activity Feed outside of Rails, you can do:
|
91
|
+
If you need to handle any exceptions when loading activity feed items, please do this in the Proc.
|
115
92
|
|
116
|
-
|
117
|
-
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
|
118
|
-
MongoMapper.database = 'activity_feeds_production'
|
119
|
-
```
|
120
|
-
|
121
|
-
```ruby
|
122
|
-
require 'mongo_mapper'
|
123
|
-
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
|
124
|
-
MongoMapper.database = 'activity_feed_gem_test'
|
125
|
-
require 'redis'
|
126
|
-
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
127
|
-
require 'activity_feed'
|
128
|
-
ActivityFeed.redis = $redis
|
129
|
-
ActivityFeed.persistence = :mongo_mapper
|
130
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'Text')
|
131
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'More text')
|
132
|
-
feed = ActivityFeed::Feed.new(1)
|
133
|
-
feed.page(1)
|
134
|
-
```
|
93
|
+
## Usage
|
135
94
|
|
136
|
-
###
|
95
|
+
### Developing an Activity Feed for an Individual
|
137
96
|
|
138
|
-
|
139
|
-
|
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
|
100
|
+
activity feed.
|
140
101
|
|
141
102
|
```ruby
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
Make sure Mongoid is configured correctly before setting this option.
|
146
|
-
If using Activity Feed outside of Rails, you can do:
|
103
|
+
# Configure Mongoid
|
104
|
+
require 'mongoid'
|
147
105
|
|
148
|
-
```ruby
|
149
106
|
Mongoid.configure do |config|
|
150
107
|
config.master = Mongo::Connection.new.db("activity_feed_gem_test")
|
151
108
|
end
|
152
|
-
```
|
153
109
|
|
154
|
-
|
155
|
-
|
156
|
-
Mongoid
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
161
|
-
require 'activity_feed'
|
162
|
-
ActivityFeed.redis = $redis
|
163
|
-
ActivityFeed.persistence = :mongoid
|
164
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'Text')
|
165
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'More text')
|
166
|
-
feed = ActivityFeed::Feed.new(1)
|
167
|
-
feed.page(1)
|
168
|
-
```
|
110
|
+
# Create a class for activity feed items
|
111
|
+
module ActivityFeed
|
112
|
+
module Mongoid
|
113
|
+
class Item
|
114
|
+
include ::Mongoid::Document
|
115
|
+
include ::Mongoid::Timestamps
|
169
116
|
|
170
|
-
|
117
|
+
field :user_id, type: String
|
118
|
+
validates_presence_of :user_id
|
171
119
|
|
172
|
-
|
120
|
+
field :nickname, type: String
|
121
|
+
field :type, type: String
|
122
|
+
field :title, type: String
|
123
|
+
field :text, type: String
|
124
|
+
field :url, type: String
|
125
|
+
field :icon, type: String
|
126
|
+
field :sticky, type: Boolean
|
173
127
|
|
174
|
-
|
175
|
-
require 'redis'
|
176
|
-
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
177
|
-
require 'activity_feed'
|
178
|
-
ActivityFeed.redis = $redis
|
179
|
-
ActivityFeed.persistence = :ohm
|
180
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'Text')
|
181
|
-
ActivityFeed.create_item(:user_id => 1, :nickname => 'David Czarnecki', :type => 'activity-type', :text => 'More text')
|
182
|
-
feed = ActivityFeed::Feed.new(1)
|
183
|
-
feed.page(1)
|
184
|
-
```
|
128
|
+
index :user_id
|
185
129
|
|
186
|
-
|
130
|
+
after_save :update_item_in_activity_feed
|
131
|
+
after_destroy :remove_item_from_activity_feed
|
187
132
|
|
188
|
-
|
133
|
+
private
|
189
134
|
|
190
|
-
|
191
|
-
ActivityFeed.
|
192
|
-
|
135
|
+
def update_item_in_activity_feed
|
136
|
+
ActivityFeed.update_item(self.user_id, self.id, self.updated_at.to_i)
|
137
|
+
end
|
193
138
|
|
194
|
-
|
139
|
+
def remove_item_from_activity_feed
|
140
|
+
ActivityFeed.remove_item(self.user_id, self.id)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
195
145
|
|
196
|
-
|
197
|
-
|
198
|
-
```
|
146
|
+
# Configure ActivityFeed
|
147
|
+
require 'activity_feed'
|
199
148
|
|
200
|
-
|
149
|
+
ActivityFeed.configure do |configuration|
|
150
|
+
configuration.redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
151
|
+
configuration.namespace = 'activity_feed'
|
152
|
+
configuration.aggregate = false
|
153
|
+
configuration.aggregate_key = 'aggregate'
|
154
|
+
configuration.page_size = 25
|
155
|
+
configuration.item_loader = Proc.new { |id| ActivityFeed::Mongoid::Item.find(id) }
|
156
|
+
end
|
201
157
|
|
202
|
-
|
203
|
-
ActivityFeed::
|
204
|
-
|
158
|
+
# Create a couple of activity feed items
|
159
|
+
activity_item_1 = ActivityFeed::Mongoid::Item.create(
|
160
|
+
:user_id => 'david',
|
161
|
+
:nickname => 'David Czarnecki',
|
162
|
+
:type => 'some_activity',
|
163
|
+
:title => 'Great activity',
|
164
|
+
:text => 'This is text for the activity feed item',
|
165
|
+
:url => 'http://url.com'
|
166
|
+
)
|
205
167
|
|
206
|
-
|
207
|
-
|
168
|
+
activity_item_2 = ActivityFeed::Mongoid::Item.create(
|
169
|
+
:user_id => 'david',
|
170
|
+
:nickname => 'David Czarnecki',
|
171
|
+
:type => 'some_activity',
|
172
|
+
:title => 'Another great activity',
|
173
|
+
:text => 'This is some other text for the activity feed item',
|
174
|
+
:url => 'http://url.com'
|
175
|
+
)
|
208
176
|
|
209
|
-
|
177
|
+
# Pull up the activity feed
|
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>]
|
210
180
|
|
211
|
-
|
181
|
+
# Update an actitivity feed item
|
182
|
+
activity_item_1.text = 'Updated some text for the activity feed item'
|
183
|
+
activity_item_1.save
|
212
184
|
|
213
|
-
|
214
|
-
ActivityFeed.feed(
|
185
|
+
# Pull up the activity feed item and notice that the item you updated has "bubbled up" to the top of the feed
|
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>]
|
215
188
|
```
|
216
189
|
|
217
|
-
|
190
|
+
### Developing an Aggregate Activity Feed for an Individual
|
218
191
|
|
219
192
|
```ruby
|
220
|
-
|
221
|
-
|
193
|
+
# Configure Mongoid
|
194
|
+
require 'mongoid'
|
195
|
+
|
196
|
+
Mongoid.configure do |config|
|
197
|
+
config.master = Mongo::Connection.new.db("activity_feed_gem_test")
|
198
|
+
end
|
222
199
|
|
223
|
-
|
224
|
-
|
200
|
+
# Create a class for activity feed items
|
201
|
+
module ActivityFeed
|
202
|
+
module Mongoid
|
203
|
+
class Item
|
204
|
+
include ::Mongoid::Document
|
205
|
+
include ::Mongoid::Timestamps
|
225
206
|
|
226
|
-
|
227
|
-
|
207
|
+
field :user_id, type: String
|
208
|
+
validates_presence_of :user_id
|
228
209
|
|
229
|
-
|
210
|
+
field :text, type: String
|
230
211
|
|
231
|
-
|
212
|
+
after_save :update_item_in_activity_feed
|
213
|
+
after_destroy :remove_item_from_activity_feed
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def update_item_in_activity_feed
|
218
|
+
ActivityFeed.update_item(self.user_id, self.id, self.updated_at.to_i)
|
219
|
+
end
|
220
|
+
|
221
|
+
def remove_item_from_activity_feed
|
222
|
+
ActivityFeed.remove_item(self.user_id, self.id)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Configure ActivityFeed
|
232
229
|
require 'activity_feed'
|
233
|
-
require 'pp'
|
234
|
-
$redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
235
|
-
ActivityFeed.redis = $redis
|
236
|
-
ActivityFeed.persistence = :ohm
|
237
230
|
|
231
|
+
ActivityFeed.configure do |configuration|
|
232
|
+
configuration.redis = Redis.new(:host => '127.0.0.1', :port => 6379)
|
233
|
+
configuration.namespace = 'activity_feed'
|
234
|
+
configuration.aggregate = true
|
235
|
+
configuration.aggregate_key = 'aggregate'
|
236
|
+
configuration.page_size = 25
|
237
|
+
configuration.item_loader = Proc.new { |id| ActivityFeed::Mongoid::Item.find(id) }
|
238
|
+
end
|
239
|
+
|
240
|
+
# 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
|
238
241
|
1.upto(5) do |index|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
242
|
+
ActivityFeed::Mongoid::Item.create(
|
243
|
+
:user_id => 'david',
|
244
|
+
:text => "This is from david's activity feed"
|
245
|
+
)
|
246
|
+
|
247
|
+
sleep(1) # Sleep a little so we make sure to have unique timestamps between activity feed items
|
248
|
+
|
249
|
+
another_item = ActivityFeed::Mongoid::Item.create(
|
250
|
+
:user_id => 'unknown',
|
251
|
+
:text => "This is from unknown's activity feed"
|
252
|
+
)
|
253
|
+
|
254
|
+
sleep(1)
|
255
|
+
|
256
|
+
ActivityFeed.aggregate_item('david', another_item.id, another_item.updated_at.to_i)
|
244
257
|
end
|
245
258
|
|
246
|
-
|
247
|
-
pp feed.
|
259
|
+
# Pull up the aggregate activity feed
|
260
|
+
pp feed = ActivityFeed.feed('david', 1, true)
|
261
|
+
[#<ActivityFeed::Mongoid::Item _id: 4fe289248bb895b79500000a, _type: nil, created_at: 2012-06-21 02:38:28 UTC, updated_at: 2012-06-21 02:38:28 UTC, user_id: "unknown", text: "This is from unknown's activity feed">,
|
262
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe289238bb895b795000009, _type: nil, created_at: 2012-06-21 02:38:27 UTC, updated_at: 2012-06-21 02:38:27 UTC, user_id: "david", text: "This is from david's activity feed">,
|
263
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe289228bb895b795000008, _type: nil, created_at: 2012-06-21 02:38:26 UTC, updated_at: 2012-06-21 02:38:26 UTC, user_id: "unknown", text: "This is from unknown's activity feed">,
|
264
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe289218bb895b795000007, _type: nil, created_at: 2012-06-21 02:38:25 UTC, updated_at: 2012-06-21 02:38:25 UTC, user_id: "david", text: "This is from david's activity feed">,
|
265
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe289208bb895b795000006, _type: nil, created_at: 2012-06-21 02:38:24 UTC, updated_at: 2012-06-21 02:38:24 UTC, user_id: "unknown", text: "This is from unknown's activity feed">,
|
266
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe2891f8bb895b795000005, _type: nil, created_at: 2012-06-21 02:38:23 UTC, updated_at: 2012-06-21 02:38:23 UTC, user_id: "david", text: "This is from david's activity feed">,
|
267
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe2891e8bb895b795000004, _type: nil, created_at: 2012-06-21 02:38:22 UTC, updated_at: 2012-06-21 02:38:22 UTC, user_id: "unknown", text: "This is from unknown's activity feed">,
|
268
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe2891d8bb895b795000003, _type: nil, created_at: 2012-06-21 02:38:21 UTC, updated_at: 2012-06-21 02:38:21 UTC, user_id: "david", text: "This is from david's activity feed">,
|
269
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe2891c8bb895b795000002, _type: nil, created_at: 2012-06-21 02:38:20 UTC, updated_at: 2012-06-21 02:38:20 UTC, user_id: "unknown", text: "This is from unknown's activity feed">,
|
270
|
+
#<ActivityFeed::Mongoid::Item _id: 4fe2891b8bb895b795000001, _type: nil, created_at: 2012-06-21 02:38:19 UTC, updated_at: 2012-06-21 02:38:19 UTC, user_id: "david", text: "This is from david's activity feed">]
|
248
271
|
```
|
249
272
|
|
250
|
-
|
273
|
+
## ActivityFeed Caveats
|
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
|
277
|
+
feeds in which that activity feed item may have been aggregated.
|
251
278
|
|
252
|
-
|
279
|
+
## ActivityFeed method summary
|
253
280
|
|
254
281
|
```ruby
|
255
|
-
|
256
|
-
|
282
|
+
# Item-related
|
283
|
+
|
284
|
+
ActivityFeed.update_item(user_id, item_id, timestamp, aggregate = ActivityFeed.aggregate)
|
285
|
+
ActivityFeed.aggregate_item(user_id, item_id, timestamp)
|
286
|
+
ActivityFeed.remove_item(user_id, item_id)
|
287
|
+
|
288
|
+
# Feed-related
|
289
|
+
|
290
|
+
ActivityFeed.feed(user_id, page, aggregate = ActivityFeed.aggregate)
|
291
|
+
ActivityFeed.feed_between_timestamps(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
292
|
+
ActivityFeed.total_pages_in_feed(user_id, aggregate = ActivityFeed.aggregate, page_size = ActivityFeed.page_size)
|
293
|
+
ActivityFeed.total_items_in_feed(user_id, aggregate = ActivityFeed.aggregate)
|
294
|
+
ActivityFeed.trim_feed(user_id, starting_timestamp, ending_timestamp, aggregate = ActivityFeed.aggregate)
|
295
|
+
ActivityFeed.remove_feeds(user_id)
|
257
296
|
```
|
258
297
|
|
259
|
-
## Contributing to
|
298
|
+
## Contributing to ActivityFeed
|
260
299
|
|
261
300
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
262
301
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
@@ -268,5 +307,4 @@ ActivityFeed.delete_item(user_id, item_id, aggregate = false)
|
|
268
307
|
|
269
308
|
## Copyright
|
270
309
|
|
271
|
-
Copyright (c) 2011-2012 David Czarnecki. See LICENSE.txt for further details.
|
272
|
-
|
310
|
+
Copyright (c) 2011-2012 David Czarnecki. See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
data/activity_feed.gemspec
CHANGED
@@ -21,26 +21,20 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency('rake')
|
23
23
|
s.add_development_dependency('rspec')
|
24
|
-
s.add_development_dependency('
|
25
|
-
s.add_development_dependency('
|
26
|
-
|
24
|
+
s.add_development_dependency('activesupport')
|
25
|
+
s.add_development_dependency('timecop')
|
26
|
+
|
27
27
|
s.add_development_dependency('mongoid')
|
28
|
-
s.add_development_dependency('mongo_mapper')
|
29
|
-
s.add_development_dependency('mongo_ext')
|
30
28
|
s.add_development_dependency('bson_ext')
|
31
|
-
|
29
|
+
|
32
30
|
s.add_development_dependency('activerecord')
|
33
31
|
s.add_development_dependency('sqlite3')
|
34
32
|
|
35
|
-
s.add_development_dependency('
|
36
|
-
s.add_development_dependency('ohm-contrib')
|
33
|
+
s.add_development_dependency('database_cleaner')
|
37
34
|
|
38
|
-
|
35
|
+
if '1.8.7'.eql?(RUBY_VERSION)
|
36
|
+
s.add_development_dependency('SystemTimer')
|
37
|
+
end
|
39
38
|
|
40
|
-
s.add_dependency('activesupport')
|
41
|
-
s.add_dependency('i18n')
|
42
|
-
|
43
|
-
s.add_dependency('json')
|
44
|
-
s.add_dependency('redis')
|
45
39
|
s.add_dependency('leaderboard')
|
46
40
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ActivityFeed
|
2
|
+
# Configuration settings for ActivityFeed.
|
3
|
+
module Configuration
|
4
|
+
# Redis instance.
|
5
|
+
attr_accessor :redis
|
6
|
+
|
7
|
+
# Proc that will be called for loading an item from an ORM (e.g. ActiveRecord) or ODM (e.g. Mongoid). Proc will be called with the ID of the item from the feed.
|
8
|
+
attr_accessor :item_loader
|
9
|
+
|
10
|
+
# ActivityFeed namespace for Redis.
|
11
|
+
attr_writer :namespace
|
12
|
+
|
13
|
+
# Indicates whether or not aggregation is enabled.
|
14
|
+
attr_writer :aggregate
|
15
|
+
|
16
|
+
# Key used in Redis for an individual's aggregate feed.
|
17
|
+
attr_writer :aggregate_key
|
18
|
+
|
19
|
+
# Page size to be used when paging through the activity feed.
|
20
|
+
attr_writer :page_size
|
21
|
+
|
22
|
+
# Yield self to be able to configure ActivityFeed with block-style configuration.
|
23
|
+
#
|
24
|
+
# Example:
|
25
|
+
#
|
26
|
+
# ActivityFeed.configure do |configuration|
|
27
|
+
# configuration.redis = Redis.new
|
28
|
+
# configuration.namespace = 'activity_feed'
|
29
|
+
# configuration.aggregate = false
|
30
|
+
# configuration.aggregate_key = 'aggregate'
|
31
|
+
# configuration.page_size = 25
|
32
|
+
# end
|
33
|
+
def configure
|
34
|
+
yield self
|
35
|
+
end
|
36
|
+
|
37
|
+
# ActivityFeed namespace for Redis.
|
38
|
+
#
|
39
|
+
# @return the ActivityFeed namespace or the default of 'activity_feed' if not set.
|
40
|
+
def namespace
|
41
|
+
@namespace ||= 'activity_feed'
|
42
|
+
end
|
43
|
+
|
44
|
+
# Indicates whether or not aggregation is enabled.
|
45
|
+
#
|
46
|
+
# @return whether or not aggregation is enabled or the default of +false+ if not set.
|
47
|
+
def aggregate
|
48
|
+
@aggregate ||= false
|
49
|
+
end
|
50
|
+
|
51
|
+
# Key used in Redis for an individul's aggregate feed.
|
52
|
+
#
|
53
|
+
# @return the key used in Redis for an individual's aggregate feed or the default of 'aggregate' if not set.
|
54
|
+
def aggregate_key
|
55
|
+
@aggregate_key ||= 'aggregate'
|
56
|
+
end
|
57
|
+
|
58
|
+
# Default page size.
|
59
|
+
#
|
60
|
+
# @return the page size or the default of 25 if not set.
|
61
|
+
def page_size
|
62
|
+
@page_size ||= 25
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|