the_viking 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/Rakefile +7 -0
- data/gem_version.rb +3 -0
- data/lib/core_ext/object.rb +15 -0
- data/lib/core_ext/transformations.rb +35 -0
- data/lib/the_viking.rb +80 -0
- data/lib/the_viking/akismet.rb +203 -0
- data/lib/the_viking/base.rb +74 -0
- data/lib/the_viking/version.rb +1 -0
- data/spec/core_ext/object_spec.rb +21 -0
- data/spec/core_ext/transformations_spec.rb +41 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/viking/akismet_spec.rb +99 -0
- data/spec/viking/base_spec.rb +47 -0
- data/spec/viking/viking_spec.rb +35 -0
- data/the_viking.gemspec +22 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 61b5ca2605b4bc43665fdafcf0cde34cb65f3ca5
|
4
|
+
data.tar.gz: 7774d1f91ba3dfd013d422d267a53b7268bd5c10
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 04156c163c1414dc988c6352aedbcbd5e8c769db9ba8dc6b08e9e61971820c0fceffd66e9f0c61ae56a0e7b519fa7c2b586b217f770ceedbe2f4d4fa58396bc3
|
7
|
+
data.tar.gz: 2e8f84c1b424326948e7ea418a944503d28c8d589db7d3a26d4f73976f0c7ff09a1a37db7624af2ed52e18252a660c5ee11619cb9a787646c70ceebb7b69cbb3
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Risk Danger Olson, James Herdman & Pierre-Louis Gottfrois
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
### TheViking 1.0
|
2
|
+
|
3
|
+
Akismet anti-spam service for Ruby and Rails
|
4
|
+
|
5
|
+
====
|
6
|
+
|
7
|
+
1. TheViking - **is repack** of [Viking gem](https://github.com/dimelo/viking) without support of Defensio anti-spam service
|
8
|
+
2. [Viking gem](https://github.com/dimelo/viking) is a fork of [Vikinggem](https://rubygems.org/gems/vikinggem). Bug fix and new feature for this gem should be place here.
|
9
|
+
|
10
|
+
### Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'the_viking'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```sh
|
21
|
+
bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
```sh
|
27
|
+
gem install the_viking
|
28
|
+
```
|
29
|
+
|
30
|
+
### Usage
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
@vik = TheViking::Akismet.new(api_key: '1234', blog: 'http://foo.com')
|
34
|
+
```
|
35
|
+
|
36
|
+
### Spam or ham ?
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
@vik.check_comment(
|
40
|
+
user_ip: '111.222.333.444',
|
41
|
+
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:33.0) Gecko/20100101 Firefox/33.0',
|
42
|
+
comment_author: 'Spammer Bot',
|
43
|
+
comment_author_email: 'spam@spam-server.com',
|
44
|
+
comment_content: 'Hello! <a href='http://viagra-for-u.xxx'>I am spammer! Click it!</a>'
|
45
|
+
)
|
46
|
+
|
47
|
+
# additional options
|
48
|
+
#
|
49
|
+
# referrer
|
50
|
+
# comment_author_url
|
51
|
+
# permalink - url of commented page
|
52
|
+
# comment_type - may be blank, comment, trackback, pingback, or a made up value like
|
53
|
+
```
|
54
|
+
|
55
|
+
## History
|
56
|
+
|
57
|
+
### TheViking 1.0.0
|
58
|
+
|
59
|
+
4 dec 2015, repack by github.com/the-teacher
|
60
|
+
|
61
|
+
### 1.0.0 2013-03-04
|
62
|
+
|
63
|
+
* Recreated new gem using current standards
|
64
|
+
* Fix some bugs
|
65
|
+
|
66
|
+
### 0.0.3 2008-04-25
|
67
|
+
|
68
|
+
* Made contents of script/ executable
|
69
|
+
|
70
|
+
### 0.0.2 2008-04-22
|
71
|
+
|
72
|
+
* Changed Manifest to include spec_helper.rb and website
|
73
|
+
|
74
|
+
### 0.0.1 2008-04-22
|
75
|
+
|
76
|
+
* Initial release
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
1. Fork it
|
81
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
82
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
83
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
84
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/gem_version.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Hash
|
2
|
+
unless method_defined?(:symbolize_keys)
|
3
|
+
def symbolize_keys
|
4
|
+
inject({}) do |options, (key, value)|
|
5
|
+
options[(key.to_sym rescue key) || key] = value
|
6
|
+
options
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
unless method_defined?(:dasherize_keys)
|
12
|
+
def dasherize_keys
|
13
|
+
inject({}) do |options, (key, value)|
|
14
|
+
options[key.to_s.gsub(/_/, '-')] = value
|
15
|
+
options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
unless method_defined?(:to_query) && method(:to_query).arity == -1
|
21
|
+
def to_query(namespace=nil)
|
22
|
+
collect do |key, value|
|
23
|
+
value.to_query(namespace ? "#{namespace}[#{key}]" : key)
|
24
|
+
end.sort * '&'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Array
|
30
|
+
unless method_defined?(:to_query) && method(:to_query).arity == -1
|
31
|
+
def to_query(key)
|
32
|
+
collect { |value| value.to_query("#{key}[]") } * '&'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/the_viking.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require "core_ext/object"
|
2
|
+
require "core_ext/transformations"
|
3
|
+
require "the_viking/version"
|
4
|
+
|
5
|
+
# = Description
|
6
|
+
# Provides a simple interface to polymorphically access to the spam protection
|
7
|
+
# service of your choice.
|
8
|
+
#
|
9
|
+
# = Usage
|
10
|
+
# I find it useful to first initialize TheViking in a separate file during
|
11
|
+
# framework initialization. Rails initializers, for instance, work great for
|
12
|
+
# this. An example of such an initializer would be as follows:
|
13
|
+
#
|
14
|
+
# TheViking.default_engine = 'akismet'
|
15
|
+
# TheViking.connect_options = { :api_key => '1234abc' }
|
16
|
+
#
|
17
|
+
# From this point out, TheViking should have everything it needs to access the
|
18
|
+
# service of your choice. Merely call methods on your service of choice as
|
19
|
+
# documented. For instance:
|
20
|
+
#
|
21
|
+
# TheViking.mark_as_spam(:signaturs => "1234abc")
|
22
|
+
module TheViking
|
23
|
+
class Error < StandardError; end
|
24
|
+
|
25
|
+
autoload :Akismet, 'the_viking/akismet'
|
26
|
+
|
27
|
+
class << self
|
28
|
+
|
29
|
+
attr_accessor :logger
|
30
|
+
attr_accessor :default_engine
|
31
|
+
attr_accessor :connect_options
|
32
|
+
attr_writer :default_instance
|
33
|
+
|
34
|
+
def default_instance
|
35
|
+
@default_instance ||= connect(self.default_engine, self.connect_options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def enabled?
|
39
|
+
!self.default_instance.nil?
|
40
|
+
end
|
41
|
+
|
42
|
+
def connect(engine, options)
|
43
|
+
engine = engine.to_s
|
44
|
+
if !engine.empty?
|
45
|
+
TheViking.const_get(engine.capitalize).new(options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def verified?
|
50
|
+
self.default_instance.verified?
|
51
|
+
end
|
52
|
+
|
53
|
+
def check_article(options = {})
|
54
|
+
self.default_instance.check_article(options)
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_comment(options = {})
|
58
|
+
self.default_instance.check_comment(options)
|
59
|
+
end
|
60
|
+
|
61
|
+
def mark_as_spam(options = {})
|
62
|
+
self.default_instance.mark_as_spam(options)
|
63
|
+
end
|
64
|
+
|
65
|
+
def mark_as_ham(options = {})
|
66
|
+
self.default_instance.mark_as_ham(options)
|
67
|
+
end
|
68
|
+
|
69
|
+
def stats
|
70
|
+
self.default_instance.stats
|
71
|
+
end
|
72
|
+
|
73
|
+
def mark_as_spam_or_ham(is_spam, options = {})
|
74
|
+
self.default_instance.mark_as_spam_or_ham(is_spam, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
require "the_viking/base"
|
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
# Akismet
|
6
|
+
#
|
7
|
+
# Author:: David Czarnecki
|
8
|
+
# Copyright:: Copyright (c) 2005 - David Czarnecki
|
9
|
+
# License:: BSD
|
10
|
+
#
|
11
|
+
# Rewritten to be more agnostic
|
12
|
+
module TheViking
|
13
|
+
class Akismet < Base
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
attr_accessor :valid_responses
|
18
|
+
attr_accessor :normal_responses
|
19
|
+
attr_accessor :standard_headers
|
20
|
+
attr_accessor :host
|
21
|
+
attr_accessor :port
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
self.host = 'rest.akismet.com'
|
26
|
+
self.port = 80
|
27
|
+
self.valid_responses = Set.new(['false', ''])
|
28
|
+
self.normal_responses = valid_responses.dup << 'true'
|
29
|
+
self.standard_headers = {
|
30
|
+
'User-Agent' => "TheViking (Ruby Gem) v#{TheViking::VERSION}",
|
31
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
32
|
+
}
|
33
|
+
|
34
|
+
# Create a new instance of the Akismet class
|
35
|
+
#
|
36
|
+
# ==== Arguments
|
37
|
+
# Arguments are provided in the form of a Hash with the following keys
|
38
|
+
# (as Symbols) available:
|
39
|
+
#
|
40
|
+
# +api_key+:: your Akismet API key
|
41
|
+
# +blog+:: the blog associated with your api key
|
42
|
+
#
|
43
|
+
# The following keys are available and are entirely optional. They are
|
44
|
+
# available incase communication with Akismet's servers requires a
|
45
|
+
# proxy port and/or host:
|
46
|
+
#
|
47
|
+
# * +proxy_port+
|
48
|
+
# * +proxy_host+
|
49
|
+
def initialize(options)
|
50
|
+
super
|
51
|
+
self.verified_key = false
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns +true+ if the API key has been verified, +false+ otherwise
|
55
|
+
def verified?
|
56
|
+
(@verified_key ||= verify_api_key) != :false
|
57
|
+
end
|
58
|
+
|
59
|
+
# This is basically the core of everything. This call takes a number of
|
60
|
+
# arguments and characteristics about the submitted content and then
|
61
|
+
# returns a thumbs up or thumbs down. Almost everything is optional, but
|
62
|
+
# performance can drop dramatically if you exclude certain elements.
|
63
|
+
#
|
64
|
+
# ==== Arguments
|
65
|
+
# +options+ <Hash>:: describes the comment being verified
|
66
|
+
#
|
67
|
+
# The following keys are available for the +options+ hash:
|
68
|
+
#
|
69
|
+
# +user_ip+ (*required*)::
|
70
|
+
# IP address of the comment submitter.
|
71
|
+
# +user_agent+ (*required*)::
|
72
|
+
# user agent information.
|
73
|
+
# +referrer+ (<i>note spelling</i>)::
|
74
|
+
# the content of the HTTP_REFERER header should be sent here.
|
75
|
+
# +permalink+::
|
76
|
+
# permanent location of the entry the comment was submitted to
|
77
|
+
# +comment_type+::
|
78
|
+
# may be blank, comment, trackback, pingback, or a made up value like
|
79
|
+
# "registration".
|
80
|
+
# +comment_author+::
|
81
|
+
# submitted name with the comment
|
82
|
+
# +comment_author_email+::
|
83
|
+
# submitted email address
|
84
|
+
# +comment_author_url+::
|
85
|
+
# commenter URL
|
86
|
+
# +comment_content+::
|
87
|
+
# the content that was submitted
|
88
|
+
# Other server enviroment variables::
|
89
|
+
# In PHP there is an array of enviroment variables called <tt>_SERVER</tt>
|
90
|
+
# which contains information about the web server itself as well as a
|
91
|
+
# key/value for every HTTP header sent with the request. This data is
|
92
|
+
# highly useful to Akismet as how the submited content interacts with
|
93
|
+
# the server can be very telling, so please include as much information
|
94
|
+
# as possible.
|
95
|
+
def check_comment(options = {})
|
96
|
+
return false if invalid_options?
|
97
|
+
message = call_akismet('comment-check', options)
|
98
|
+
{ :spam => !self.class.valid_responses.include?(message), :message => message }
|
99
|
+
end
|
100
|
+
|
101
|
+
# This call is for submitting comments that weren't marked as spam but
|
102
|
+
# should have been (i.e. false negatives). It takes identical arguments as
|
103
|
+
# +check_comment+.
|
104
|
+
def mark_as_spam(options = {})
|
105
|
+
return false if invalid_options?
|
106
|
+
{ :message => call_akismet('submit-spam', options) }
|
107
|
+
end
|
108
|
+
|
109
|
+
# This call is intended for the marking of false positives, things that
|
110
|
+
# were incorrectly marked as spam. It takes identical arguments as
|
111
|
+
# +check_comment+ and +mark_as_spam+.
|
112
|
+
def mark_as_ham(options = {})
|
113
|
+
return false if invalid_options?
|
114
|
+
{ :message => call_akismet('submit-ham', options) }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns the URL for an Akismet request
|
118
|
+
#
|
119
|
+
# ==== Arguments
|
120
|
+
# +action+ <~to_s>:: a valid Akismet function name
|
121
|
+
#
|
122
|
+
# ==== Returns
|
123
|
+
# String
|
124
|
+
def self.url(action)
|
125
|
+
"/1.1/#{action}"
|
126
|
+
end
|
127
|
+
|
128
|
+
protected
|
129
|
+
|
130
|
+
# Internal call to Akismet. Prepares the data for posting to the Akismet
|
131
|
+
# service.
|
132
|
+
#
|
133
|
+
# ==== Arguments
|
134
|
+
# +akismet_function+ <String>::
|
135
|
+
# the Akismet function that should be called
|
136
|
+
#
|
137
|
+
# The following keys are available to configure a given call to Akismet:
|
138
|
+
#
|
139
|
+
# +user_ip+ (*required*)::
|
140
|
+
# IP address of the comment submitter.
|
141
|
+
# +user_agent+ (*required*)::
|
142
|
+
# user agent information.
|
143
|
+
# +referrer+ (<i>note spelling</i>)::
|
144
|
+
# the content of the HTTP_REFERER header should be sent here.
|
145
|
+
# +permalink+::
|
146
|
+
# the permanent location of the entry the comment was submitted to.
|
147
|
+
# +comment_type+::
|
148
|
+
# may be blank, comment, trackback, pingback, or a made up value like
|
149
|
+
# "registration".
|
150
|
+
# +comment_author+::
|
151
|
+
# submitted name with the comment
|
152
|
+
# +comment_author_email+::
|
153
|
+
# submitted email address
|
154
|
+
# +comment_author_url+::
|
155
|
+
# commenter URL
|
156
|
+
# +comment_content+::
|
157
|
+
# the content that was submitted
|
158
|
+
# Other server enviroment variables::
|
159
|
+
# In PHP there is an array of enviroment variables called <tt>_SERVER</tt>
|
160
|
+
# which contains information about the web server itself as well as a
|
161
|
+
# key/value for every HTTP header sent with the request. This data is
|
162
|
+
# highly useful to Akismet as how the submited content interacts with
|
163
|
+
# the server can be very telling, so please include as much information
|
164
|
+
# as possible.
|
165
|
+
def call_akismet(akismet_function, options = {})
|
166
|
+
http_post(
|
167
|
+
Net::HTTP.new([self.options[:api_key], self.class.host].join('.'), options[:proxy_host], options[:proxy_port]),
|
168
|
+
akismet_function,
|
169
|
+
options.update(:blog => self.options[:blog]).to_query
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Call to check and verify your API key. You may then call the
|
174
|
+
# <tt>verified?</tt> method to see if your key has been validated
|
175
|
+
def verify_api_key
|
176
|
+
return :false if invalid_options?
|
177
|
+
value = http_post(
|
178
|
+
Net::HTTP.new(self.class.host, self.class.port, options[:proxy_host], options[:proxy_port]),
|
179
|
+
'verify-key',
|
180
|
+
{
|
181
|
+
:key => self.options[:api_key],
|
182
|
+
:blog => self.options[:blog]
|
183
|
+
}.to_query
|
184
|
+
)
|
185
|
+
self.verified_key = (value == 'valid') ? true : :false
|
186
|
+
end
|
187
|
+
|
188
|
+
def http_post(http, action, data)
|
189
|
+
resp = http.post(self.url(action), data, self.class.standard_headers)
|
190
|
+
log_request(self.url(action), data, resp)
|
191
|
+
resp.body
|
192
|
+
end
|
193
|
+
|
194
|
+
def url(action)
|
195
|
+
"/1.1/#{action}"
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
attr_accessor :verified_key
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module TheViking
|
2
|
+
class Base
|
3
|
+
|
4
|
+
attr_accessor :options
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
self.options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def verified?
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_article(options = {})
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_comment(options = {})
|
17
|
+
end
|
18
|
+
|
19
|
+
def mark_as_spam(options = {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def mark_as_ham(options = {})
|
23
|
+
end
|
24
|
+
|
25
|
+
# Automatically determines whether to mark as spam or ham depending on a
|
26
|
+
# boolean switch, +is_spam+. The post will be marked as spam when
|
27
|
+
# +is_spam+ is +true+. The post will be marked as ham if +is_spam+ is
|
28
|
+
# +false+.
|
29
|
+
#
|
30
|
+
# ==== Arguments
|
31
|
+
# +is_spam+ <Boolean>::
|
32
|
+
# determines whether to mark a post as spam or ham -- spam when true,
|
33
|
+
# ham when false
|
34
|
+
#
|
35
|
+
# +options+ <Hash>::
|
36
|
+
# any options either +mark_as_spam+ or +mark_as_ham+ accepts
|
37
|
+
def mark_as_spam_or_ham(is_spam, options = {})
|
38
|
+
is_spam ? mark_as_spam(options) : mark_as_ham(options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def stats
|
42
|
+
end
|
43
|
+
|
44
|
+
def logger
|
45
|
+
TheViking.logger
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.logger
|
49
|
+
TheViking.logger
|
50
|
+
end
|
51
|
+
|
52
|
+
# Checks to ensure that the minimum number of +options+ have been provided
|
53
|
+
# to make a call to the spam protection service.
|
54
|
+
#
|
55
|
+
# Required options include:
|
56
|
+
# * +api_key+
|
57
|
+
# * +blog+
|
58
|
+
#
|
59
|
+
# See the module for your desired spam protection service for details on
|
60
|
+
# the format of these options.
|
61
|
+
def invalid_options?
|
62
|
+
self.options[:api_key].nil? || self.options[:blog].nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def log_request(url, data, response)
|
68
|
+
return unless logger
|
69
|
+
logger.info("[#{self.class.name}] POST '%s' with %s" % [url, data])
|
70
|
+
logger.debug(">> #{response.body.inspect}")
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../../gem_version'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
|
5
|
+
describe '#to_param' do
|
6
|
+
|
7
|
+
it 'should return a representation of an object' do
|
8
|
+
1.to_param.should == '1'
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#to_query' do
|
14
|
+
|
15
|
+
it 'should CGI escape an object and its associated key' do
|
16
|
+
'foo'.to_query('bar').should == 'bar=foo'
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hash do
|
4
|
+
|
5
|
+
describe '#symbolize_keys' do
|
6
|
+
|
7
|
+
it 'should convert all keys to symbols' do
|
8
|
+
{ 'foo' => 'bar', :baz => 1 }.symbolize_keys.should == { :foo => 'bar', :baz => 1 }
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should handle bad keys' do
|
12
|
+
{ nil => 'bar' }.symbolize_keys[nil].should == 'bar'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#dasherize_keys' do
|
18
|
+
|
19
|
+
it 'should convert all all underscores in keys to dashes' do
|
20
|
+
{ 'foo_bar' => 'baz' }.dasherize_keys.should == { 'foo-bar' => 'baz' }
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#to_query' do
|
26
|
+
|
27
|
+
it 'should convert to a valid URI query' do
|
28
|
+
{ :foo => 'baz', :bar => 1 }.to_query.should == 'bar=1&foo=baz'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe Array, '#to_query' do
|
36
|
+
|
37
|
+
it 'should convert to a valid URI query' do
|
38
|
+
[:foo, :bar].to_query('baz').should == 'baz%5B%5D=foo&baz%5B%5D=bar'
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
|
3
|
+
require 'viking'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.mock_with :rspec
|
7
|
+
end
|
8
|
+
|
9
|
+
# See http://blog.jayfields.com/2007/11/ruby-testing-private-methods.html
|
10
|
+
class Class
|
11
|
+
def publicize_methods(instance=nil)
|
12
|
+
saved_private_instance_methods = self.private_instance_methods
|
13
|
+
self.class_eval { public *saved_private_instance_methods }
|
14
|
+
yield(instance)
|
15
|
+
ensure
|
16
|
+
self.class_eval { private *saved_private_instance_methods }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# rSpec Hash additions.
|
22
|
+
#
|
23
|
+
# From
|
24
|
+
# * http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F
|
25
|
+
# * Neil Rahilly
|
26
|
+
class Hash
|
27
|
+
##
|
28
|
+
# Filter keys out of a Hash.
|
29
|
+
#
|
30
|
+
# { :a => 1, :b => 2, :c => 3 }.except(:a)
|
31
|
+
# => { :b => 2, :c => 3 }
|
32
|
+
def except(*keys)
|
33
|
+
self.reject { |k,v| keys.include?(k || k.to_sym) }
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Override some keys.
|
38
|
+
#
|
39
|
+
# { :a => 1, :b => 2, :c => 3 }.with(:a => 4)
|
40
|
+
# => { :a => 4, :b => 2, :c => 3 }
|
41
|
+
def with(overrides = {})
|
42
|
+
self.merge overrides
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Returns a Hash with only the pairs identified by +keys+.
|
47
|
+
#
|
48
|
+
# { :a => 1, :b => 2, :c => 3 }.only(:a)
|
49
|
+
# => { :a => 1 }
|
50
|
+
def only(*keys)
|
51
|
+
self.reject { |k,v| !keys.include?(k || k.to_sym) }
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Viking::Akismet do
|
4
|
+
|
5
|
+
def valid_options
|
6
|
+
{
|
7
|
+
:blog => 'foo',
|
8
|
+
:api_key => 'bar'
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:akismet) { Viking.connect('akismet', valid_options) }
|
13
|
+
let(:http) { Net::HTTP.new('url') }
|
14
|
+
|
15
|
+
before do
|
16
|
+
Net::HTTP.stub(:new).and_return(http)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".new" do
|
20
|
+
|
21
|
+
it "should not have a verified key when initialized" do
|
22
|
+
akismet.send(:verified_key).should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '.url' do
|
28
|
+
|
29
|
+
it 'should return an URL for a request' do
|
30
|
+
Viking::Akismet.url('bar').should == '/1.1/bar'
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#verified?" do
|
36
|
+
|
37
|
+
it "should be verified when all parameters are provided" do
|
38
|
+
http.should_receive(:post).and_return(stub("response", :body => "valid"))
|
39
|
+
|
40
|
+
akismet.should be_verified # #verified? is called twice to make sure #verify_api_key is not called twice
|
41
|
+
akismet.should be_verified
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should not be verified if Akismet doesn't validate" do
|
45
|
+
http.should_receive(:post).and_return(stub("response", :body => "invalid"))
|
46
|
+
akismet.should_not be_verified
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should not be verified if its options are invalid" do
|
50
|
+
Viking.connect('akismet', {}).should_not be_verified
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#check_comment" do
|
56
|
+
|
57
|
+
it "should be false if the instance has invalid options" do
|
58
|
+
Viking.connect('akismet', {}).check_comment({}).should be_false
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should be spam when the response body isn't a valid response" do
|
62
|
+
http.should_receive(:post).and_return(stub("response", :body => "invalid"))
|
63
|
+
akismet.check_comment(:user_ip => "127.0.0.1", :user_agent => "Mozilla").should == { :message => "invalid", :spam => true }
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not be spam when the response body is a valid response" do
|
67
|
+
http.should_receive(:post).and_return(stub("response", :body => "false"))
|
68
|
+
akismet.check_comment(:user_ip => "127.0.0.1", :user_agent => "Mozilla").should == { :message => "false", :spam => false }
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#mark_as_spam" do
|
74
|
+
|
75
|
+
it 'should be false if the instance has invalid options' do
|
76
|
+
Viking.connect('akismet', {}).mark_as_spam({}).should be_false
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return the response body' do
|
80
|
+
http.should_receive(:post).and_return(stub('response', :body => "foo"))
|
81
|
+
akismet.mark_as_spam({}).should == { :message => "foo" }
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#mark_as_ham' do
|
87
|
+
|
88
|
+
it 'should be false if the instance has invalid options' do
|
89
|
+
Viking.connect('akismet', {}).mark_as_ham({}).should be_false
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should return the response body' do
|
93
|
+
http.should_receive(:post).and_return(stub('response', :body => "foo"))
|
94
|
+
akismet.mark_as_ham({}).should == { :message => "foo" }
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Viking::Base do
|
4
|
+
|
5
|
+
def valid_base_options
|
6
|
+
{
|
7
|
+
:api_key => "1234abc",
|
8
|
+
:blog => "wiki.mysite.com"
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:base) { Viking::Base.new({}) }
|
13
|
+
|
14
|
+
describe "#mark_as_spam_or_ham" do
|
15
|
+
|
16
|
+
it "should mark as spam when is_spam is true" do
|
17
|
+
base.should_receive(:mark_as_spam).and_return("I will be spam")
|
18
|
+
base.mark_as_spam_or_ham(true, {}).should == "I will be spam"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should mark as ham when is_spam is false" do
|
22
|
+
base.should_receive(:mark_as_ham).and_return("I will be ham")
|
23
|
+
base.mark_as_spam_or_ham(false, {}).should == "I will be ham"
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#invalid_options?" do
|
29
|
+
|
30
|
+
it "should be false if the required options are non-nil" do
|
31
|
+
base.options = valid_base_options
|
32
|
+
base.should_not be_invalid_options
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be true if the options don't include an API key" do
|
36
|
+
base.options = valid_base_options.except(:api_key)
|
37
|
+
base.should be_invalid_options
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be true if the options don't include a blog address" do
|
41
|
+
base.options = valid_base_options.except(:blog)
|
42
|
+
base.should be_invalid_options
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Viking do
|
4
|
+
|
5
|
+
it { should respond_to :logger }
|
6
|
+
it { should respond_to :default_engine }
|
7
|
+
it { should respond_to :connect_options }
|
8
|
+
it { should respond_to :default_instance }
|
9
|
+
|
10
|
+
describe ".connect" do
|
11
|
+
it "should load the Akismet engine" do
|
12
|
+
Viking.connect('akismet', {}).should be_a_kind_of(Viking::Akismet)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should load the Akismet engine with Symbol" do
|
16
|
+
Viking.connect(:akismet, {}).should be_a_kind_of(Viking::Akismet)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be nil if the engine is nil" do
|
20
|
+
Viking.connect(nil, {}).should be_nil
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be nil if the engine is blank" do
|
24
|
+
Viking.connect('', {}).should be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".enabled?" do
|
30
|
+
it "should not be enabled if a default instance has not be initialized" do
|
31
|
+
Viking.should_not be_enabled
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/the_viking.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'the_viking/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "the_viking"
|
8
|
+
gem.version = TheViking::VERSION
|
9
|
+
gem.authors = ["Risk Danger Olson", "James Herdman", "Pierre-Louis Gottfrois", "Ilya N. Zykin"]
|
10
|
+
gem.email = ["ilya-zykin@ya.ru", "pl.gottfrois@dimelo.com"]
|
11
|
+
gem.description = %q{TheViking is repack of Viking gem}
|
12
|
+
gem.summary = %q{Akismet anti-spam service for Ruby and Rails}
|
13
|
+
gem.homepage = "https://github.com/the-teacher/the_viking"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency(%q{rspec}, ['~> 2.12.0'])
|
21
|
+
gem.add_development_dependency(%q{rake})
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: the_viking
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Risk Danger Olson
|
8
|
+
- James Herdman
|
9
|
+
- Pierre-Louis Gottfrois
|
10
|
+
- Ilya N. Zykin
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2014-12-04 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rspec
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - "~>"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.12.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.12.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
description: TheViking is repack of Viking gem
|
45
|
+
email:
|
46
|
+
- ilya-zykin@ya.ru
|
47
|
+
- pl.gottfrois@dimelo.com
|
48
|
+
executables: []
|
49
|
+
extensions: []
|
50
|
+
extra_rdoc_files: []
|
51
|
+
files:
|
52
|
+
- ".gitignore"
|
53
|
+
- ".rspec"
|
54
|
+
- ".travis.yml"
|
55
|
+
- Gemfile
|
56
|
+
- LICENSE.txt
|
57
|
+
- README.md
|
58
|
+
- Rakefile
|
59
|
+
- gem_version.rb
|
60
|
+
- lib/core_ext/object.rb
|
61
|
+
- lib/core_ext/transformations.rb
|
62
|
+
- lib/the_viking.rb
|
63
|
+
- lib/the_viking/akismet.rb
|
64
|
+
- lib/the_viking/base.rb
|
65
|
+
- lib/the_viking/version.rb
|
66
|
+
- spec/core_ext/object_spec.rb
|
67
|
+
- spec/core_ext/transformations_spec.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
- spec/viking/akismet_spec.rb
|
70
|
+
- spec/viking/base_spec.rb
|
71
|
+
- spec/viking/viking_spec.rb
|
72
|
+
- the_viking.gemspec
|
73
|
+
homepage: https://github.com/the-teacher/the_viking
|
74
|
+
licenses: []
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.2.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Akismet anti-spam service for Ruby and Rails
|
96
|
+
test_files:
|
97
|
+
- spec/core_ext/object_spec.rb
|
98
|
+
- spec/core_ext/transformations_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/viking/akismet_spec.rb
|
101
|
+
- spec/viking/base_spec.rb
|
102
|
+
- spec/viking/viking_spec.rb
|