awesome_bot_factory 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in awesomebotfactory.gemspec
4
+ gemspec
@@ -0,0 +1,23 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+ require "rspec"
4
+ require "rspec/core/rake_task"
5
+
6
+ task :gem => :build
7
+ task :build do
8
+ system "gem build awesome_bot_factory.gemspec"
9
+ end
10
+
11
+ task :install => :build do
12
+ system "gem install awesome_bot_factory-#{AwesomeBotFactory::VERSION}.gem"
13
+ end
14
+
15
+ task :release => :build do
16
+ system "git tag -a #{AwesomeBotFactory::VERSION} -m 'Tagging #{AwesomeBotFactory::VERSION}'"
17
+ system "git push --tags"
18
+ system "gem push awesome_bot_factory-#{AwesomeBotFactory::VERSION}.gem"
19
+ end
20
+
21
+ RSpec::Core::RakeTask.new(:spec) do |spec|
22
+ spec.pattern = "spec/**/*_spec.rb"
23
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $: << File.expand_path('../lib', __FILE__)
3
+ require "awesome_bot_factory/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "awesome_bot_factory"
7
+ s.version = AwesomeBotFactory::VERSION
8
+ s.authors = ["Michael Bumann"]
9
+ s.email = ["michael@railslove.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{The AwesomeBotFactory gem}
12
+ s.description = %q{The AwesomeBotFactory lets you generate lovely bots for your campfire rooms. This gem brings a simple skeleton to build your bots}
13
+
14
+ s.rubyforge_project = "[none]"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_path = "lib"
20
+
21
+ s.add_dependency 'activesupport', '~> 3.0.0'
22
+ s.add_dependency 'thor', '~> 0.14.6'
23
+ s.add_development_dependency "rake"
24
+ s.add_development_dependency "rspec"
25
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "thor"
5
+ require 'active_support/inflector'
6
+ require 'awesome_bot_factory'
7
+ class AwsomeBotFactoryRunner < Thor
8
+ include Thor::Actions
9
+ source_root File.expand_path("../lib/templates", File.dirname(__FILE__))
10
+
11
+ desc "deploy", "deploys the application to heroku"
12
+ def deploy(name=nil)
13
+ @skill_app_name = name || "abf-#{Dir.getwd.split("/").last}"
14
+ if !bot_directory?
15
+ say "no bot found. please make sure to run this command in your application directory", :red
16
+ return
17
+ end
18
+
19
+ run "bundle install", :capture => true
20
+
21
+ git_dirty = !(run("git status", :capture => true) =~ /nothing to commit/)
22
+ if git_dirty
23
+ run "git add .", :capture => true
24
+ run "git commit -a -m 'deployment'", :capture => true
25
+ end
26
+
27
+ remotes = run "git remote", :capture => true
28
+ heroku_initialized = remotes =~ /heroku/
29
+ if !heroku_initialized
30
+ say "creating a new heroku application", :green
31
+ run "heroku apps:create #{skill_app_name} --stack cedar"
32
+ end
33
+ run "git push heroku master"
34
+ end
35
+
36
+ desc "create name", "Creates a new application skeleton for a new awesome bot factory skill"
37
+ def create(name)
38
+ directory = bot_directory? ? "." : name.underscore
39
+ say "Welcome to the AWESOME BOT FACTORY!", :green
40
+ say "setting up your laboratory for #{name}", :green
41
+ @skill_class_name = name.underscore.camelize
42
+ @skill_file_name = name.underscore
43
+ template('skill.rb.erb', "#{directory}/#{skill_file_name}.rb")
44
+ if bot_directory?
45
+ insert_into_file("#{directory}/config.ru", "\nrequire File.join(File.dirname(__FILE__), '#{skill_file_name}.rb')", :after => "Bundler.require")
46
+ append_file("#{directory}/config.ru", %Q{
47
+ map '/#{skill_file_name}' do
48
+ run #{skill_class_name}
49
+ end
50
+ });
51
+ inside(directory) do
52
+ run "git commit -a -m 'hello #{name}'"
53
+ end
54
+ else
55
+ template('config.ru.erb', "#{directory}/config.ru")
56
+ template('Procfile.erb', "#{directory}/Procfile")
57
+ template('Gemfile.erb', "#{directory}/Gemfile")
58
+ template('readme.md.erb', "#{directory}/README.md")
59
+ template('skill_spec.rb.erb', "#{directory}/spec/#{skill_file_name}_spec.rb")
60
+ template('spec_helper.rb.erb', "#{directory}/spec/spec_helper.rb")
61
+ inside(directory) do
62
+ run 'bundle install', :capture => true
63
+ run 'git init'
64
+ run 'git add .'
65
+ run "git commit -a -m 'hello #{name}'"
66
+ end
67
+ end
68
+ say "#{skill_author}, #{name} was created, happy hacking!", :green
69
+ end
70
+
71
+ desc "request", "send a test payload to your local application and see what it returns"
72
+ def request(name, matches="")
73
+ require "net/http"
74
+ require "awesome_bot_factory"
75
+ require "json"
76
+
77
+ attributes = JSON.parse(matches) rescue {"match" => matches.split(",")}
78
+ name = name.underscore
79
+
80
+ url = URI.parse("http://localhost:9292/#{name}")
81
+ request = Net::HTTP::Post.new(url.path)
82
+ request.body = AwesomeBotFactory::ExamplePayload.new(attributes).as_json
83
+ response = Net::HTTP.new(url.host, url.port).start {|http| http.request(request) }
84
+
85
+ say response.body
86
+ end
87
+
88
+ private
89
+
90
+ def skill_file_name
91
+ @skill_file_name
92
+ end
93
+
94
+ def skill_class_name
95
+ @skill_class_name
96
+ end
97
+
98
+ def skill_author
99
+ @skill_author ||= ENV["USER"]
100
+ end
101
+
102
+ def skill_app_name
103
+ (@skill_app_name || @skill_file_name).to_s.gsub("_","-").downcase
104
+ end
105
+
106
+ def bot_directory?
107
+ !Dir["*.rb"].find{|f| File.read(f) =~ /AwesomeBotFactory::Skill/ }.nil?
108
+ end
109
+ end
110
+
111
+ AwsomeBotFactoryRunner.start
@@ -0,0 +1,9 @@
1
+ require "json"
2
+ require "awesome_bot_factory/version"
3
+ require 'active_support/configurable'
4
+ require 'active_support/core_ext/hash/keys'
5
+
6
+ module AwesomeBotFactory
7
+ autoload :Skill, 'awesome_bot_factory/skill'
8
+ autoload :ExamplePayload, 'awesome_bot_factory/example_payload'
9
+ end
@@ -0,0 +1,32 @@
1
+ module AwesomeBotFactory
2
+ class ExamplePayload < Hash
3
+ DEFAULTS = {
4
+ "body" => "campfire message",
5
+ "room_id" => "123456",
6
+ "user_id" => "7890",
7
+ "user" => {
8
+ "name" => "Choco Bit",
9
+ "avatar_url" => "http://asset0.37img.com/global/.../avatar.png",
10
+ "type" => "Member",
11
+ "admin" => false
12
+ },
13
+ "user_name" => "choco",
14
+ "match" => ["key:command value", "command", "value"],
15
+ "slug" => "hexhash"
16
+ }
17
+
18
+ def initialize(attributes={})
19
+ self.merge!(DEFAULTS)
20
+ self.merge!(attributes)
21
+ end
22
+
23
+ def as_hash
24
+ self
25
+ end
26
+
27
+ def as_json
28
+ as_hash.to_json
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,41 @@
1
+ module AwesomeBotFactory
2
+ class Skill
3
+ include ActiveSupport::Configurable
4
+
5
+ attr_accessor :message
6
+
7
+ def self.matches(*matches)
8
+ @@matches = matches
9
+ end
10
+
11
+ def self.call(env)
12
+ message = JSON.parse(env["rack.input"].read)
13
+ [200, {"Content-Type" => "application/json"}, [ self.new(message).reply.to_json] ]
14
+ end
15
+
16
+ def initialize(campfire_message={})
17
+ self.message = campfire_message
18
+ self.message["match"] ||= [] # let's just make sure we have an hash there and don't break if it is in any case empty
19
+ end
20
+
21
+ def read_attribute(attr)
22
+ index = @@matches.index(attr.to_sym)
23
+ if index
24
+ self.message["match"][index+1]
25
+ else
26
+ self.message[attr.to_s] || self.message[attr.to_sym]
27
+ end
28
+ end
29
+
30
+ def attribute_defined?(attr)
31
+ !@@matches.index(attr).nil?
32
+ end
33
+
34
+ def method_missing(name, *args)
35
+ return self.message[name.to_s] if self.message.key?(name.to_s)
36
+ return self.message[name.to_sym] if self.message.key?(name.to_sym)
37
+ return self.read_attribute(name) if self.attribute_defined?(name)
38
+ super(name,*args)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module AwesomeBotFactory
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "thin"
4
+ gem "rack"
5
+ gem "awesome_bot_factory", '~><%= AwesomeBotFactory::VERSION %>'
6
+
7
+ group :development do
8
+ gem "heroku"
9
+ end
10
+ group :test do
11
+ gem "rspec", '~>2.6.0'
12
+ gem "rack-test", '~>0.6.1', :require => "rack/test"
13
+ end
@@ -0,0 +1,2 @@
1
+ web: thin start -R config.ru -p $PORT
2
+
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+ Bundler.require(:default, :production)
3
+ require File.join(File.dirname(__FILE__), "<%= skill_file_name %>.rb")
4
+
5
+ use Rack::CommonLogger
6
+ map '/<%= skill_file_name %>' do
7
+ run <%= skill_class_name %>
8
+ end
@@ -0,0 +1,4 @@
1
+ <%= skill_class_name %>
2
+ ==============
3
+
4
+ an awesome skill for the [awesomebotfactory.com](http://awesomebotfactory.com)
@@ -0,0 +1,18 @@
1
+ class <%= skill_class_name %> < AwesomeBotFactory::Skill
2
+
3
+ configure do |c|
4
+ c.name = "<%= skill_class_name %>"
5
+ c.description = ""
6
+ c.author = "<%= skill_author %>"
7
+ c.url = "http://abf-<%= skill_app_name %>.herokuapp.com/<%= skill_file_name %>"
8
+ c.regex = "<%= skill_file_name %>:(.+)"
9
+ c.help = ""
10
+ end
11
+
12
+ matches :matches, :of, :your, :regex
13
+
14
+ def reply
15
+ { :type => "TextMessage", :body => "hello world" }
16
+ end
17
+
18
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe <%= skill_class_name %> do
4
+
5
+ subject { <%= skill_class_name %>.new(AwesomeBotFactory::ExamplePayload.new("match" => ["bot:dance around the world", "dance", "around", "the", "world"])) }
6
+
7
+ it { should have_matches_for(:matches, :of, :your, :regex) }
8
+ its(:matches) { should eql("dance") }
9
+ its(:reply) { should eql({ :type => "TextMessage", :body => "hello world" })}
10
+
11
+ describe "as a rack application" do
12
+ let(:app) { <%= skill_class_name %> }
13
+ before do
14
+ post "/<%= skill_file_name %>", {}, :input => AwesomeBotFactory::ExamplePayload.new("match" => ["bot:dance around the world", "dance", "around", "the", "world"]).as_json
15
+ end
16
+ let(:json_body) { JSON.parse(last_response.body) }
17
+
18
+ it { last_response.should be_ok }
19
+ it { json_body["type"].should eql("TextMessage") }
20
+ it { json_body["body"].should eql("hello world") }
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ require "bundler/setup"
2
+ Bundler.require(:default, :test)
3
+
4
+ require File.expand_path("../<%= skill_file_name %>.rb", File.dirname(__FILE__))
5
+
6
+ RSpec.configure do |config|
7
+ config.include Rack::Test::Methods
8
+ end
9
+
10
+ RSpec::Matchers.define :have_matches_for do |*expected|
11
+ match do |actual|
12
+ expected.all? { |e| actual.class.class_variable_get("@@matches").include?(e) }
13
+ end
14
+ end
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+ describe AwesomeBotFactory::Skill do
3
+
4
+ it "should initialize an empty match array if nothing given" do
5
+ TestSkill.new.match.should eql([])
6
+ end
7
+
8
+ describe "Rack endpoint" do
9
+
10
+ before do
11
+ JSON.should_receive(:parse).with("body").and_return({:all=>:fake})
12
+ TestSkill.should_receive(:new).with({:all => :fake}).and_return(mock(:reply => {:body => "response"}))
13
+ end
14
+ subject {
15
+ TestSkill.call({"rack.input" => StringIO.new("body")})
16
+ }
17
+
18
+ its([0]) { should eql(200) }
19
+ its([1]) { should eql({"Content-Type" => "application/json"}) }
20
+ its([2]) { should eql(['{"body":"response"}']) }
21
+
22
+ end
23
+
24
+ describe "Attributes" do
25
+ before do
26
+ TestSkill.matches :one, :two
27
+ end
28
+
29
+ subject { TestSkill.new({"user" => "Mole", :room_id => "12345", :nill => nil, "match" => [1,2,3]}) }
30
+
31
+ describe "accessors" do
32
+
33
+ its(:one) { should eql(2)}
34
+ its(:two) { should eql(3)}
35
+ its(:user) { should eql("Mole") }
36
+ its(:room_id) { should eql("12345") }
37
+ its(:nill) { should be_nil }
38
+ its(:message) { should eql({"user" => "Mole", :room_id => "12345", :nill => nil, "match" => [1,2,3]})}
39
+ specify { expect { subject.undefined_methdo }.to raise_error(NoMethodError) }
40
+ end
41
+
42
+ describe "read attributes" do
43
+ it { subject.read_attribute(:user).should eql("Mole") }
44
+ it { subject.read_attribute(:room_id).should eql("12345") }
45
+ it { subject.read_attribute(:nill).should be_nil }
46
+ it { subject.read_attribute(:not_found).should be_nil }
47
+ end
48
+ end
49
+
50
+ describe "Configuration" do
51
+ before(:all) do
52
+ TestSkill.configure do |c|
53
+ c.name = "Bender"
54
+ c.description = "THE Bot"
55
+ end
56
+ end
57
+
58
+ subject { TestSkill.config }
59
+ its(:name) { should eql("Bender") }
60
+ its(:description) { should eql("THE Bot") }
61
+ end
62
+
63
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require "rspec"
4
+ require "awesome_bot_factory"
5
+
6
+ class TestSkill < AwesomeBotFactory::Skill
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awesome_bot_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Bumann
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-07 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: &2159771200 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2159771200
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &2159770700 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.14.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2159770700
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &2159770320 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2159770320
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &2159769860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2159769860
58
+ description: The AwesomeBotFactory lets you generate lovely bots for your campfire
59
+ rooms. This gem brings a simple skeleton to build your bots
60
+ email:
61
+ - michael@railslove.com
62
+ executables:
63
+ - awesomebotfactory
64
+ extensions: []
65
+ extra_rdoc_files: []
66
+ files:
67
+ - .gitignore
68
+ - Gemfile
69
+ - Rakefile
70
+ - awesome_bot_factory.gemspec
71
+ - bin/awesomebotfactory
72
+ - lib/awesome_bot_factory.rb
73
+ - lib/awesome_bot_factory/example_payload.rb
74
+ - lib/awesome_bot_factory/skill.rb
75
+ - lib/awesome_bot_factory/version.rb
76
+ - lib/templates/Gemfile.erb
77
+ - lib/templates/Procfile.erb
78
+ - lib/templates/config.ru.erb
79
+ - lib/templates/readme.md.erb
80
+ - lib/templates/skill.rb.erb
81
+ - lib/templates/skill_spec.rb.erb
82
+ - lib/templates/spec_helper.rb.erb
83
+ - spec/awesome_bot_factory/skill_spec.rb
84
+ - spec/spec_helper.rb
85
+ homepage: ''
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ segments:
98
+ - 0
99
+ hash: 3025311330780698384
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ segments:
107
+ - 0
108
+ hash: 3025311330780698384
109
+ requirements: []
110
+ rubyforge_project: ! '[none]'
111
+ rubygems_version: 1.8.5
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: The AwesomeBotFactory gem
115
+ test_files:
116
+ - spec/awesome_bot_factory/skill_spec.rb
117
+ - spec/spec_helper.rb