awesome_bot_factory 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.
@@ -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