em-spamc 0.1.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/.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: []
|