qbert_bot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDNiYWFhNTFhMDEwYzVkNGI4OTc0ODI0Zjc4N2MwNDhkNTQzODQ3Nw==
5
+ data.tar.gz: !binary |-
6
+ YTk5OWI0YTcyODFjNmYzZDVkMmI5OWI0N2E4NjM0YjFlNjdjNTY5NA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MmE0NjY5YjMzMzYwYjkwZWJmMDUxNjRlNmEzZDdkZTgxYzUxYTllYjBjN2Y2
10
+ OTU2ZjU2MTFjNWI1NzZmOTE5MmUxYzU1OWViYzJlNWEyMzZiOWNkOGI3YmZl
11
+ MDAyYjk2OWVhOTk2MmM1ODkyZTg3NDg5M2VmZjA5MGFkM2QxN2Y=
12
+ data.tar.gz: !binary |-
13
+ NjdmY2E5ODgwYzliZjAxYmMyM2FmMmIzNmZmOGM5MDY2YzZjZmIzNWY0Yzgx
14
+ MjMzM2YxMzRiYmYzMGE5NjQwNmM5NWYzYTA4N2MzZGI5ODg2YTYwYzQwY2Zi
15
+ Nzc0ZDg4M2Q4MGYzODZhNTJhZmM0ZjI5MGY4Y2VmMDRhMmRkMzc=
data/bin/qbert_bot ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'qbert_bot'
3
+ QbertBot.run!
@@ -0,0 +1,28 @@
1
+ module QbertBot
2
+ class Message
3
+ attr_accessor :token, :team_id, :channel_id, :channel_name, :timestamp,
4
+ :user_id, :user_name, :raw_text, :trigger_word
5
+ attr_accessor :matches
6
+
7
+ def initialize(bot, post_data)
8
+ @bot = bot
9
+ [:token, :team_id, :channel_id, :channel_name, :timestamp,
10
+ :user_id, :user_name, :trigger_word].each do |k|
11
+ send("#{k.to_s}=", post_data[k])
12
+ end
13
+ self.raw_text = post_data[:text]
14
+ end
15
+
16
+ def say(*args)
17
+ @bot.say(*args)
18
+ end
19
+
20
+ def reply(text, opts = {})
21
+ say(channel_name, text, opts)
22
+ end
23
+
24
+ def text
25
+ raw_text.sub(trigger_word, '').strip
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module QbertBot
2
+ module Plugin
3
+ def self.included(klass)
4
+ @plugins ||= []
5
+ @plugins << klass
6
+ puts "Loading plugin #{klass}"
7
+ end
8
+
9
+ def self.plugins
10
+ @plugins
11
+ end
12
+
13
+ attr_accessor :bot, :slack, :router, :scheduler
14
+ def register
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,116 @@
1
+ require 'singleton'
2
+ require 'sinatra/base'
3
+ require 'yaml'
4
+ require 'rufus-scheduler'
5
+
6
+ module QbertBot
7
+ Listener = Struct.new(:pattern, :proc)
8
+ BlankListener = Listener.new(//, proc {})
9
+
10
+ class Match
11
+ attr_reader :listener, :matches
12
+ def initialize(listener, matches)
13
+ @listener = listener
14
+ @matches = matches
15
+ end
16
+
17
+ def proc
18
+ @listener.proc
19
+ end
20
+ end
21
+
22
+ class Robot
23
+ include Singleton
24
+ attr_reader :config, :slack, :router, :scheduler
25
+
26
+ def initialize
27
+ @plugins = []
28
+ @listeners = []
29
+ end
30
+
31
+ def load_config
32
+ @config = YAML.load_file('qbert.yml')
33
+ end
34
+
35
+ def run!
36
+ prepare_workers
37
+ load_plugins
38
+ start_workers
39
+ end
40
+
41
+ def hear(pattern, &block)
42
+ puts("Adding #{pattern.source}")
43
+ @listeners << Listener.new(pattern, block)
44
+ end
45
+
46
+ def handle_web(method, request, params)
47
+ if method == :post && request.path_info == @router.endpoint
48
+ return handle_slack(params)
49
+ end
50
+
51
+ @router.exec_route(method, request, params)
52
+ end
53
+
54
+ def handle_slack(params)
55
+ msg = Message.new(self, params)
56
+ match = find_listener(msg)
57
+ msg.matches = match.matches
58
+ match.proc.call(msg)
59
+ ''
60
+ end
61
+
62
+ def say(*args)
63
+ @slack.say(*args)
64
+ end
65
+
66
+ private
67
+ def prepare_workers
68
+ @scheduler = Rufus::Scheduler.new
69
+ @router = Router.new(config['http'])
70
+ @slack = Slack.new(config['slack'])
71
+ end
72
+
73
+ def load_plugins
74
+ Plugin.plugins.each do |klass|
75
+ p = klass.new
76
+ p.bot = self
77
+ p.router = router
78
+ p.slack = slack
79
+ p.scheduler = scheduler
80
+ p.register
81
+ @plugins << p
82
+ end
83
+ end
84
+
85
+ def start_workers
86
+ Thread.new {
87
+ @scheduler.join
88
+ }
89
+ Web.run!
90
+ end
91
+
92
+ def find_listener(msg)
93
+ puts("Checking '#{msg.text}'")
94
+ @listeners.each do |l|
95
+ if match = msg.text.match(l.pattern)
96
+ puts("Found '#{l.pattern.source}'")
97
+ return Match.new(l, match)
98
+ end
99
+ end
100
+ return Match.new(BlankListener, [])
101
+ end
102
+ end
103
+
104
+ class Web < Sinatra::Base
105
+ set :port, proc { Robot.instance.router.port }
106
+ set :bind, proc { Robot.instance.router.bind }
107
+
108
+ get(//) do
109
+ Robot.instance.handle_web(:get, request, params)
110
+ end
111
+
112
+ post(//) do
113
+ Robot.instance.handle_web(:post, request, params)
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,47 @@
1
+ module QbertBot
2
+ Route = Struct.new(:method, :path, :proc)
3
+
4
+ class Router
5
+ attr_reader :routes, :port, :bind, :endpoint
6
+
7
+ def initialize(conf)
8
+ @routes = []
9
+ @bind = conf['bind']
10
+ @port = conf['port']
11
+ @endpoint = conf['endpoint']
12
+ end
13
+
14
+ def get(path, &block)
15
+ add_route(:get, path, &block)
16
+ end
17
+
18
+ def post(path, &block)
19
+ add_route(:post, path, &block)
20
+ end
21
+
22
+ def exec_route(method, request, params)
23
+ @routes.each do |route|
24
+ next unless route.method == method
25
+ next unless match = request.path_info.match(route.path)
26
+ return route.proc.call(request, params, match)
27
+ end
28
+ return 'no route'
29
+ end
30
+
31
+ private
32
+ def add_route(method, path, &block)
33
+ clean_path = nil
34
+
35
+ if path.is_a?(Regexp)
36
+ clean_path = path.source
37
+ elsif path.is_a?(String)
38
+ clean_path = Regexp.escape(path)
39
+ clean_path = "/#{clean_path}" unless clean_path[0] == '/'
40
+ clean_path = "#{clean_path}$" unless clean_path[-1, 1] == '$'
41
+ end
42
+
43
+ puts("Adding route for #{method} #{clean_path}")
44
+ @routes << Route.new(method, Regexp.new(clean_path), block)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module QbertBot
5
+ class Slack
6
+ attr_reader :hook, :default_name, :default_icon
7
+ def initialize(conf)
8
+ @hook = conf['hook']
9
+ @default_name = conf['name']
10
+ @default_icon = conf['icon']
11
+ end
12
+
13
+ def channel_or_dm(name)
14
+ return name if name[0] == '#'
15
+ return name if name[0] == '@'
16
+ "##{name}"
17
+ end
18
+
19
+
20
+ def say(to, text, opts = {})
21
+ payload = {
22
+ text: text,
23
+ channel: channel_or_dm(to),
24
+ username: default_name,
25
+ icon_emoji: default_icon,
26
+ }
27
+ payload[:icon_emoji] = opts[:icon] if opts.key?(:icon)
28
+ payload[:icon_url] = opts[:icon_url] if opts.key?(:icon_url)
29
+ payload[:username] = opts[:name] if opts.key?(:name)
30
+ payload[:attachments] = opts[:attachments] if opts.key?(:attachments)
31
+
32
+ puts("Saying: #{payload[:channel]} -> #{text}")
33
+ Faraday.post(@hook, payload: payload.to_json)
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module QbertBot
2
+ VERSION = "0.0.1"
3
+ end
data/lib/qbert_bot.rb ADDED
@@ -0,0 +1,21 @@
1
+ require "qbert_bot/version"
2
+ require "qbert_bot/plugin"
3
+ require "qbert_bot/message"
4
+ require "qbert_bot/router"
5
+ require "qbert_bot/slack"
6
+ require "qbert_bot/robot"
7
+
8
+
9
+
10
+ module QbertBot
11
+ def self.run!
12
+ bot = Robot.instance
13
+ bot.load_config
14
+
15
+ Dir['plugins/*.rb'].each do |f|
16
+ load f
17
+ end
18
+
19
+ bot.run!
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qbert_bot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - lxfontes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rufus-scheduler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sinatra
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ description: ''
84
+ email:
85
+ - lxfontes@gmail.com
86
+ executables:
87
+ - qbert_bot
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - bin/qbert_bot
92
+ - lib/qbert_bot.rb
93
+ - lib/qbert_bot/message.rb
94
+ - lib/qbert_bot/plugin.rb
95
+ - lib/qbert_bot/robot.rb
96
+ - lib/qbert_bot/router.rb
97
+ - lib/qbert_bot/slack.rb
98
+ - lib/qbert_bot/version.rb
99
+ homepage: http://github.com/lxfontes/qbert_bot
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.4.4
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: The no frills ruby bot for Slack
123
+ test_files: []