amico 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +93 -1
- data/lib/amico/configuration.rb +48 -26
- data/lib/amico/relationships.rb +196 -102
- data/lib/amico/version.rb +1 -1
- data/spec/amico/configuration_spec.rb +2 -0
- data/spec/amico/relationships_spec.rb +121 -0
- data/spec/spec_helper.rb +11 -3
- metadata +10 -10
    
        data/.gitignore
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -27,6 +27,8 @@ Amico.configure do |configuration| | |
| 27 27 | 
             
              configuration.followers_key = 'followers'
         | 
| 28 28 | 
             
              configuration.blocked_key = 'blocked'
         | 
| 29 29 | 
             
              configuration.reciprocated_key = 'reciprocated'
         | 
| 30 | 
            +
              configuration.pending_key = 'pending'
         | 
| 31 | 
            +
              configuration.pending_follow = false
         | 
| 30 32 | 
             
              configuration.page_size = 25
         | 
| 31 33 | 
             
            end
         | 
| 32 34 | 
             
            ```
         | 
| @@ -44,6 +46,8 @@ Amico.configure do |configuration| | |
| 44 46 | 
             
              configuration.followers_key = 'followers'
         | 
| 45 47 | 
             
              configuration.blocked_key = 'blocked'
         | 
| 46 48 | 
             
              configuration.reciprocated_key = 'reciprocated'
         | 
| 49 | 
            +
              configuration.pending_key = 'pending'
         | 
| 50 | 
            +
              configuration.pending_follow = false
         | 
| 47 51 | 
             
              configuration.page_size = 25
         | 
| 48 52 | 
             
            end
         | 
| 49 53 |  | 
| @@ -111,10 +115,98 @@ Amico.reciprocated(1) | |
| 111 115 | 
             
             => ["11"]
         | 
| 112 116 | 
             
            ```
         | 
| 113 117 |  | 
| 118 | 
            +
            Use amico (with pending relationships for follow):
         | 
| 119 | 
            +
             | 
| 120 | 
            +
            ```ruby
         | 
| 121 | 
            +
            require 'amico'
         | 
| 122 | 
            +
             => true 
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            Amico.configure do |configuration|
         | 
| 125 | 
            +
              configuration.redis = Redis.new
         | 
| 126 | 
            +
              configuration.namespace = 'amico'
         | 
| 127 | 
            +
              configuration.following_key = 'following'
         | 
| 128 | 
            +
              configuration.followers_key = 'followers'
         | 
| 129 | 
            +
              configuration.blocked_key = 'blocked'
         | 
| 130 | 
            +
              configuration.reciprocated_key = 'reciprocated'
         | 
| 131 | 
            +
              configuration.pending_key = 'pending'
         | 
| 132 | 
            +
              configuration.pending_follow = true
         | 
| 133 | 
            +
              configuration.page_size = 25
         | 
| 134 | 
            +
            end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            Amico.follow(1, 11)
         | 
| 137 | 
            +
             => true 
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            Amico.follow(11, 1)
         | 
| 140 | 
            +
             => true 
         | 
| 141 | 
            +
             | 
| 142 | 
            +
            Amico.pending?(1, 11)
         | 
| 143 | 
            +
             => true 
         | 
| 144 | 
            +
             | 
| 145 | 
            +
            Amico.pending?(11, 1)
         | 
| 146 | 
            +
             => true 
         | 
| 147 | 
            +
             | 
| 148 | 
            +
            Amico.accept(1, 11)
         | 
| 149 | 
            +
             => nil 
         | 
| 150 | 
            +
             | 
| 151 | 
            +
            Amico.pending?(1, 11)
         | 
| 152 | 
            +
             => false 
         | 
| 153 | 
            +
             | 
| 154 | 
            +
            Amico.pending?(11, 1)
         | 
| 155 | 
            +
             => true 
         | 
| 156 | 
            +
             | 
| 157 | 
            +
            Amico.following?(1, 11)
         | 
| 158 | 
            +
             => true 
         | 
| 159 | 
            +
             | 
| 160 | 
            +
            Amico.following?(11, 1)
         | 
| 161 | 
            +
             => false 
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            Amico.follower?(11, 1)
         | 
| 164 | 
            +
             => true 
         | 
| 165 | 
            +
             | 
| 166 | 
            +
            Amico.follower?(1, 11)
         | 
| 167 | 
            +
             => false 
         | 
| 168 | 
            +
             | 
| 169 | 
            +
            Amico.accept(11, 1)
         | 
| 170 | 
            +
             => [1, 1] 
         | 
| 171 | 
            +
             | 
| 172 | 
            +
            Amico.pending?(1, 11)
         | 
| 173 | 
            +
             => false 
         | 
| 174 | 
            +
             | 
| 175 | 
            +
            Amico.pending?(11, 1)
         | 
| 176 | 
            +
             => false 
         | 
| 177 | 
            +
             | 
| 178 | 
            +
            Amico.following?(1, 11)
         | 
| 179 | 
            +
             => true 
         | 
| 180 | 
            +
             | 
| 181 | 
            +
            Amico.following?(11, 1)
         | 
| 182 | 
            +
             => true 
         | 
| 183 | 
            +
             | 
| 184 | 
            +
            Amico.follower?(11, 1)
         | 
| 185 | 
            +
             => true 
         | 
| 186 | 
            +
             | 
| 187 | 
            +
            Amico.follower?(1, 11)
         | 
| 188 | 
            +
             => true 
         | 
| 189 | 
            +
             
         | 
| 190 | 
            +
            Amico.reciprocated?(1, 11)
         | 
| 191 | 
            +
             => true 
         | 
| 192 | 
            +
            ```
         | 
| 193 | 
            +
             | 
| 114 194 | 
             
            ## Documentation 
         | 
| 115 195 |  | 
| 116 196 | 
             
            The source for the [relationships module](https://github.com/agoragames/amico/blob/master/lib/amico/relationships.rb) is well-documented. There are some 
         | 
| 117 | 
            -
            simple examples in the method documentation. You can also refer to the [online documentation](http://rubydoc.info/ | 
| 197 | 
            +
            simple examples in the method documentation. You can also refer to the [online documentation](http://rubydoc.info/github/agoragames/amico/master/frames).
         | 
| 198 | 
            +
             | 
| 199 | 
            +
            ## FAQ?
         | 
| 200 | 
            +
             | 
| 201 | 
            +
            ### Why use Redis sorted sets and not Redis sets?
         | 
| 202 | 
            +
             | 
| 203 | 
            +
            Based on the work I did in developing [leaderboard](https://github.com/agoragames/leaderboard), 
         | 
| 204 | 
            +
            leaderboards backed by Redis, I know I wanted to be able to page through the various relationships. 
         | 
| 205 | 
            +
            This does not seem to be possible given the current set of commands for Redis sets. 
         | 
| 206 | 
            +
             | 
| 207 | 
            +
            Also, by using the "score" in Redis sorted sets that is based on the time of when a relationship 
         | 
| 208 | 
            +
            is established, we can get our "recent friends". It is possible that the scoring function may be 
         | 
| 209 | 
            +
            user-defined in the future to allow for some specific ordering.
         | 
| 118 210 |  | 
| 119 211 | 
             
            ## Contributing to amico
         | 
| 120 212 |  | 
    
        data/lib/amico/configuration.rb
    CHANGED
    
    | @@ -1,28 +1,34 @@ | |
| 1 1 | 
             
            module Amico
         | 
| 2 2 | 
             
              # Configuration settings for Amico.
         | 
| 3 3 | 
             
              module Configuration
         | 
| 4 | 
            -
                #  | 
| 4 | 
            +
                # Redis instance.
         | 
| 5 5 | 
             
                attr_accessor :redis
         | 
| 6 6 |  | 
| 7 | 
            -
                #  | 
| 8 | 
            -
                 | 
| 7 | 
            +
                # Amico namespace for Redis.
         | 
| 8 | 
            +
                attr_writer :namespace
         | 
| 9 9 |  | 
| 10 | 
            -
                #  | 
| 11 | 
            -
                 | 
| 10 | 
            +
                # Key used in Redis for tracking who an individual is following.
         | 
| 11 | 
            +
                attr_writer :following_key
         | 
| 12 12 |  | 
| 13 | 
            -
                #  | 
| 14 | 
            -
                 | 
| 13 | 
            +
                # Key used in Redis for tracking the followers of an individual.
         | 
| 14 | 
            +
                attr_writer :followers_key
         | 
| 15 15 |  | 
| 16 | 
            -
                #  | 
| 17 | 
            -
                 | 
| 16 | 
            +
                # Key used in Redis for tracking who an individual blocks.
         | 
| 17 | 
            +
                attr_writer :blocked_key
         | 
| 18 18 |  | 
| 19 | 
            -
                #  | 
| 20 | 
            -
                 | 
| 19 | 
            +
                # Key used in Redis for tracking who has reciprocated a follow for an individual.
         | 
| 20 | 
            +
                attr_writer :reciprocated_key
         | 
| 21 21 |  | 
| 22 | 
            -
                #  | 
| 23 | 
            -
                 | 
| 22 | 
            +
                # Key used in Redis for tracking pending follow relationships for an individual.
         | 
| 23 | 
            +
                attr_writer :pending_key
         | 
| 24 24 |  | 
| 25 | 
            -
                #  | 
| 25 | 
            +
                # Key used to indicate whether or not a follow should be pending or not.
         | 
| 26 | 
            +
                attr_writer :pending_follow
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                # Page size to be used when paging through the various types of relationships.
         | 
| 29 | 
            +
                attr_writer :page_size
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # Yield self to be able to configure Amico with block-style configuration.
         | 
| 26 32 | 
             
                #
         | 
| 27 33 | 
             
                # Example:
         | 
| 28 34 | 
             
                #
         | 
| @@ -33,50 +39,66 @@ module Amico | |
| 33 39 | 
             
                #     configuration.followers_key = 'followers'
         | 
| 34 40 | 
             
                #     configuration.blocked_key = 'blocked'
         | 
| 35 41 | 
             
                #     configuration.reciprocated_key = 'reciprocated'
         | 
| 42 | 
            +
                #     configuration.pending_key = 'pending'
         | 
| 43 | 
            +
                #     configuration.pending_follow = false
         | 
| 36 44 | 
             
                #     configuration.page_size = 25
         | 
| 37 45 | 
             
                #   end
         | 
| 38 46 | 
             
                def configure
         | 
| 39 47 | 
             
                  yield self
         | 
| 40 48 | 
             
                end
         | 
| 41 49 |  | 
| 42 | 
            -
                #  | 
| 50 | 
            +
                # Amico namespace for Redis.
         | 
| 43 51 | 
             
                #
         | 
| 44 | 
            -
                #  | 
| 52 | 
            +
                # @return the Amico namespace or the default of 'amico' if not set.
         | 
| 45 53 | 
             
                def namespace
         | 
| 46 54 | 
             
                  @namespace ||= 'amico'
         | 
| 47 55 | 
             
                end
         | 
| 48 56 |  | 
| 49 | 
            -
                #  | 
| 57 | 
            +
                # Key used in Redis for tracking who an individual is following.
         | 
| 50 58 | 
             
                #
         | 
| 51 | 
            -
                #  | 
| 59 | 
            +
                # @return the key used in Redis for tracking who an individual is following or the default of 'following' if not set.
         | 
| 52 60 | 
             
                def following_key
         | 
| 53 61 | 
             
                  @following_key ||= 'following'
         | 
| 54 62 | 
             
                end
         | 
| 55 63 |  | 
| 56 | 
            -
                #  | 
| 64 | 
            +
                # Key used in Redis for tracking the followers of an individual.
         | 
| 57 65 | 
             
                #
         | 
| 58 | 
            -
                #  | 
| 66 | 
            +
                # @return the key used in Redis for tracking the followers of an individual or the default of 'followers' if not set.
         | 
| 59 67 | 
             
                def followers_key
         | 
| 60 68 | 
             
                  @followers_key ||= 'followers'
         | 
| 61 69 | 
             
                end
         | 
| 62 70 |  | 
| 63 | 
            -
                #  | 
| 71 | 
            +
                # Key used in Redis for tracking who an individual blocks.
         | 
| 64 72 | 
             
                # 
         | 
| 65 | 
            -
                #  | 
| 73 | 
            +
                # @return the key used in Redis for tracking who an individual blocks or the default of 'blocked' if not set.
         | 
| 66 74 | 
             
                def blocked_key
         | 
| 67 75 | 
             
                  @blocked_key ||= 'blocked'
         | 
| 68 76 | 
             
                end
         | 
| 69 77 |  | 
| 70 | 
            -
                #  | 
| 78 | 
            +
                # Key used in Redis for tracking who has reciprocated a follow for an individual.
         | 
| 71 79 | 
             
                #
         | 
| 72 | 
            -
                #  | 
| 80 | 
            +
                # @return the key used in Redis for tracking who has reciprocated a follow for an individual or the default of 'reciprocated' if not set.
         | 
| 73 81 | 
             
                def reciprocated_key
         | 
| 74 82 | 
             
                  @reciprocated_key ||= 'reciprocated'
         | 
| 75 83 | 
             
                end
         | 
| 76 84 |  | 
| 77 | 
            -
                #  | 
| 85 | 
            +
                # Key used in Redis for tracking pending follow relationships for an individual.
         | 
| 86 | 
            +
                #
         | 
| 87 | 
            +
                # @return the key used in Redis for tracking pending follow relationships for an individual.
         | 
| 88 | 
            +
                def pending_key
         | 
| 89 | 
            +
                  @pending_key ||= 'pending'
         | 
| 90 | 
            +
                end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                # Key used to indicate whether or not a follow should be pending or not.
         | 
| 93 | 
            +
                #
         | 
| 94 | 
            +
                # @return the key used to indicate whether or not a follow should be pending or not.
         | 
| 95 | 
            +
                def pending_follow
         | 
| 96 | 
            +
                  @pending_follow ||= false
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                # Page size to be used when paging through the various types of relationships.
         | 
| 78 100 | 
             
                #
         | 
| 79 | 
            -
                #  | 
| 101 | 
            +
                # @return the page size to be used when paging through the various types of relationships or the default of 25 if not set.
         | 
| 80 102 | 
             
                def page_size
         | 
| 81 103 | 
             
                  @page_size ||= 25
         | 
| 82 104 | 
             
                end
         | 
    
        data/lib/amico/relationships.rb
    CHANGED
    
    | @@ -1,11 +1,11 @@ | |
| 1 1 | 
             
            module Amico
         | 
| 2 2 | 
             
              module Relationships
         | 
| 3 | 
            -
                #  | 
| 4 | 
            -
                # | 
| 5 | 
            -
                # | 
| 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 6 | 
             
                # 
         | 
| 7 | 
            -
                # from_id  | 
| 8 | 
            -
                # to_id | 
| 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 9 | 
             
                #
         | 
| 10 10 | 
             
                # Examples
         | 
| 11 11 | 
             
                #
         | 
| @@ -13,26 +13,21 @@ module Amico | |
| 13 13 | 
             
                def follow(from_id, to_id)
         | 
| 14 14 | 
             
                  return if from_id == to_id
         | 
| 15 15 | 
             
                  return if blocked?(to_id, from_id)
         | 
| 16 | 
            +
                  return if Amico.pending_follow && pending?(from_id, to_id)
         | 
| 16 17 |  | 
| 17 | 
            -
                  Amico. | 
| 18 | 
            -
                     | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
                  if reciprocated?(from_id, to_id)
         | 
| 23 | 
            -
                    Amico.redis.multi do
         | 
| 24 | 
            -
                      Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", Time.now.to_i, to_id)
         | 
| 25 | 
            -
                      Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", Time.now.to_i, from_id)
         | 
| 26 | 
            -
                    end
         | 
| 18 | 
            +
                  unless Amico.pending_follow
         | 
| 19 | 
            +
                    add_following_followers_reciprocated(from_id, to_id)
         | 
| 20 | 
            +
                  else
         | 
| 21 | 
            +
                    Amico.redis.zadd("#{Amico.namespace}:#{Amico.pending_key}:#{to_id}", Time.now.to_i, from_id)
         | 
| 27 22 | 
             
                  end
         | 
| 28 23 | 
             
                end
         | 
| 29 24 |  | 
| 30 | 
            -
                #  | 
| 31 | 
            -
                # | 
| 32 | 
            -
                # | 
| 25 | 
            +
                # Remove a follow relationship between two IDs. After removing the follow 
         | 
| 26 | 
            +
                # relationship, if a reciprocated relationship was established, it is 
         | 
| 27 | 
            +
                # also removed.
         | 
| 33 28 | 
             
                #
         | 
| 34 | 
            -
                # from_id  | 
| 35 | 
            -
                # to_id | 
| 29 | 
            +
                # @param from_id [String] The ID of the individual removing the follow relationship.
         | 
| 30 | 
            +
                # @param to_id [String] The ID of the individual to be unfollowed.
         | 
| 36 31 | 
             
                # 
         | 
| 37 32 | 
             
                # Examples
         | 
| 38 33 | 
             
                #
         | 
| @@ -46,14 +41,15 @@ module Amico | |
| 46 41 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{to_id}", from_id)
         | 
| 47 42 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", to_id)
         | 
| 48 43 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", from_id)
         | 
| 44 | 
            +
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{to_id}", from_id)
         | 
| 49 45 | 
             
                  end
         | 
| 50 | 
            -
                end
         | 
| 46 | 
            +
                end  
         | 
| 51 47 |  | 
| 52 | 
            -
                #  | 
| 53 | 
            -
                # | 
| 48 | 
            +
                # Block a relationship between two IDs. This method also has the side effect 
         | 
| 49 | 
            +
                # of removing any follower or following relationship between the two IDs. 
         | 
| 54 50 | 
             
                #
         | 
| 55 | 
            -
                # from_id  | 
| 56 | 
            -
                # to_id | 
| 51 | 
            +
                # @param from_id [String] The ID of the individual blocking the relationship.
         | 
| 52 | 
            +
                # @param to_id [String] The ID of the individual being blocked.
         | 
| 57 53 | 
             
                #
         | 
| 58 54 | 
             
                # Examples
         | 
| 59 55 | 
             
                #
         | 
| @@ -68,14 +64,15 @@ module Amico | |
| 68 64 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.followers_key}:#{from_id}", to_id)
         | 
| 69 65 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", to_id)
         | 
| 70 66 | 
             
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", from_id)
         | 
| 67 | 
            +
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{from_id}", to_id)
         | 
| 71 68 | 
             
                    Amico.redis.zadd("#{Amico.namespace}:#{Amico.blocked_key}:#{from_id}", Time.now.to_i, to_id)
         | 
| 72 69 | 
             
                  end
         | 
| 73 70 | 
             
                end
         | 
| 74 71 |  | 
| 75 | 
            -
                #  | 
| 72 | 
            +
                # Unblock a relationship between two IDs.
         | 
| 76 73 | 
             
                #
         | 
| 77 | 
            -
                # from_id  | 
| 78 | 
            -
                # to_id | 
| 74 | 
            +
                # @param from_id [String] The ID of the individual unblocking the relationship.
         | 
| 75 | 
            +
                # @param to_id [String] The ID of the blocked individual.
         | 
| 79 76 | 
             
                # 
         | 
| 80 77 | 
             
                # Examples
         | 
| 81 78 | 
             
                # 
         | 
| @@ -87,51 +84,69 @@ module Amico | |
| 87 84 | 
             
                  Amico.redis.zrem("#{Amico.namespace}:#{Amico.blocked_key}:#{from_id}", to_id)
         | 
| 88 85 | 
             
                end
         | 
| 89 86 |  | 
| 90 | 
            -
                #  | 
| 87 | 
            +
                # Accept a relationship that is pending between two IDs.
         | 
| 88 | 
            +
                #
         | 
| 89 | 
            +
                # @param from_id [String] The ID of the individual accepting the relationship.
         | 
| 90 | 
            +
                # @param to_id [String] The ID of the individual to be accepted.
         | 
| 91 | 
            +
                #
         | 
| 92 | 
            +
                # Example
         | 
| 93 | 
            +
                #
         | 
| 94 | 
            +
                #   Amico.follow(1, 11)
         | 
| 95 | 
            +
                #   Amico.pending?(1, 11) # true
         | 
| 96 | 
            +
                #   Amico.accept(1, 11)
         | 
| 97 | 
            +
                #   Amico.pending?(1, 11) # false
         | 
| 98 | 
            +
                #   Amico.following?(1, 11) #true
         | 
| 99 | 
            +
                def accept(from_id, to_id)
         | 
| 100 | 
            +
                  return if from_id == to_id
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  add_following_followers_reciprocated(from_id, to_id)
         | 
| 103 | 
            +
                end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                # Count the number of individuals that someone is following.
         | 
| 91 106 | 
             
                #
         | 
| 92 | 
            -
                # id  | 
| 107 | 
            +
                # @param id [String] ID of the individual to retrieve following count for.
         | 
| 93 108 | 
             
                # 
         | 
| 94 109 | 
             
                # Examples
         | 
| 95 110 | 
             
                # 
         | 
| 96 111 | 
             
                #   Amico.follow(1, 11)
         | 
| 97 112 | 
             
                #   Amico.following_count(1)
         | 
| 98 113 | 
             
                #
         | 
| 99 | 
            -
                #  | 
| 114 | 
            +
                # @return the count of the number of individuals that someone is following.
         | 
| 100 115 | 
             
                def following_count(id)
         | 
| 101 116 | 
             
                  Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:#{id}")
         | 
| 102 117 | 
             
                end
         | 
| 103 118 |  | 
| 104 | 
            -
                #  | 
| 119 | 
            +
                # Count the number of individuals that are following someone.
         | 
| 105 120 | 
             
                #
         | 
| 106 | 
            -
                # id  | 
| 121 | 
            +
                # @param id [String] ID of the individual to retrieve followers count for.
         | 
| 107 122 | 
             
                #
         | 
| 108 123 | 
             
                # Examples
         | 
| 109 124 | 
             
                #
         | 
| 110 125 | 
             
                #   Amico.follow(11, 1)
         | 
| 111 126 | 
             
                #   Amico.followers_count(1)
         | 
| 112 127 | 
             
                # 
         | 
| 113 | 
            -
                #  | 
| 128 | 
            +
                # @return the count of the number of individuals that are following someone.
         | 
| 114 129 | 
             
                def followers_count(id)
         | 
| 115 130 | 
             
                  Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:#{id}")
         | 
| 116 131 | 
             
                end
         | 
| 117 132 |  | 
| 118 | 
            -
                #  | 
| 133 | 
            +
                # Count the number of individuals that someone has blocked.
         | 
| 119 134 | 
             
                #
         | 
| 120 | 
            -
                # id  | 
| 135 | 
            +
                # @param id [String] ID of the individual to retrieve blocked count for.
         | 
| 121 136 | 
             
                # 
         | 
| 122 137 | 
             
                # Examples
         | 
| 123 138 | 
             
                #
         | 
| 124 139 | 
             
                #   Amico.block(1, 11)
         | 
| 125 140 | 
             
                #   Amico.blocked_count(1)
         | 
| 126 141 | 
             
                #
         | 
| 127 | 
            -
                #  | 
| 142 | 
            +
                # @return the count of the number of individuals that someone has blocked.
         | 
| 128 143 | 
             
                def blocked_count(id)
         | 
| 129 144 | 
             
                  Amico.redis.zcard("#{Amico.namespace}:#{Amico.blocked_key}:#{id}")
         | 
| 130 145 | 
             
                end
         | 
| 131 146 |  | 
| 132 | 
            -
                #  | 
| 147 | 
            +
                # Count the number of individuals that have reciprocated a following relationship.
         | 
| 133 148 | 
             
                #
         | 
| 134 | 
            -
                # id  | 
| 149 | 
            +
                # @param id [String] ID of the individual to retrieve reciprocated following count for.
         | 
| 135 150 | 
             
                # 
         | 
| 136 151 | 
             
                # Examples
         | 
| 137 152 | 
             
                # 
         | 
| @@ -139,59 +154,75 @@ module Amico | |
| 139 154 | 
             
                #   Amico.follow(11, 1)
         | 
| 140 155 | 
             
                #   Amico.reciprocated_count(1)
         | 
| 141 156 | 
             
                #
         | 
| 142 | 
            -
                #  | 
| 157 | 
            +
                # @return the count of the number of individuals that have reciprocated a following relationship.
         | 
| 143 158 | 
             
                def reciprocated_count(id)
         | 
| 144 159 | 
             
                  Amico.redis.zcard("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}")
         | 
| 145 160 | 
             
                end
         | 
| 146 161 |  | 
| 147 | 
            -
                #  | 
| 162 | 
            +
                # Count the number of relationships pending for an individual.
         | 
| 148 163 | 
             
                #
         | 
| 149 | 
            -
                # id  | 
| 150 | 
            -
                #  | 
| 164 | 
            +
                # @param id [String] ID of the individual to retrieve pending count for.
         | 
| 165 | 
            +
                # 
         | 
| 166 | 
            +
                # Examples
         | 
| 167 | 
            +
                #
         | 
| 168 | 
            +
                #   Amico.follow(11, 1)
         | 
| 169 | 
            +
                #   Amico.follow(12, 1)
         | 
| 170 | 
            +
                #   Amico.pending_count(1) # 2
         | 
| 171 | 
            +
                #
         | 
| 172 | 
            +
                # @return the count of the number of relationships pending for an individual.
         | 
| 173 | 
            +
                def pending_count(id)
         | 
| 174 | 
            +
                  Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:#{id}")
         | 
| 175 | 
            +
                end
         | 
| 176 | 
            +
             | 
| 177 | 
            +
                # Check to see if one individual is following another individual.
         | 
| 178 | 
            +
                #
         | 
| 179 | 
            +
                # @param id [String] ID of the individual checking the following status.
         | 
| 180 | 
            +
                # @param following_id [String] ID of the individual to see if they are being followed by id.
         | 
| 151 181 | 
             
                #
         | 
| 152 182 | 
             
                # Examples
         | 
| 153 183 | 
             
                #
         | 
| 154 184 | 
             
                #   Amico.follow(1, 11)
         | 
| 155 185 | 
             
                #   Amico.following?(1, 11)
         | 
| 156 186 | 
             
                #
         | 
| 157 | 
            -
                #  | 
| 187 | 
            +
                # @return true if id is following following_id, false otherwise
         | 
| 158 188 | 
             
                def following?(id, following_id)
         | 
| 159 189 | 
             
                  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.following_key}:#{id}", following_id).nil?
         | 
| 160 190 | 
             
                end
         | 
| 161 191 |  | 
| 162 | 
            -
                #  | 
| 192 | 
            +
                # Check to see if one individual is a follower of another individual.
         | 
| 163 193 | 
             
                #
         | 
| 164 | 
            -
                # id  | 
| 165 | 
            -
                # following_id  | 
| 194 | 
            +
                # @param id [String] ID of the individual checking the follower status.
         | 
| 195 | 
            +
                # @param following_id [String] ID of the individual to see if they are following id.
         | 
| 166 196 | 
             
                #
         | 
| 167 197 | 
             
                # Examples
         | 
| 168 198 | 
             
                #
         | 
| 169 199 | 
             
                #   Amico.follow(11, 1)
         | 
| 170 200 | 
             
                #   Amico.follower?(1, 11)
         | 
| 171 | 
            -
                # | 
| 201 | 
            +
                #
         | 
| 202 | 
            +
                # @return true if follower_id is following id, false otherwise
         | 
| 172 203 | 
             
                def follower?(id, follower_id)
         | 
| 173 204 | 
             
                  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.followers_key}:#{id}", follower_id).nil?
         | 
| 174 205 | 
             
                end
         | 
| 175 206 |  | 
| 176 | 
            -
                #  | 
| 207 | 
            +
                # Check to see if one individual has blocked another individual.
         | 
| 177 208 | 
             
                #
         | 
| 178 | 
            -
                # id  | 
| 179 | 
            -
                # blocked_id  | 
| 209 | 
            +
                # @param id [String] ID of the individual checking the blocked status.
         | 
| 210 | 
            +
                # @param blocked_id [String] ID of the individual to see if they are blocked by id.
         | 
| 180 211 | 
             
                #
         | 
| 181 212 | 
             
                # Examples
         | 
| 182 213 | 
             
                # 
         | 
| 183 214 | 
             
                #   Amico.block(1, 11)
         | 
| 184 215 | 
             
                #   Amico.blocked?(1, 11)
         | 
| 185 216 | 
             
                #
         | 
| 186 | 
            -
                #  | 
| 217 | 
            +
                # @return true if id has blocked blocked_id, false otherwise
         | 
| 187 218 | 
             
                def blocked?(id, blocked_id)
         | 
| 188 219 | 
             
                  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", blocked_id).nil?
         | 
| 189 220 | 
             
                end
         | 
| 190 221 |  | 
| 191 | 
            -
                #  | 
| 222 | 
            +
                # Check to see if one individual has reciprocated in following another individual.
         | 
| 192 223 | 
             
                #
         | 
| 193 | 
            -
                # from_id  | 
| 194 | 
            -
                # to_id  | 
| 224 | 
            +
                # @param from_id [String] ID of the individual checking the reciprocated relationship.
         | 
| 225 | 
            +
                # @param to_id [String] ID of the individual to see if they are following from_id.
         | 
| 195 226 | 
             
                #
         | 
| 196 227 | 
             
                # Examples
         | 
| 197 228 | 
             
                #
         | 
| @@ -199,16 +230,30 @@ module Amico | |
| 199 230 | 
             
                #   Amico.follow(11, 1)
         | 
| 200 231 | 
             
                #   Amico.reciprocated?(1, 11)
         | 
| 201 232 | 
             
                #
         | 
| 202 | 
            -
                #  | 
| 233 | 
            +
                # @return true if both individuals are following each other, false otherwise
         | 
| 203 234 | 
             
                def reciprocated?(from_id, to_id)
         | 
| 204 235 | 
             
                  following?(from_id, to_id) && following?(to_id, from_id)
         | 
| 205 236 | 
             
                end
         | 
| 206 237 |  | 
| 207 | 
            -
                #  | 
| 238 | 
            +
                # Check to see if one individual has a pending relationship in following another individual.
         | 
| 208 239 | 
             
                #
         | 
| 209 | 
            -
                #  | 
| 210 | 
            -
                #  | 
| 211 | 
            -
                # | 
| 240 | 
            +
                # @param from_id [String] ID of the individual checking the pending relationships.
         | 
| 241 | 
            +
                # @param to_id [String] ID of the individual to see if they are pending a follow from from_id.
         | 
| 242 | 
            +
                #
         | 
| 243 | 
            +
                # Examples
         | 
| 244 | 
            +
                #
         | 
| 245 | 
            +
                #   Amico.follow(1, 11)
         | 
| 246 | 
            +
                #   Amico.pending?(1, 11) # true
         | 
| 247 | 
            +
                #
         | 
| 248 | 
            +
                # @return true if the relationship is pending, false otherwise
         | 
| 249 | 
            +
                def pending?(from_id, to_id)
         | 
| 250 | 
            +
                  !Amico.redis.zscore("#{Amico.namespace}:#{Amico.pending_key}:#{to_id}", from_id).nil?
         | 
| 251 | 
            +
                end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
                # Retrieve a page of followed individuals for a given ID.
         | 
| 254 | 
            +
                #
         | 
| 255 | 
            +
                # @param id [String] ID of the individual.
         | 
| 256 | 
            +
                # @param options [Hash] Options to be passed for retrieving a page of followed individuals.
         | 
| 212 257 | 
             
                #
         | 
| 213 258 | 
             
                # Examples
         | 
| 214 259 | 
             
                #
         | 
| @@ -216,16 +261,15 @@ module Amico | |
| 216 261 | 
             
                #   Amico.follow(1, 12)
         | 
| 217 262 | 
             
                #   Amico.following(1, :page => 1)
         | 
| 218 263 | 
             
                #
         | 
| 219 | 
            -
                #  | 
| 264 | 
            +
                # @return a page of followed individuals for a given ID.
         | 
| 220 265 | 
             
                def following(id, options = default_options)
         | 
| 221 266 | 
             
                  members("#{Amico.namespace}:#{Amico.following_key}:#{id}", options)
         | 
| 222 267 | 
             
                end
         | 
| 223 268 |  | 
| 224 | 
            -
                #  | 
| 269 | 
            +
                # Retrieve a page of followers for a given ID.
         | 
| 225 270 | 
             
                #
         | 
| 226 | 
            -
                # id  | 
| 227 | 
            -
                # options  | 
| 228 | 
            -
                #           default({:page_size => Amico.page_size, :page => 1})
         | 
| 271 | 
            +
                # @param id [String] ID of the individual.
         | 
| 272 | 
            +
                # @param options [Hash] Options to be passed for retrieving a page of followers.
         | 
| 229 273 | 
             
                #
         | 
| 230 274 | 
             
                # Examples
         | 
| 231 275 | 
             
                # 
         | 
| @@ -233,16 +277,15 @@ module Amico | |
| 233 277 | 
             
                #   Amico.follow(12, 1)
         | 
| 234 278 | 
             
                #   Amico.followers(1, :page => 1)
         | 
| 235 279 | 
             
                #
         | 
| 236 | 
            -
                #  | 
| 280 | 
            +
                # @return a page of followers for a given ID.
         | 
| 237 281 | 
             
                def followers(id, options = default_options)
         | 
| 238 282 | 
             
                  members("#{Amico.namespace}:#{Amico.followers_key}:#{id}", options)
         | 
| 239 283 | 
             
                end
         | 
| 240 284 |  | 
| 241 | 
            -
                #  | 
| 285 | 
            +
                # Retrieve a page of blocked individuals for a given ID.
         | 
| 242 286 | 
             
                #
         | 
| 243 | 
            -
                # id  | 
| 244 | 
            -
                # options  | 
| 245 | 
            -
                #           default({:page_size => Amico.page_size, :page => 1})
         | 
| 287 | 
            +
                # @param id [String] ID of the individual.
         | 
| 288 | 
            +
                # @param options [Hash] Options to be passed for retrieving a page of blocked individuals.
         | 
| 246 289 | 
             
                #
         | 
| 247 290 | 
             
                # Examples
         | 
| 248 291 | 
             
                #
         | 
| @@ -250,16 +293,15 @@ module Amico | |
| 250 293 | 
             
                #   Amico.block(1, 12)
         | 
| 251 294 | 
             
                #   Amico.blocked(1, :page => 1)
         | 
| 252 295 | 
             
                #
         | 
| 253 | 
            -
                #  | 
| 296 | 
            +
                # @return a page of blocked individuals for a given ID.
         | 
| 254 297 | 
             
                def blocked(id, options = default_options)
         | 
| 255 298 | 
             
                  members("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", options)
         | 
| 256 299 | 
             
                end
         | 
| 257 300 |  | 
| 258 | 
            -
                #  | 
| 301 | 
            +
                # Retrieve a page of individuals that have reciprocated a follow for a given ID.
         | 
| 259 302 | 
             
                #
         | 
| 260 | 
            -
                # id  | 
| 261 | 
            -
                # options  | 
| 262 | 
            -
                #           default({:page_size => Amico.page_size, :page => 1})
         | 
| 303 | 
            +
                # @param id [String] ID of the individual.
         | 
| 304 | 
            +
                # @param options [Hash] Options to be passed for retrieving a page of individuals that have reciprocated a follow.
         | 
| 263 305 | 
             
                #
         | 
| 264 306 | 
             
                # Examples
         | 
| 265 307 | 
             
                #
         | 
| @@ -269,15 +311,31 @@ module Amico | |
| 269 311 | 
             
                #   Amico.follow(12, 1)
         | 
| 270 312 | 
             
                #   Amico.reciprocated(1, :page => 1)
         | 
| 271 313 | 
             
                #
         | 
| 272 | 
            -
                #  | 
| 314 | 
            +
                # @return a page of individuals that have reciprocated a follow for a given ID.
         | 
| 273 315 | 
             
                def reciprocated(id, options = default_options)
         | 
| 274 316 | 
             
                  members("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}", options)
         | 
| 275 317 | 
             
                end
         | 
| 276 318 |  | 
| 277 | 
            -
                #  | 
| 319 | 
            +
                # Retrieve a page of pending relationships for a given ID.
         | 
| 278 320 | 
             
                #
         | 
| 279 | 
            -
                # id  | 
| 280 | 
            -
                #  | 
| 321 | 
            +
                # @param id [String] ID of the individual.
         | 
| 322 | 
            +
                # @param options [Hash] Options to be passed for retrieving a page of pending relationships.
         | 
| 323 | 
            +
                #
         | 
| 324 | 
            +
                # Examples
         | 
| 325 | 
            +
                #
         | 
| 326 | 
            +
                #   Amico.follow(1, 11)
         | 
| 327 | 
            +
                #   Amico.follow(2, 11)
         | 
| 328 | 
            +
                #   Amico.pending(1, :page => 1)
         | 
| 329 | 
            +
                #
         | 
| 330 | 
            +
                # @return a page of pending relationships for a given ID.
         | 
| 331 | 
            +
                def pending(id, options = default_options)
         | 
| 332 | 
            +
                  members("#{Amico.namespace}:#{Amico.pending_key}:#{id}", options)
         | 
| 333 | 
            +
                end
         | 
| 334 | 
            +
             | 
| 335 | 
            +
                # Count the number of pages of following relationships for an individual.
         | 
| 336 | 
            +
                #
         | 
| 337 | 
            +
                # @param id [String] ID of the individual.
         | 
| 338 | 
            +
                # @param page_size [int] Page size.
         | 
| 281 339 | 
             
                #
         | 
| 282 340 | 
             
                # Examples
         | 
| 283 341 | 
             
                #
         | 
| @@ -285,15 +343,15 @@ module Amico | |
| 285 343 | 
             
                #   Amico.follow(1, 12)
         | 
| 286 344 | 
             
                #   Amico.following_page_count(1)
         | 
| 287 345 | 
             
                #
         | 
| 288 | 
            -
                #  | 
| 346 | 
            +
                # @return the number of pages of following relationships for an individual.
         | 
| 289 347 | 
             
                def following_page_count(id, page_size = Amico.page_size)
         | 
| 290 348 | 
             
                  total_pages("#{Amico.namespace}:#{Amico.following_key}:#{id}", page_size)
         | 
| 291 349 | 
             
                end
         | 
| 292 350 |  | 
| 293 | 
            -
                #  | 
| 351 | 
            +
                # Count the number of pages of follower relationships for an individual.
         | 
| 294 352 | 
             
                #
         | 
| 295 | 
            -
                # id  | 
| 296 | 
            -
                # page_size  | 
| 353 | 
            +
                # @param id [String] ID of the individual.
         | 
| 354 | 
            +
                # @param page_size [int] Page size (default: Amico.page_size).
         | 
| 297 355 | 
             
                #
         | 
| 298 356 | 
             
                # Examples
         | 
| 299 357 | 
             
                #
         | 
| @@ -301,15 +359,15 @@ module Amico | |
| 301 359 | 
             
                #   Amico.follow(12, 1)
         | 
| 302 360 | 
             
                #   Amico.followers_page_count(1)
         | 
| 303 361 | 
             
                #
         | 
| 304 | 
            -
                #  | 
| 362 | 
            +
                # @return the number of pages of follower relationships for an individual.
         | 
| 305 363 | 
             
                def followers_page_count(id, page_size = Amico.page_size)
         | 
| 306 364 | 
             
                  total_pages("#{Amico.namespace}:#{Amico.followers_key}:#{id}", page_size)
         | 
| 307 365 | 
             
                end
         | 
| 308 366 |  | 
| 309 | 
            -
                #  | 
| 367 | 
            +
                # Count the number of pages of blocked relationships for an individual.
         | 
| 310 368 | 
             
                #
         | 
| 311 | 
            -
                # id  | 
| 312 | 
            -
                # page_size  | 
| 369 | 
            +
                # @param id [String] ID of the individual.
         | 
| 370 | 
            +
                # @param page_size [int] Page size (default: Amico.page_size).
         | 
| 313 371 | 
             
                #
         | 
| 314 372 | 
             
                # Examples
         | 
| 315 373 | 
             
                #
         | 
| @@ -317,15 +375,15 @@ module Amico | |
| 317 375 | 
             
                #   Amico.block(1, 12)
         | 
| 318 376 | 
             
                #   Amico.blocked_page_count(1)
         | 
| 319 377 | 
             
                #    
         | 
| 320 | 
            -
                #  | 
| 378 | 
            +
                # @return the number of pages of blocked relationships for an individual.
         | 
| 321 379 | 
             
                def blocked_page_count(id, page_size = Amico.page_size)
         | 
| 322 380 | 
             
                  total_pages("#{Amico.namespace}:#{Amico.blocked_key}:#{id}", page_size)
         | 
| 323 381 | 
             
                end
         | 
| 324 382 |  | 
| 325 | 
            -
                #  | 
| 383 | 
            +
                # Count the number of pages of reciprocated relationships for an individual.
         | 
| 326 384 | 
             
                #
         | 
| 327 | 
            -
                # id  | 
| 328 | 
            -
                # page_size  | 
| 385 | 
            +
                # @param id [String] ID of the individual.
         | 
| 386 | 
            +
                # @param page_size [int] Page size (default: Amico.page_size).
         | 
| 329 387 | 
             
                #
         | 
| 330 388 | 
             
                # Examples
         | 
| 331 389 | 
             
                #
         | 
| @@ -335,36 +393,72 @@ module Amico | |
| 335 393 | 
             
                #   Amico.follow(12, 1)
         | 
| 336 394 | 
             
                #   Amico.reciprocated_page_count(1)
         | 
| 337 395 | 
             
                #    
         | 
| 338 | 
            -
                #  | 
| 396 | 
            +
                # @return the number of pages of reciprocated relationships for an individual.
         | 
| 339 397 | 
             
                def reciprocated_page_count(id, page_size = Amico.page_size)
         | 
| 340 398 | 
             
                  total_pages("#{Amico.namespace}:#{Amico.reciprocated_key}:#{id}", page_size)
         | 
| 341 399 | 
             
                end
         | 
| 342 400 |  | 
| 401 | 
            +
                # Count the number of pages of pending relationships for an individual.
         | 
| 402 | 
            +
                #
         | 
| 403 | 
            +
                # @param id [String] ID of the individual.
         | 
| 404 | 
            +
                # @param page_size [int] Page size (default: Amico.page_size).
         | 
| 405 | 
            +
                #
         | 
| 406 | 
            +
                # Examples
         | 
| 407 | 
            +
                #
         | 
| 408 | 
            +
                #   Amico.follow(11, 1)
         | 
| 409 | 
            +
                #   Amico.follow(12, 1)
         | 
| 410 | 
            +
                #   Amico.pending_page_count(1) # 1
         | 
| 411 | 
            +
                #    
         | 
| 412 | 
            +
                # @return the number of pages of pending relationships for an individual.
         | 
| 413 | 
            +
                def pending_page_count(id, page_size = Amico.page_size)
         | 
| 414 | 
            +
                  total_pages("#{Amico.namespace}:#{Amico.pending_key}:#{id}", page_size)
         | 
| 415 | 
            +
                end
         | 
| 416 | 
            +
             | 
| 343 417 | 
             
                private
         | 
| 344 418 |  | 
| 345 | 
            -
                #  | 
| 419 | 
            +
                # Add the following, followers and check for a reciprocated relationship. To be used from the 
         | 
| 420 | 
            +
                # +follow++ and ++accept++ methods.
         | 
| 421 | 
            +
                #
         | 
| 422 | 
            +
                # @param from_id [String] The ID of the individual establishing the follow relationship.
         | 
| 423 | 
            +
                # @param to_id [String] The ID of the individual to be followed. 
         | 
| 424 | 
            +
                def add_following_followers_reciprocated(from_id, to_id)
         | 
| 425 | 
            +
                  Amico.redis.multi do
         | 
| 426 | 
            +
                    Amico.redis.zadd("#{Amico.namespace}:#{Amico.following_key}:#{from_id}", Time.now.to_i, to_id)
         | 
| 427 | 
            +
                    Amico.redis.zadd("#{Amico.namespace}:#{Amico.followers_key}:#{to_id}", Time.now.to_i, from_id)
         | 
| 428 | 
            +
                    Amico.redis.zrem("#{Amico.namespace}:#{Amico.pending_key}:#{to_id}", from_id)
         | 
| 429 | 
            +
                  end
         | 
| 430 | 
            +
             | 
| 431 | 
            +
                  if reciprocated?(from_id, to_id)
         | 
| 432 | 
            +
                    Amico.redis.multi do
         | 
| 433 | 
            +
                      Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{from_id}", Time.now.to_i, to_id)
         | 
| 434 | 
            +
                      Amico.redis.zadd("#{Amico.namespace}:#{Amico.reciprocated_key}:#{to_id}", Time.now.to_i, from_id)
         | 
| 435 | 
            +
                    end
         | 
| 436 | 
            +
                  end      
         | 
| 437 | 
            +
                end
         | 
| 438 | 
            +
             | 
| 439 | 
            +
                # Default options for doing, for example, paging.
         | 
| 346 440 | 
             
                #
         | 
| 347 | 
            -
                #  | 
| 441 | 
            +
                # @return a hash of the default options.
         | 
| 348 442 | 
             
                def default_options
         | 
| 349 443 | 
             
                  {:page_size => Amico.page_size, :page => 1}
         | 
| 350 444 | 
             
                end
         | 
| 351 445 |  | 
| 352 | 
            -
                #  | 
| 446 | 
            +
                # Count the total number of pages for a given key in a Redis sorted set.
         | 
| 353 447 | 
             
                #
         | 
| 354 | 
            -
                # key  | 
| 355 | 
            -
                # page_size  | 
| 448 | 
            +
                # @param key [String] Redis key.
         | 
| 449 | 
            +
                # @param page_size [int] Page size from which to calculate total pages.
         | 
| 356 450 | 
             
                #
         | 
| 357 | 
            -
                #  | 
| 451 | 
            +
                # @return total number of pages for a given key in a Redis sorted set.
         | 
| 358 452 | 
             
                def total_pages(key, page_size)
         | 
| 359 453 | 
             
                  (Amico.redis.zcard(key) / page_size.to_f).ceil
         | 
| 360 454 | 
             
                end
         | 
| 361 455 |  | 
| 362 | 
            -
                #  | 
| 456 | 
            +
                # Retrieve a page of items from a Redis sorted set without scores.
         | 
| 363 457 | 
             
                #
         | 
| 364 | 
            -
                # key  | 
| 365 | 
            -
                # options  | 
| 458 | 
            +
                # @param key [String] Redis key.
         | 
| 459 | 
            +
                # @param options [Hash] Default options for paging.
         | 
| 366 460 | 
             
                #
         | 
| 367 | 
            -
                #  | 
| 461 | 
            +
                # @return a page of items from a Redis sorted set without scores.
         | 
| 368 462 | 
             
                def members(key, options = default_options)
         | 
| 369 463 | 
             
                  options = default_options.dup.merge!(options)
         | 
| 370 464 | 
             
                  if options[:page] < 1
         | 
    
        data/lib/amico/version.rb
    CHANGED
    
    
| @@ -9,6 +9,8 @@ describe Amico::Configuration do | |
| 9 9 | 
             
                    configuration.followers_key.should eql('followers')
         | 
| 10 10 | 
             
                    configuration.blocked_key.should eql('blocked')
         | 
| 11 11 | 
             
                    configuration.reciprocated_key.should eql('reciprocated')
         | 
| 12 | 
            +
                    configuration.pending_key.should eql('pending')
         | 
| 13 | 
            +
                    configuration.pending_follow.should be_false
         | 
| 12 14 | 
             
                    configuration.page_size.should be(25)
         | 
| 13 15 | 
             
                  end
         | 
| 14 16 | 
             
                end
         | 
| @@ -269,6 +269,127 @@ describe Amico::Relationships do | |
| 269 269 | 
             
                end
         | 
| 270 270 | 
             
              end
         | 
| 271 271 |  | 
| 272 | 
            +
              describe 'pending_follow enabled' do
         | 
| 273 | 
            +
                before(:each) do
         | 
| 274 | 
            +
                  Amico.pending_follow = true
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                after(:each) do
         | 
| 278 | 
            +
                  Amico.pending_follow = false
         | 
| 279 | 
            +
                end
         | 
| 280 | 
            +
             | 
| 281 | 
            +
                describe '#follow' do
         | 
| 282 | 
            +
                  it 'should allow you to follow but the relationship is initially pending' do
         | 
| 283 | 
            +
                    Amico.follow(1, 11)
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(0)
         | 
| 286 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:11").should be(0)
         | 
| 287 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:11").should be(1)
         | 
| 288 | 
            +
                  end
         | 
| 289 | 
            +
             | 
| 290 | 
            +
                  it 'should remove the pending relationship if you have a pending follow, but you unfollow' do
         | 
| 291 | 
            +
                    Amico.follow(1, 11)
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(0)
         | 
| 294 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:11").should be(0)
         | 
| 295 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:11").should be(1)
         | 
| 296 | 
            +
             | 
| 297 | 
            +
                    Amico.unfollow(1, 11)
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.following_key}:1").should be(0)
         | 
| 300 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.followers_key}:11").should be(0)
         | 
| 301 | 
            +
                    Amico.redis.zcard("#{Amico.namespace}:#{Amico.pending_key}:11").should be(0)
         | 
| 302 | 
            +
                  end
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                  it 'should remove the pending relationship and add to following and followers if #accept is called' do
         | 
| 305 | 
            +
                    Amico.follow(1, 11)
         | 
| 306 | 
            +
                    Amico.pending?(1, 11).should be_true
         | 
| 307 | 
            +
             | 
| 308 | 
            +
                    Amico.accept(1, 11)
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                    Amico.pending?(1, 11).should be_false
         | 
| 311 | 
            +
                    Amico.following?(1, 11).should be_true
         | 
| 312 | 
            +
                    Amico.following?(11, 1).should be_false
         | 
| 313 | 
            +
                    Amico.follower?(11, 1).should be_true
         | 
| 314 | 
            +
                    Amico.follower?(1, 11).should be_false
         | 
| 315 | 
            +
                  end
         | 
| 316 | 
            +
             | 
| 317 | 
            +
                  it 'should remove the pending relationship and add to following and followers if #accept is called and add to reciprocated relationship' do
         | 
| 318 | 
            +
                    Amico.follow(1, 11)
         | 
| 319 | 
            +
                    Amico.follow(11, 1)
         | 
| 320 | 
            +
                    Amico.pending?(1, 11).should be_true
         | 
| 321 | 
            +
                    Amico.pending?(11, 1).should be_true
         | 
| 322 | 
            +
             | 
| 323 | 
            +
                    Amico.accept(1, 11)
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                    Amico.pending?(1, 11).should be_false
         | 
| 326 | 
            +
                    Amico.pending?(11, 1).should be_true
         | 
| 327 | 
            +
                    Amico.following?(1, 11).should be_true
         | 
| 328 | 
            +
                    Amico.following?(11, 1).should be_false
         | 
| 329 | 
            +
                    Amico.follower?(11, 1).should be_true
         | 
| 330 | 
            +
                    Amico.follower?(1, 11).should be_false
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                    Amico.accept(11, 1)
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                    Amico.pending?(1, 11).should be_false
         | 
| 335 | 
            +
                    Amico.pending?(11, 1).should be_false
         | 
| 336 | 
            +
                    Amico.following?(1, 11).should be_true
         | 
| 337 | 
            +
                    Amico.following?(11, 1).should be_true
         | 
| 338 | 
            +
                    Amico.follower?(11, 1).should be_true
         | 
| 339 | 
            +
                    Amico.follower?(1, 11).should be_true
         | 
| 340 | 
            +
                    Amico.reciprocated?(1, 11).should be_true
         | 
| 341 | 
            +
                  end
         | 
| 342 | 
            +
                end
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                describe '#block' do
         | 
| 345 | 
            +
                  it 'should remove the pending relationship if you block someone' do
         | 
| 346 | 
            +
                    Amico.follow(11, 1)
         | 
| 347 | 
            +
                    Amico.pending?(11, 1).should be_true
         | 
| 348 | 
            +
                    Amico.block(1, 11)
         | 
| 349 | 
            +
                    Amico.pending?(11, 1).should be_false
         | 
| 350 | 
            +
                    Amico.blocked?(1, 11).should be_true
         | 
| 351 | 
            +
                  end
         | 
| 352 | 
            +
                end
         | 
| 353 | 
            +
             | 
| 354 | 
            +
                describe '#pending' do
         | 
| 355 | 
            +
                  it 'should return the correct list' do
         | 
| 356 | 
            +
                    Amico.follow(1, 11)
         | 
| 357 | 
            +
                    Amico.follow(11, 1)
         | 
| 358 | 
            +
                    Amico.pending(1).should eql(["11"])
         | 
| 359 | 
            +
                    Amico.pending(11).should eql(["1"])
         | 
| 360 | 
            +
                  end
         | 
| 361 | 
            +
             | 
| 362 | 
            +
                  it 'should page correctly' do
         | 
| 363 | 
            +
                    add_reciprocal_followers
         | 
| 364 | 
            +
             | 
| 365 | 
            +
                    Amico.pending(1, :page => 1, :page_size => 5).size.should be(5)
         | 
| 366 | 
            +
                    Amico.pending(1, :page => 1, :page_size => 10).size.should be(10)
         | 
| 367 | 
            +
                    Amico.pending(1, :page => 1, :page_size => 26).size.should be(25)
         | 
| 368 | 
            +
                  end
         | 
| 369 | 
            +
                end
         | 
| 370 | 
            +
             | 
| 371 | 
            +
                describe '#pending_count' do
         | 
| 372 | 
            +
                  it 'should return the correct count' do
         | 
| 373 | 
            +
                    Amico.follow(1, 11)
         | 
| 374 | 
            +
                    Amico.follow(11, 1)
         | 
| 375 | 
            +
                    Amico.follow(1, 12)
         | 
| 376 | 
            +
                    Amico.follow(12, 1)
         | 
| 377 | 
            +
                    Amico.follow(1, 13)
         | 
| 378 | 
            +
                    Amico.pending_count(1).should be(2)
         | 
| 379 | 
            +
                  end
         | 
| 380 | 
            +
                end
         | 
| 381 | 
            +
             | 
| 382 | 
            +
                describe '#pending_page_count' do
         | 
| 383 | 
            +
                  it 'should return the correct count' do
         | 
| 384 | 
            +
                    add_reciprocal_followers
         | 
| 385 | 
            +
             | 
| 386 | 
            +
                    Amico.pending_page_count(1).should be(1)
         | 
| 387 | 
            +
                    Amico.pending_page_count(1, 10).should be(3)
         | 
| 388 | 
            +
                    Amico.pending_page_count(1, 5).should be(5)
         | 
| 389 | 
            +
                  end
         | 
| 390 | 
            +
                end
         | 
| 391 | 
            +
              end
         | 
| 392 | 
            +
             | 
| 272 393 | 
             
              private
         | 
| 273 394 |  | 
| 274 395 | 
             
              def add_reciprocal_followers(count = 26, block_relationship = false)
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | @@ -4,11 +4,19 @@ require 'amico' | |
| 4 4 | 
             
            Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
         | 
| 5 5 |  | 
| 6 6 | 
             
            RSpec.configure do |config|
         | 
| 7 | 
            -
              config.before(: | 
| 7 | 
            +
              config.before(:all) do
         | 
| 8 8 | 
             
                Amico.configure do |configuration|
         | 
| 9 | 
            -
                  redis = Redis.new
         | 
| 10 | 
            -
                  redis.flushall
         | 
| 9 | 
            +
                  redis = Redis.new(:db => 15)
         | 
| 11 10 | 
             
                  configuration.redis = redis
         | 
| 12 11 | 
             
                end
         | 
| 13 12 | 
             
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              config.before(:each) do
         | 
| 15 | 
            +
                Amico.redis.flushdb
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              config.after(:all) do
         | 
| 19 | 
            +
              	Amico.redis.flushdb
         | 
| 20 | 
            +
                Amico.redis.quit
         | 
| 21 | 
            +
              end
         | 
| 14 22 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: amico
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.2.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012- | 
| 12 | 
            +
            date: 2012-02-22 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: redis
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &2157986940 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ! '>='
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: '0'
         | 
| 22 22 | 
             
              type: :runtime
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *2157986940
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: rake
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &2157986520 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ! '>='
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: '0'
         | 
| 33 33 | 
             
              type: :development
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *2157986520
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: rspec
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &2157986100 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -43,7 +43,7 @@ dependencies: | |
| 43 43 | 
             
                    version: '0'
         | 
| 44 44 | 
             
              type: :development
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *2157986100
         | 
| 47 47 | 
             
            description: Relationships (e.g. friendships) backed by Redis
         | 
| 48 48 | 
             
            email:
         | 
| 49 49 | 
             
            - dczarnecki@agoragames.com
         | 
| @@ -81,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 81 81 | 
             
                  version: '0'
         | 
| 82 82 | 
             
                  segments:
         | 
| 83 83 | 
             
                  - 0
         | 
| 84 | 
            -
                  hash:  | 
| 84 | 
            +
                  hash: 4319511261827775332
         | 
| 85 85 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 86 86 | 
             
              none: false
         | 
| 87 87 | 
             
              requirements:
         | 
| @@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 90 90 | 
             
                  version: '0'
         | 
| 91 91 | 
             
                  segments:
         | 
| 92 92 | 
             
                  - 0
         | 
| 93 | 
            -
                  hash:  | 
| 93 | 
            +
                  hash: 4319511261827775332
         | 
| 94 94 | 
             
            requirements: []
         | 
| 95 95 | 
             
            rubyforge_project: amico
         | 
| 96 96 | 
             
            rubygems_version: 1.8.10
         |