chatroid 0.0.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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ryo NAKAMURA
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # Chatroid
2
+ Chatroid is a gem for quickly creating chatterbot in Ruby.
3
+
4
+ ## Installation
5
+
6
+ ```
7
+ $ gem "chatroid"
8
+ ```
9
+
10
+ ## Example
11
+ You can create your own bot working in a chat service.
12
+
13
+ ```ruby
14
+ require "chatroid"
15
+
16
+ Chatroid.new do
17
+ set :service, "Twitter"
18
+ set :consumer_key, "..."
19
+ set :consumer_secret, "..."
20
+ set :access_key, "..."
21
+ set :access_secret, "..."
22
+
23
+ on_message do |event|
24
+ post "Hello"
25
+ end
26
+
27
+ on_message /^Hi/ do |event|
28
+ post "Hi!"
29
+ end
30
+
31
+ on_reply do |event|
32
+ post "Hi!", :to => event
33
+ end
34
+
35
+ on_reply /^Nice to meet you/ do |event|
36
+ post "Nice to meet you too", :to => event
37
+ end
38
+
39
+ on_join do |event|
40
+ post "Nice to meet you, #{event.username}", :to => event
41
+ end
42
+ end.run!
43
+ ```
44
+
45
+ ## API
46
+
47
+ In the block of Chatroid.new, you can call following instance methods.
48
+
49
+ * set
50
+ * post
51
+ * on_xxx
52
+
53
+ xxx can be anything, and the adapter class for the specified service trigger on_xxx properly.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
data/chatroid.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/chatroid/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ryo NAKAMURA"]
6
+ gem.email = ["r7kamura@gmail.com"]
7
+ gem.description = "Chatroid is a gem for quickly creating chatterbot in Ruby"
8
+ gem.summary = "Chatterbot builder"
9
+ gem.homepage = "https://github.com/r7kamura/chatroid"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "chatroid"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Chatroid::VERSION
17
+
18
+ gem.add_dependency "twitter-stream"
19
+ gem.add_development_dependency "rspec"
20
+ end
@@ -0,0 +1,68 @@
1
+ require "twitter/json_stream"
2
+
3
+ class Chatroid
4
+ module Adapter
5
+ class Twitter
6
+ def initialize(chatroid)
7
+ @chatroid = chatroid
8
+ end
9
+
10
+ def connect
11
+ EventMachine::run do
12
+ stream.each_item(&method(:on_each_event))
13
+ end
14
+ end
15
+
16
+ def post(body, options = {})
17
+ client.update(body)
18
+ end
19
+
20
+ def user_info
21
+ @user_info ||= @client.info
22
+ end
23
+
24
+ private
25
+
26
+ def stream
27
+ @stream ||= ::Twitter::JSONStream.connect(
28
+ :host => "userstream.twitter.com",
29
+ :path => "/2/user.json",
30
+ :port => 443,
31
+ :ssl => true,
32
+ :oauth => {
33
+ :consumer_key => @chatroid.config[:consumer_key],
34
+ :consumer_secret => @chatroid.config[:consumer_secret],
35
+ :access_key => @chatroid.config[:access_key],
36
+ :access_secret => @chatroid.config[:access_secret],
37
+ }
38
+ )
39
+ end
40
+
41
+ def client
42
+ @client ||= TwitterOAuth::Client.new(
43
+ :consumer_key => @chatroid.config[:consumer_key],
44
+ :consumer_secret => @chatroid.config[:consumer_secret],
45
+ :token => @chatroid.config[:access_key],
46
+ :secret => @chatroid.config[:access_secret]
47
+ )
48
+ end
49
+
50
+ def on_each_event(event)
51
+ case
52
+ when event["in_reply_to_id"]
53
+ on_reply(event)
54
+ when event["text"]
55
+ on_tweet(event)
56
+ end
57
+ end
58
+
59
+ def on_tweet(event)
60
+ @chatroid.trigger_tweet(event)
61
+ end
62
+
63
+ def on_reply(event)
64
+ @chatroid.trigger_reply(event)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,11 @@
1
+ require "chatroid/adapter/twitter"
2
+
3
+ class Chatroid
4
+ module Adapter
5
+ def self.find(service_name)
6
+ const_get(service_name)
7
+ rescue NameError
8
+ nil
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ class Chatroid
2
+ module Callback
3
+ # You can call methods like this:
4
+ # * list_message : return Array of callbacks for "message"
5
+ # * on_message : store a given block as callback for "message"
6
+ # * trigger_message : trigger callbacks for "message" with given args
7
+ def method_missing(method_name, *args, &block)
8
+ if method_name =~ /(list|on|trigger)_([a-z]+)/
9
+ send($1, $2, *args, &block)
10
+ else
11
+ super
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def callbacks
18
+ @callbacks ||= Hash.new do |hash, key|
19
+ hash[key] = []
20
+ end
21
+ end
22
+
23
+ def list(type)
24
+ callbacks[type]
25
+ end
26
+
27
+ def on(type, &block)
28
+ callbacks[type] << block
29
+ end
30
+
31
+ def trigger(type, *args)
32
+ callbacks[type].each do |callback|
33
+ callback.call(*args)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ class Chatroid
2
+ VERSION = "0.0.1"
3
+ end
data/lib/chatroid.rb ADDED
@@ -0,0 +1,78 @@
1
+ require "chatroid/version"
2
+ require "chatroid/callback"
3
+ require "chatroid/adapter"
4
+
5
+ class Chatroid
6
+ include Callback
7
+
8
+ def initialize(&block)
9
+ instance_eval(&block) if block_given?
10
+ end
11
+
12
+ def config
13
+ @config ||= {}
14
+ end
15
+
16
+ def run!
17
+ validate_connection
18
+ adapter.connect
19
+ end
20
+
21
+ private
22
+
23
+ # Utility method for configure
24
+ def set(*args)
25
+ case args.size
26
+ when 1
27
+ configure(args[0])
28
+ when 2
29
+ configure(args[0] => args[1])
30
+ else
31
+ raise ArgumentError
32
+ end
33
+ end
34
+
35
+ def configure(hash)
36
+ config.merge!(hash)
37
+ end
38
+
39
+ # Post message via adapter
40
+ def post(*args)
41
+ adapter.post(*args)
42
+ end
43
+
44
+ def validate_connection
45
+ validate_config
46
+ validate_adapter
47
+ end
48
+
49
+ def validate_config
50
+ unless has_service?
51
+ raise ConnectionError.new("config.service is not configured")
52
+ end
53
+ end
54
+
55
+ def validate_adapter
56
+ unless has_adapter?
57
+ raise ConnectionError.new("#{config[:service]} is not supported")
58
+ end
59
+ end
60
+
61
+ def has_service?
62
+ config[:service]
63
+ end
64
+
65
+ def has_adapter?
66
+ has_service? && adapter_class
67
+ end
68
+
69
+ def adapter_class
70
+ Adapter.find(config[:service])
71
+ end
72
+
73
+ def adapter
74
+ @adapter ||= adapter_class.new(self)
75
+ end
76
+
77
+ class ConnectionError < StandardError; end
78
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe Chatroid::Adapter::Twitter do
4
+ shared_examples_for "interface of Chatroid::Adapter" do
5
+ it do
6
+ Chatroid::Adapter::Twitter.should be_respond_to(:new)
7
+ end
8
+
9
+ it do
10
+ Chatroid::Adapter::Twitter.new(mock).should be_respond_to(:connect)
11
+ end
12
+
13
+ it do
14
+ Chatroid::Adapter::Twitter.new(mock).should be_respond_to(:post)
15
+ end
16
+ end
17
+
18
+ it_should_behave_like "interface of Chatroid::Adapter"
19
+
20
+ describe "#connect" do
21
+ it "should work in EventMachine::run" do
22
+ EventMachine.should_receive(:run) do |&block|
23
+ block.should be_a(Proc)
24
+ end
25
+ Chatroid::Adapter::Twitter.new(mock).connect
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe Chatroid::Adapter do
4
+ describe ".find" do
5
+ context "when proper adapter class exists" do
6
+ before do
7
+ Chatroid::Adapter.stub(:const_get).and_return(adapter_class)
8
+ end
9
+
10
+ let(:adapter_class) do
11
+ Class.new
12
+ end
13
+
14
+ it "should return it" do
15
+ Chatroid::Adapter.find("AdapterClassName").should == adapter_class
16
+ end
17
+ end
18
+
19
+ context "when proper adapter class does not exist" do
20
+ it do
21
+ Chatroid::Adapter.find("AdapterClassName").should == nil
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+
3
+ describe Chatroid::Callback do
4
+ let(:instance) do
5
+ mod = described_class
6
+ Class.new { include mod }.new
7
+ end
8
+
9
+ describe "#on_xxx" do
10
+ it "should store given block as callback" do
11
+ callback = proc {}
12
+ instance.on_xxx(&callback)
13
+ instance.list_xxx.should == [callback]
14
+ end
15
+ end
16
+
17
+ describe "#list_xxx" do
18
+ context "before #on_xxx is called" do
19
+ it do
20
+ instance.list_xxx.should have(0).callback
21
+ end
22
+ end
23
+
24
+ context "after #on_yyy is called" do
25
+ before do
26
+ instance.on_yyy {}
27
+ end
28
+
29
+ it do
30
+ instance.list_xxx.should have(0).callback
31
+ end
32
+ end
33
+
34
+ context "after #on_xxx is called" do
35
+ before do
36
+ instance.on_xxx {}
37
+ end
38
+
39
+ it do
40
+ instance.list_xxx.should have(1).callback
41
+ end
42
+ end
43
+ end
44
+
45
+ describe "#trigger_xxx" do
46
+ it "should trigger all callbacks for xxx" do
47
+ callback = proc {}
48
+ callback.should_receive(:call)
49
+ instance.on_xxx(&callback)
50
+ instance.trigger_xxx
51
+ end
52
+
53
+ it "should trigger callbacks with given args" do
54
+ args = mock
55
+ instance.on_xxx { |block_args| block_args.should == args }
56
+ instance.trigger_xxx(args)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ describe Chatroid do
4
+ describe "#set" do
5
+ context "when given a hash" do
6
+ it "should set it to config" do
7
+ Chatroid.new { set :key => "val" }.config.should == { :key => "val" }
8
+ end
9
+ end
10
+
11
+ context "when given two args" do
12
+ it "should set it to config as key-value config" do
13
+ Chatroid.new { set :key, "val" }.config.should == { :key => "val" }
14
+ end
15
+ end
16
+
17
+ context "when given args more than two args" do
18
+ it do
19
+ expect do
20
+ Chatroid.new { set 1, 2, 3 }
21
+ end.to raise_error(ArgumentError)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#run!" do
27
+ context "when service to connect is not specified" do
28
+ it do
29
+ expect do
30
+ Chatroid.new.run!
31
+ end.to raise_error(Chatroid::ConnectionError)
32
+ end
33
+ end
34
+
35
+ context "when specified service is not supported" do
36
+ it do
37
+ expect do
38
+ Chatroid.new { set :service, "NotSupportedService" }.run!
39
+ end.to raise_error(Chatroid::ConnectionError)
40
+ end
41
+ end
42
+
43
+ context "when specified service is supported" do
44
+ let(:adapter) do
45
+ Class.new do
46
+ def initialize(chatroid)
47
+ end
48
+
49
+ def connect
50
+ end
51
+ end.new(mock)
52
+ end
53
+
54
+ it "should find adapter and call #connect of it" do
55
+ chatroid = Chatroid.new
56
+ chatroid.stub(:has_service?).and_return(true)
57
+ chatroid.stub(:has_adapter?).and_return(true)
58
+ chatroid.stub(:adapter).and_return(adapter)
59
+ adapter.should_receive(:connect)
60
+ chatroid.run!
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "chatroid"
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chatroid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ryo NAKAMURA
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: twitter-stream
16
+ requirement: &70137995987880 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70137995987880
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70137995987160 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70137995987160
36
+ description: Chatroid is a gem for quickly creating chatterbot in Ruby
37
+ email:
38
+ - r7kamura@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - LICENSE
46
+ - README.md
47
+ - Rakefile
48
+ - chatroid.gemspec
49
+ - lib/chatroid.rb
50
+ - lib/chatroid/adapter.rb
51
+ - lib/chatroid/adapter/twitter.rb
52
+ - lib/chatroid/callback.rb
53
+ - lib/chatroid/version.rb
54
+ - spec/chatroid/adapter/twitter_spec.rb
55
+ - spec/chatroid/adapter_spec.rb
56
+ - spec/chatroid/callback_spec.rb
57
+ - spec/chatroid_spec.rb
58
+ - spec/spec_helper.rb
59
+ homepage: https://github.com/r7kamura/chatroid
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 1.8.15
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Chatterbot builder
83
+ test_files:
84
+ - spec/chatroid/adapter/twitter_spec.rb
85
+ - spec/chatroid/adapter_spec.rb
86
+ - spec/chatroid/callback_spec.rb
87
+ - spec/chatroid_spec.rb
88
+ - spec/spec_helper.rb
89
+ has_rdoc: