twke 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ # twke
2
+
3
+ twke (pronounced *twee-kee*) is an extensible Campfire bot inspired by
4
+ Hubot and created by the [Librato team](http://librato.com)
5
+ with the [Scamp framework](https://github.com/wjessop/Scamp).
6
+ His primary mission is to assist in the day-to-day DevOps activities of
7
+ a team building and operating a *SaaS* platform.
8
+
9
+ ## Contributing to twke
10
+ twke's plugin system is modeled after
11
+ [Github-Services](https://github.com/github/github-services) and
12
+ creating a new plugin is extremely straightforward:
13
+
14
+ 1. Fork the project
15
+ 1. Start a feature branch
16
+ 1. Create a new file in `/plugins` called `plugin_name.rb`, using the
17
+ following template:
18
+
19
+ ```ruby
20
+ class Plugin::PluginName < Plugin
21
+ def add_routes(rp)
22
+ rp.route 'foo' do
23
+ say 'bar'
24
+ end
25
+
26
+ rp.route 'hello' do
27
+ say "Hello World!"
28
+ end
29
+ end
30
+ end
31
+ ```
32
+ 1. Commit and push until you are happy with your contribution
33
+ 1. Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
34
+ 1. Submit a pull request from your fork to josephruscio/twke
35
+
36
+ ## Colophon
37
+
38
+ twke is named after the [ambuquad designated
39
+ TWKE-4](https://secure.wikimedia.org/wikipedia/en/wiki/Twiki) who
40
+ faithfully accompanied Buck Rogers in the 25th Century. His
41
+ voice has been described as a cross between Yosemite Sam and Porky Pig,
42
+ and he usually prefixed any speech with a low-pitched "bidi-bidi-bidi".
43
+
44
+ ### Copyright
45
+
46
+ Copyright (c) 2011 Joseph Ruscio. See LICENSE.txt for
47
+ further details.
data/Rakefile CHANGED
@@ -20,7 +20,7 @@ Jeweler::Tasks.new do |gem|
20
20
  gem.summary = %Q{Bidi-Bidi-Bidi!}
21
21
  gem.description = %Q{The ambuquad that has your back.}
22
22
  gem.email = "joe@ruscio.org"
23
- gem.authors = ["Joseph Ruscio"]
23
+ gem.authors = ["Joseph Ruscio", "Mike Heffner"]
24
24
  # dependencies defined in Gemfile
25
25
  end
26
26
  Jeweler::RubygemsDotOrgTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
data/bin/twke CHANGED
@@ -11,19 +11,54 @@ require 'twke'
11
11
  require 'optparse'
12
12
 
13
13
  # Define the options and their default values
14
- $options = {}
14
+ $options = {
15
+ :api_key => ENV['TWKE_API_KEY'],
16
+ :subdomain => ENV['TWKE_SUBDOMAIN'],
17
+ :name => "twke",
18
+ :rooms => ENV['TWKE_ROOMS'],
19
+ :verbose => false
20
+ }
15
21
 
16
22
  optparse = OptionParser.new do|opts|
17
- opts.banner = "Usage: #{File.basename(__FILE__)} <options>\n"
23
+ opts.banner = "Usage: #{File.basename(__FILE__)} <options>\n"
18
24
 
19
- # help
20
- opts.on( '-h', '--help', 'Display this screen' ) do
21
- puts opts
22
- exit
23
- end
25
+ opts.on( '-k', '--api-key k', "Campfire API Key") do |k|
26
+ $options[:api_key] = k
27
+ end
28
+
29
+ opts.on( '-s', '--subdomain s', "Campfire Subdomain") do |s|
30
+ $options[:subdomain] = s
31
+ end
32
+
33
+ opts.on( '-n', '--name n', "Name that twke responds to (defaults to 'twke')") do |n|
34
+ $options[:name] = n
35
+ end
36
+
37
+ #TODO: support more than one room
38
+ opts.on( '-r', '--rooms r', "Room IDs for twke to join") do |r|
39
+ $options[:rooms] = r
40
+ end
41
+
42
+ opts.on( '-V', '--verbose', "Operate in verbose fashion") do
43
+ $options[:verbose] = true
44
+ end
45
+
46
+ # help
47
+ opts.on( '-h', '--help', 'Display this screen' ) do
48
+ puts opts
49
+ exit
50
+ end
24
51
  end
25
52
 
26
53
  # Parse the options
27
54
  optparse.parse!
28
55
 
29
- puts "bidi-bidi-bidi!"
56
+ # Add :verbose => true to get debug output, otherwise the logger will output INFO
57
+ scamp = Scamp.new(:api_key => $options[:api_key],
58
+ :subdomain => $options[:subdomain],
59
+ :verbose => $options[:verbose])
60
+
61
+ Twke::Routes.load(scamp)
62
+
63
+ #TODO: support more than one room
64
+ scamp.connect!([$options[:rooms].to_i])
@@ -1,3 +1,22 @@
1
1
  module Twke
2
+ require 'scamp'
3
+
4
+ require 'twke/routes.rb'
2
5
  require 'twke/plugin.rb'
6
+
7
+ def self.version
8
+ File.read(File.join(File.dirname(__FILE__), '../VERSION')).chomp
9
+ end
10
+
11
+ def self.plugin(plgn)
12
+ puts "Registering plugin #{plgn.plugin_name}"
13
+ end
14
+
15
+ def self.shutdown
16
+ exit 0
17
+ end
3
18
  end
19
+
20
+ Dir["#{File.dirname(__FILE__)}/../plugins/**/*.rb"].each { |plugin|
21
+ load plugin
22
+ }
@@ -1,2 +1,41 @@
1
1
  class Plugin
2
+ class << self
3
+
4
+ # Returns a short name for the plugin
5
+ #
6
+ def plugin_name
7
+ @plugin_name ||= begin
8
+ str = name.dup
9
+ str.downcase!
10
+ str.sub! /.*:/, ''
11
+ str
12
+ end
13
+ end
14
+
15
+ # Track all the available plugins
16
+ #
17
+ def plugins
18
+ @plugins ||= []
19
+ end
20
+
21
+ # Invoked when adding routes. Pass in params here. Could expand
22
+ # this to receive a number of events.
23
+ #
24
+ def routes(rp)
25
+ plgin = new()
26
+
27
+ if plgin.respond_to?(:add_routes)
28
+ plgin.add_routes(rp)
29
+ end
30
+ end
31
+
32
+ # Registers the current plugin with the system.
33
+ #
34
+ # Returns nothing.
35
+ def inherited(plgn)
36
+ Plugin.plugins << plgn
37
+ Twke.plugin(plgn)
38
+ super
39
+ end
40
+ end
2
41
  end
@@ -0,0 +1,42 @@
1
+ module Twke
2
+ module Routes
3
+ class RoutePrefix
4
+ def initialize(str = nil)
5
+ @levels = []
6
+ @levels.push(str) if str
7
+ end
8
+
9
+ def route(str, *opts, &blk)
10
+ @levels.push(str)
11
+ Routes.add(@levels.join(" "), *opts, &blk)
12
+ @levels.pop
13
+ end
14
+
15
+ def method_missing(name, &blk)
16
+ @levels.push(name)
17
+ yield
18
+ @levels.pop
19
+ end
20
+ end
21
+
22
+ class << self
23
+ attr_accessor :conn
24
+
25
+ def load(scamp)
26
+ @@conn = scamp
27
+
28
+ # TODO: Only load the configured plugins
29
+ Plugin.plugins.each do |plgin|
30
+ # TODO: always prefix with 'twke', configurable later?
31
+ plgin.routes(RoutePrefix.new('twke'))
32
+ end
33
+ end
34
+
35
+ def add(str, *opts, &blk)
36
+ @@conn.behaviour do
37
+ match(str, *opts, &blk)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ class Plugin::Admin < Plugin
2
+ # Invoked to define routes.
3
+ def add_routes(rp)
4
+ rp.admin do
5
+ rp.route 'respawn' do
6
+ say "Initiating respawn"
7
+ EM::Timer.new(2) do
8
+ Twke::shutdown
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ # Fun with twke
2
+ #
3
+ class Plugin::Twiki < Plugin
4
+ # Invoked to define routes.
5
+ def add_routes(rp)
6
+ rp.route 'bidi' do
7
+ say 'bidi-bidi-bidi!'
8
+ end
9
+
10
+ rp.route 'version' do
11
+ say "Twke version: #{Twke.version}"
12
+ end
13
+ end
14
+ end
@@ -5,30 +5,33 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{twke}
8
- s.version = "0.0.1"
8
+ s.version = "0.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Joseph Ruscio"]
12
- s.date = %q{2011-09-24}
11
+ s.authors = ["Joseph Ruscio", "Mike Heffner"]
12
+ s.date = %q{2011-09-27}
13
13
  s.default_executable = %q{twke}
14
14
  s.description = %q{The ambuquad that has your back.}
15
15
  s.email = %q{joe@ruscio.org}
16
16
  s.executables = ["twke"]
17
17
  s.extra_rdoc_files = [
18
18
  "LICENSE.txt",
19
- "README.rdoc"
19
+ "README.md"
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
23
  "Gemfile",
24
24
  "Gemfile.lock",
25
25
  "LICENSE.txt",
26
- "README.rdoc",
26
+ "README.md",
27
27
  "Rakefile",
28
28
  "VERSION",
29
29
  "bin/twke",
30
30
  "lib/twke.rb",
31
31
  "lib/twke/plugin.rb",
32
+ "lib/twke/routes.rb",
33
+ "plugins/admin.rb",
34
+ "plugins/twiki.rb",
32
35
  "test/helper.rb",
33
36
  "test/test_twke.rb",
34
37
  "twke.gemspec"
metadata CHANGED
@@ -1,20 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twke
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Joseph Ruscio
9
+ - Mike Heffner
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2011-09-24 00:00:00.000000000 -07:00
13
+ date: 2011-09-27 00:00:00.000000000 -07:00
13
14
  default_executable: twke
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: scamp
17
- requirement: &2161492380 !ruby/object:Gem::Requirement
18
+ requirement: &2153515900 !ruby/object:Gem::Requirement
18
19
  none: false
19
20
  requirements:
20
21
  - - ~>
@@ -22,10 +23,10 @@ dependencies:
22
23
  version: 0.1.1
23
24
  type: :runtime
24
25
  prerelease: false
25
- version_requirements: *2161492380
26
+ version_requirements: *2153515900
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: shoulda
28
- requirement: &2161491620 !ruby/object:Gem::Requirement
29
+ requirement: &2153515080 !ruby/object:Gem::Requirement
29
30
  none: false
30
31
  requirements:
31
32
  - - ! '>='
@@ -33,10 +34,10 @@ dependencies:
33
34
  version: '0'
34
35
  type: :development
35
36
  prerelease: false
36
- version_requirements: *2161491620
37
+ version_requirements: *2153515080
37
38
  - !ruby/object:Gem::Dependency
38
39
  name: bundler
39
- requirement: &2161490840 !ruby/object:Gem::Requirement
40
+ requirement: &2153514320 !ruby/object:Gem::Requirement
40
41
  none: false
41
42
  requirements:
42
43
  - - ~>
@@ -44,10 +45,10 @@ dependencies:
44
45
  version: 1.0.0
45
46
  type: :development
46
47
  prerelease: false
47
- version_requirements: *2161490840
48
+ version_requirements: *2153514320
48
49
  - !ruby/object:Gem::Dependency
49
50
  name: jeweler
50
- requirement: &2161489500 !ruby/object:Gem::Requirement
51
+ requirement: &2153513580 !ruby/object:Gem::Requirement
51
52
  none: false
52
53
  requirements:
53
54
  - - ~>
@@ -55,10 +56,10 @@ dependencies:
55
56
  version: 1.6.4
56
57
  type: :development
57
58
  prerelease: false
58
- version_requirements: *2161489500
59
+ version_requirements: *2153513580
59
60
  - !ruby/object:Gem::Dependency
60
61
  name: rcov
61
- requirement: &2161477440 !ruby/object:Gem::Requirement
62
+ requirement: &2153512780 !ruby/object:Gem::Requirement
62
63
  none: false
63
64
  requirements:
64
65
  - - ! '>='
@@ -66,7 +67,7 @@ dependencies:
66
67
  version: '0'
67
68
  type: :development
68
69
  prerelease: false
69
- version_requirements: *2161477440
70
+ version_requirements: *2153512780
70
71
  description: The ambuquad that has your back.
71
72
  email: joe@ruscio.org
72
73
  executables:
@@ -74,18 +75,21 @@ executables:
74
75
  extensions: []
75
76
  extra_rdoc_files:
76
77
  - LICENSE.txt
77
- - README.rdoc
78
+ - README.md
78
79
  files:
79
80
  - .document
80
81
  - Gemfile
81
82
  - Gemfile.lock
82
83
  - LICENSE.txt
83
- - README.rdoc
84
+ - README.md
84
85
  - Rakefile
85
86
  - VERSION
86
87
  - bin/twke
87
88
  - lib/twke.rb
88
89
  - lib/twke/plugin.rb
90
+ - lib/twke/routes.rb
91
+ - plugins/admin.rb
92
+ - plugins/twiki.rb
89
93
  - test/helper.rb
90
94
  - test/test_twke.rb
91
95
  - twke.gemspec
@@ -105,7 +109,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
109
  version: '0'
106
110
  segments:
107
111
  - 0
108
- hash: -4543077646895532291
112
+ hash: -3484703329107985583
109
113
  required_rubygems_version: !ruby/object:Gem::Requirement
110
114
  none: false
111
115
  requirements:
@@ -1,19 +0,0 @@
1
- = twke
2
-
3
- Description goes here.
4
-
5
- == Contributing to twke
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
- * Fork the project
10
- * Start a feature/bugfix branch
11
- * Commit and push until you are happy with your contribution
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
16
-
17
- Copyright (c) 2011 Joseph Ruscio. See LICENSE.txt for
18
- further details.
19
-