semantic_antispam 0.1.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/Gemfile +4 -0
- data/README.md +50 -0
- data/Rakefile +2 -0
- data/lib/semantic_antispam.rb +4 -0
- data/lib/semantic_antispam/antispam.rb +64 -0
- data/lib/semantic_antispam/version.rb +5 -0
- data/semantic_antispam.gemspec +25 -0
- data/spec/antispam.yml +3 -0
- data/spec/semantic_antispam_spec.rb +35 -0
- data/spec/spec_helper.rb +26 -0
- metadata +143 -0
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Semantic Antispam
|
2
|
+
|
3
|
+
Simple semantic antispam solution for ActiveRecord-based applications.
|
4
|
+
|
5
|
+
Define questions and answers in a YAML file and validate your models with a single line of code. No more captchas or other stupid tricks.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add the dependency to your `Gemfile`
|
10
|
+
|
11
|
+
gem 'semantic_antispam'
|
12
|
+
|
13
|
+
Create a questions file at `config/antispam.yml` with the following format:
|
14
|
+
|
15
|
+
- Color of the sea?: blue
|
16
|
+
- Color of the sky?: blue
|
17
|
+
- Capital of France?: paris
|
18
|
+
|
19
|
+
If you are not using Rails or want to save this file in a different location:
|
20
|
+
|
21
|
+
# config/application.rb if this is a Rails app
|
22
|
+
|
23
|
+
Semantic::Antispam.config_file = Rails.root + '/antispam.yml'
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
If you want to check the humanness of your commenters, just modify your `Comment` model:
|
28
|
+
|
29
|
+
class Comment < ActiveRecord::Base
|
30
|
+
semantic_antispam
|
31
|
+
end
|
32
|
+
|
33
|
+
And add this code in your comment form:
|
34
|
+
|
35
|
+
<%= f.hidden_field :antispam_hash %>
|
36
|
+
<%= f.label :antispam_answer, f.object.antispam_question %>
|
37
|
+
<%= f.text_field :antispam_answer %>
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
If you want to improve semantic_antispam
|
42
|
+
|
43
|
+
1. Fork the repo
|
44
|
+
2. Create a topic branch `git checkout -b my_feature`
|
45
|
+
3. Push it! `git push origin my_feature`
|
46
|
+
4. Open a pull request
|
47
|
+
|
48
|
+
## Issues
|
49
|
+
|
50
|
+
<http://github.com/jrom/semantic_antispam/issues>
|
data/Rakefile
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Semantic
|
2
|
+
module Antispam
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.config_file=(file)
|
9
|
+
@config_file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config_file
|
13
|
+
@config_file || (defined?(Rails) ? Rails.root + 'config/antispam.yml' : nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load_file
|
17
|
+
YAML.load_file config_file
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.hash(value)
|
21
|
+
Digest::SHA1.hexdigest value
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.questions
|
25
|
+
@questions ||= load_file.collect { |e| { :question => e.keys.first, :answer => e.values.first, :hash => hash(e.keys.first) } }
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.find(hash)
|
29
|
+
questions.select { |q| q[:hash] == hash }.first
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
def semantic_antispam
|
34
|
+
class_eval do
|
35
|
+
attr_writer :antispam_hash, :antispam_answer
|
36
|
+
attr_reader :antispam_answer
|
37
|
+
|
38
|
+
private
|
39
|
+
def semantic_antispam_question
|
40
|
+
@semantic_antispam_question ||= Semantic::Antispam.questions.sample
|
41
|
+
end
|
42
|
+
|
43
|
+
public
|
44
|
+
def antispam_question
|
45
|
+
semantic_antispam_question[:question]
|
46
|
+
end
|
47
|
+
|
48
|
+
def antispam_hash
|
49
|
+
@antispam_hash || semantic_antispam_question[:hash]
|
50
|
+
end
|
51
|
+
|
52
|
+
validate :check_semantic_antispam, :on => :create
|
53
|
+
private
|
54
|
+
def check_semantic_antispam
|
55
|
+
errors.add :antispam_answer, 'SPAM' unless antispam_answer and Semantic::Antispam.find(antispam_hash)[:answer].downcase == antispam_answer.downcase
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
ActiveRecord::Base.send :include, Semantic::Antispam
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "semantic_antispam/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "semantic_antispam"
|
7
|
+
s.version = Semantic::Antispam::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jordi Romero"]
|
10
|
+
s.email = ["jordi@jrom.net"]
|
11
|
+
s.homepage = "http://github.com/jrom/semantic_antispam"
|
12
|
+
s.summary = %q{Simple semantic antispam solution for ActiveRecord-based applications.}
|
13
|
+
s.description = %q{Define questions and answers in a YAML file and validate your models with a single line of code. No more captchas or other stupid tricks.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n") - ['.gitignore', '.rspec', 'autotest/discover.rb']
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
# Dependencies
|
21
|
+
s.add_dependency "activerecord", ">= 3.0.0"
|
22
|
+
s.add_development_dependency "rspec", "~> 2.0.0.rc"
|
23
|
+
s.add_development_dependency "autotest", "~> 4.4.1"
|
24
|
+
s.add_development_dependency "sqlite3-ruby", "~> 1.3.1"
|
25
|
+
end
|
data/spec/antispam.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Comment do
|
4
|
+
before do
|
5
|
+
Comment.destroy_all
|
6
|
+
@comment = Comment.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have an antispam question" do
|
10
|
+
@comment.antispam_question.should_not be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have the question's hash" do
|
14
|
+
@comment.antispam_hash.should_not be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should fail without an answer" do
|
18
|
+
@comment.should_not be_valid
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should fail without a valid answer" do
|
22
|
+
@comment.antispam_answer = 'shit'
|
23
|
+
@comment.should_not be_valid
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should succeed with a valid answer" do
|
27
|
+
answer = case @comment.antispam_question
|
28
|
+
when /sea/i then 'blue'
|
29
|
+
when /sky/i then 'blue'
|
30
|
+
when /france/i then 'paris'
|
31
|
+
end
|
32
|
+
@comment.antispam_answer = answer
|
33
|
+
@comment.should be_valid
|
34
|
+
end
|
35
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'active_record'
|
3
|
+
require 'semantic_antispam'
|
4
|
+
|
5
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
6
|
+
|
7
|
+
old_stdout = $stdout
|
8
|
+
$stdout = StringIO.new
|
9
|
+
|
10
|
+
begin
|
11
|
+
ActiveRecord::Schema.define do
|
12
|
+
create_table :comments do |t|
|
13
|
+
t.string :author
|
14
|
+
t.text :body
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
end
|
18
|
+
ensure
|
19
|
+
$stdout = old_stdout
|
20
|
+
end
|
21
|
+
|
22
|
+
class Comment < ActiveRecord::Base
|
23
|
+
semantic_antispam
|
24
|
+
end
|
25
|
+
|
26
|
+
Semantic::Antispam.config_file = File.dirname(__FILE__) + '/antispam.yml'
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: semantic_antispam
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Jordi Romero
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-31 01:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activerecord
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
- 0
|
34
|
+
version: 3.0.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 7712058
|
46
|
+
segments:
|
47
|
+
- 2
|
48
|
+
- 0
|
49
|
+
- 0
|
50
|
+
- rc
|
51
|
+
version: 2.0.0.rc
|
52
|
+
type: :development
|
53
|
+
version_requirements: *id002
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: autotest
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 45
|
63
|
+
segments:
|
64
|
+
- 4
|
65
|
+
- 4
|
66
|
+
- 1
|
67
|
+
version: 4.4.1
|
68
|
+
type: :development
|
69
|
+
version_requirements: *id003
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: sqlite3-ruby
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 25
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 3
|
82
|
+
- 1
|
83
|
+
version: 1.3.1
|
84
|
+
type: :development
|
85
|
+
version_requirements: *id004
|
86
|
+
description: Define questions and answers in a YAML file and validate your models with a single line of code. No more captchas or other stupid tricks.
|
87
|
+
email:
|
88
|
+
- jordi@jrom.net
|
89
|
+
executables: []
|
90
|
+
|
91
|
+
extensions: []
|
92
|
+
|
93
|
+
extra_rdoc_files: []
|
94
|
+
|
95
|
+
files:
|
96
|
+
- Gemfile
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- lib/semantic_antispam.rb
|
100
|
+
- lib/semantic_antispam/antispam.rb
|
101
|
+
- lib/semantic_antispam/version.rb
|
102
|
+
- semantic_antispam.gemspec
|
103
|
+
- spec/antispam.yml
|
104
|
+
- spec/semantic_antispam_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
has_rdoc: true
|
107
|
+
homepage: http://github.com/jrom/semantic_antispam
|
108
|
+
licenses: []
|
109
|
+
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
hash: 3
|
121
|
+
segments:
|
122
|
+
- 0
|
123
|
+
version: "0"
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
hash: 3
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
requirements: []
|
134
|
+
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 1.3.7
|
137
|
+
signing_key:
|
138
|
+
specification_version: 3
|
139
|
+
summary: Simple semantic antispam solution for ActiveRecord-based applications.
|
140
|
+
test_files:
|
141
|
+
- spec/antispam.yml
|
142
|
+
- spec/semantic_antispam_spec.rb
|
143
|
+
- spec/spec_helper.rb
|