mollom 0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,25 +1,37 @@
1
1
  == Mollom
2
2
 
3
- This is a Ruby class for easy interfacing with the mollom.com open API for spam detection and content quality assesment.
3
+ This is a Ruby class for easy interfacing with the mollom.com open API for spam detection and content quality assessment.
4
+
5
+ == Installation
6
+
7
+ You can either install the library as a gem
8
+ gem install mollom
9
+
10
+ Or you can get the latest development version from GitHub:
11
+ git clone git://github.com/DefV/ruby-mollom.git
4
12
 
5
13
  == Usage
6
14
 
7
- After you have requested a public/private keypair from Mollom (on http://www.mollom.com), you can start using this class.
15
+ After you have requested a public/private key-pair from Mollom (on http://www.mollom.com), you can start using this class.
8
16
 
9
- require 'lib/mollom'
17
+ require 'rubygems'
18
+ require 'mollom'
10
19
 
11
- m = Mollom.new(:private_key => 'azkaozdkoakdzkodazdz', :public_key => '34342ikdiozeezioez')
20
+ m = Mollom.new(:private_key => 'your-private-key', :public_key => 'your-public-key')
12
21
 
13
22
  content = m.check_content(:post_title => 'Mollem is an open API',
14
- :post_body => "Mollem is an open API for spam detection and content quality assessment.",
23
+ :post_body => "Lorem Ipsum dolor...",
15
24
  :author_name => 'Jan De Poorter',
16
25
  :author_url => 'http://blog.defv.be')
17
- if content.unsure? or content.spam?
18
- puts "Captcha: " + m.image_captcha(:session_id => content.session_id)["url"]
19
- print "Captcha is: "
20
- puts m.check_captcha(:session_id => content.session_id, :solution => STDIN.gets.chomp)
26
+ if content.spam?
27
+ puts "You, sir, are a spammer.. Goodbye!"
28
+ elsif content.unsure?
29
+ # possible spam, possible ham, show CAPTCHA
30
+ puts "CAPTCHA: " + m.image_captcha(:session_id => content.session_id)["url"]
31
+
32
+ captcha_correct = m.check_captcha(:session_id => content.session_id, :solution => STDIN.gets.chomp)
21
33
  else
22
34
  puts "The post is perfect! No spam!"
23
35
  end
24
36
 
25
- Copyright (c) 2008 Jan De Poorter - Openminds BVBA, released under the MIT license
37
+ Copyright (c) 2008 Jan De Poorter - Openminds BVBA, released under the MIT license
data/lib/mollom.rb CHANGED
@@ -2,6 +2,9 @@ require 'xmlrpc/client'
2
2
  require 'openssl'
3
3
  require 'base64'
4
4
 
5
+ # Mollom API requires this to change, but this gives a warning!
6
+ # XMLRPC::Client::USER_AGENT = "Ruby Mollom/0.1"
7
+
5
8
  class Mollom
6
9
  API_VERSION = '1.0'
7
10
  module Errors
@@ -116,26 +119,36 @@ class Mollom
116
119
  def send_command(command, data = {})
117
120
  server_list.each do |server|
118
121
  begin
119
- return XMLRPC::Client.new(server, "/#{API_VERSION}").call(command, data.merge(authentication_hash))
122
+ return XMLRPC::Client.new(server[:ip], "/#{API_VERSION}").call(command, data.merge(authentication_hash))
123
+ # TODO: Rescue more stuff (Connection Timeout and such)
120
124
  rescue XMLRPC::FaultException => error
121
125
  case error.faultCode
122
126
  when Errors::Standard
123
127
  raise Error.new(error.faultString)
124
128
  when Errors::Refresh
125
- # TO IMPLEMENT
129
+ # we take this one out of our loop
130
+ raise
126
131
  when Errors::Redirect
127
132
  next
128
133
  else
129
- raise
134
+ next
130
135
  end
131
136
  end
132
137
  end
138
+ raise Mollom::NoAvailableServers
139
+ rescue XMLRPC::FaultException
140
+ # We know it is Errors::Refresh
141
+ server_list(true)
142
+ retry
133
143
  end
134
144
 
135
145
  # Gets a list of servers from Mollom
136
- def server_list
137
- # Mollom prepends 'http://' to the IP.. Ruby doesn't like that
138
- @server_list ||= XMLRPC::Client.new("xmlrpc.mollom.com", "/#{API_VERSION}").call('mollom.getServerList', authentication_hash).collect { |s| s.sub('http://', '') }
146
+ def server_list refresh = false
147
+ @server_list = nil if refresh
148
+ @server_list ||= XMLRPC::Client.new("xmlrpc.mollom.com", "/#{API_VERSION}").call('mollom.getServerList', authentication_hash).collect do |server|
149
+ proto, ip = server.split('://')
150
+ {:proto => proto, :ip => ip}
151
+ end
139
152
  end
140
153
 
141
154
  # Creates a HMAC-SHA1 Hash with the current timestamp, and your private key.
@@ -143,8 +156,8 @@ class Mollom
143
156
  now = Time.now.gmtime.strftime('%Y-%m-%dT%H:%M:%S.000+0000')
144
157
 
145
158
  hash = Base64.encode64(
146
- OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, @private_key, now)
147
- )
159
+ OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, @private_key, now)
160
+ ).chomp
148
161
 
149
162
  return :public_key=> @public_key, :time => now, :hash => hash
150
163
  end
@@ -196,4 +209,5 @@ class Mollom
196
209
  end
197
210
 
198
211
  class Error < StandardError; end
212
+ class NoAvailableServers < Error; end
199
213
  end
@@ -0,0 +1,33 @@
1
+ require "test/unit"
2
+
3
+ require "mollom"
4
+
5
+ class TestContentResponse < Test::Unit::TestCase
6
+ def test_spam
7
+ cr = Mollom::ContentResponse.new('spam' => 3, 'session_id' => '1', 'quality' => '10')
8
+ assert cr.spam?
9
+ assert !cr.ham?
10
+ assert_equal 'spam', cr.to_s
11
+ end
12
+
13
+ def test_ham
14
+ cr = Mollom::ContentResponse.new('spam' => 1, 'session_id' => '1', 'quality' => '10')
15
+ assert cr.ham?
16
+ assert !cr.spam?
17
+ assert_equal 'ham', cr.to_s
18
+ end
19
+
20
+ def test_unknown
21
+ cr = Mollom::ContentResponse.new('spam' => 0, 'session_id' => '1', 'quality' => '10')
22
+ assert cr.unknown?
23
+ assert !cr.unsure?
24
+ assert_equal 'unknown', cr.to_s
25
+ end
26
+
27
+ def test_unsure
28
+ cr = Mollom::ContentResponse.new('spam' => 2, 'session_id' => '1', 'quality' => '10')
29
+ assert cr.unsure?
30
+ assert !cr.unknown?
31
+ assert_equal 'unsure', cr.to_s
32
+ end
33
+ end
@@ -0,0 +1,136 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'mocha'
4
+
5
+ require 'mollom'
6
+
7
+ class Mollom
8
+ # Unprivate all methods
9
+ public :authentication_hash
10
+ public :server_list
11
+ public :send_command
12
+ end
13
+
14
+ class TestMollom < Test::Unit::TestCase
15
+ def setup
16
+ @mollom = Mollom.new(:private_key => 'xxxxxxxxx', :public_key => 'yyyyyyyyy')
17
+ end
18
+
19
+ def test_initialize
20
+ assert_equal 'xxxxxxxxx', @mollom.private_key
21
+ assert_equal 'yyyyyyyyy', @mollom.public_key
22
+ end
23
+
24
+ def test_authentication_hash
25
+ time = mock
26
+ time.expects(:strftime).with('%Y-%m-%dT%H:%M:%S.000+0000').returns('2008-04-01T13:54:26.000+0000')
27
+ Time.stubs(:now).returns(stub(:gmtime => time))
28
+ hash = @mollom.authentication_hash
29
+ assert_equal("24qAgAC1v1U+5NbKyrQSp/XKWAI=", hash[:hash])
30
+ assert_equal('yyyyyyyyy', hash[:public_key])
31
+ assert_equal('2008-04-01T13:54:26.000+0000', hash[:time])
32
+ end
33
+
34
+ def test_server_list
35
+ xml_rpc = mock
36
+ xml_rpc.expects(:call).with('mollom.getServerList', is_a(Hash)).returns(['http://172.16.0.1', 'http://172.16.0.2', 'https://172.16.0.2'])
37
+ XMLRPC::Client.stubs(:new).with('xmlrpc.mollom.com', '/1.0').returns(xml_rpc)
38
+
39
+ assert_equal [{:ip => '172.16.0.1', :proto => 'http'}, {:ip => '172.16.0.2', :proto => 'http'}, {:ip => '172.16.0.2', :proto => 'https'}], @mollom.server_list
40
+ end
41
+
42
+ def test_server_list_force_reload
43
+ xml_rpc = mock
44
+ xml_rpc.expects(:call).times(2).with('mollom.getServerList', is_a(Hash)).returns(['http://172.16.0.1', 'http://172.16.0.2', 'https://172.16.0.2'])
45
+ XMLRPC::Client.stubs(:new).with('xmlrpc.mollom.com', '/1.0').returns(xml_rpc)
46
+
47
+ @mollom.server_list
48
+ @mollom.server_list
49
+ @mollom.server_list(true)
50
+ end
51
+
52
+ def test_send_command_with_good_server
53
+ Mollom.any_instance.stubs(:server_list).returns([{:ip => '172.16.0.1', :proto => 'http'}])
54
+ xml_rpc = mock
55
+ xml_rpc.expects(:call).with('mollom.testMessage', has_entry(:options => 'foo'))
56
+ XMLRPC::Client.stubs(:new).with('172.16.0.1', '/1.0').returns(xml_rpc)
57
+
58
+ @mollom.send_command('mollom.testMessage', {:options => 'foo'})
59
+ end
60
+
61
+
62
+ def test_send_command_with_bad_server
63
+ Mollom.any_instance.stubs(:server_list).returns([{:ip => '172.16.0.1', :proto => 'http'}, {:ip => '172.16.0.2', :proto => 'http'}])
64
+ xml_rpc = mock
65
+ xml_rpc.expects(:call).with('mollom.testMessage', has_entry(:options => 'foo')).raises(XMLRPC::FaultException.new(1200, "Redirect"))
66
+ xml_rpc2 = mock
67
+ xml_rpc2.expects(:call).with('mollom.testMessage', has_entry(:options => 'foo'))
68
+
69
+ XMLRPC::Client.stubs(:new).with('172.16.0.1', '/1.0').returns(xml_rpc)
70
+ XMLRPC::Client.stubs(:new).with('172.16.0.2', '/1.0').returns(xml_rpc2)
71
+ @mollom.send_command('mollom.testMessage', {:options => 'foo'})
72
+ end
73
+
74
+ def test_send_command_with_reload_exception
75
+ # TODO: Test this
76
+ @mollom.send_command('mollom.testMessage', {:options => 'foo'})
77
+ end
78
+
79
+ def test_send_command_with_bad_command
80
+ Mollom.any_instance.stubs(:server_list).returns([{:ip => '172.16.0.1', :proto => 'http'}])
81
+ xml_rpc = mock
82
+ xml_rpc.expects(:call).with('mollom.testMessage', has_entry(:options => 'foo')).raises(XMLRPC::FaultException.new(1000, "Fault String"))
83
+ XMLRPC::Client.stubs(:new).with('172.16.0.1', '/1.0').returns(xml_rpc)
84
+
85
+ assert_raise(Mollom::Error) { @mollom.send_command('mollom.testMessage', {:options => 'foo'}) }
86
+ end
87
+
88
+ def test_send_command_with_bad_server_and_no_more_available
89
+ Mollom.any_instance.stubs(:server_list).returns([{:ip => '172.16.0.1', :proto => 'http'}])
90
+ xml_rpc = mock
91
+ xml_rpc.expects(:call).with('mollom.testMessage', has_entry(:options => 'foo')).raises(XMLRPC::FaultException.new(1200, "Redirect"))
92
+
93
+ XMLRPC::Client.stubs(:new).with('172.16.0.1', '/1.0').returns(xml_rpc)
94
+
95
+ assert_raise(Mollom::NoAvailableServers) { @mollom.send_command('mollom.testMessage', {:options => 'foo'}) }
96
+ end
97
+
98
+ def test_check_content
99
+ Mollom.any_instance.expects(:send_command).with('mollom.checkContent', :author_ip => '172.16.0.1', :post_body => 'Lorem Ipsum').returns("spam" => 1, "quality" => 0.40, "session_id" => 1)
100
+ cr = @mollom.check_content(:author_ip => '172.16.0.1', :post_body => 'Lorem Ipsum')
101
+ assert cr.ham?
102
+ assert_equal 1, cr.session_id
103
+ assert_equal 0.40, cr.quality
104
+ end
105
+
106
+ def test_image_captcha
107
+ Mollom.any_instance.expects(:send_command).with('mollom.getImageCaptcha', :author_ip => '172.16.0.1').returns('url' => 'http://xmlrpc1.mollom.com:80/a9616e6b4cd6a81ecdd509fa624d895d.png', 'session_id' => 'a9616e6b4cd6a81ecdd509fa624d895d')
108
+ @mollom.image_captcha(:author_ip => '172.16.0.1')
109
+ end
110
+
111
+ def test_audio_captcha
112
+ Mollom.any_instance.expects(:send_command).with('mollom.getAudioCaptcha', :author_ip => '172.16.0.1').returns('url' => 'http://xmlrpc1.mollom.com:80/a9616e6b4cd6a81ecdd509fa624d895d.mp3', 'session_id' => 'a9616e6b4cd6a81ecdd509fa624d895d')
113
+ @mollom.audio_captcha(:author_ip => '172.16.0.1')
114
+ end
115
+
116
+ def test_valid_captcha
117
+ Mollom.any_instance.expects(:send_command).with('mollom.checkCaptcha', :session_id => 'a9616e6b4cd6a81ecdd509fa624d895d', :solution => 'foo').returns(true)
118
+ @mollom.valid_captcha?(:session_id => 'a9616e6b4cd6a81ecdd509fa624d895d', :solution => 'foo')
119
+ end
120
+
121
+ def test_key_ok
122
+ Mollom.any_instance.expects(:send_command).with('mollom.verifyKey').returns(true)
123
+ @mollom.key_ok?
124
+ end
125
+
126
+ def test_statistics
127
+ Mollom.any_instance.expects(:send_command).with('mollom.getStatistics', :type => 'total_accepted').returns(123)
128
+ @mollom.statistics(:type => 'total_accepted')
129
+ end
130
+
131
+ def test_send_feedback
132
+ Mollom.any_instance.expects(:send_command).with('mollom.sendFeedback', :session_id => 1, :feedback => 'profanity')
133
+ @mollom.send_feedback :session_id => 1, :feedback => 'profanity'
134
+ end
135
+
136
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mollom
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan De Poorter
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-04-01 00:00:00 +02:00
12
+ date: 2008-04-04 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -45,10 +45,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
45
  version:
46
46
  requirements: []
47
47
 
48
- rubyforge_project:
48
+ rubyforge_project: mollom
49
49
  rubygems_version: 1.0.1
50
50
  signing_key:
51
51
  specification_version: 2
52
52
  summary: Ruby class for easy interfacing with the mollom.com open API for spam detection and content quality assesment.
53
- test_files: []
54
-
53
+ test_files:
54
+ - test/content_response_test.rb
55
+ - test/mollom_test.rb