vikinggem 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.autotest ADDED
@@ -0,0 +1,29 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ at.clear_mappings
3
+
4
+ # Any change to spec_helper should result in all specs being run
5
+ at.add_mapping %r%^spec/spec_helper\.rb$% do |_, m|
6
+ at.files_matching %r%^spec/.*_spec\.rb$%
7
+ end
8
+
9
+ # Any change to an example should result in running itself
10
+ at.add_mapping %r%^spec/(lib|core_ext)/.*_spec\.rb$% do |filename, _|
11
+ filename
12
+ end
13
+
14
+ # Any core extension should result in all specs being run
15
+ at.add_mapping %r%^lib/core_ext/.*\.rb$% do |_, m|
16
+ at.files_matching %r%^spec/.*_spec\.rb$%
17
+ end
18
+
19
+ # Any change to viking.rb should run all specs
20
+ at.add_mapping %r%^lib/viking.rb$% do |_, m|
21
+ at.files_matching %r%^spec/.*_spec\.rb$%
22
+ end
23
+
24
+ # Any change to an engine should result in that spec being run
25
+ at.add_mapping %r%^lib/viking/(.*)\.rb$% do |_, m|
26
+ at.files_matching %r%^spec/lib/#{m[1]}_spec\.rb$%
27
+ end
28
+ end
29
+
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.tmproj
2
+ .DS_Store
3
+ coverage/*
4
+ ri/*
5
+ doc/*
6
+ pkg/*
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-04-22
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,25 @@
1
+ .autotest
2
+ .gitignore
3
+ History.txt
4
+ Manifest.txt
5
+ README.markdown
6
+ README.txt
7
+ Rakefile
8
+ config/requirements.rb
9
+ lib/core_ext/object.rb
10
+ lib/core_ext/transformations.rb
11
+ lib/viking.rb
12
+ lib/viking/akismet.rb
13
+ lib/viking/base.rb
14
+ lib/viking/defensio.rb
15
+ lib/viking/version.rb
16
+ lib/viking/viking.rb
17
+ setup.rb
18
+ spec/core_ext/object_spec.rb
19
+ spec/core_ext/transformations_spec.rb
20
+ spec/lib/akismet_spec.rb
21
+ spec/lib/base_spec.rb
22
+ spec/lib/defensio_spec.rb
23
+ spec/lib/viking_spec.rb
24
+ spec/spec.opts
25
+ spec/spec_helper.rb
data/README.markdown ADDED
@@ -0,0 +1,32 @@
1
+ Description
2
+ -----------
3
+ This is a fork of Technoweenie's Rails plugin, Viking. It is meant to bring
4
+ Viking to other Ruby web frameworks by gem-ifying the plugin, and extending it
5
+ with a few of the additions that were generated by the Collective project
6
+ (<http://github.com/meekish/collective>).
7
+
8
+ License
9
+ -------
10
+
11
+ (The MIT License)
12
+
13
+ Copyright (c) 2008 James Herdman
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining
16
+ a copy of this software and associated documentation files (the
17
+ 'Software'), to deal in the Software without restriction, including
18
+ without limitation the rights to use, copy, modify, merge, publish,
19
+ distribute, sublicense, and/or sell copies of the Software, and to
20
+ permit persons to whom the Software is furnished to do so, subject to
21
+ the following conditions:
22
+
23
+ The above copyright notice and this permission notice shall be
24
+ included in all copies or substantial portions of the Software.
25
+
26
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
27
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
29
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
30
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.txt ADDED
@@ -0,0 +1,30 @@
1
+ = Description
2
+ This is a fork of Technoweenie's Rails plugin, Viking. It is meant to bring
3
+ Viking to other Ruby web frameworks by gem-ifying the plugin, and extending it
4
+ with a few of the additions that were generated by the Collective project
5
+ (http://github.com/meekish/collective).
6
+
7
+ = License
8
+
9
+ (The MIT License)
10
+
11
+ Copyright (c) 2008 James Herdman
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining
14
+ a copy of this software and associated documentation files (the
15
+ 'Software'), to deal in the Software without restriction, including
16
+ without limitation the rights to use, copy, modify, merge, publish,
17
+ distribute, sublicense, and/or sell copies of the Software, and to
18
+ permit persons to whom the Software is furnished to do so, subject to
19
+ the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be
22
+ included in all copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
@@ -0,0 +1,15 @@
1
+ require 'cgi'
2
+
3
+ class Object
4
+ unless method_defined?(:to_param)
5
+ def to_param
6
+ to_s
7
+ end
8
+ end
9
+
10
+ unless method_defined?(:to_query)
11
+ def to_query(key)
12
+ [CGI.escape(key.to_s), CGI.escape(to_param.to_s)].join('=')
13
+ end
14
+ end
15
+ end
@@ -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/viking.rb ADDED
@@ -0,0 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ ## Load core extensions
5
+ Dir[File.join(File.dirname(__FILE__), 'core_ext', '*.rb')].each do |core_ext|
6
+ require(core_ext)
7
+ end
8
+
9
+ ## Let's get this party started
10
+ require 'viking/viking'
11
+ require 'viking/version'
@@ -0,0 +1,194 @@
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 Viking
13
+ class Akismet < Base
14
+ class << self
15
+ attr_accessor :valid_responses, :normal_responses, :standard_headers,
16
+ :host, :port
17
+ end
18
+
19
+ self.host = 'rest.akismet.com'
20
+ self.port = 80
21
+ self.valid_responses = Set.new(['false', ''])
22
+ self.normal_responses = valid_responses.dup << 'true'
23
+ self.standard_headers = {
24
+ 'User-Agent' => "Viking (Ruby Gem) v#{Viking::VERSION::STRING}",
25
+ 'Content-Type' => 'application/x-www-form-urlencoded'
26
+ }
27
+
28
+ # Create a new instance of the Akismet class
29
+ #
30
+ # ==== Arguments
31
+ # Arguments are provided in the form of a Hash with the following keys
32
+ # (as Symbols) available:
33
+ #
34
+ # +api_key+:: your Akismet API key
35
+ # +blog+:: the blog associated with your api key
36
+ #
37
+ # The following keys are available and are entirely optional. They are
38
+ # available incase communication with Akismet's servers requires a
39
+ # proxy port and/or host:
40
+ #
41
+ # * +proxy_port+
42
+ # * +proxy_host+
43
+ def initialize(options)
44
+ super
45
+ self.verified_key = false
46
+ end
47
+
48
+ # Returns +true+ if the API key has been verified, +false+ otherwise
49
+ def verified?
50
+ (@verified_key ||= verify_api_key) != :false
51
+ end
52
+
53
+ # This is basically the core of everything. This call takes a number of
54
+ # arguments and characteristics about the submitted content and then
55
+ # returns a thumbs up or thumbs down. Almost everything is optional, but
56
+ # performance can drop dramatically if you exclude certain elements.
57
+ #
58
+ # ==== Arguments
59
+ # +options+ <Hash>:: describes the comment being verified
60
+ #
61
+ # The following keys are available for the +options+ hash:
62
+ #
63
+ # +user_ip+ (*required*)::
64
+ # IP address of the comment submitter.
65
+ # +user_agent+ (*required*)::
66
+ # user agent information.
67
+ # +referrer+ (<i>note spelling</i>)::
68
+ # the content of the HTTP_REFERER header should be sent here.
69
+ # +permalink+::
70
+ # permanent location of the entry the comment was submitted to
71
+ # +comment_type+::
72
+ # may be blank, comment, trackback, pingback, or a made up value like
73
+ # "registration".
74
+ # +comment_author+::
75
+ # submitted name with the comment
76
+ # +comment_author_email+::
77
+ # submitted email address
78
+ # +comment_author_url+::
79
+ # commenter URL
80
+ # +comment_content+::
81
+ # the content that was submitted
82
+ # Other server enviroment variables::
83
+ # In PHP there is an array of enviroment variables called <tt>_SERVER</tt>
84
+ # which contains information about the web server itself as well as a
85
+ # key/value for every HTTP header sent with the request. This data is
86
+ # highly useful to Akismet as how the submited content interacts with
87
+ # the server can be very telling, so please include as much information
88
+ # as possible.
89
+ def check_comment(options={})
90
+ return false if invalid_options?
91
+ message = call_akismet('comment-check', options)
92
+ {:spam => !self.class.valid_responses.include?(message), :message => message}
93
+ end
94
+
95
+ # This call is for submitting comments that weren't marked as spam but
96
+ # should have been (i.e. false negatives). It takes identical arguments as
97
+ # +check_comment+.
98
+ def mark_as_spam(options={})
99
+ return false if invalid_options?
100
+ {:message => call_akismet('submit-spam', options)}
101
+ end
102
+
103
+ # This call is intended for the marking of false positives, things that
104
+ # were incorrectly marked as spam. It takes identical arguments as
105
+ # +check_comment+ and +mark_as_spam+.
106
+ def mark_as_ham(options={})
107
+ return false if invalid_options?
108
+ {:message => call_akismet('submit-ham', options)}
109
+ end
110
+
111
+ # Returns the URL for an Akismet request
112
+ #
113
+ # ==== Arguments
114
+ # +action+ <~to_s>:: a valid Akismet function name
115
+ #
116
+ # ==== Returns
117
+ # String
118
+ def self.url(action)
119
+ "/1.1/#{action}"
120
+ end
121
+
122
+ protected
123
+ # Internal call to Akismet. Prepares the data for posting to the Akismet
124
+ # service.
125
+ #
126
+ # ==== Arguments
127
+ # +akismet_function+ <String>::
128
+ # the Akismet function that should be called
129
+ #
130
+ # The following keys are available to configure a given call to Akismet:
131
+ #
132
+ # +user_ip+ (*required*)::
133
+ # IP address of the comment submitter.
134
+ # +user_agent+ (*required*)::
135
+ # user agent information.
136
+ # +referrer+ (<i>note spelling</i>)::
137
+ # the content of the HTTP_REFERER header should be sent here.
138
+ # +permalink+::
139
+ # the permanent location of the entry the comment was submitted to.
140
+ # +comment_type+::
141
+ # may be blank, comment, trackback, pingback, or a made up value like
142
+ # "registration".
143
+ # +comment_author+::
144
+ # submitted name with the comment
145
+ # +comment_author_email+::
146
+ # submitted email address
147
+ # +comment_author_url+::
148
+ # commenter URL
149
+ # +comment_content+::
150
+ # the content that was submitted
151
+ # Other server enviroment variables::
152
+ # In PHP there is an array of enviroment variables called <tt>_SERVER</tt>
153
+ # which contains information about the web server itself as well as a
154
+ # key/value for every HTTP header sent with the request. This data is
155
+ # highly useful to Akismet as how the submited content interacts with
156
+ # the server can be very telling, so please include as much information
157
+ # as possible.
158
+ def call_akismet(akismet_function, options={})
159
+ http_post(
160
+ Net::HTTP.new([options[:api_key], self.class.host].join("."), options[:proxy_host], options[:proxy_port]),
161
+ akismet_function,
162
+ options.update(:blog => options[:blog]).to_query
163
+ )
164
+ end
165
+
166
+ # Call to check and verify your API key. You may then call the
167
+ # <tt>verified?</tt> method to see if your key has been validated
168
+ def verify_api_key
169
+ return :false if invalid_options?
170
+ value = http_post(
171
+ Net::HTTP.new(self.class.host, self.class.port, options[:proxy_host], options[:proxy_port]),
172
+ 'verify-key',
173
+ {
174
+ :key => options[:api_key],
175
+ :blog => options[:blog]
176
+ }.to_query
177
+ )
178
+ self.verified_key = (value == "valid") ? true : :false
179
+ end
180
+
181
+ def http_post(http, action, data)
182
+ resp = http.post(self.url(action), data, self.class.standard_headers)
183
+ log_request(self.url(action), data, resp)
184
+ resp.body
185
+ end
186
+
187
+ def url(action)
188
+ "/1.1/#{action}"
189
+ end
190
+
191
+ private
192
+ attr_accessor :verified_key
193
+ end
194
+ end
@@ -0,0 +1,76 @@
1
+ module Viking
2
+
3
+ class Base
4
+
5
+ attr_accessor :options
6
+
7
+ def initialize(options)
8
+ self.options = options
9
+ end
10
+
11
+ def verified?
12
+ end
13
+
14
+ def check_article(options={})
15
+ end
16
+
17
+ def check_comment(options={})
18
+ end
19
+
20
+ def mark_as_spam(options={})
21
+ end
22
+
23
+ def mark_as_ham(options={})
24
+ end
25
+
26
+ # Automatically determines whether to mark as spam or ham depending on a
27
+ # boolean switch, +is_spam+. The post will be marked as spam when
28
+ # +is_spam+ is +true+. The post will be marked as ham if +is_spam+ is
29
+ # +false+.
30
+ #
31
+ # ==== Arguments
32
+ # +is_spam+ <Boolean>::
33
+ # determines whether to mark a post as spam or ham -- spam when true,
34
+ # ham when false
35
+ #
36
+ # +options+ <Hash>::
37
+ # any options either +mark_as_spam+ or +mark_as_ham+ accepts
38
+ def mark_as_spam_or_ham(is_spam, options={})
39
+ is_spam ? mark_as_spam(options) : mark_as_ham(options)
40
+ end
41
+
42
+ def stats
43
+ end
44
+
45
+ def self.logger
46
+ Viking.logger
47
+ end
48
+
49
+ def logger
50
+ Viking.logger
51
+ end
52
+
53
+ # Checks to ensure that the minimum number of +options+ have been provided
54
+ # to make a call to the spam protection service.
55
+ #
56
+ # Required options include:
57
+ # * +api_key+
58
+ # * +blog+
59
+ #
60
+ # See the module for your desired spam protection service for details on
61
+ # the format of these options.
62
+ def invalid_options?
63
+ options[:api_key].nil? || options[:blog].nil?
64
+ end
65
+
66
+ protected
67
+
68
+ def log_request(url, data, response)
69
+ return unless logger
70
+ logger.info("[#{self.class.name}] POST '%s' with %s" % [url, data])
71
+ logger.debug(">> #{response.body.inspect}")
72
+ end
73
+
74
+ end
75
+
76
+ end