amico 2.3.0 → 2.3.1

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.
@@ -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