amico 2.3.0 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.3.1 (2012-09-13)
4
+
5
+ * Wrapped a few operations in Redis multi/exec blocks to be consistent with the rest of the library.
6
+
3
7
  ## 2.3.0 (2012-08-29)
4
8
 
5
9
  * Added `deny(from_id, to_id, scope = Amico.default_scope_key)` to remove a relationship that is pending between two IDs.
@@ -1,752 +1,758 @@
1
1
  module Amico
2
2
  module Relationships
3
- # Establish a follow relationship between two IDs. After adding the follow
4
- # relationship, it checks to see if the relationship is reciprocated and establishes that
5
- # relationship if so.
6
- #
7
- # @param from_id [String] The ID of the individual establishing the follow relationship.
8
- # @param to_id [String] The ID of the individual to be followed.
9
- # @param scope [String] Scope for the call.
10
- #
11
- # Examples
12
- #
13
- # Amico.follow(1, 11)
14
- def follow(from_id, to_id, scope = Amico.default_scope_key)
15
- return if from_id == to_id
16
- return if blocked?(to_id, from_id, scope)
17
- return if Amico.pending_follow && pending?(from_id, to_id, scope)
18
-
19
- unless Amico.pending_follow
20
- add_following_followers_reciprocated(from_id, to_id, scope)
21
- else
22
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
23
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
24
- end
25
- end
26
-
27
- # Remove a follow relationship between two IDs. After removing the follow
28
- # relationship, if a reciprocated relationship was established, it is
29
- # also removed.
30
- #
31
- # @param from_id [String] The ID of the individual removing the follow relationship.
32
- # @param to_id [String] The ID of the individual to be unfollowed.
33
- # @param scope [String] Scope for the call.
34
- #
35
- # Examples
36
- #
37
- # Amico.follow(1, 11)
38
- # Amico.unfollow(1, 11)
39
- def unfollow(from_id, to_id, scope = Amico.default_scope_key)
40
- return if from_id == to_id
41
-
42
- Amico.redis.multi do
43
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", to_id)
44
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", from_id)
45
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", to_id)
46
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", from_id)
47
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
48
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
49
- end
50
- end
51
-
52
- # Block a relationship between two IDs. This method also has the side effect
53
- # of removing any follower or following relationship between the two IDs.
54
- #
55
- # @param from_id [String] The ID of the individual blocking the relationship.
56
- # @param to_id [String] The ID of the individual being blocked.
57
- # @param scope [String] Scope for the call.
58
- #
59
- # Examples
60
- #
61
- # Amico.block(1, 11)
62
- def block(from_id, to_id, scope = Amico.default_scope_key)
63
- return if from_id == to_id
64
-
65
- Amico.redis.multi do
66
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", to_id)
67
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{to_id}", from_id)
68
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", from_id)
69
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{from_id}", to_id)
70
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", to_id)
71
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", from_id)
72
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{from_id}", to_id)
73
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{to_id}", from_id)
74
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
75
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
76
- end
77
- end
78
-
79
- # Unblock a relationship between two IDs.
80
- #
81
- # @param from_id [String] The ID of the individual unblocking the relationship.
82
- # @param to_id [String] The ID of the blocked individual.
83
- # @param scope [String] Scope for the call.
84
- #
85
- # Examples
86
- #
87
- # Amico.block(1, 11)
88
- # Amico.unblock(1, 11)
89
- def unblock(from_id, to_id, scope = Amico.default_scope_key)
90
- return if from_id == to_id
91
-
92
- Amico.redis.multi do
93
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{from_id}", to_id)
94
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{to_id}", from_id)
95
- end
96
- end
97
-
98
- # Accept a relationship that is pending between two IDs.
99
- #
100
- # @param from_id [String] The ID of the individual accepting the relationship.
101
- # @param to_id [String] The ID of the individual to be accepted.
102
- # @param scope [String] Scope for the call.
103
- #
104
- # Example
105
- #
106
- # Amico.follow(1, 11)
107
- # Amico.pending?(1, 11) # true
108
- # Amico.accept(1, 11)
109
- # Amico.pending?(1, 11) # false
110
- # Amico.following?(1, 11) #true
111
- def accept(from_id, to_id, scope = Amico.default_scope_key)
112
- return if from_id == to_id
113
-
114
- add_following_followers_reciprocated(from_id, to_id, scope)
115
- end
116
-
117
- # Deny a relationship that is pending between two IDs.
118
- #
119
- # @param from_id [String] The ID of the individual denying the relationship.
120
- # @param to_id [String] The ID of the individual to be denied.
121
- # @param scope [String] Scope for the call.
122
- #
123
- # Example
124
- #
125
- # Amico.follow(1, 11)
126
- # Amico.pending?(1, 11) # true
127
- # Amico.deny(1, 11)
128
- # Amico.pending?(1, 11) # false
129
- # Amico.following?(1, 11) #false
130
- def deny(from_id, to_id, scope = Amico.default_scope_key)
131
- return if from_id == to_id
132
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
133
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
134
- end
135
-
136
- # Clears all relationships (in either direction) stored for an individual.
137
- # Helpful to prevent orphaned associations when deleting users.
138
- #
139
- # @param id [String] ID of the individual to clear info for.
140
- # @param scope [String] Scope for the call.
141
- #
142
- # Examples
143
- #
144
- # Amico.follow(1, 11)
145
- # Amico.followers_count(11) => 1
146
- # Amico.clear(1)
147
- # Amico.followers_count(11) => 0
148
- def clear(id, scope = Amico.default_scope_key)
149
- # no longer following (or followed by) anyone
150
- clear_bidirectional_sets_for_id(id, Amico.following_key, Amico.followers_key, scope)
151
- clear_bidirectional_sets_for_id(id, Amico.followers_key, Amico.following_key, scope)
152
- clear_bidirectional_sets_for_id(id, Amico.reciprocated_key, Amico.reciprocated_key, scope)
153
- # no longer blocked by (or blocking) anyone
154
- clear_bidirectional_sets_for_id(id, Amico.blocked_by_key, Amico.blocked_key, scope)
155
- clear_bidirectional_sets_for_id(id, Amico.blocked_key, Amico.blocked_by_key, scope)
156
- # no longer pending with anyone (or have any pending followers)
157
- clear_bidirectional_sets_for_id(id, Amico.pending_with_key, Amico.pending_key, scope)
158
- clear_bidirectional_sets_for_id(id, Amico.pending_key, Amico.pending_with_key, scope)
159
- end
3
+ # Establish a follow relationship between two IDs. After adding the follow
4
+ # relationship, it checks to see if the relationship is reciprocated and establishes that
5
+ # relationship if so.
6
+ #
7
+ # @param from_id [String] The ID of the individual establishing the follow relationship.
8
+ # @param to_id [String] The ID of the individual to be followed.
9
+ # @param scope [String] Scope for the call.
10
+ #
11
+ # Examples
12
+ #
13
+ # Amico.follow(1, 11)
14
+ def follow(from_id, to_id, scope = Amico.default_scope_key)
15
+ return if from_id == to_id
16
+ return if blocked?(to_id, from_id, scope)
17
+ return if Amico.pending_follow && pending?(from_id, to_id, scope)
18
+
19
+ unless Amico.pending_follow
20
+ add_following_followers_reciprocated(from_id, to_id, scope)
21
+ else
22
+ Amico.redis.multi do
23
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
24
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
25
+ end
26
+ end
27
+ end
28
+
29
+ # Remove a follow relationship between two IDs. After removing the follow
30
+ # relationship, if a reciprocated relationship was established, it is
31
+ # also removed.
32
+ #
33
+ # @param from_id [String] The ID of the individual removing the follow relationship.
34
+ # @param to_id [String] The ID of the individual to be unfollowed.
35
+ # @param scope [String] Scope for the call.
36
+ #
37
+ # Examples
38
+ #
39
+ # Amico.follow(1, 11)
40
+ # Amico.unfollow(1, 11)
41
+ def unfollow(from_id, to_id, scope = Amico.default_scope_key)
42
+ return if from_id == to_id
43
+
44
+ Amico.redis.multi do
45
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", to_id)
46
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", from_id)
47
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", to_id)
48
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", from_id)
49
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
50
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
51
+ end
52
+ end
53
+
54
+ # Block a relationship between two IDs. This method also has the side effect
55
+ # of removing any follower or following relationship between the two IDs.
56
+ #
57
+ # @param from_id [String] The ID of the individual blocking the relationship.
58
+ # @param to_id [String] The ID of the individual being blocked.
59
+ # @param scope [String] Scope for the call.
60
+ #
61
+ # Examples
62
+ #
63
+ # Amico.block(1, 11)
64
+ def block(from_id, to_id, scope = Amico.default_scope_key)
65
+ return if from_id == to_id
66
+
67
+ Amico.redis.multi do
68
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", to_id)
69
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{to_id}", from_id)
70
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", from_id)
71
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{from_id}", to_id)
72
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", to_id)
73
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", from_id)
74
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{from_id}", to_id)
75
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{to_id}", from_id)
76
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
77
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
78
+ end
79
+ end
80
+
81
+ # Unblock a relationship between two IDs.
82
+ #
83
+ # @param from_id [String] The ID of the individual unblocking the relationship.
84
+ # @param to_id [String] The ID of the blocked individual.
85
+ # @param scope [String] Scope for the call.
86
+ #
87
+ # Examples
88
+ #
89
+ # Amico.block(1, 11)
90
+ # Amico.unblock(1, 11)
91
+ def unblock(from_id, to_id, scope = Amico.default_scope_key)
92
+ return if from_id == to_id
93
+
94
+ Amico.redis.multi do
95
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{from_id}", to_id)
96
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{to_id}", from_id)
97
+ end
98
+ end
99
+
100
+ # Accept a relationship that is pending between two IDs.
101
+ #
102
+ # @param from_id [String] The ID of the individual accepting the relationship.
103
+ # @param to_id [String] The ID of the individual to be accepted.
104
+ # @param scope [String] Scope for the call.
105
+ #
106
+ # Example
107
+ #
108
+ # Amico.follow(1, 11)
109
+ # Amico.pending?(1, 11) # true
110
+ # Amico.accept(1, 11)
111
+ # Amico.pending?(1, 11) # false
112
+ # Amico.following?(1, 11) #true
113
+ def accept(from_id, to_id, scope = Amico.default_scope_key)
114
+ return if from_id == to_id
115
+
116
+ add_following_followers_reciprocated(from_id, to_id, scope)
117
+ end
118
+
119
+ # Deny a relationship that is pending between two IDs.
120
+ #
121
+ # @param from_id [String] The ID of the individual denying the relationship.
122
+ # @param to_id [String] The ID of the individual to be denied.
123
+ # @param scope [String] Scope for the call.
124
+ #
125
+ # Example
126
+ #
127
+ # Amico.follow(1, 11)
128
+ # Amico.pending?(1, 11) # true
129
+ # Amico.deny(1, 11)
130
+ # Amico.pending?(1, 11) # false
131
+ # Amico.following?(1, 11) #false
132
+ def deny(from_id, to_id, scope = Amico.default_scope_key)
133
+ return if from_id == to_id
134
+
135
+ Amico.redis.multi do
136
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
137
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
138
+ end
139
+ end
140
+
141
+ # Clears all relationships (in either direction) stored for an individual.
142
+ # Helpful to prevent orphaned associations when deleting users.
143
+ #
144
+ # @param id [String] ID of the individual to clear info for.
145
+ # @param scope [String] Scope for the call.
146
+ #
147
+ # Examples
148
+ #
149
+ # Amico.follow(1, 11)
150
+ # Amico.followers_count(11) => 1
151
+ # Amico.clear(1)
152
+ # Amico.followers_count(11) => 0
153
+ def clear(id, scope = Amico.default_scope_key)
154
+ # no longer following (or followed by) anyone
155
+ clear_bidirectional_sets_for_id(id, Amico.following_key, Amico.followers_key, scope)
156
+ clear_bidirectional_sets_for_id(id, Amico.followers_key, Amico.following_key, scope)
157
+ clear_bidirectional_sets_for_id(id, Amico.reciprocated_key, Amico.reciprocated_key, scope)
158
+ # no longer blocked by (or blocking) anyone
159
+ clear_bidirectional_sets_for_id(id, Amico.blocked_by_key, Amico.blocked_key, scope)
160
+ clear_bidirectional_sets_for_id(id, Amico.blocked_key, Amico.blocked_by_key, scope)
161
+ # no longer pending with anyone (or have any pending followers)
162
+ clear_bidirectional_sets_for_id(id, Amico.pending_with_key, Amico.pending_key, scope)
163
+ clear_bidirectional_sets_for_id(id, Amico.pending_key, Amico.pending_with_key, scope)
164
+ end
160
165
 
161
- # Count the number of individuals that someone is following.
162
- #
163
- # @param id [String] ID of the individual to retrieve following count for.
164
- # @param scope [String] Scope for the call.
165
- #
166
- # Examples
167
- #
168
- # Amico.follow(1, 11)
169
- # Amico.following_count(1)
170
- #
171
- # @return the count of the number of individuals that someone is following.
172
- def following_count(id, scope = Amico.default_scope_key)
173
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}")
174
- end
175
-
176
- # Count the number of individuals that are following someone.
177
- #
178
- # @param id [String] ID of the individual to retrieve followers count for.
179
- # @param scope [String] Scope for the call.
180
- #
181
- # Examples
182
- #
183
- # Amico.follow(11, 1)
184
- # Amico.followers_count(1)
185
- #
186
- # @return the count of the number of individuals that are following someone.
187
- def followers_count(id, scope = Amico.default_scope_key)
188
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}")
189
- end
190
-
191
- # Count the number of individuals that someone has blocked.
192
- #
193
- # @param id [String] ID of the individual to retrieve blocked count for.
194
- # @param scope [String] Scope for the call.
195
- #
196
- # Examples
197
- #
198
- # Amico.block(1, 11)
199
- # Amico.blocked_count(1)
200
- #
201
- # @return the count of the number of individuals that someone has blocked.
202
- def blocked_count(id, scope = Amico.default_scope_key)
203
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}")
204
- end
205
-
206
- # Count the number of individuals blocking another.
207
- #
208
- # @param id [String] ID of the individual to retrieve blocked_by count for.
209
- # @param scope [String] Scope for the call.
210
- #
211
- # Examples
212
- #
213
- # Amico.block(1, 11)
214
- # Amico.blocked_by_count(11)
215
- #
216
- # @return the count of the number of individuals blocking someone.
217
- def blocked_by_count(id, scope = Amico.default_scope_key)
218
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}")
219
- end
220
-
221
- # Count the number of individuals that have reciprocated a following relationship.
222
- #
223
- # @param id [String] ID of the individual to retrieve reciprocated following count for.
224
- # @param scope [String] Scope for the call.
225
- #
226
- # Examples
227
- #
228
- # Amico.follow(1, 11)
229
- # Amico.follow(11, 1)
230
- # Amico.reciprocated_count(1)
231
- #
232
- # @return the count of the number of individuals that have reciprocated a following relationship.
233
- def reciprocated_count(id, scope = Amico.default_scope_key)
234
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}")
235
- end
236
-
237
- # Count the number of relationships pending for an individual.
238
- #
239
- # @param id [String] ID of the individual to retrieve pending count for.
240
- # @param scope [String] Scope for the call.
241
- #
242
- # Examples
243
- #
244
- # Amico.follow(11, 1)
245
- # Amico.follow(12, 1)
246
- # Amico.pending_count(1) # 2
247
- #
248
- # @return the count of the number of relationships pending for an individual.
249
- def pending_count(id, scope = Amico.default_scope_key)
250
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}")
251
- end
252
-
253
- # Count the number of relationships an individual has pending with another.
254
- #
255
- # @param id [String] ID of the individual to retrieve pending count for.
256
- # @param scope [String] Scope for the call.
257
- #
258
- # Examples
259
- #
260
- # Amico.follow(1, 11)
261
- # Amico.follow(1, 12)
262
- # Amico.pending_count(1) # 2
263
- #
264
- # @return the count of the number of relationships an individual has pending with another.
265
- def pending_with_count(id, scope = Amico.default_scope_key)
266
- Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}")
267
- end
268
-
269
- # Check to see if one individual is following another individual.
270
- #
271
- # @param id [String] ID of the individual checking the following status.
272
- # @param following_id [String] ID of the individual to see if they are being followed by id.
273
- # @param scope [String] Scope for the call.
274
- #
275
- # Examples
276
- #
277
- # Amico.follow(1, 11)
278
- # Amico.following?(1, 11)
279
- #
280
- # @return true if id is following following_id, false otherwise
281
- def following?(id, following_id, scope = Amico.default_scope_key)
282
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", following_id).nil?
283
- end
284
-
285
- # Check to see if one individual is a follower of another individual.
286
- #
287
- # @param id [String] ID of the individual checking the follower status.
288
- # @param following_id [String] ID of the individual to see if they are following id.
289
- # @param scope [String] Scope for the call.
290
- #
291
- # Examples
292
- #
293
- # Amico.follow(11, 1)
294
- # Amico.follower?(1, 11)
295
- #
296
- # @return true if follower_id is following id, false otherwise
297
- def follower?(id, follower_id, scope = Amico.default_scope_key)
298
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", follower_id).nil?
299
- end
300
-
301
- # Check to see if one individual has blocked another individual.
302
- #
303
- # @param id [String] ID of the individual checking the blocked status.
304
- # @param blocked_id [String] ID of the individual to see if they are blocked by id.
305
- # @param scope [String] Scope for the call.
306
- #
307
- # Examples
308
- #
309
- # Amico.block(1, 11)
310
- # Amico.blocked?(1, 11)
311
- #
312
- # @return true if id has blocked blocked_id, false otherwise
313
- def blocked?(id, blocked_id, scope = Amico.default_scope_key)
314
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", blocked_id).nil?
315
- end
316
-
317
- # Check to see if one individual is blocked by another individual.
318
- #
319
- # @param id [String] ID of the individual checking the blocked by status.
320
- # @param blocked_id [String] ID of the individual to see if they have blocked id.
321
- # @param scope [String] Scope for the call.
322
- #
323
- # Examples
324
- #
325
- # Amico.block(1, 11)
326
- # Amico.blocked_by?(11, 1)
327
- #
328
- # @return true if id is blocked by blocked_by_id, false otherwise
329
- def blocked_by?(id, blocked_by_id, scope = Amico.default_scope_key)
330
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", blocked_by_id).nil?
331
- end
332
-
333
- # Check to see if one individual has reciprocated in following another individual.
334
- #
335
- # @param from_id [String] ID of the individual checking the reciprocated relationship.
336
- # @param to_id [String] ID of the individual to see if they are following from_id.
337
- # @param scope [String] Scope for the call.
338
- #
339
- # Examples
340
- #
341
- # Amico.follow(1, 11)
342
- # Amico.follow(11, 1)
343
- # Amico.reciprocated?(1, 11)
344
- #
345
- # @return true if both individuals are following each other, false otherwise
346
- def reciprocated?(from_id, to_id, scope = Amico.default_scope_key)
347
- following?(from_id, to_id, scope) && following?(to_id, from_id, scope)
348
- end
349
-
350
- # Check to see if one individual has a pending relationship in following another individual.
351
- #
352
- # @param from_id [String] ID of the individual checking the pending relationships.
353
- # @param to_id [String] ID of the individual to see if they are pending a follow from from_id.
354
- # @param scope [String] Scope for the call.
355
- #
356
- # Examples
357
- #
358
- # Amico.follow(1, 11)
359
- # Amico.pending?(1, 11) # true
360
- #
361
- # @return true if the relationship is pending, false otherwise
362
- def pending?(from_id, to_id, scope = Amico.default_scope_key)
363
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id).nil?
364
- end
365
-
366
- # Check to see if one individual has a pending relationship with another.
367
- #
368
- # @param from_id [String] ID of the individual checking the pending relationships.
369
- # @param to_id [String] ID of the individual to see if they are pending an approval from from_id.
370
- # @param scope [String] Scope for the call.
371
- #
372
- # Examples
373
- #
374
- # Amico.follow(1, 11)
375
- # Amico.pending_with?(11, 1) # true
376
- #
377
- # @return true if the relationship is pending, false otherwise
378
- def pending_with?(from_id, to_id, scope = Amico.default_scope_key)
379
- !Amico.redis.zscore("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{to_id}", from_id).nil?
380
- end
381
-
382
- # Retrieve a page of followed individuals for a given ID.
383
- #
384
- # @param id [String] ID of the individual.
385
- # @param page_options [Hash] Options to be passed for retrieving a page of followed individuals.
386
- # @param scope [String] Scope for the call.
387
- #
388
- # Examples
389
- #
390
- # Amico.follow(1, 11)
391
- # Amico.follow(1, 12)
392
- # Amico.following(1, :page => 1)
393
- #
394
- # @return a page of followed individuals for a given ID.
395
- def following(id, page_options = default_paging_options, scope = Amico.default_scope_key)
396
- members("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", page_options)
397
- end
398
-
399
- # Retrieve a page of followers for a given ID.
400
- #
401
- # @param id [String] ID of the individual.
402
- # @param page_options [Hash] Options to be passed for retrieving a page of followers.
403
- # @param scope [String] Scope for the call.
404
- #
405
- # Examples
406
- #
407
- # Amico.follow(11, 1)
408
- # Amico.follow(12, 1)
409
- # Amico.followers(1, :page => 1)
410
- #
411
- # @return a page of followers for a given ID.
412
- def followers(id, page_options = default_paging_options, scope = Amico.default_scope_key)
413
- members("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", page_options)
414
- end
415
-
416
- # Retrieve a page of blocked individuals for a given ID.
417
- #
418
- # @param id [String] ID of the individual.
419
- # @param page_options [Hash] Options to be passed for retrieving a page of blocked individuals.
420
- # @param scope [String] Scope for the call.
421
- #
422
- # Examples
423
- #
424
- # Amico.block(1, 11)
425
- # Amico.block(1, 12)
426
- # Amico.blocked(1, :page => 1)
427
- #
428
- # @return a page of blocked individuals for a given ID.
429
- def blocked(id, page_options = default_paging_options, scope = Amico.default_scope_key)
430
- members("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", page_options)
431
- end
432
-
433
- # Retrieve a page of individuals who have blocked a given ID.
434
- #
435
- # @param id [String] ID of the individual.
436
- # @param page_options [Hash] Options to be passed for retrieving a page of blocking individuals.
437
- # @param scope [String] Scope for the call.
438
- #
439
- # Examples
440
- #
441
- # Amico.block(11, 1)
442
- # Amico.block(12, 1)
443
- # Amico.blocked_by(1, :page => 1)
444
- #
445
- # @return a page of individuals who have blocked a given ID.
446
- def blocked_by(id, page_options = default_paging_options, scope = Amico.default_scope_key)
447
- members("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", page_options)
448
- end
449
-
450
- # Retrieve a page of individuals that have reciprocated a follow for a given ID.
451
- #
452
- # @param id [String] ID of the individual.
453
- # @param page_options [Hash] Options to be passed for retrieving a page of individuals that have reciprocated a follow.
454
- # @param scope [String] Scope for the call.
455
- #
456
- # Examples
457
- #
458
- # Amico.follow(1, 11)
459
- # Amico.follow(1, 12)
460
- # Amico.follow(11, 1)
461
- # Amico.follow(12, 1)
462
- # Amico.reciprocated(1, :page => 1)
463
- #
464
- # @return a page of individuals that have reciprocated a follow for a given ID.
465
- def reciprocated(id, page_options = default_paging_options, scope = Amico.default_scope_key)
466
- members("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}", page_options)
467
- end
468
-
469
- # Retrieve a page of pending relationships for a given ID.
470
- #
471
- # @param id [String] ID of the individual.
472
- # @param page_options [Hash] Options to be passed for retrieving a page of pending relationships.
473
- # @param scope [String] Scope for the call.
474
- #
475
- # Examples
476
- #
477
- # Amico.follow(11, 1)
478
- # Amico.follow(12, 1)
479
- # Amico.pending(1, :page => 1)
480
- #
481
- # @return a page of pending relationships for a given ID.
482
- def pending(id, page_options = default_paging_options, scope = Amico.default_scope_key)
483
- members("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}", page_options)
484
- end
485
-
486
- # Retrieve a page of individuals that are waiting to approve the given ID.
487
- #
488
- # @param id [String] ID of the individual.
489
- # @param page_options [Hash] Options to be passed for retrieving a page of pending relationships.
490
- # @param scope [String] Scope for the call.
491
- #
492
- # Examples
493
- #
494
- # Amico.follow(1, 11)
495
- # Amico.follow(1, 12)
496
- # Amico.pending_with(1, :page => 1)
497
- #
498
- # @return a page of individuals that are waiting to approve the given ID.
499
- def pending_with(id, page_options = default_paging_options, scope = Amico.default_scope_key)
500
- members("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}", page_options)
501
- end
502
-
503
- # Count the number of pages of following relationships for an individual.
504
- #
505
- # @param id [String] ID of the individual.
506
- # @param page_size [int] Page size.
507
- # @param scope [String] Scope for the call.
508
- #
509
- # Examples
510
- #
511
- # Amico.follow(1, 11)
512
- # Amico.follow(1, 12)
513
- # Amico.following_page_count(1)
514
- #
515
- # @return the number of pages of following relationships for an individual.
516
- def following_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
517
- total_pages("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", page_size)
518
- end
519
-
520
- # Count the number of pages of follower relationships for an individual.
521
- #
522
- # @param id [String] ID of the individual.
523
- # @param page_size [int] Page size (default: Amico.page_size).
524
- # @param scope [String] Scope for the call.
525
- #
526
- # Examples
527
- #
528
- # Amico.follow(11, 1)
529
- # Amico.follow(12, 1)
530
- # Amico.followers_page_count(1)
531
- #
532
- # @return the number of pages of follower relationships for an individual.
533
- def followers_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
534
- total_pages("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", page_size)
535
- end
536
-
537
- # Count the number of pages of blocked relationships for an individual.
538
- #
539
- # @param id [String] ID of the individual.
540
- # @param page_size [int] Page size (default: Amico.page_size).
541
- # @param scope [String] Scope for the call.
542
- #
543
- # Examples
544
- #
545
- # Amico.block(1, 11)
546
- # Amico.block(1, 12)
547
- # Amico.blocked_page_count(1)
548
- #
549
- # @return the number of pages of blocked relationships for an individual.
550
- def blocked_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
551
- total_pages("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", page_size)
552
- end
553
-
554
- # Count the number of pages of blocked_by relationships for an individual.
555
- #
556
- # @param id [String] ID of the individual.
557
- # @param page_size [int] Page size (default: Amico.page_size).
558
- # @param scope [String] Scope for the call.
559
- #
560
- # Examples
561
- #
562
- # Amico.block(11, 1)
563
- # Amico.block(12, 1)
564
- # Amico.blocked_by_page_count(1)
565
- #
566
- # @return the number of pages of blocked_by relationships for an individual.
567
- def blocked_by_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
568
- total_pages("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", page_size)
569
- end
570
-
571
- # Count the number of pages of reciprocated relationships for an individual.
572
- #
573
- # @param id [String] ID of the individual.
574
- # @param page_size [int] Page size (default: Amico.page_size).
575
- # @param scope [String] Scope for the call.
576
- #
577
- # Examples
578
- #
579
- # Amico.follow(1, 11)
580
- # Amico.follow(1, 12)
581
- # Amico.follow(11, 1)
582
- # Amico.follow(12, 1)
583
- # Amico.reciprocated_page_count(1)
584
- #
585
- # @return the number of pages of reciprocated relationships for an individual.
586
- def reciprocated_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
587
- total_pages("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}", page_size)
588
- end
589
-
590
- # Count the number of pages of pending relationships for an individual.
591
- #
592
- # @param id [String] ID of the individual.
593
- # @param page_size [int] Page size (default: Amico.page_size).
594
- # @param scope [String] Scope for the call.
595
- #
596
- # Examples
597
- #
598
- # Amico.follow(11, 1)
599
- # Amico.follow(12, 1)
600
- # Amico.pending_page_count(1) # 1
601
- #
602
- # @return the number of pages of pending relationships for an individual.
603
- def pending_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
604
- total_pages("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}", page_size)
605
- end
606
-
607
- # Count the number of pages of individuals waiting to approve another individual.
608
- #
609
- # @param id [String] ID of the individual.
610
- # @param page_size [int] Page size (default: Amico.page_size).
611
- # @param scope [String] Scope for the call.
612
- #
613
- # Examples
614
- #
615
- # Amico.follow(1, 11)
616
- # Amico.follow(1, 12)
617
- # Amico.pending_with_page_count(1) # 1
618
- #
619
- # @return the number of pages of individuals waiting to approve another individual.
620
- def pending_with_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
621
- total_pages("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}", page_size)
622
- end
623
-
624
- # Retrieve all of the individuals for a given id, type (e.g. following) and scope
625
- #
626
- # @param id [String] ID of the individual.
627
- # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
628
- # @param scope [String] Scope for the call.
629
- def all(id, type, scope = Amico.default_scope_key)
630
- validate_relationship_type(type)
631
- count = self.send("#{type.to_s}_count".to_sym, id, scope)
632
- count > 0 ? self.send("#{type}", id, {:page_size => count}, scope) : []
633
- end
634
-
635
- # Retrieve a count of all of a given type of relationship for the specified id.
636
- #
637
- # @param id [String] ID of the individual.
638
- # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
639
- # @param scope [String] Scope for the call.
640
- #
641
- # @return Count of all of a given type of relationship for the specified id.
642
- def count(id, type, scope = Amico.default_scope_key)
643
- validate_relationship_type(type)
644
- self.send("#{type.to_s}_count".to_sym, id, scope)
645
- end
646
-
647
- # Retrieve a page count of a given type of relationship for the specified id.
648
- #
649
- # @param id [String] ID of the individual.
650
- # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
651
- # @param page_size [int] Page size (default: Amico.page_size).
652
- # @param scope [String] Scope for the call.
653
- #
654
- # @return Page count of a given type of relationship for the specified id.
655
- def page_count(id, type, page_size = Amico.page_size, scope = Amico.default_scope_key)
656
- validate_relationship_type(type)
657
- self.send("#{type.to_s}_page_count".to_sym, id, page_size, scope)
658
- end
166
+ # Count the number of individuals that someone is following.
167
+ #
168
+ # @param id [String] ID of the individual to retrieve following count for.
169
+ # @param scope [String] Scope for the call.
170
+ #
171
+ # Examples
172
+ #
173
+ # Amico.follow(1, 11)
174
+ # Amico.following_count(1)
175
+ #
176
+ # @return the count of the number of individuals that someone is following.
177
+ def following_count(id, scope = Amico.default_scope_key)
178
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}")
179
+ end
180
+
181
+ # Count the number of individuals that are following someone.
182
+ #
183
+ # @param id [String] ID of the individual to retrieve followers count for.
184
+ # @param scope [String] Scope for the call.
185
+ #
186
+ # Examples
187
+ #
188
+ # Amico.follow(11, 1)
189
+ # Amico.followers_count(1)
190
+ #
191
+ # @return the count of the number of individuals that are following someone.
192
+ def followers_count(id, scope = Amico.default_scope_key)
193
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}")
194
+ end
195
+
196
+ # Count the number of individuals that someone has blocked.
197
+ #
198
+ # @param id [String] ID of the individual to retrieve blocked count for.
199
+ # @param scope [String] Scope for the call.
200
+ #
201
+ # Examples
202
+ #
203
+ # Amico.block(1, 11)
204
+ # Amico.blocked_count(1)
205
+ #
206
+ # @return the count of the number of individuals that someone has blocked.
207
+ def blocked_count(id, scope = Amico.default_scope_key)
208
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}")
209
+ end
210
+
211
+ # Count the number of individuals blocking another.
212
+ #
213
+ # @param id [String] ID of the individual to retrieve blocked_by count for.
214
+ # @param scope [String] Scope for the call.
215
+ #
216
+ # Examples
217
+ #
218
+ # Amico.block(1, 11)
219
+ # Amico.blocked_by_count(11)
220
+ #
221
+ # @return the count of the number of individuals blocking someone.
222
+ def blocked_by_count(id, scope = Amico.default_scope_key)
223
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}")
224
+ end
225
+
226
+ # Count the number of individuals that have reciprocated a following relationship.
227
+ #
228
+ # @param id [String] ID of the individual to retrieve reciprocated following count for.
229
+ # @param scope [String] Scope for the call.
230
+ #
231
+ # Examples
232
+ #
233
+ # Amico.follow(1, 11)
234
+ # Amico.follow(11, 1)
235
+ # Amico.reciprocated_count(1)
236
+ #
237
+ # @return the count of the number of individuals that have reciprocated a following relationship.
238
+ def reciprocated_count(id, scope = Amico.default_scope_key)
239
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}")
240
+ end
241
+
242
+ # Count the number of relationships pending for an individual.
243
+ #
244
+ # @param id [String] ID of the individual to retrieve pending count for.
245
+ # @param scope [String] Scope for the call.
246
+ #
247
+ # Examples
248
+ #
249
+ # Amico.follow(11, 1)
250
+ # Amico.follow(12, 1)
251
+ # Amico.pending_count(1) # 2
252
+ #
253
+ # @return the count of the number of relationships pending for an individual.
254
+ def pending_count(id, scope = Amico.default_scope_key)
255
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}")
256
+ end
257
+
258
+ # Count the number of relationships an individual has pending with another.
259
+ #
260
+ # @param id [String] ID of the individual to retrieve pending count for.
261
+ # @param scope [String] Scope for the call.
262
+ #
263
+ # Examples
264
+ #
265
+ # Amico.follow(1, 11)
266
+ # Amico.follow(1, 12)
267
+ # Amico.pending_count(1) # 2
268
+ #
269
+ # @return the count of the number of relationships an individual has pending with another.
270
+ def pending_with_count(id, scope = Amico.default_scope_key)
271
+ Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}")
272
+ end
273
+
274
+ # Check to see if one individual is following another individual.
275
+ #
276
+ # @param id [String] ID of the individual checking the following status.
277
+ # @param following_id [String] ID of the individual to see if they are being followed by id.
278
+ # @param scope [String] Scope for the call.
279
+ #
280
+ # Examples
281
+ #
282
+ # Amico.follow(1, 11)
283
+ # Amico.following?(1, 11)
284
+ #
285
+ # @return true if id is following following_id, false otherwise
286
+ def following?(id, following_id, scope = Amico.default_scope_key)
287
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", following_id).nil?
288
+ end
289
+
290
+ # Check to see if one individual is a follower of another individual.
291
+ #
292
+ # @param id [String] ID of the individual checking the follower status.
293
+ # @param following_id [String] ID of the individual to see if they are following id.
294
+ # @param scope [String] Scope for the call.
295
+ #
296
+ # Examples
297
+ #
298
+ # Amico.follow(11, 1)
299
+ # Amico.follower?(1, 11)
300
+ #
301
+ # @return true if follower_id is following id, false otherwise
302
+ def follower?(id, follower_id, scope = Amico.default_scope_key)
303
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", follower_id).nil?
304
+ end
305
+
306
+ # Check to see if one individual has blocked another individual.
307
+ #
308
+ # @param id [String] ID of the individual checking the blocked status.
309
+ # @param blocked_id [String] ID of the individual to see if they are blocked by id.
310
+ # @param scope [String] Scope for the call.
311
+ #
312
+ # Examples
313
+ #
314
+ # Amico.block(1, 11)
315
+ # Amico.blocked?(1, 11)
316
+ #
317
+ # @return true if id has blocked blocked_id, false otherwise
318
+ def blocked?(id, blocked_id, scope = Amico.default_scope_key)
319
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", blocked_id).nil?
320
+ end
321
+
322
+ # Check to see if one individual is blocked by another individual.
323
+ #
324
+ # @param id [String] ID of the individual checking the blocked by status.
325
+ # @param blocked_id [String] ID of the individual to see if they have blocked id.
326
+ # @param scope [String] Scope for the call.
327
+ #
328
+ # Examples
329
+ #
330
+ # Amico.block(1, 11)
331
+ # Amico.blocked_by?(11, 1)
332
+ #
333
+ # @return true if id is blocked by blocked_by_id, false otherwise
334
+ def blocked_by?(id, blocked_by_id, scope = Amico.default_scope_key)
335
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", blocked_by_id).nil?
336
+ end
337
+
338
+ # Check to see if one individual has reciprocated in following another individual.
339
+ #
340
+ # @param from_id [String] ID of the individual checking the reciprocated relationship.
341
+ # @param to_id [String] ID of the individual to see if they are following from_id.
342
+ # @param scope [String] Scope for the call.
343
+ #
344
+ # Examples
345
+ #
346
+ # Amico.follow(1, 11)
347
+ # Amico.follow(11, 1)
348
+ # Amico.reciprocated?(1, 11)
349
+ #
350
+ # @return true if both individuals are following each other, false otherwise
351
+ def reciprocated?(from_id, to_id, scope = Amico.default_scope_key)
352
+ following?(from_id, to_id, scope) && following?(to_id, from_id, scope)
353
+ end
354
+
355
+ # Check to see if one individual has a pending relationship in following another individual.
356
+ #
357
+ # @param from_id [String] ID of the individual checking the pending relationships.
358
+ # @param to_id [String] ID of the individual to see if they are pending a follow from from_id.
359
+ # @param scope [String] Scope for the call.
360
+ #
361
+ # Examples
362
+ #
363
+ # Amico.follow(1, 11)
364
+ # Amico.pending?(1, 11) # true
365
+ #
366
+ # @return true if the relationship is pending, false otherwise
367
+ def pending?(from_id, to_id, scope = Amico.default_scope_key)
368
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id).nil?
369
+ end
370
+
371
+ # Check to see if one individual has a pending relationship with another.
372
+ #
373
+ # @param from_id [String] ID of the individual checking the pending relationships.
374
+ # @param to_id [String] ID of the individual to see if they are pending an approval from from_id.
375
+ # @param scope [String] Scope for the call.
376
+ #
377
+ # Examples
378
+ #
379
+ # Amico.follow(1, 11)
380
+ # Amico.pending_with?(11, 1) # true
381
+ #
382
+ # @return true if the relationship is pending, false otherwise
383
+ def pending_with?(from_id, to_id, scope = Amico.default_scope_key)
384
+ !Amico.redis.zscore("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{to_id}", from_id).nil?
385
+ end
386
+
387
+ # Retrieve a page of followed individuals for a given ID.
388
+ #
389
+ # @param id [String] ID of the individual.
390
+ # @param page_options [Hash] Options to be passed for retrieving a page of followed individuals.
391
+ # @param scope [String] Scope for the call.
392
+ #
393
+ # Examples
394
+ #
395
+ # Amico.follow(1, 11)
396
+ # Amico.follow(1, 12)
397
+ # Amico.following(1, :page => 1)
398
+ #
399
+ # @return a page of followed individuals for a given ID.
400
+ def following(id, page_options = default_paging_options, scope = Amico.default_scope_key)
401
+ members("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", page_options)
402
+ end
403
+
404
+ # Retrieve a page of followers for a given ID.
405
+ #
406
+ # @param id [String] ID of the individual.
407
+ # @param page_options [Hash] Options to be passed for retrieving a page of followers.
408
+ # @param scope [String] Scope for the call.
409
+ #
410
+ # Examples
411
+ #
412
+ # Amico.follow(11, 1)
413
+ # Amico.follow(12, 1)
414
+ # Amico.followers(1, :page => 1)
415
+ #
416
+ # @return a page of followers for a given ID.
417
+ def followers(id, page_options = default_paging_options, scope = Amico.default_scope_key)
418
+ members("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", page_options)
419
+ end
420
+
421
+ # Retrieve a page of blocked individuals for a given ID.
422
+ #
423
+ # @param id [String] ID of the individual.
424
+ # @param page_options [Hash] Options to be passed for retrieving a page of blocked individuals.
425
+ # @param scope [String] Scope for the call.
426
+ #
427
+ # Examples
428
+ #
429
+ # Amico.block(1, 11)
430
+ # Amico.block(1, 12)
431
+ # Amico.blocked(1, :page => 1)
432
+ #
433
+ # @return a page of blocked individuals for a given ID.
434
+ def blocked(id, page_options = default_paging_options, scope = Amico.default_scope_key)
435
+ members("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", page_options)
436
+ end
437
+
438
+ # Retrieve a page of individuals who have blocked a given ID.
439
+ #
440
+ # @param id [String] ID of the individual.
441
+ # @param page_options [Hash] Options to be passed for retrieving a page of blocking individuals.
442
+ # @param scope [String] Scope for the call.
443
+ #
444
+ # Examples
445
+ #
446
+ # Amico.block(11, 1)
447
+ # Amico.block(12, 1)
448
+ # Amico.blocked_by(1, :page => 1)
449
+ #
450
+ # @return a page of individuals who have blocked a given ID.
451
+ def blocked_by(id, page_options = default_paging_options, scope = Amico.default_scope_key)
452
+ members("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", page_options)
453
+ end
454
+
455
+ # Retrieve a page of individuals that have reciprocated a follow for a given ID.
456
+ #
457
+ # @param id [String] ID of the individual.
458
+ # @param page_options [Hash] Options to be passed for retrieving a page of individuals that have reciprocated a follow.
459
+ # @param scope [String] Scope for the call.
460
+ #
461
+ # Examples
462
+ #
463
+ # Amico.follow(1, 11)
464
+ # Amico.follow(1, 12)
465
+ # Amico.follow(11, 1)
466
+ # Amico.follow(12, 1)
467
+ # Amico.reciprocated(1, :page => 1)
468
+ #
469
+ # @return a page of individuals that have reciprocated a follow for a given ID.
470
+ def reciprocated(id, page_options = default_paging_options, scope = Amico.default_scope_key)
471
+ members("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}", page_options)
472
+ end
473
+
474
+ # Retrieve a page of pending relationships for a given ID.
475
+ #
476
+ # @param id [String] ID of the individual.
477
+ # @param page_options [Hash] Options to be passed for retrieving a page of pending relationships.
478
+ # @param scope [String] Scope for the call.
479
+ #
480
+ # Examples
481
+ #
482
+ # Amico.follow(11, 1)
483
+ # Amico.follow(12, 1)
484
+ # Amico.pending(1, :page => 1)
485
+ #
486
+ # @return a page of pending relationships for a given ID.
487
+ def pending(id, page_options = default_paging_options, scope = Amico.default_scope_key)
488
+ members("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}", page_options)
489
+ end
490
+
491
+ # Retrieve a page of individuals that are waiting to approve the given ID.
492
+ #
493
+ # @param id [String] ID of the individual.
494
+ # @param page_options [Hash] Options to be passed for retrieving a page of pending relationships.
495
+ # @param scope [String] Scope for the call.
496
+ #
497
+ # Examples
498
+ #
499
+ # Amico.follow(1, 11)
500
+ # Amico.follow(1, 12)
501
+ # Amico.pending_with(1, :page => 1)
502
+ #
503
+ # @return a page of individuals that are waiting to approve the given ID.
504
+ def pending_with(id, page_options = default_paging_options, scope = Amico.default_scope_key)
505
+ members("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}", page_options)
506
+ end
507
+
508
+ # Count the number of pages of following relationships for an individual.
509
+ #
510
+ # @param id [String] ID of the individual.
511
+ # @param page_size [int] Page size.
512
+ # @param scope [String] Scope for the call.
513
+ #
514
+ # Examples
515
+ #
516
+ # Amico.follow(1, 11)
517
+ # Amico.follow(1, 12)
518
+ # Amico.following_page_count(1)
519
+ #
520
+ # @return the number of pages of following relationships for an individual.
521
+ def following_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
522
+ total_pages("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{id}", page_size)
523
+ end
524
+
525
+ # Count the number of pages of follower relationships for an individual.
526
+ #
527
+ # @param id [String] ID of the individual.
528
+ # @param page_size [int] Page size (default: Amico.page_size).
529
+ # @param scope [String] Scope for the call.
530
+ #
531
+ # Examples
532
+ #
533
+ # Amico.follow(11, 1)
534
+ # Amico.follow(12, 1)
535
+ # Amico.followers_page_count(1)
536
+ #
537
+ # @return the number of pages of follower relationships for an individual.
538
+ def followers_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
539
+ total_pages("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{id}", page_size)
540
+ end
541
+
542
+ # Count the number of pages of blocked relationships for an individual.
543
+ #
544
+ # @param id [String] ID of the individual.
545
+ # @param page_size [int] Page size (default: Amico.page_size).
546
+ # @param scope [String] Scope for the call.
547
+ #
548
+ # Examples
549
+ #
550
+ # Amico.block(1, 11)
551
+ # Amico.block(1, 12)
552
+ # Amico.blocked_page_count(1)
553
+ #
554
+ # @return the number of pages of blocked relationships for an individual.
555
+ def blocked_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
556
+ total_pages("#{Amico.namespace}:#{Amico.blocked_key}:#{scope}:#{id}", page_size)
557
+ end
558
+
559
+ # Count the number of pages of blocked_by relationships for an individual.
560
+ #
561
+ # @param id [String] ID of the individual.
562
+ # @param page_size [int] Page size (default: Amico.page_size).
563
+ # @param scope [String] Scope for the call.
564
+ #
565
+ # Examples
566
+ #
567
+ # Amico.block(11, 1)
568
+ # Amico.block(12, 1)
569
+ # Amico.blocked_by_page_count(1)
570
+ #
571
+ # @return the number of pages of blocked_by relationships for an individual.
572
+ def blocked_by_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
573
+ total_pages("#{Amico.namespace}:#{Amico.blocked_by_key}:#{scope}:#{id}", page_size)
574
+ end
575
+
576
+ # Count the number of pages of reciprocated relationships for an individual.
577
+ #
578
+ # @param id [String] ID of the individual.
579
+ # @param page_size [int] Page size (default: Amico.page_size).
580
+ # @param scope [String] Scope for the call.
581
+ #
582
+ # Examples
583
+ #
584
+ # Amico.follow(1, 11)
585
+ # Amico.follow(1, 12)
586
+ # Amico.follow(11, 1)
587
+ # Amico.follow(12, 1)
588
+ # Amico.reciprocated_page_count(1)
589
+ #
590
+ # @return the number of pages of reciprocated relationships for an individual.
591
+ def reciprocated_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
592
+ total_pages("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{id}", page_size)
593
+ end
594
+
595
+ # Count the number of pages of pending relationships for an individual.
596
+ #
597
+ # @param id [String] ID of the individual.
598
+ # @param page_size [int] Page size (default: Amico.page_size).
599
+ # @param scope [String] Scope for the call.
600
+ #
601
+ # Examples
602
+ #
603
+ # Amico.follow(11, 1)
604
+ # Amico.follow(12, 1)
605
+ # Amico.pending_page_count(1) # 1
606
+ #
607
+ # @return the number of pages of pending relationships for an individual.
608
+ def pending_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
609
+ total_pages("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{id}", page_size)
610
+ end
611
+
612
+ # Count the number of pages of individuals waiting to approve another individual.
613
+ #
614
+ # @param id [String] ID of the individual.
615
+ # @param page_size [int] Page size (default: Amico.page_size).
616
+ # @param scope [String] Scope for the call.
617
+ #
618
+ # Examples
619
+ #
620
+ # Amico.follow(1, 11)
621
+ # Amico.follow(1, 12)
622
+ # Amico.pending_with_page_count(1) # 1
623
+ #
624
+ # @return the number of pages of individuals waiting to approve another individual.
625
+ def pending_with_page_count(id, page_size = Amico.page_size, scope = Amico.default_scope_key)
626
+ total_pages("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{id}", page_size)
627
+ end
628
+
629
+ # Retrieve all of the individuals for a given id, type (e.g. following) and scope
630
+ #
631
+ # @param id [String] ID of the individual.
632
+ # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
633
+ # @param scope [String] Scope for the call.
634
+ def all(id, type, scope = Amico.default_scope_key)
635
+ validate_relationship_type(type)
636
+ count = self.send("#{type.to_s}_count".to_sym, id, scope)
637
+ count > 0 ? self.send("#{type}", id, {:page_size => count}, scope) : []
638
+ end
639
+
640
+ # Retrieve a count of all of a given type of relationship for the specified id.
641
+ #
642
+ # @param id [String] ID of the individual.
643
+ # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
644
+ # @param scope [String] Scope for the call.
645
+ #
646
+ # @return Count of all of a given type of relationship for the specified id.
647
+ def count(id, type, scope = Amico.default_scope_key)
648
+ validate_relationship_type(type)
649
+ self.send("#{type.to_s}_count".to_sym, id, scope)
650
+ end
651
+
652
+ # Retrieve a page count of a given type of relationship for the specified id.
653
+ #
654
+ # @param id [String] ID of the individual.
655
+ # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
656
+ # @param page_size [int] Page size (default: Amico.page_size).
657
+ # @param scope [String] Scope for the call.
658
+ #
659
+ # @return Page count of a given type of relationship for the specified id.
660
+ def page_count(id, type, page_size = Amico.page_size, scope = Amico.default_scope_key)
661
+ validate_relationship_type(type)
662
+ self.send("#{type.to_s}_page_count".to_sym, id, page_size, scope)
663
+ end
659
664
 
660
- private
665
+ private
661
666
 
662
- # Valid relationtionships that can be used in #all, #count, #page_count, etc...
663
- VALID_RELATIONSHIPS = [:following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with]
667
+ # Valid relationtionships that can be used in #all, #count, #page_count, etc...
668
+ VALID_RELATIONSHIPS = [:following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with]
664
669
 
665
- # Ensure that a relationship type is valid.
666
- #
667
- # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
668
- # @raise [StandardError] if the type is not included in VALID_RELATIONSHIPS
669
- def validate_relationship_type(type)
670
- raise "Must be one of #{VALID_RELATIONSHIPS.to_s}" if !VALID_RELATIONSHIPS.include?(type)
671
- end
670
+ # Ensure that a relationship type is valid.
671
+ #
672
+ # @param type [Symbol] One of :following, :followers, :reciprocated, :blocked, :blocked_by, :pending, :pending_with.
673
+ # @raise [StandardError] if the type is not included in VALID_RELATIONSHIPS
674
+ def validate_relationship_type(type)
675
+ raise "Must be one of #{VALID_RELATIONSHIPS.to_s}" if !VALID_RELATIONSHIPS.include?(type)
676
+ end
672
677
 
673
- # Default paging options.
674
- #
675
- # @return a hash of the default paging options.
676
- def default_paging_options
677
- {:page_size => Amico.page_size, :page => 1}
678
- end
679
-
680
- # Add the following, followers and check for a reciprocated relationship. To be used from the
681
- # +follow++ and ++accept++ methods.
682
- #
683
- # @param from_id [String] The ID of the individual establishing the follow relationship.
684
- # @param to_id [String] The ID of the individual to be followed.
685
- def add_following_followers_reciprocated(from_id, to_id, scope)
686
- Amico.redis.multi do
687
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
688
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
689
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
690
- Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
691
- end
692
-
693
- if reciprocated?(from_id, to_id)
694
- Amico.redis.multi do
695
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
696
- Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
697
- end
698
- end
699
- end
700
-
701
- # Removes references to an individual in sets that are named with other individual's keys.
702
- # Assumes two set keys that are used together such as followers/following, blocked/blocked_by, etc...
703
- #
704
- # @param id [String] The ID of the individual to clear info for.
705
- # @param source_set_key [String] The key identifying the souce set to iterate over.
706
- # @param related_set_key [String] The key identifying the sets that the idividual needs to be removed from.
707
- # @param scope [String] Scope for the call.
708
- def clear_bidirectional_sets_for_id(id, source_set_key, related_set_key, scope = Amico.default_scope_key)
709
- Amico.redis.zrange("#{Amico.namespace}:#{source_set_key}:#{scope}:#{id}", 0, -1).each do |related_id|
710
- Amico.redis.zrem("#{Amico.namespace}:#{related_set_key}:#{scope}:#{related_id}", id)
678
+ # Default paging options.
679
+ #
680
+ # @return a hash of the default paging options.
681
+ def default_paging_options
682
+ {:page_size => Amico.page_size, :page => 1}
683
+ end
684
+
685
+ # Add the following, followers and check for a reciprocated relationship. To be used from the
686
+ # +follow+ and +accept+ methods.
687
+ #
688
+ # @param from_id [String] The ID of the individual establishing the follow relationship.
689
+ # @param to_id [String] The ID of the individual to be followed.
690
+ def add_following_followers_reciprocated(from_id, to_id, scope)
691
+ Amico.redis.multi do
692
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.following_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
693
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.followers_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
694
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{scope}:#{to_id}", from_id)
695
+ Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_with_key}:#{scope}:#{from_id}", to_id)
696
+ end
697
+
698
+ if reciprocated?(from_id, to_id)
699
+ Amico.redis.multi do
700
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{from_id}", Time.now.to_i, to_id)
701
+ Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{scope}:#{to_id}", Time.now.to_i, from_id)
702
+ end
703
+ end
704
+ end
705
+
706
+ # Removes references to an individual in sets that are named with other individual's keys.
707
+ # Assumes two set keys that are used together such as followers/following, blocked/blocked_by, etc...
708
+ #
709
+ # @param id [String] The ID of the individual to clear info for.
710
+ # @param source_set_key [String] The key identifying the souce set to iterate over.
711
+ # @param related_set_key [String] The key identifying the sets that the idividual needs to be removed from.
712
+ # @param scope [String] Scope for the call.
713
+ def clear_bidirectional_sets_for_id(id, source_set_key, related_set_key, scope = Amico.default_scope_key)
714
+ Amico.redis.zrange("#{Amico.namespace}:#{source_set_key}:#{scope}:#{id}", 0, -1).each do |related_id|
715
+ Amico.redis.zrem("#{Amico.namespace}:#{related_set_key}:#{scope}:#{related_id}", id)
716
+ end
717
+
718
+ Amico.redis.del("#{Amico.namespace}:#{source_set_key}:#{scope}:#{id}")
711
719
  end
712
- Amico.redis.del("#{Amico.namespace}:#{source_set_key}:#{scope}:#{id}")
713
- end
714
720
 
715
- # Count the total number of pages for a given key in a Redis sorted set.
716
- #
717
- # @param key [String] Redis key.
718
- # @param page_size [int] Page size from which to calculate total pages.
719
- #
720
- # @return total number of pages for a given key in a Redis sorted set.
721
- def total_pages(key, page_size)
722
- (Amico.redis.zcard(key) / page_size.to_f).ceil
723
- end
724
-
725
- # Retrieve a page of items from a Redis sorted set without scores.
726
- #
727
- # @param key [String] Redis key.
728
- # @param options [Hash] Default options for paging.
729
- #
730
- # @return a page of items from a Redis sorted set without scores.
731
- def members(key, options = default_paging_options)
732
- options = default_paging_options.dup.merge!(options)
733
- if options[:page] < 1
734
- options[:page] = 1
735
- end
736
-
737
- if options[:page] > total_pages(key, options[:page_size])
738
- options[:page] = total_pages(key, options[:page_size])
739
- end
740
-
741
- index_for_redis = options[:page] - 1
742
- starting_offset = (index_for_redis * options[:page_size])
743
-
744
- if starting_offset < 0
745
- starting_offset = 0
746
- end
747
-
748
- ending_offset = (starting_offset + options[:page_size]) - 1
749
- Amico.redis.zrevrange(key, starting_offset, ending_offset, :with_scores => false)
750
- end
721
+ # Count the total number of pages for a given key in a Redis sorted set.
722
+ #
723
+ # @param key [String] Redis key.
724
+ # @param page_size [int] Page size from which to calculate total pages.
725
+ #
726
+ # @return total number of pages for a given key in a Redis sorted set.
727
+ def total_pages(key, page_size)
728
+ (Amico.redis.zcard(key) / page_size.to_f).ceil
729
+ end
730
+
731
+ # Retrieve a page of items from a Redis sorted set without scores.
732
+ #
733
+ # @param key [String] Redis key.
734
+ # @param options [Hash] Default options for paging.
735
+ #
736
+ # @return a page of items from a Redis sorted set without scores.
737
+ def members(key, options = default_paging_options)
738
+ options = default_paging_options.dup.merge!(options)
739
+ if options[:page] < 1
740
+ options[:page] = 1
741
+ end
742
+
743
+ if options[:page] > total_pages(key, options[:page_size])
744
+ options[:page] = total_pages(key, options[:page_size])
745
+ end
746
+
747
+ index_for_redis = options[:page] - 1
748
+ starting_offset = (index_for_redis * options[:page_size])
749
+
750
+ if starting_offset < 0
751
+ starting_offset = 0
752
+ end
753
+
754
+ ending_offset = (starting_offset + options[:page_size]) - 1
755
+ Amico.redis.zrevrange(key, starting_offset, ending_offset, :with_scores => false)
756
+ end
751
757
  end
752
758
  end