em-spamc 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +8 -0
- data/Rakefile +37 -0
- data/VERSION +1 -0
- data/em-spamc.gemspec +71 -0
- data/lib/em-spamc.rb +1 -0
- data/lib/em_spamc.rb +8 -0
- data/lib/em_spamc/connection.rb +105 -0
- data/lib/em_spamc/header_parser.rb +27 -0
- data/lib/em_spamc/report_parser.rb +37 -0
- data/lib/em_spamc/result.rb +30 -0
- data/test/config/spamassassin.yml +4 -0
- data/test/config/spamassassin.yml.example +2 -0
- data/test/examples/messages/sample.txt +5 -0
- data/test/examples/messages/zero-score.txt +23 -0
- data/test/examples/reports/spam-report.txt +27 -0
- data/test/examples/reports/zero-report.txt +1 -0
- data/test/examples/sample.txt +5 -0
- data/test/helper.rb +52 -0
- data/test/unit/test_em_spamc.rb +4 -0
- data/test/unit/test_em_spamc_connection.rb +44 -0
- data/test/unit/test_em_spamc_header_parser.rb +18 -0
- data/test/unit/test_em_spamc_report_parser.rb +20 -0
- data/test/unit/test_em_spamc_result.rb +20 -0
- metadata +122 -0
data/.document
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Scott Tadman, The Working Group Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
begin
|
7
|
+
Bundler.setup(:default, :development)
|
8
|
+
rescue Bundler::BundlerError => e
|
9
|
+
$stderr.puts e.message
|
10
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
11
|
+
exit e.status_code
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'rake'
|
15
|
+
require 'jeweler'
|
16
|
+
|
17
|
+
Jeweler::Tasks.new do |gem|
|
18
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
19
|
+
gem.name = "em-spamc"
|
20
|
+
gem.homepage = "http://github.com/twg/em-spamc"
|
21
|
+
gem.license = "MIT"
|
22
|
+
gem.summary = %Q{SpamAssassin Connection for EventMachine}
|
23
|
+
gem.description = %Q{Implementation of the "spamc" protocol for EventMachine}
|
24
|
+
gem.email = "github@tadman.ca"
|
25
|
+
gem.authors = [ "Scott Tadman", "Stephan Leroux" ]
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
|
29
|
+
Jeweler::RubygemsDotOrgTasks.new
|
30
|
+
|
31
|
+
require 'rake/testtask'
|
32
|
+
|
33
|
+
Rake::TestTask.new(:test) do |test|
|
34
|
+
test.libs << 'lib' << 'test'
|
35
|
+
test.pattern = 'test/**/test_*.rb'
|
36
|
+
test.verbose = true
|
37
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/em-spamc.gemspec
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "em-spamc"
|
8
|
+
s.version = "0.1.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Scott Tadman", "Stephan Leroux"]
|
12
|
+
s.date = "2013-04-17"
|
13
|
+
s.description = "Implementation of the \"spamc\" protocol for EventMachine"
|
14
|
+
s.email = "github@tadman.ca"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.md",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"em-spamc.gemspec",
|
27
|
+
"lib/em-spamc.rb",
|
28
|
+
"lib/em_spamc.rb",
|
29
|
+
"lib/em_spamc/connection.rb",
|
30
|
+
"lib/em_spamc/header_parser.rb",
|
31
|
+
"lib/em_spamc/report_parser.rb",
|
32
|
+
"lib/em_spamc/result.rb",
|
33
|
+
"test/config/spamassassin.yml",
|
34
|
+
"test/config/spamassassin.yml.example",
|
35
|
+
"test/examples/messages/sample.txt",
|
36
|
+
"test/examples/messages/zero-score.txt",
|
37
|
+
"test/examples/reports/spam-report.txt",
|
38
|
+
"test/examples/reports/zero-report.txt",
|
39
|
+
"test/examples/sample.txt",
|
40
|
+
"test/helper.rb",
|
41
|
+
"test/unit/test_em_spamc.rb",
|
42
|
+
"test/unit/test_em_spamc_connection.rb",
|
43
|
+
"test/unit/test_em_spamc_header_parser.rb",
|
44
|
+
"test/unit/test_em_spamc_report_parser.rb",
|
45
|
+
"test/unit/test_em_spamc_result.rb"
|
46
|
+
]
|
47
|
+
s.homepage = "http://github.com/twg/em-spamc"
|
48
|
+
s.licenses = ["MIT"]
|
49
|
+
s.require_paths = ["lib"]
|
50
|
+
s.rubygems_version = "1.8.25"
|
51
|
+
s.summary = "SpamAssassin Connection for EventMachine"
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
s.specification_version = 3
|
55
|
+
|
56
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
57
|
+
s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
|
58
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
59
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
62
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
63
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
64
|
+
end
|
65
|
+
else
|
66
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
67
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
68
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
data/lib/em-spamc.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'em_spamc'
|
data/lib/em_spamc.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'fiber'
|
2
|
+
require 'eventmachine'
|
3
|
+
|
4
|
+
class EmSpamc::Connection < EventMachine::Connection
|
5
|
+
# == Constants ============================================================
|
6
|
+
|
7
|
+
PROTO_VERSION = 'SPAMC/1.2'.freeze
|
8
|
+
|
9
|
+
DEFAULT_OPTIONS = {
|
10
|
+
:host => 'localhost',
|
11
|
+
:port => 783
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# == Properties ===========================================================
|
15
|
+
|
16
|
+
attr_reader :error
|
17
|
+
|
18
|
+
# == Class Methods ========================================================
|
19
|
+
|
20
|
+
def self.check(message, options = nil)
|
21
|
+
request('CHECK', message, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.symbols(message, options = nil)
|
25
|
+
request('SYMBOLS', message, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.report(message, options = nil)
|
29
|
+
request('REPORT', message, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.ping(options = nil)
|
33
|
+
request('PING', nil, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.request(command, message, options = nil)
|
37
|
+
if (options)
|
38
|
+
options = DEFAULT_OPTIONS.merge(options)
|
39
|
+
else
|
40
|
+
options = DEFAULT_OPTIONS
|
41
|
+
end
|
42
|
+
|
43
|
+
EventMachine.connect(
|
44
|
+
options[:host],
|
45
|
+
options[:port],
|
46
|
+
self,
|
47
|
+
[
|
48
|
+
Fiber.current,
|
49
|
+
command,
|
50
|
+
message
|
51
|
+
]
|
52
|
+
)
|
53
|
+
|
54
|
+
Fiber.yield
|
55
|
+
end
|
56
|
+
|
57
|
+
# == Instance Methods =====================================================
|
58
|
+
|
59
|
+
def initialize(options)
|
60
|
+
@fiber = options[0]
|
61
|
+
@command = options[1]
|
62
|
+
@message = options[2] && (options[2].gsub(/\r?\n/, "\r\n") + "\r\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
# EventMachine hook that's engaged after the client is initialized.
|
66
|
+
def post_init
|
67
|
+
if (error?)
|
68
|
+
@fiber.resume
|
69
|
+
else
|
70
|
+
send_data("#{@command} #{PROTO_VERSION}\r\n")
|
71
|
+
|
72
|
+
if (@message)
|
73
|
+
send_data("Content-length: #{@message.bytesize}\r\n")
|
74
|
+
send_data("\r\n")
|
75
|
+
send_data(@message)
|
76
|
+
else
|
77
|
+
send_data("\r\n")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def receive_data(data)
|
83
|
+
@data ||= ''
|
84
|
+
@data << data
|
85
|
+
end
|
86
|
+
|
87
|
+
def unbind
|
88
|
+
result = EmSpamc::Result.new
|
89
|
+
|
90
|
+
if (@data)
|
91
|
+
result.headers = EmSpamc::HeaderParser.parse(@data)
|
92
|
+
|
93
|
+
case (@command)
|
94
|
+
when 'REPORT'
|
95
|
+
result.report = EmSpamc::ReportParser.parse(@data)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
@fiber.resume(result)
|
100
|
+
end
|
101
|
+
|
102
|
+
def error?
|
103
|
+
!!@error
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class EmSpamc::HeaderParser
|
2
|
+
def self.parse(data)
|
3
|
+
lines = data.split(/\r?\n/)
|
4
|
+
headers = { }
|
5
|
+
|
6
|
+
lines.each do |line|
|
7
|
+
case (line)
|
8
|
+
when /^SPAMD\/(\d+\.\d+) (.*)/
|
9
|
+
code, message = $2.split(/\s+/)
|
10
|
+
|
11
|
+
headers[:version] = $1
|
12
|
+
headers[:code] = code.match(/\d/) ? code.to_i : code
|
13
|
+
headers[:message] = message
|
14
|
+
when /^(\S+): (.*)\s;\s([0-9]*.[0-9]*)/
|
15
|
+
headers[:spam] = $2 == 'True'
|
16
|
+
headers[:score] = $3.to_f
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Special case: if we only have one header line back, means score of 0
|
21
|
+
if (lines.length == 1)
|
22
|
+
headers.merge!(:score => 0.0, :spam => false)
|
23
|
+
end
|
24
|
+
|
25
|
+
headers
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class EmSpamc::ReportParser
|
2
|
+
LINE_REGEXP = /-$/
|
3
|
+
RULE_REGEXP = /[0-9]*[.][0-9]\s\w*\s/
|
4
|
+
|
5
|
+
def self.parse(data)
|
6
|
+
split_data = data.split(LINE_REGEXP)
|
7
|
+
|
8
|
+
# Only status line is back - no report returned, no rules
|
9
|
+
if (split_data.length == 1)
|
10
|
+
return [ ]
|
11
|
+
end
|
12
|
+
|
13
|
+
last_part = split_data[1].sub(/^[\n\r]./,'').chomp.chomp
|
14
|
+
|
15
|
+
points_rules = last_part.gsub(RULE_REGEXP).collect do |sub|
|
16
|
+
sub.chomp(' ')
|
17
|
+
end
|
18
|
+
|
19
|
+
rule_texts = last_part.split(RULE_REGEXP).collect do |text|
|
20
|
+
text.delete("\n").squeeze.chomp(' ').sub(/^\s/, '')
|
21
|
+
end
|
22
|
+
|
23
|
+
rules = [ ]
|
24
|
+
|
25
|
+
points_rules.each_with_index do |points_rule, i|
|
26
|
+
split = points_rule.split(' ')
|
27
|
+
|
28
|
+
rules << {
|
29
|
+
:pts => split[0].to_f,
|
30
|
+
:rule => split[1],
|
31
|
+
:text => rule_texts[i + 1]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
rules
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class EmSpamc::Result
|
2
|
+
# == Constants ============================================================
|
3
|
+
|
4
|
+
ATTRIBUTES = [
|
5
|
+
:headers,
|
6
|
+
:threshold,
|
7
|
+
:tags,
|
8
|
+
:report
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
# == Instance Methods =====================================================
|
12
|
+
|
13
|
+
def initialize(attributes = nil)
|
14
|
+
@attributes = attributes || { }
|
15
|
+
end
|
16
|
+
|
17
|
+
ATTRIBUTES.each do |name|
|
18
|
+
define_method(name) do
|
19
|
+
@attributes[name]
|
20
|
+
end
|
21
|
+
|
22
|
+
define_method(:"#{name}=") do |value|
|
23
|
+
@attributes[name] = value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def spam?
|
28
|
+
headers and headers[:spam]
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Delivered-To: test@test.com
|
2
|
+
Received: by 10.180.189.141 with SMTP id gi13csp63398wic;
|
3
|
+
Thu, 14 Mar 2013 08:46:03 -0700 (PDT)
|
4
|
+
Return-Path: <sender@testapp.com>
|
5
|
+
Received: from outbound6.mailer.testapp.com (outbound6.mailer.testapp.com. [199.87.247.245])
|
6
|
+
by mx.google.com with ESMTPS id ep2si2060874qeb.27.2013.03.14.08.46.02
|
7
|
+
(version=TLSv1 cipher=RC4-SHA bits=128/128);
|
8
|
+
Thu, 14 Mar 2013 08:46:03 -0700 (PDT)
|
9
|
+
Received-SPF: pass (google.com: domain of sender@testapp.com designates 199.87.247.245 as permitted sender) client-ip=199.87.247.245;
|
10
|
+
Authentication-Results: mx.google.com;
|
11
|
+
spf=pass (google.com: domain of sender@testapp.com designates 199.87.247.245 as permitted sender) smtp.mail=sender@testapp.com
|
12
|
+
Date: Thu, 14 Mar 2013 15:46:02 +0000
|
13
|
+
To: person@test.com
|
14
|
+
Message-ID: <17ee1aab2074416831081825744deffb026f0dfe@outbound6.mailer.testapp.com>
|
15
|
+
Subject: Test Message RECIPIENT SUBJECT person@test.com
|
16
|
+
Mime-Version: 1.0
|
17
|
+
Content-Type: text/plain
|
18
|
+
Content-Transfer-Encoding: 7bit
|
19
|
+
Auto-Submitted: auto-generated
|
20
|
+
From: sender@testapp.com
|
21
|
+
|
22
|
+
Hey!
|
23
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
SPAMD/1.1 0 EX_OK
|
2
|
+
Spam: True ; 18.1 / 5.0
|
3
|
+
|
4
|
+
Spam detection software, running on the system "scan1.blue.postageapp.com", has
|
5
|
+
identified this incoming email as possible spam. The original message
|
6
|
+
has been attached to this so you can view it (if it isn't spam) or label
|
7
|
+
similar future email. If you have any questions, see
|
8
|
+
the administrator of that system for details.
|
9
|
+
|
10
|
+
Content preview: I found a way to "get even" with the financial market! I've
|
11
|
+
stumbled to this page: http://advertismenmore.com/ This dude is just crazy,
|
12
|
+
he will teach you how you can make up to $87 every minute! No string attached
|
13
|
+
and zero risk for you! and the best fact, its 100% free [...]
|
14
|
+
|
15
|
+
Content analysis details: (18.1 points, 5.0 required)
|
16
|
+
|
17
|
+
pts rule name description
|
18
|
+
---- ---------------------- --------------------------------------------------
|
19
|
+
3.6 RCVD_IN_PBL RBL: Received via a relay in Spamhaus PBL
|
20
|
+
[91.115.88.37 listed in zen.spamhaus.org]
|
21
|
+
0.7 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL
|
22
|
+
0.0 RCVD_IN_DNSWL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to DNSWL
|
23
|
+
was blocked. See
|
24
|
+
http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block
|
25
|
+
for more information.
|
26
|
+
[91.115.88.37 listed in list.dnswl.org]
|
27
|
+
1.6 RCVD_IN_BRBL_LASTEXT RBL: RCVD_IN_BRBL_LASTEXT
|
@@ -0,0 +1 @@
|
|
1
|
+
SPAMD/1.1 0 EX_OK
|
data/test/helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'yaml'
|
13
|
+
require 'test/unit'
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
|
18
|
+
require 'em-spamc'
|
19
|
+
require 'eventmachine'
|
20
|
+
|
21
|
+
class Test::Unit::TestCase
|
22
|
+
def example_message(name)
|
23
|
+
message_path = File.expand_path("examples/messages/#{name}.txt", File.dirname(__FILE__))
|
24
|
+
|
25
|
+
File.open(message_path).read
|
26
|
+
end
|
27
|
+
|
28
|
+
def example_report(name)
|
29
|
+
message_path = File.expand_path("examples/reports/#{name}.txt", File.dirname(__FILE__))
|
30
|
+
|
31
|
+
File.open(message_path).read
|
32
|
+
end
|
33
|
+
|
34
|
+
def connection_options
|
35
|
+
config_file = File.expand_path('config/spamassassin.yml', File.dirname(__FILE__))
|
36
|
+
|
37
|
+
Hash[
|
38
|
+
YAML.load(File.open(config_file)).collect do |key, value|
|
39
|
+
[ key.to_sym, value ]
|
40
|
+
end
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
def eventmachine
|
45
|
+
EventMachine.run do
|
46
|
+
Fiber.new do
|
47
|
+
yield
|
48
|
+
EventMachine.stop_event_loop
|
49
|
+
end.resume
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class TestEmSpamcConnection < Test::Unit::TestCase
|
4
|
+
def test_ping
|
5
|
+
eventmachine do
|
6
|
+
result = EmSpamc::Connection.ping(connection_options)
|
7
|
+
|
8
|
+
assert result
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_symbols
|
13
|
+
eventmachine do
|
14
|
+
message = example_message(:sample)
|
15
|
+
result = EmSpamc::Connection.symbols(message, connection_options)
|
16
|
+
|
17
|
+
assert result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_report
|
22
|
+
eventmachine do
|
23
|
+
message = example_message(:sample)
|
24
|
+
|
25
|
+
result = EmSpamc::Connection.report(message, connection_options)
|
26
|
+
|
27
|
+
assert result
|
28
|
+
assert result.report
|
29
|
+
assert result.headers[:score]
|
30
|
+
|
31
|
+
assert_equal result.spam?, false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_check
|
36
|
+
eventmachine do
|
37
|
+
message = example_message(:sample)
|
38
|
+
|
39
|
+
result = EmSpamc::Connection.check(message)
|
40
|
+
|
41
|
+
assert result
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class TestEmSpamcHeaderParser < Test::Unit::TestCase
|
4
|
+
def test_score_header
|
5
|
+
report = example_report('spam-report')
|
6
|
+
headers = EmSpamc::HeaderParser.parse(report)
|
7
|
+
assert_equal headers[:spam], true
|
8
|
+
assert headers[:score] >= 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_zero_header
|
12
|
+
report = example_report('zero-report')
|
13
|
+
headers = EmSpamc::HeaderParser.parse(report)
|
14
|
+
assert headers[:score]
|
15
|
+
assert_equal headers[:score], 0
|
16
|
+
assert_equal headers[:spam], false
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class TestEmSpamcReportParser < Test::Unit::TestCase
|
4
|
+
def test_parsing_spam
|
5
|
+
eventmachine do
|
6
|
+
report = example_report('spam-report')
|
7
|
+
rules = EmSpamc::ReportParser.parse(report)
|
8
|
+
assert rules
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_parsing_zero
|
13
|
+
eventmachine do
|
14
|
+
report = example_report('zero-report')
|
15
|
+
rules = EmSpamc::ReportParser.parse(report)
|
16
|
+
assert rules
|
17
|
+
assert_equal rules, []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
class TestEmSpamcConnection < Test::Unit::TestCase
|
4
|
+
def test_defaults
|
5
|
+
result = EmSpamc::Result.new
|
6
|
+
|
7
|
+
assert_equal nil, result.headers
|
8
|
+
assert_equal nil, result.report
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_assignment
|
12
|
+
result = EmSpamc::Result.new
|
13
|
+
|
14
|
+
assert_equal nil, result.headers
|
15
|
+
|
16
|
+
result.headers = { :code => 0 }
|
17
|
+
|
18
|
+
assert_equal 0, result.headers[:code]
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: em-spamc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Scott Tadman
|
9
|
+
- Stephan Leroux
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-04-17 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: eventmachine
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: bundler
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: jeweler
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.8.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.8.4
|
63
|
+
description: Implementation of the "spamc" protocol for EventMachine
|
64
|
+
email: github@tadman.ca
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files:
|
68
|
+
- LICENSE.txt
|
69
|
+
- README.md
|
70
|
+
files:
|
71
|
+
- .document
|
72
|
+
- Gemfile
|
73
|
+
- LICENSE.txt
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- VERSION
|
77
|
+
- em-spamc.gemspec
|
78
|
+
- lib/em-spamc.rb
|
79
|
+
- lib/em_spamc.rb
|
80
|
+
- lib/em_spamc/connection.rb
|
81
|
+
- lib/em_spamc/header_parser.rb
|
82
|
+
- lib/em_spamc/report_parser.rb
|
83
|
+
- lib/em_spamc/result.rb
|
84
|
+
- test/config/spamassassin.yml
|
85
|
+
- test/config/spamassassin.yml.example
|
86
|
+
- test/examples/messages/sample.txt
|
87
|
+
- test/examples/messages/zero-score.txt
|
88
|
+
- test/examples/reports/spam-report.txt
|
89
|
+
- test/examples/reports/zero-report.txt
|
90
|
+
- test/examples/sample.txt
|
91
|
+
- test/helper.rb
|
92
|
+
- test/unit/test_em_spamc.rb
|
93
|
+
- test/unit/test_em_spamc_connection.rb
|
94
|
+
- test/unit/test_em_spamc_header_parser.rb
|
95
|
+
- test/unit/test_em_spamc_report_parser.rb
|
96
|
+
- test/unit/test_em_spamc_result.rb
|
97
|
+
homepage: http://github.com/twg/em-spamc
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 1.8.25
|
119
|
+
signing_key:
|
120
|
+
specification_version: 3
|
121
|
+
summary: SpamAssassin Connection for EventMachine
|
122
|
+
test_files: []
|