cleverbot 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,7 @@
1
1
  source :rubygems
2
2
 
3
+ gem 'httparty', '~> 0.8.0'
4
+
3
5
  group :development do
4
6
  gem 'bundler', '~> 1.0'
5
7
  gem 'jeweler', '~> 1.6'
@@ -3,10 +3,15 @@ GEM
3
3
  specs:
4
4
  diff-lcs (1.1.3)
5
5
  git (1.2.5)
6
+ httparty (0.8.0)
7
+ multi_json
8
+ multi_xml
6
9
  jeweler (1.6.4)
7
10
  bundler (~> 1.0)
8
11
  git (>= 1.2.5)
9
12
  rake
13
+ multi_json (1.0.3)
14
+ multi_xml (0.4.0)
10
15
  rake (0.9.2)
11
16
  rcov (0.9.10)
12
17
  rdoc (3.9.4)
@@ -24,6 +29,7 @@ PLATFORMS
24
29
 
25
30
  DEPENDENCIES
26
31
  bundler (~> 1.0)
32
+ httparty (~> 0.8.0)
27
33
  jeweler (~> 1.6)
28
34
  rcov (~> 0.9)
29
35
  rdoc (~> 3.9)
@@ -2,6 +2,28 @@
2
2
 
3
3
  Ruby wrapper for Cleverbot.
4
4
 
5
+ == Examples
6
+
7
+ === Talk to Cleverbot with Cleverbot::Client.write
8
+
9
+ @params = Cleverbot::Client.write 'Hi.'
10
+ @params['message'] # => "How are you?"
11
+ @params['sessionid'] # => "ABC01234567"
12
+
13
+ @params.keep_if { |key, value| Cleverbot::Client::DEFAULT_PARAMS.keys.include? key }
14
+ @params['message'] # => nil
15
+ @params['sessionid'] # => "ABC01234567"
16
+
17
+ @params = Cleverbot::Client.write 'Good, you?', @params
18
+ @params['message'] # => "Good."
19
+ @params['sessionid'] # => "ABC01234567"
20
+
21
+ === Talk to Cleverbot with Cleverbot::Client#write to manage parameters.
22
+
23
+ @client = Cleverbot::Client.new
24
+ @client.write 'Hi.' # => "How are you?"
25
+ @client.write 'Good, you?' # => "Good."
26
+
5
27
  == Contributing to cleverbot
6
28
 
7
29
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{cleverbot}
8
- s.version = "0.0.1"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Benjamin Manns"]
12
- s.date = %q{2011-09-14}
12
+ s.date = %q{2011-09-16}
13
13
  s.description = %q{Ruby wrapper for Cleverbot.}
14
14
  s.email = %q{benmanns@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -28,6 +28,10 @@ Gem::Specification.new do |s|
28
28
  "VERSION",
29
29
  "cleverbot.gemspec",
30
30
  "lib/cleverbot.rb",
31
+ "lib/cleverbot/client.rb",
32
+ "lib/cleverbot/parser.rb",
33
+ "spec/cleverbot/client_spec.rb",
34
+ "spec/cleverbot/parser_spec.rb",
31
35
  "spec/cleverbot_spec.rb",
32
36
  "spec/spec_helper.rb"
33
37
  ]
@@ -41,12 +45,14 @@ Gem::Specification.new do |s|
41
45
  s.specification_version = 3
42
46
 
43
47
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
48
+ s.add_runtime_dependency(%q<httparty>, ["~> 0.8.0"])
44
49
  s.add_development_dependency(%q<bundler>, ["~> 1.0"])
45
50
  s.add_development_dependency(%q<jeweler>, ["~> 1.6"])
46
51
  s.add_development_dependency(%q<rcov>, ["~> 0.9"])
47
52
  s.add_development_dependency(%q<rdoc>, ["~> 3.9"])
48
53
  s.add_development_dependency(%q<rspec>, ["~> 2.3"])
49
54
  else
55
+ s.add_dependency(%q<httparty>, ["~> 0.8.0"])
50
56
  s.add_dependency(%q<bundler>, ["~> 1.0"])
51
57
  s.add_dependency(%q<jeweler>, ["~> 1.6"])
52
58
  s.add_dependency(%q<rcov>, ["~> 0.9"])
@@ -54,6 +60,7 @@ Gem::Specification.new do |s|
54
60
  s.add_dependency(%q<rspec>, ["~> 2.3"])
55
61
  end
56
62
  else
63
+ s.add_dependency(%q<httparty>, ["~> 0.8.0"])
57
64
  s.add_dependency(%q<bundler>, ["~> 1.0"])
58
65
  s.add_dependency(%q<jeweler>, ["~> 1.6"])
59
66
  s.add_dependency(%q<rcov>, ["~> 0.9"])
@@ -1,2 +1,5 @@
1
+ require 'cleverbot/client'
2
+
3
+ # Module enclosing all Cleverbot related classes.
1
4
  module Cleverbot
2
5
  end
@@ -0,0 +1,91 @@
1
+ require 'cleverbot/parser'
2
+
3
+ module Cleverbot
4
+ # Ruby wrapper for Cleverbot.com.
5
+ class Client
6
+ include HTTParty
7
+
8
+ # The default form variables for POSTing to Cleverbot.com
9
+ DEFAULT_PARAMS = {
10
+ 'stimulus' => '',
11
+ 'start' => 'y',
12
+ 'sessionid' => '',
13
+ 'vText8' => '',
14
+ 'vText7' => '',
15
+ 'vText6' => '',
16
+ 'vText5' => '',
17
+ 'vText4' => '',
18
+ 'vText3' => '',
19
+ 'vText2' => '',
20
+ 'icognoid' => 'wsf',
21
+ 'icognocheck' => '',
22
+ 'fno' => '0',
23
+ 'prevref' => '',
24
+ 'emotionaloutput' => '',
25
+ 'emotionalhistory' => '',
26
+ 'asbotname' => '',
27
+ 'ttsvoice' => '',
28
+ 'typing' => '',
29
+ 'lineref' => '',
30
+ 'sub' => 'Say',
31
+ 'islearning' => '1',
32
+ 'cleanslate' => 'false',
33
+ }
34
+
35
+ # The path to the form endpoint on Cleverbot.com.
36
+ PATH = '/webservicemin'
37
+
38
+ base_uri 'http://www.cleverbot.com'
39
+
40
+ parser Parser
41
+
42
+ # Holds the parameters for an instantiated Cleverbot::Base.
43
+ attr_reader :params
44
+
45
+ # Creates a digest from the form parameters.
46
+ #
47
+ # ==== Parameters
48
+ #
49
+ # [<tt>body</tt>] <tt>String</tt> to be digested.
50
+ def self.digest body
51
+ Digest::MD5.hexdigest body[9...29]
52
+ end
53
+
54
+ # Sends a message to Cleverbot.com and returns a <tt>Hash</tt> containing the parameters received.
55
+ #
56
+ # ==== Parameters
57
+ #
58
+ # [<tt>message</tt>] Optional <tt>String</tt> holding the message to be sent. Defaults to <tt>''</tt>.
59
+ # [<tt>params</tt>] Optional <tt>Hash</tt> with form parameters. Merged with DEFAULT_PARAMS. Defaults to <tt>{}</tt>.
60
+ def self.write message='', params={}
61
+ body = DEFAULT_PARAMS.merge params
62
+ body['stimulus'] = message
63
+ body['icognocheck'] = digest HashConversions.to_params(body)
64
+
65
+ post(PATH, :body => body).parsed_response
66
+ end
67
+
68
+ # Initializes a Cleverbot::Base with given parameters.
69
+ #
70
+ # ==== Parameters
71
+ #
72
+ # [<tt>params</tt>] Optional <tt>Hash</tt> holding the initial parameters. Defaults to <tt>{}</tt>.
73
+ def initialize params={}
74
+ @params = params
75
+ end
76
+
77
+ # Sends a message and returns a <tt>String</tt> with the message received. Updates #params to maintain state.
78
+ #
79
+ # ==== Parameters
80
+ #
81
+ # [<tt>message</tt>] Optional <tt>String</tt> holding the message to be sent. Defaults to <tt>''</tt>.
82
+ def write message=''
83
+ response = self.class.write message, @params
84
+ message = response['message']
85
+ response.keep_if { |key, value| DEFAULT_PARAMS.keys.include? key }
86
+ @params.merge! response
87
+ @params.delete_if { |key, value| DEFAULT_PARAMS[key] == value }
88
+ message
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,44 @@
1
+ require 'httparty'
2
+
3
+ module Cleverbot
4
+ # Used in Cleverbot::Client to parse responses from Cleverbot.com.
5
+ class Parser < HTTParty::Parser
6
+ # Keys that correspond to the <tt>Array</tt> that Cleverbot.com returns.
7
+ # They are combined with the <tt>Array</tt> to form a response <tt>Hash</tt>.
8
+ KEYS = [
9
+ 'message',
10
+ 'sessionid',
11
+ 'logurl',
12
+ 'vText8',
13
+ 'vText7',
14
+ 'vText6',
15
+ 'vText5',
16
+ 'vText4',
17
+ 'vText3',
18
+ 'vText2',
19
+ 'prevref',
20
+ nil,
21
+ 'emotionalhistory',
22
+ 'ttsLocMP3',
23
+ 'ttsLocTXT',
24
+ 'ttsLocTXT3',
25
+ 'ttsText',
26
+ 'lineref',
27
+ 'lineURL',
28
+ 'linePOST',
29
+ 'lineChoices',
30
+ 'lineChoicesAbbrev',
31
+ 'typingData',
32
+ 'divert',
33
+ ]
34
+
35
+ # Formats supported by the parser.
36
+ # Parser handles <tt>text/html</tt> responses only with #html.
37
+ SupportedFormats = { 'text/html' => :html }
38
+
39
+ # Splits the body on <tt>"\\r"</tt> and zips the result with KEYS, which is then formed into a <tt>Hash</tt>.
40
+ def html
41
+ Hash[KEYS.zip(body.split("\r"))]
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,181 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Cleverbot::Client do
4
+ subject { Cleverbot::Client }
5
+
6
+ it { should <= HTTParty }
7
+
8
+ describe '::DEFAULT_PARAMS' do
9
+ subject { Cleverbot::Client::DEFAULT_PARAMS }
10
+
11
+ it do
12
+ should == {
13
+ 'stimulus' => '',
14
+ 'start' => 'y',
15
+ 'sessionid' => '',
16
+ 'vText8' => '',
17
+ 'vText7' => '',
18
+ 'vText6' => '',
19
+ 'vText5' => '',
20
+ 'vText4' => '',
21
+ 'vText3' => '',
22
+ 'vText2' => '',
23
+ 'icognoid' => 'wsf',
24
+ 'icognocheck' => '',
25
+ 'fno' => '0',
26
+ 'prevref' => '',
27
+ 'emotionaloutput' => '',
28
+ 'emotionalhistory' => '',
29
+ 'asbotname' => '',
30
+ 'ttsvoice' => '',
31
+ 'typing' => '',
32
+ 'lineref' => '',
33
+ 'sub' => 'Say',
34
+ 'islearning' => '1',
35
+ 'cleanslate' => 'false',
36
+ }
37
+ end
38
+ end
39
+
40
+ describe '::PATH' do
41
+ subject { Cleverbot::Client::PATH }
42
+
43
+ it { should == '/webservicemin' }
44
+ end
45
+
46
+ describe '.base_uri' do
47
+ subject { Cleverbot::Client.base_uri }
48
+
49
+ it { should == 'http://www.cleverbot.com' }
50
+ end
51
+
52
+ describe '.parser' do
53
+ subject { Cleverbot::Client.parser }
54
+
55
+ it { should == Cleverbot::Parser }
56
+ end
57
+
58
+ describe '.digest' do
59
+ subject { Cleverbot::Client.digest @body }
60
+ context 'given a body of 0123456789abcdefghijklmnopqrstuvwxyz' do
61
+ before :each do
62
+ @body = '0123456789abcdefghijklmnopqrstuvwxyz'
63
+ end
64
+
65
+ it 'should call Digest::MD5.hexdigest with 9abcdefghijklmnopqrs' do
66
+ Digest::MD5.should_receive(:hexdigest).with @body[9..28]
67
+ subject
68
+ end
69
+
70
+ context 'when Digest::MD5.hexdigest returns abcd' do
71
+ before :each do
72
+ Digest::MD5.stub!(:hexdigest).and_return 'abcd'
73
+ end
74
+
75
+ it { should == 'abcd' }
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '.write' do
81
+ subject { Cleverbot::Client.write @message, @params }
82
+
83
+ context 'with params {}' do
84
+ before :each do
85
+ @params = {}
86
+ end
87
+
88
+ context 'with an empty message' do
89
+ before :each do
90
+ @message = ''
91
+ end
92
+
93
+ it 'should post to PATH' do
94
+ Cleverbot::Client.should_receive(:post).with(Cleverbot::Client::PATH, hash_including).and_return mock(:parsed_response => {})
95
+ subject
96
+ end
97
+
98
+ Cleverbot::Client::DEFAULT_PARAMS.each do |key, value|
99
+ next if ['stimulus', 'icognocheck'].include? key
100
+ it "should add #{key} => #{value.inspect} to the post body" do
101
+ Cleverbot::Client.should_receive(:post).with(Cleverbot::Client::PATH, :body => hash_including(key => value)).and_return mock(:parsed_response => {})
102
+ subject
103
+ end
104
+ end
105
+
106
+ it 'should add stimulus => "" to the post body' do
107
+ Cleverbot::Client.should_receive(:post).with(Cleverbot::Client::PATH, :body => hash_including('stimulus' => '')).and_return mock(:parsed_response => {})
108
+ subject
109
+ end
110
+
111
+ context 'when digest returns abcd' do
112
+ before :each do
113
+ Digest::MD5.stub!(:hexdigest).and_return 'abcd'
114
+ end
115
+
116
+ it 'should add icognocheck => "abcd" to the post body' do
117
+ Cleverbot::Client.should_receive(:post).with(Cleverbot::Client::PATH, :body => hash_including('icognocheck' => 'abcd')).and_return mock(:parsed_response => {})
118
+ subject
119
+ end
120
+ end
121
+
122
+ context 'when the parsed response is {}' do
123
+ before :each do
124
+ Cleverbot::Client.stub!(:post).and_return mock(:parsed_response => {})
125
+ end
126
+
127
+ it { should == {} }
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ describe '#initialize' do
134
+ subject { Cleverbot::Client.new @params }
135
+
136
+ context 'with params { "a" => "b" }' do
137
+ before :each do
138
+ @params = { 'a' => 'b' }
139
+ end
140
+
141
+ it 'sets #params to { "a" => "b" }' do
142
+ subject.params.should == { 'a' => 'b' }
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#write' do
148
+ before :each do
149
+ @client = Cleverbot::Client.new
150
+ end
151
+
152
+ subject { @client.write @message }
153
+
154
+ context 'with an empty message' do
155
+ before :each do
156
+ @message = ''
157
+ end
158
+
159
+ it 'should call .write with "" and #params' do
160
+ Cleverbot::Client.should_receive(:write).with(@message, @client.params).and_return({})
161
+ subject
162
+ end
163
+
164
+ context 'when .write returns { "message" => "Hi.", "sessionid" => "abcd" }' do
165
+ before :each do
166
+ Cleverbot::Client.stub!(:write).and_return 'message' => 'Hi.', 'sessionid' => 'abcd'
167
+ end
168
+
169
+ it 'should set #params[sessionid] to abcd' do
170
+ subject
171
+ @client.params['sessionid'].should == 'abcd'
172
+ end
173
+
174
+ it 'should not set #params[message] to Hi.' do
175
+ subject
176
+ @client.params['message'].should_not == 'abcd'
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,84 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Cleverbot::Parser do
4
+ subject { Cleverbot::Parser }
5
+
6
+ it { should <= HTTParty::Parser }
7
+
8
+ it { should be_supports_format :html }
9
+
10
+ describe '::KEYS' do
11
+ subject { Cleverbot::Parser::KEYS }
12
+
13
+ it do
14
+ should == [
15
+ 'message',
16
+ 'sessionid',
17
+ 'logurl',
18
+ 'vText8',
19
+ 'vText7',
20
+ 'vText6',
21
+ 'vText5',
22
+ 'vText4',
23
+ 'vText3',
24
+ 'vText2',
25
+ 'prevref',
26
+ nil,
27
+ 'emotionalhistory',
28
+ 'ttsLocMP3',
29
+ 'ttsLocTXT',
30
+ 'ttsLocTXT3',
31
+ 'ttsText',
32
+ 'lineref',
33
+ 'lineURL',
34
+ 'linePOST',
35
+ 'lineChoices',
36
+ 'lineChoicesAbbrev',
37
+ 'typingData',
38
+ 'divert',
39
+ ]
40
+ end
41
+ end
42
+
43
+ describe '#call' do
44
+ subject { Cleverbot::Parser.call @body, @format }
45
+
46
+ context 'with a format of :html' do
47
+ before :each do
48
+ @format = :html
49
+ end
50
+
51
+ context 'with an empty body' do
52
+ before :each do
53
+ @body = ''
54
+ end
55
+
56
+ it { should be_nil }
57
+ end
58
+
59
+ context 'with an body of 0\r1\r2' do
60
+ before :each do
61
+ @body = (0..2).to_a.join "\r"
62
+ end
63
+
64
+ (0..2).each do |key|
65
+ it { should include({ Cleverbot::Parser::KEYS[key] => key.to_s }) }
66
+ end
67
+ (3..(Cleverbot::Parser::KEYS.length - 1)).each do |key|
68
+ it { should include({ Cleverbot::Parser::KEYS[key] => nil }) }
69
+ end
70
+ end
71
+
72
+ context 'with a body of length greater than KEYS.length' do
73
+ before :each do
74
+ @body = (0..Cleverbot::Parser::KEYS.length).to_a.join "\r"
75
+ end
76
+
77
+ (0..(Cleverbot::Parser::KEYS.length - 1)).each do |key|
78
+ it { should include({ Cleverbot::Parser::KEYS[key] => key.to_s }) }
79
+ end
80
+ it { should_not have_key Cleverbot::Parser::KEYS.length }
81
+ end
82
+ end
83
+ end
84
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cleverbot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-14 00:00:00.000000000 -04:00
12
+ date: 2011-09-16 00:00:00.000000000 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: httparty
17
+ requirement: &17723180 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.8.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *17723180
15
26
  - !ruby/object:Gem::Dependency
16
27
  name: bundler
17
- requirement: &20490020 !ruby/object:Gem::Requirement
28
+ requirement: &17722640 !ruby/object:Gem::Requirement
18
29
  none: false
19
30
  requirements:
20
31
  - - ~>
@@ -22,10 +33,10 @@ dependencies:
22
33
  version: '1.0'
23
34
  type: :development
24
35
  prerelease: false
25
- version_requirements: *20490020
36
+ version_requirements: *17722640
26
37
  - !ruby/object:Gem::Dependency
27
38
  name: jeweler
28
- requirement: &20488940 !ruby/object:Gem::Requirement
39
+ requirement: &17722040 !ruby/object:Gem::Requirement
29
40
  none: false
30
41
  requirements:
31
42
  - - ~>
@@ -33,10 +44,10 @@ dependencies:
33
44
  version: '1.6'
34
45
  type: :development
35
46
  prerelease: false
36
- version_requirements: *20488940
47
+ version_requirements: *17722040
37
48
  - !ruby/object:Gem::Dependency
38
49
  name: rcov
39
- requirement: &20487100 !ruby/object:Gem::Requirement
50
+ requirement: &17719820 !ruby/object:Gem::Requirement
40
51
  none: false
41
52
  requirements:
42
53
  - - ~>
@@ -44,10 +55,10 @@ dependencies:
44
55
  version: '0.9'
45
56
  type: :development
46
57
  prerelease: false
47
- version_requirements: *20487100
58
+ version_requirements: *17719820
48
59
  - !ruby/object:Gem::Dependency
49
60
  name: rdoc
50
- requirement: &20485800 !ruby/object:Gem::Requirement
61
+ requirement: &17719320 !ruby/object:Gem::Requirement
51
62
  none: false
52
63
  requirements:
53
64
  - - ~>
@@ -55,10 +66,10 @@ dependencies:
55
66
  version: '3.9'
56
67
  type: :development
57
68
  prerelease: false
58
- version_requirements: *20485800
69
+ version_requirements: *17719320
59
70
  - !ruby/object:Gem::Dependency
60
71
  name: rspec
61
- requirement: &20484600 !ruby/object:Gem::Requirement
72
+ requirement: &17718800 !ruby/object:Gem::Requirement
62
73
  none: false
63
74
  requirements:
64
75
  - - ~>
@@ -66,7 +77,7 @@ dependencies:
66
77
  version: '2.3'
67
78
  type: :development
68
79
  prerelease: false
69
- version_requirements: *20484600
80
+ version_requirements: *17718800
70
81
  description: Ruby wrapper for Cleverbot.
71
82
  email: benmanns@gmail.com
72
83
  executables: []
@@ -86,6 +97,10 @@ files:
86
97
  - VERSION
87
98
  - cleverbot.gemspec
88
99
  - lib/cleverbot.rb
100
+ - lib/cleverbot/client.rb
101
+ - lib/cleverbot/parser.rb
102
+ - spec/cleverbot/client_spec.rb
103
+ - spec/cleverbot/parser_spec.rb
89
104
  - spec/cleverbot_spec.rb
90
105
  - spec/spec_helper.rb
91
106
  has_rdoc: true
@@ -104,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
119
  version: '0'
105
120
  segments:
106
121
  - 0
107
- hash: 2178588374968580678
122
+ hash: 1100025997213852890
108
123
  required_rubygems_version: !ruby/object:Gem::Requirement
109
124
  none: false
110
125
  requirements: