dickburt 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ script/
2
+ pkg/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@dickburt --create
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in camper_van.gemspec
4
+ gemspec
5
+
6
+ # specified here rather than in gemspec because they're
7
+ # for local mac development only
8
+ group :development do
9
+ gem "rb-fsevent"
10
+ gem "growl"
11
+ gem "guard"
12
+ # 0.4.0.rc versions are still git-only
13
+ gem "guard-minitest", :git => "https://github.com/guard/guard-minitest.git"
14
+ gem "fabrication"
15
+ gem "ffaker", :require => "ffaker"
16
+ gem 'vcr'
17
+ gem "fakeweb"
18
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ GIT
2
+ remote: https://github.com/guard/guard-minitest.git
3
+ revision: a5479b18222ba4f95e65d558484d6c32456ca401
4
+ specs:
5
+ guard-minitest (0.4.0)
6
+ guard (~> 0.4)
7
+
8
+ PATH
9
+ remote: .
10
+ specs:
11
+ dickburt (0.0.5)
12
+ addressable (~> 2.2.6)
13
+ eventmachine (~> 0.12.10)
14
+ json (~> 1.5.1)
15
+ logging (~> 1.5.1)
16
+ map (~> 4.3.0)
17
+ patron (~> 0.4.11)
18
+ trollop (~> 1.16.2)
19
+ twitter-stream (~> 0.1.14)
20
+
21
+ GEM
22
+ remote: http://rubygems.org/
23
+ specs:
24
+ addressable (2.2.6)
25
+ eventmachine (0.12.10)
26
+ fabrication (1.0.1)
27
+ fakeweb (1.3.0)
28
+ ffaker (1.8.0)
29
+ growl (1.0.3)
30
+ guard (0.6.2)
31
+ thor (~> 0.14.6)
32
+ http_parser.rb (0.5.1)
33
+ json (1.5.3)
34
+ little-plugger (1.1.2)
35
+ logging (1.5.2)
36
+ little-plugger (>= 1.1.2)
37
+ map (4.3.0)
38
+ minitest (2.2.2)
39
+ patron (0.4.14)
40
+ rb-fsevent (0.4.3.1)
41
+ simple_oauth (0.1.5)
42
+ thor (0.14.6)
43
+ trollop (1.16.2)
44
+ twitter-stream (0.1.14)
45
+ eventmachine (>= 0.12.8)
46
+ http_parser.rb (~> 0.5.1)
47
+ simple_oauth (~> 0.1.4)
48
+ vcr (1.11.1)
49
+
50
+ PLATFORMS
51
+ ruby
52
+
53
+ DEPENDENCIES
54
+ dickburt!
55
+ fabrication
56
+ fakeweb
57
+ ffaker
58
+ growl
59
+ guard
60
+ guard-minitest!
61
+ minitest (~> 2.2.2)
62
+ rb-fsevent
63
+ vcr
data/Guardfile ADDED
@@ -0,0 +1,7 @@
1
+ guard 'minitest' do
2
+ # with Minitest::Spec
3
+ watch(%r|^spec/(.*)_spec\.rb|)
4
+ watch(%r|^spec/fabricators/(.*)_fabricator\.rb|) { |m| "spec/dickburt/#{m[1]}_spec.rb" }
5
+ watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
6
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
7
+ end
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ Dickburt: A campfire bot
2
+ ========================
3
+
4
+ gem install dickburt
5
+
6
+ dickburt desertbeaver the_overlook --token the_token_for_your_bot_user
7
+
8
+ Connecting to Campfire™
9
+ -----------------------
10
+ Dickburt runs from the command line, he gets installed when the gem gets installed. Connecting him to your campfire requires a few things.
11
+
12
+ First, you need a user for your bot. Go make a user, you'll need an email for your bot, but I'll assume you know how to make an email and signup for campfire. Once you've signed up and signed in as your bot, you're going to need to find the API token. Click "My info" and the [API token is pretty easy to spot](http://cl.ly/3W0r1H1h3a281z1a1C00 "Spotting the api token").
13
+
14
+ Second, the command line args are:
15
+
16
+ 1. The subdomain of the campfire you want to join, so, in the example above we're trying to join http://desertbeaver.campfirenow.com
17
+
18
+ 2. The campfire room we want to join, downcased and spaces replaced with underscores. So again in the above example the_overlook is means we'll join The Overlook room. Pretty easy.
19
+
20
+ 3. The last argument is the API token. Dickburt will store the api token in ~/.dickburt/config.yml after the first time you give him a token for a subdomain. Note! API Tokens are unique by subdomain.
21
+
22
+ Commands
23
+ --------
24
+ Right now, this sucks, but you have to say "dickburt <somecommand>" or "somecommand blah lbah blah dickburt". You just have to say a command and dickburt in the same message.
25
+
26
+ His commands are really limited but it is easy to make new ones.
27
+
28
+ - hi
29
+ - imageme (takes a query)
30
+ - beerme
31
+ - whatup
32
+ - fuckyeah
33
+
34
+ Examples
35
+ --------
36
+
37
+ Tyler: dickburt imageme hipster ferrets
38
+ # => will upload the first image it finds for "hipster ferrets" on google image search
39
+
40
+ Tyler: dickburt whatup
41
+ # => dickburt: whatup Tyler
42
+
43
+ TODO
44
+ ----
45
+ * Use a better http library like faraday. Patron sucks.
46
+ * Use yajl to parse json stream.
47
+ * Make dickburt helpful. Like if he doesn't know a command he should tell you and probably also tell you what he does know.
48
+ * Keep a list of Dickburt::Users around
49
+ * Lookup everyone in the Room when we connect
50
+ * Lookup the user that messaged dickburt from our list of Users, or, go get the info for the user and store them in the list.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs = %w(lib spec)
7
+ t.pattern = "spec/**/*_spec.rb"
8
+ end
9
+
10
+ task :default => :test
data/bin/dickburt ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require "trollop"
4
+ $:.unshift File.expand_path('../../lib/', __FILE__)
5
+ require "dickburt"
6
+
7
+ t = Trollop::Parser.new do
8
+ opt :token, "The campfire token for dickburt", :type => :string
9
+ end
10
+
11
+ opts = Trollop::with_standard_exception_handling( t ) do
12
+ opts = t.parse ARGV
13
+ host = t.leftovers.shift
14
+ room = t.leftovers.shift
15
+ unless host && room
16
+ raise Trollop::CommandlineError, "host and room must be provided as arguments. Ex: dickburt subdomain_of_my_campfire super_awesome_room"
17
+ end
18
+
19
+ begin
20
+ Dickburt::Config.set_token(host.to_sym, opts[:token])
21
+ config = Dickburt::Config.config_hash(host, room)
22
+ Dickburt::Server.run(config)
23
+ rescue ::StandardError => se
24
+ raise Trollop::CommandlineError, se.message
25
+ end
26
+ end
data/dickburt.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dickburt/version"
4
+ Gem::Specification.new do |s|
5
+ s.name = "dickburt"
6
+ s.version = Dickburt::VERSION
7
+ s.authors = ["Tyler Montgomery"]
8
+ s.email = ["tyler@everlater.com"]
9
+ s.homepage = "http://github.com/ubermajestix/dickburt"
10
+ s.summary = %q{Campfire bot}
11
+ s.description = %q{Dickburt finds pugs}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency "eventmachine" , "~> 0.12.10"
19
+ s.add_dependency "patron" , "~> 0.4.11"
20
+ s.add_dependency "logging" , "~> 1.5.1"
21
+ s.add_dependency "trollop" , "~> 1.16.2"
22
+ s.add_dependency 'twitter-stream' , "~> 0.1.14"
23
+ s.add_dependency 'json' , "~> 1.5.1"
24
+ s.add_dependency "addressable" , "~> 2.2.6"
25
+ s.add_dependency 'map' , "~> 4.3.0"
26
+
27
+ s.add_development_dependency "minitest", "~> 2.2.2"
28
+ end
data/lib/dickburt.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'dickburt/version'
2
+ require 'twitter/json_stream'
3
+ require 'patron'
4
+ require 'json'
5
+ require "addressable/uri"
6
+ require 'map'
7
+ require 'logging'
8
+ require 'fileutils'
9
+
10
+ module Dickburt
11
+ require 'dickburt/bot'
12
+ require 'dickburt/campfire'
13
+ require 'dickburt/config'
14
+ require 'dickburt/logger'
15
+ require 'dickburt/message'
16
+ require 'dickburt/response'
17
+ require 'dickburt/retryable'
18
+ require 'dickburt/room'
19
+ require 'dickburt/server'
20
+ require 'dickburt/user'
21
+ class Error < StandardError; end;
22
+ def self.logger
23
+ @logger = Logging::Logger[self.name]
24
+ end
25
+
26
+ end
27
+
28
+
29
+
@@ -0,0 +1,137 @@
1
+ class Dickburt::Bot
2
+ attr_accessor :message
3
+ attr_accessor :user
4
+ attr_accessor :room
5
+ def initialize(message, user, room)
6
+ @message = message
7
+ @user = user
8
+ @room = room
9
+ end
10
+
11
+ def self.used_images
12
+ @used_images ||= {}
13
+ end
14
+
15
+ def self.image_page
16
+ @image_page ||= {}
17
+ end
18
+
19
+ def self.process(message, room, campfire)
20
+ if message[:type] == 'TextMessage' && message.body.match(/\bdickburt\b/i)
21
+ dickburt = Dickburt::Bot.new(message, room.find_user(message.user_id), room)
22
+ command = dickburt.parse_command
23
+ args = dickburt.parse_args
24
+ if command
25
+ response = args ? dickburt.send(command, args) : dickburt.send(command)
26
+ room.speak(response)
27
+ end
28
+ end
29
+ end
30
+
31
+ def commands
32
+ @commands ||= %w(imageme beerme hi fuckyeah)
33
+ end
34
+
35
+ def commands_regex
36
+ Regexp.union(commands.map{|c| /\b#{c}\b/})
37
+ end
38
+
39
+ def parse_command
40
+ command = commands.detect{|c| message.body.downcase.match(/\b#{c}\b/)}
41
+ command = 'whatup' if message[:type] == 'EnterMessage'
42
+ command
43
+ end
44
+
45
+ def parse_args
46
+ reg = Regexp.union(/dickburt:?/, commands_regex)
47
+ args = message.body.downcase.gsub(reg,'').strip
48
+ args.empty? ? nil : args
49
+ end
50
+
51
+ def whatup
52
+ Dickburt::Response.new("whatup #{user.name}", 'Text')
53
+ end
54
+
55
+ def fuckyeah
56
+ Dickburt::Response.new('FUCKYEAH BUDDIE!', 'Text')
57
+ end
58
+
59
+ def imageme(query='funny pugs')
60
+ image = google_image(query)
61
+ if image
62
+ Dickburt::Response.new(image, 'Upload')
63
+ else
64
+ Dickburt::Response.new("couldn't find any pics of #{query}", 'Text')
65
+ end
66
+ end
67
+
68
+ def beerme
69
+ Dickburt::Response.new('http://f.cl.ly/items/333i290f1x2N330u303N/beerme.png', 'Upload')
70
+ end
71
+
72
+ def hi
73
+ whatup if rand(5) == 4
74
+ fuckyeah if rand(10) == 4
75
+ Dickburt::Response.new("Hi #{user.name}", 'Text')
76
+ end
77
+
78
+ def google_image(query='funny pugs', page=0)
79
+ @search_server ||= Patron::Session.new
80
+ @search_server.base_url = "https://ajax.googleapis.com/ajax/services/search"
81
+ Dickburt::Bot.used_images[query] ||= []
82
+ page = Dickburt::Bot.image_page[query].to_i + 1 if Dickburt::Bot.image_page[query].to_i > page
83
+ Dickburt::Bot.image_page[query] = page
84
+ uri = Addressable::URI.new
85
+ uri.query_values = {:v => "1.0", :q => query, :rsz=>'8', :start=>page.to_s}
86
+ puts "finding #{query} on page #{page}"
87
+ response = @search_server.get("/images?#{uri.query}")
88
+ if response.status < 400
89
+ body = JSON.parse(response.body)
90
+ if body["responseData"]
91
+ results = JSON.parse(response.body)["responseData"]["results"]
92
+ results.each_with_index do |image, i|
93
+ image = Map.new(image)
94
+ # check to see if we've seen this image for this query
95
+ next if Dickburt::Bot.used_images[query].include?(image.imageId)
96
+ Dickburt::Bot.used_images[query] << image.imageId
97
+ # check to make sure the image doesn't 404
98
+ exists = image_exists?(image.url)
99
+ next if exists == false
100
+ # return the image
101
+ @image_url = image.url
102
+ break # cause we found an image
103
+ end
104
+ else
105
+ @error= true
106
+ end
107
+ else
108
+ @error = true
109
+ puts "="*45
110
+ puts response.status
111
+ puts response.body.inspect
112
+ puts "="*45
113
+ end
114
+ puts @image_url.inspect
115
+ puts @error.inspect
116
+ # Keep going to the next page of results unless we got an image or blowzed up.
117
+ google_image(query, page+=1) unless @image_url or @error
118
+ @image_url
119
+ end
120
+
121
+ def image_exists?(url)
122
+ begin
123
+ image = Patron::Session.new
124
+ split_url = url.split("/",4)
125
+ image_url = split_url.pop
126
+ image.base_url = split_url.join("/")
127
+ response = image.head("/#{image_url}")
128
+ response.status < 400
129
+ rescue Patron::ConnectionFailed, Patron::ConnectionFailed
130
+ puts "="*45
131
+ puts "DNE!"
132
+ puts "="*45
133
+ false
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,38 @@
1
+ class Dickburt::Campfire
2
+ attr_accessor :token
3
+ attr_accessor :host
4
+
5
+ class Error < StandardError; end;
6
+
7
+ def initialize(args={})
8
+ @token = args[:token]
9
+ @host = "https://#{args[:host]}.campfirenow.com"
10
+ end
11
+
12
+ def http
13
+ @http ||= Patron::Session.new
14
+ @http.base_url = host
15
+ @http.headers["Content-Type"] = "application/json"
16
+ @http.headers['User-Agent'] = "Dickburt #{Dickburt::VERSION}"
17
+ @http.username = token
18
+ @http.password = "x"
19
+ @http.connect_timeout = 6000
20
+ @http.timeout = 6000
21
+ @http
22
+ end
23
+
24
+ def rooms
25
+ return @rooms if @rooms
26
+ response = http.get("/rooms.json")
27
+ @rooms = []
28
+ if response.status < 400
29
+ @rooms = JSON.parse(response.body)['rooms']
30
+ @rooms.collect! do |room|
31
+ Dickburt::Room.new(room, self)
32
+ end
33
+ else
34
+ raise Dickburt::Campfire::Error, response.status.to_s + ": " + response.body
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,63 @@
1
+ # Store the campfire api token b/c I'm sick of looking that shit up.
2
+ # I know the host and room I want to access, but not the token, so if the token
3
+ # is provided, store it - tokens are uniq by host - so store it per host.
4
+ # Provides a nice config hash that we build up from the command line to hand off to Dickburt::Server.
5
+
6
+ module Dickburt
7
+ module Config
8
+
9
+ class << self
10
+
11
+ # Provides a nice config hash that we build up from the command line to hand off to Dickburt::Server.
12
+ # This is only ever called bin/dickburt. That script raises errors for missing host and room, so its
13
+ # a bit redundant redundant to check that here.
14
+ def config_hash(host, room)
15
+ token = config[host.to_sym][:token] if config[host.to_sym]
16
+ unless token
17
+ raise Dickburt::Error, "You need to provide an api token.\n Just add: --token yourtokenfromcampfire to the command line args.\n The token will get stored in ~/.dickburt/config.yml for next time so you don't have to remember it"
18
+ end
19
+ { host: host,
20
+ token: token,
21
+ room: room.downcase.gsub(/\s/,'_') }
22
+ end
23
+
24
+ # Public: Stores the given token for the given host.
25
+ # Will not raise an error if the token is not given, leaves that up to bin/dickburt.
26
+ def set_token(host, token=nil)
27
+ if token
28
+ config[host.to_sym] = {:token => token}
29
+ write
30
+ end
31
+ end
32
+
33
+ # Reads the config, or gives you an empty hash.
34
+ def config
35
+ ensure_config_exists
36
+ @config ||= (YAML.load_file(config_file) || {})
37
+ end
38
+
39
+ private
40
+
41
+ # Make sure the config dir and config file are on disk.
42
+ def ensure_config_exists
43
+ FileUtils.mkdir(config_dir) unless Dir.exists?(config_dir)
44
+ FileUtils.touch(config_file) unless File.exists?(config_file)
45
+ end
46
+
47
+ def config_file
48
+ "#{config_dir}/config.yml"
49
+ end
50
+
51
+ def config_dir
52
+ "#{Dir.home}/.dickburt"
53
+ end
54
+
55
+ # Writes the @config as yaml to disk.
56
+ def write
57
+ ensure_config_exists
58
+ File.open(config_file, "wb"){|f| f.write @config.to_yaml}
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,7 @@
1
+ module Dickburt
2
+ module Logger
3
+ def logger
4
+ Dickburt.logger
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,25 @@
1
+ class Dickburt::Message < Map
2
+
3
+ attr_accessor :command
4
+ attr_accessor :args
5
+
6
+ def initialize(json)
7
+ super(JSON.parse(json))
8
+ puts self.inspect
9
+ puts "="*45
10
+ self
11
+ end
12
+
13
+ def process_command
14
+ return unless @command
15
+ # TODO make dickburt aware of users so he can respond to them.
16
+ # I really don't like this setup of not having instances of the bot.
17
+ # If i got an instance I could save things to it, like the user and message object
18
+ # Then it wouldn't be as weird to process the command here on the message object
19
+ @args ? Dickburt::Bot.send(@command, @args) : Dickburt::Bot.send(@command)
20
+ end
21
+
22
+ def user
23
+
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ class Dickburt::Response
2
+ attr_accessor :message_type
3
+ attr_accessor :body
4
+
5
+ def initialize(body, message_type)
6
+ @message_type = message_type
7
+ @body = body
8
+ end
9
+
10
+ def to_campfire_hash
11
+ {:message => {:body => @body, :type => @message_type + "Message"}}
12
+ end
13
+
14
+ def to_json
15
+ self.to_campfire_hash.to_json
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ module Dickburt
2
+ module Retryable
3
+ # Options:
4
+ # * :tries - Number of retries to perform. Defaults to 1.
5
+ # * :on - The Exception on which a retry will be performed. Defaults to Exception, which retries on any Exception.
6
+ #
7
+ # Example
8
+ # =======
9
+ # retryable(:tries => 1, :on => OpenURI::HTTPError) do
10
+ # # your code here
11
+ # end
12
+ #
13
+ def retryable(options = {}, &block)
14
+ opts = { :tries => 1, :on => Exception }.merge(options)
15
+
16
+ retry_exception, retries = opts[:on], opts[:tries]
17
+
18
+ begin
19
+ return yield
20
+ rescue retry_exception
21
+ puts "="*45
22
+ puts "#{retry_exception} raised. Retrying #{retries - 1} more times"
23
+ puts "="*45
24
+ retry if (retries -= 1) > 0
25
+ end
26
+
27
+ yield
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,64 @@
1
+ module Dickburt
2
+ class Room < Map
3
+ attr_accessor :campfire
4
+ attr_accessor :response
5
+ include Logger
6
+ def initialize(room, campfire)
7
+ super(room)
8
+ @campfire = campfire
9
+ end
10
+
11
+ def response=(response)
12
+ puts "="*45
13
+ puts response.status
14
+ puts "="*45
15
+ if response.status >= 400
16
+ logger.error JSON.parse(speak.body).inspect
17
+ end
18
+ end
19
+
20
+ def speak(response)
21
+ response = @campfire.http.post("/room/#{id}/speak.json", response.to_json)
22
+ end
23
+
24
+ def join
25
+ response = @campfire.http.post("/room/#{id}/join.json", {})
26
+ end
27
+
28
+ def leave
29
+ response = @campfire.http.post("/room/#{id}/leave.json", {})
30
+ end
31
+
32
+ def stream
33
+ Twitter::JSONStream.connect(
34
+ :path => "/room/#{id}/live.json",
35
+ :host => 'streaming.campfirenow.com',
36
+ :auth => "#{campfire.token}:x"
37
+ )
38
+ end
39
+
40
+ # Returns an Array of current users for the room.
41
+ def users
42
+ response = @campfire.http.get("/room/#{id}.json")
43
+ room = Map.new(JSON.parse(response.body)["room"])
44
+ room.users
45
+ end
46
+
47
+ # Looks up the user by user_id for the current users in the room
48
+ #
49
+ # user_id - String 37signals user id
50
+ #
51
+ # Returns a Dickburt::User if it finds that user in the room
52
+ # Raises an error if they can't be found.
53
+ def find_user(user_id)
54
+ user = users.detect{|u| u.id == user_id}
55
+ raise Dickburt::Error, "user #{user_id} not found" unless user
56
+ User.new(user.to_json, campfire)
57
+ end
58
+
59
+ def handle_failure
60
+
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,46 @@
1
+ module Dickburt
2
+ module Server
3
+ class << self
4
+ include Logger
5
+ include Retryable
6
+ end
7
+ def self.run(args={})
8
+ logger.info "boom!"
9
+ EventMachine::run do
10
+ retryable(:tries => 5, :on => Patron::TimeoutError) do
11
+ @campfire = Dickburt::Campfire.new(args)
12
+ puts "="*45
13
+ puts "Connected to #{@campfire.host} with token #{@campfire.token}"
14
+ puts "="*45
15
+ @room = @campfire.rooms.detect{|r| r.name.downcase.gsub(/\s/,'_') == args[:room].downcase.gsub(/\s/,'_')}
16
+ raise Dickburt::Error, "Could not find a campfire room that matches \"#{args[:room]}\"" unless @room
17
+ @room.join
18
+ puts "Ready for messages..."
19
+ puts "="*45
20
+ end
21
+ stream = @room.stream
22
+
23
+ stream.each_item do |item|
24
+ message = Dickburt::Message.new(item)
25
+ puts message.inspect
26
+ Dickburt::Bot.process(message, @room, @campfire)
27
+ end
28
+
29
+ stream.on_error do |message|
30
+ puts "ERROR: #{message.inspect}"
31
+ end
32
+
33
+ stream.on_max_reconnects do |timeout, retries|
34
+ puts "Tried #{retries} times to connect."
35
+ exit
36
+ end
37
+
38
+ trap("INT") do
39
+ @room.leave if @room
40
+ EM.stop
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ module Dickburt
2
+ class User < Map
3
+ attr_accessor :campfire
4
+ include Logger
5
+ def initialize(json, campfire)
6
+ super(JSON.parse(json))
7
+ @campfire = campfire
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Dickburt
2
+ VERSION = "0.0.5"
3
+ end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe Dickburt::Bot do
4
+
5
+ before(:each) do
6
+ @message = Dickburt::Message.new({type: "TextMessage", body: "dickburt beerme"}.to_json)
7
+ @user = Dickburt::User.new({name: "Human"}.to_json, campfire )
8
+ @room = Dickburt::Room.new({name: 'Campfire Room'}, campfire)
9
+ @dickburt = Dickburt::Bot.new(@message, @user, @room)
10
+ end
11
+
12
+ it "must deliver beer" do
13
+ @dickburt.must_respond_to :beerme
14
+ @dickburt.beerme.must_be_kind_of Dickburt::Response
15
+ end
16
+
17
+ it "must deliver images" do
18
+ skip "use vcr to mock web response"
19
+ @dickburt.must_respond_to :imageme
20
+ @dickburt.imageme.must_be_kind_of Dickburt::Response
21
+ end
22
+
23
+ context ".parse_args" do
24
+ it "must parse arguments from a message" do
25
+ message = Dickburt::Message.new({type: "TextMessage", body: "dickburt imageme funny hipsters"}.to_json)
26
+ dickburt = Dickburt::Bot.new(message, @user, @room)
27
+ dickburt.parse_args.must_equal 'funny hipsters'
28
+
29
+ end
30
+
31
+ it "must return nil if no args exist" do
32
+ message = Dickburt::Message.new({type: "TextMessage", body: "dickburt imageme"}.to_json)
33
+ dickburt = Dickburt::Bot.new(message, @user, @room)
34
+ dickburt.parse_args.must_be_nil
35
+ end
36
+ end
37
+
38
+ context 'imageme' do
39
+ end
40
+
41
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dickburt::Campfire do
4
+ it "should take the subdomain as the host and format it" do
5
+ c = Dickburt::Campfire.new(:host=>"everlater")
6
+ c.host.must_equal "https://everlater.campfirenow.com"
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dickburt::Config do
4
+
5
+ before(:each) do
6
+ FileUtils.rm_rf("#{Dir.home}/.dickburt/config.yml", :noop=>true)
7
+ end
8
+
9
+ it "should create the ~/.dickburt dir" do
10
+ end
11
+
12
+ it "should write the config when we add a token" do
13
+ Dickburt::Config.set_token("shabam", 'boooooom')
14
+ Dir.exists?("#{Dir.home}/.dickburt").must_equal true
15
+ File.exists?("#{Dir.home}/.dickburt/config.yml").must_equal true
16
+ Dickburt::Config.config.keys.must_include :shabam
17
+ Dickburt::Config.config[:shabam].must_equal ({:token => "boooooom"})
18
+ end
19
+
20
+ it "should read config" do
21
+ Dickburt::Config.config.must_be_kind_of Hash
22
+ end
23
+
24
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ describe Dickburt::Response do
3
+ before :each do
4
+ @response = Dickburt::Response.new("beer", "Text")
5
+ end
6
+
7
+ it "should give me a hash for campfire" do
8
+ @response.to_campfire_hash.must_be_kind_of Hash
9
+ @response.to_campfire_hash.keys.must_include :message
10
+ end
11
+
12
+ it "should respond to to_json with the appropriate hash" do
13
+ JSON.parse(@response.to_json).keys.must_include "message"
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dickburt::Room do
4
+ context "handling failure" do
5
+ before :each do
6
+ @response = Map.new(:status => 401, :body => "you fucked up")
7
+ @room = Dickburt::Room.new({name: 'Campfire Room'}, campfire)
8
+ end
9
+
10
+ it "handles failure if the response is bad" do
11
+ skip
12
+ @room.response = @response
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+
3
+ describe Dickburt::Server do
4
+ it "has a run module method" do
5
+ Dickburt::Server.must_respond_to :run
6
+ end
7
+
8
+ end
@@ -0,0 +1,23 @@
1
+ require "bundler"
2
+
3
+ Bundler.setup :default, :development
4
+
5
+ require "minitest/spec"
6
+ require "minitest/autorun"
7
+ require "minitest/mock"
8
+
9
+ require 'fabrication'
10
+ require 'ffaker'
11
+
12
+ require "dickburt"
13
+
14
+ alias :context :describe
15
+
16
+ def user_mock
17
+ mock = MiniTest::Mock.new
18
+ mock.expect("name", "Human")
19
+ end
20
+
21
+ def campfire
22
+ @campfire ||= Dickburt::Campfire.new(:host=>"everlater")
23
+ end
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dickburt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tyler Montgomery
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-06 00:00:00.000000000 -06:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: eventmachine
17
+ requirement: &2164638520 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.12.10
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *2164638520
26
+ - !ruby/object:Gem::Dependency
27
+ name: patron
28
+ requirement: &2164638020 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.11
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *2164638020
37
+ - !ruby/object:Gem::Dependency
38
+ name: logging
39
+ requirement: &2164637560 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.5.1
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *2164637560
48
+ - !ruby/object:Gem::Dependency
49
+ name: trollop
50
+ requirement: &2164637100 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 1.16.2
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *2164637100
59
+ - !ruby/object:Gem::Dependency
60
+ name: twitter-stream
61
+ requirement: &2164636640 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 0.1.14
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *2164636640
70
+ - !ruby/object:Gem::Dependency
71
+ name: json
72
+ requirement: &2164636180 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 1.5.1
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *2164636180
81
+ - !ruby/object:Gem::Dependency
82
+ name: addressable
83
+ requirement: &2164635720 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: 2.2.6
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: *2164635720
92
+ - !ruby/object:Gem::Dependency
93
+ name: map
94
+ requirement: &2164562540 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 4.3.0
100
+ type: :runtime
101
+ prerelease: false
102
+ version_requirements: *2164562540
103
+ - !ruby/object:Gem::Dependency
104
+ name: minitest
105
+ requirement: &2164562080 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 2.2.2
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: *2164562080
114
+ description: Dickburt finds pugs
115
+ email:
116
+ - tyler@everlater.com
117
+ executables:
118
+ - dickburt
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - .gitignore
123
+ - .rvmrc
124
+ - Gemfile
125
+ - Gemfile.lock
126
+ - Guardfile
127
+ - README.md
128
+ - Rakefile
129
+ - bin/dickburt
130
+ - dickburt.gemspec
131
+ - lib/dickburt.rb
132
+ - lib/dickburt/bot.rb
133
+ - lib/dickburt/campfire.rb
134
+ - lib/dickburt/config.rb
135
+ - lib/dickburt/logger.rb
136
+ - lib/dickburt/message.rb
137
+ - lib/dickburt/response.rb
138
+ - lib/dickburt/retryable.rb
139
+ - lib/dickburt/room.rb
140
+ - lib/dickburt/server.rb
141
+ - lib/dickburt/user.rb
142
+ - lib/dickburt/version.rb
143
+ - spec/dickburt/bot_spec.rb
144
+ - spec/dickburt/campfire_spec.rb
145
+ - spec/dickburt/config_spec.rb
146
+ - spec/dickburt/response_spec.rb
147
+ - spec/dickburt/room_spec.rb
148
+ - spec/dickburt/server_spec.rb
149
+ - spec/spec_helper.rb
150
+ has_rdoc: true
151
+ homepage: http://github.com/ubermajestix/dickburt
152
+ licenses: []
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ none: false
159
+ requirements:
160
+ - - ! '>='
161
+ - !ruby/object:Gem::Version
162
+ version: '0'
163
+ required_rubygems_version: !ruby/object:Gem::Requirement
164
+ none: false
165
+ requirements:
166
+ - - ! '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project:
171
+ rubygems_version: 1.6.2
172
+ signing_key:
173
+ specification_version: 3
174
+ summary: Campfire bot
175
+ test_files:
176
+ - spec/dickburt/bot_spec.rb
177
+ - spec/dickburt/campfire_spec.rb
178
+ - spec/dickburt/config_spec.rb
179
+ - spec/dickburt/response_spec.rb
180
+ - spec/dickburt/room_spec.rb
181
+ - spec/dickburt/server_spec.rb
182
+ - spec/spec_helper.rb