rate_limiter 0.0.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.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
4
+ .DS_Store
5
+ ._*
6
+ .idea/
7
+ .redcar/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --tty
2
+ --colour
3
+ --format p
data/.rvmrc ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.3-p327@rate_limiter"
8
+
9
+ #
10
+ # Uncomment the following lines if you want to verify rvm version per project
11
+ #
12
+ # rvmrc_rvm_version="1.10.2" # 1.10.1 seams as a safe start
13
+ # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
14
+ # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
15
+ # return 1
16
+ # }
17
+ #
18
+
19
+ #
20
+ # Uncomment following line if you want options to be set only for given project.
21
+ #
22
+ # PROJECT_JRUBY_OPTS=( --1.9 )
23
+ #
24
+ # The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
25
+ #
26
+ # chmod +x ${rvm_path}/hooks/after_use_jruby_opts
27
+ #
28
+
29
+ #
30
+ # First we attempt to load the desired environment directly from the environment
31
+ # file. This is very fast and efficient compared to running through the entire
32
+ # CLI and selector. If you want feedback on which environment was used then
33
+ # insert the word 'use' after --create as this triggers verbose mode.
34
+ #
35
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
36
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
37
+ then
38
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
39
+
40
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
41
+ then
42
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
43
+ fi
44
+ else
45
+ # If the environment file has not yet been created, use the RVM CLI to select.
46
+ if ! rvm --create "$environment_id"
47
+ then
48
+ echo "Failed to create RVM environment '${environment_id}'."
49
+ return 1
50
+ fi
51
+ fi
52
+
53
+ #
54
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
55
+ # it be automatically loaded. Uncomment the following and adjust the filename if
56
+ # necessary.
57
+ #
58
+ # filename=".gems"
59
+ # if [[ -s "$filename" ]]
60
+ # then
61
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
62
+ # fi
63
+
64
+ # If you use bundler, this might be useful to you:
65
+ # if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
66
+ # then
67
+ # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n"
68
+ # gem install bundler
69
+ # fi
70
+ # if [[ -s Gemfile ]] && command -v bundle
71
+ # then
72
+ # bundle install
73
+ # fi
74
+
75
+ if [[ $- == *i* ]] # check for interactive shells
76
+ then
77
+ echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
78
+ else
79
+ echo "Using: $GEM_HOME" # don't use colors in interactive shells
80
+ fi
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * Initial release.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rate_limiter (0.0.1)
5
+ activerecord (~> 3.0)
6
+ railties (~> 3.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ actionpack (3.2.9)
12
+ activemodel (= 3.2.9)
13
+ activesupport (= 3.2.9)
14
+ builder (~> 3.0.0)
15
+ erubis (~> 2.7.0)
16
+ journey (~> 1.0.4)
17
+ rack (~> 1.4.0)
18
+ rack-cache (~> 1.2)
19
+ rack-test (~> 0.6.1)
20
+ sprockets (~> 2.2.1)
21
+ activemodel (3.2.9)
22
+ activesupport (= 3.2.9)
23
+ builder (~> 3.0.0)
24
+ activerecord (3.2.9)
25
+ activemodel (= 3.2.9)
26
+ activesupport (= 3.2.9)
27
+ arel (~> 3.0.2)
28
+ tzinfo (~> 0.3.29)
29
+ activesupport (3.2.9)
30
+ i18n (~> 0.6)
31
+ multi_json (~> 1.0)
32
+ arel (3.0.2)
33
+ builder (3.0.4)
34
+ diff-lcs (1.1.3)
35
+ erubis (2.7.0)
36
+ hike (1.2.1)
37
+ i18n (0.6.1)
38
+ journey (1.0.4)
39
+ json (1.7.5)
40
+ multi_json (1.5.0)
41
+ rack (1.4.1)
42
+ rack-cache (1.2)
43
+ rack (>= 0.4)
44
+ rack-ssl (1.3.2)
45
+ rack
46
+ rack-test (0.6.2)
47
+ rack (>= 1.0)
48
+ railties (3.2.9)
49
+ actionpack (= 3.2.9)
50
+ activesupport (= 3.2.9)
51
+ rack-ssl (~> 1.3.2)
52
+ rake (>= 0.8.7)
53
+ rdoc (~> 3.4)
54
+ thor (>= 0.14.6, < 2.0)
55
+ rake (10.0.2)
56
+ rdoc (3.12)
57
+ json (~> 1.4)
58
+ rspec (2.12.0)
59
+ rspec-core (~> 2.12.0)
60
+ rspec-expectations (~> 2.12.0)
61
+ rspec-mocks (~> 2.12.0)
62
+ rspec-core (2.12.1)
63
+ rspec-expectations (2.12.0)
64
+ diff-lcs (~> 1.1.3)
65
+ rspec-mocks (2.12.0)
66
+ sprockets (2.2.2)
67
+ hike (~> 1.2)
68
+ multi_json (~> 1.0)
69
+ rack (~> 1.0)
70
+ tilt (~> 1.1, != 1.3.0)
71
+ thor (0.16.0)
72
+ tilt (1.3.3)
73
+ tzinfo (0.3.35)
74
+
75
+ PLATFORMS
76
+ ruby
77
+
78
+ DEPENDENCIES
79
+ rate_limiter!
80
+ rspec
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # rate_limiter
2
+
3
+ A gem that limits the rate at which ActiveRecord model instances can be created.
4
+
5
+ ## Rails Version
6
+
7
+ This gem has only been tested on Rails 3.2. There is no reason that I am aware of that would prevent it from working on all versions of Rails 3 (and Rails 4 when it is released).
8
+
9
+ ## Installation
10
+
11
+ Add the gem to your project's Gemfile:
12
+
13
+ gem 'rate_limiter'
14
+
15
+ ## Basic Usage
16
+
17
+ In the models you want to rate limit simply call the `rate_limit` method inside the model.
18
+
19
+ ```ruby
20
+ class ProductReview < ActiveRecord::Base
21
+ rate_limit
22
+ end
23
+ ```
24
+
25
+ By default this will rate limit creation of instances using the `ip_address` attribute with an interval of one minute. This is kind of a bold assumption (that may change in future versions) since there's a good chance you don't have an `ip_address` attribute on your model. If that's the case then you can do the following:
26
+
27
+ ```ruby
28
+ class ProductReview < ActiveRecord::Base
29
+ rate_limit :on => :username
30
+ end
31
+ ```
32
+
33
+ This will instead check for `ProductReview`s with a matching `username` instead.
34
+
35
+ Because you may want to increase or decrease the interval between creating instances of your model you can do this:
36
+
37
+ ```ruby
38
+ class ProductReview < ActiveRecord::Base
39
+ rate_limit :interval => 3.hours
40
+ end
41
+ ```
42
+
43
+ ## Contributing
44
+
45
+ If you feel like you can add something useful to rate_limiter then don't hesitate to contribute! To make sure your fix/feature has a high chance of being included, please do the following:
46
+
47
+ 1. Fork the repo.
48
+
49
+ 2. Run the tests. I will only take pull requests with passing tests, and it's great to know that you have a clean slate: `bundle && rake`
50
+
51
+ 3. Add a test for your change. Only adding tests for existing code, refactoring, and documentation changes require no new tests. If you are adding functionality or fixing a bug, you need a test!
52
+
53
+ 4. Make the test pass.
54
+
55
+ 5. Push to your fork and submit a pull request.
56
+
57
+ I can't guarantee that I will accept the change, but if I don't I will be sure to let you know why!
58
+
59
+ Some things that will increase the chance that your pull request is accepted, taken straight from the Ruby on Rails guide:
60
+
61
+ * Use Rails idioms and helpers
62
+ * Include tests that fail without your code, and pass with it
63
+ * Update the documentation, guides, or whatever is affected by your contribution
64
+
65
+ Yes, I am well aware of the irony of asking for tests when there are effectively none right now. This gem is a work in progress.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,24 @@
1
+ require 'singleton'
2
+
3
+ require 'rate_limiter/config'
4
+ require 'rate_limiter/model'
5
+
6
+ module RateLimiter
7
+ def self.timestamp_field= field_name
8
+ RateLimiter.config.timestamp_field = field_name
9
+ end
10
+
11
+ def self.timestamp_field
12
+ RateLimiter.config.timestamp_field
13
+ end
14
+
15
+ private
16
+
17
+ def self.config
18
+ @@config ||= RateLimiter::Config.instance
19
+ end
20
+ end
21
+
22
+ ActiveSupport.on_load(:active_record) do
23
+ include RateLimiter::Model
24
+ end
@@ -0,0 +1,10 @@
1
+ module RateLimiter
2
+ class Config
3
+ include Singleton
4
+ attr_accessor :timestamp_field
5
+
6
+ def initialize
7
+ @timestamp_field = :created_at
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,52 @@
1
+ module RateLimiter
2
+ module Model
3
+ def self.included(base)
4
+ base.send :extend, ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def rate_limit options = {}
9
+ send :include, InstanceMethods
10
+
11
+ class_attribute :rate_limit_on
12
+ self.rate_limit_on = options[:on] || :ip_address
13
+
14
+ class_attribute :rate_limit_interval
15
+ self.rate_limit_interval = options[:interval] || 1.minute
16
+
17
+ class_attribute :rate_limit_if_condition
18
+ self.rate_limit_if_condition = options[:if]
19
+
20
+ class_attribute :rate_limit_unless_condition
21
+ self.rate_limit_unless_condition = options[:unless]
22
+
23
+ self.before_create :check_rate_limit
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ def check_rate_limit
29
+ if rate_limit?
30
+ klass = self.class
31
+
32
+ others = klass.where("#{klass.rate_limit_on} =? AND created_at >= ?", self.send(klass.rate_limit_on), Time.now - klass.rate_limit_interval)
33
+
34
+ if others.present?
35
+ # TODO: Come up with a better error message.
36
+ self.errors.add(:base, "You cannot create a new #{klass.name.downcase} yet.")
37
+
38
+ false
39
+ else
40
+ true
41
+ end
42
+ else
43
+ true
44
+ end
45
+ end
46
+
47
+ def rate_limit?
48
+ (rate_limit_if_condition.blank? || rate_limit_if_condition.call(self)) && !rate_limit_unless_condition.try(:call, self)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module RateLimiter
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'rate_limiter/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'rate_limiter'
7
+ s.version = RateLimiter::VERSION
8
+ s.authors = ['Sean Eshbaugh']
9
+ s.email = ['seaneshbaugh@gmail.com']
10
+ s.homepage = 'https://github.com/seaneshbaugh/rate_limiter'
11
+ s.summary = 'Adds creation rate limiting to ActiveRecord models.'
12
+ s.description = 'Adds creation rate limiting to ActiveRecord models.'
13
+
14
+ s.rubyforge_project = 'rate_limiter'
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ['lib']
20
+
21
+ s.add_dependency 'railties', '~> 3.0'
22
+ s.add_dependency 'activerecord', '~> 3.0'
23
+
24
+ s.add_development_dependency 'rspec'
25
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper.rb'
3
+
4
+ describe RateLimiter do
5
+ describe 'Sanity Test' do
6
+ it 'should be a Module' do
7
+ RateLimiter.should be_a(Module)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rails/railtie'
4
+ require 'active_record'
5
+
6
+ require 'rate_limiter'
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rate_limiter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sean Eshbaugh
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: railties
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Adds creation rate limiting to ActiveRecord models.
63
+ email:
64
+ - seaneshbaugh@gmail.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - .rvmrc
72
+ - CHANGELOG.md
73
+ - Gemfile
74
+ - Gemfile.lock
75
+ - README.md
76
+ - Rakefile
77
+ - lib/rate_limiter.rb
78
+ - lib/rate_limiter/config.rb
79
+ - lib/rate_limiter/model.rb
80
+ - lib/rate_limiter/version.rb
81
+ - rate_limiter.gemspec
82
+ - spec/rate_limiter/rate_limiter_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: https://github.com/seaneshbaugh/rate_limiter
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project: rate_limiter
104
+ rubygems_version: 1.8.24
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: Adds creation rate limiting to ActiveRecord models.
108
+ test_files:
109
+ - spec/rate_limiter/rate_limiter_spec.rb
110
+ - spec/spec_helper.rb