october 0.1.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.
- data/Gemfile +35 -0
- data/README.md +14 -0
- data/Rakefile +38 -0
- data/bin/october +8 -0
- data/boot.rb +5 -0
- data/config/database.yml.example +3 -0
- data/config/irc.yml.example +9 -0
- data/config/plugins.yml.example +2 -0
- data/config/redis.yml.example +7 -0
- data/lib/october.rb +16 -0
- data/lib/october/base.rb +28 -0
- data/lib/october/config.rb +23 -0
- data/lib/october/debugger.rb +51 -0
- data/lib/october/environment.rb +24 -0
- data/lib/october/plugin.rb +26 -0
- data/lib/october/plugin/help.rb +20 -0
- data/lib/october/plugins.rb +94 -0
- data/lib/october/redis.rb +20 -0
- data/lib/october/version.rb +3 -0
- data/lib/october/watchdog.rb +36 -0
- data/october.gemspec +25 -0
- data/plugins/.gitkeep +0 -0
- data/plugins/autossh.rb +23 -0
- data/plugins/fortune.rb +13 -0
- data/plugins/help.rb +11 -0
- data/plugins/hudson.rb +73 -0
- data/plugins/hudson/config.rb +41 -0
- data/plugins/hudson/fetcher.rb +40 -0
- data/plugins/hudson/reporter.rb +104 -0
- data/plugins/hudson/test_run.rb +88 -0
- data/plugins/issues.rb +161 -0
- data/plugins/joke.rb +32 -0
- data/plugins/links.rb +42 -0
- data/plugins/links/link.rb +68 -0
- data/plugins/service.rb +11 -0
- data/plugins/update.rb +79 -0
- data/plugins/whisper.rb +70 -0
- data/spec/fixtures/hudson/console.log +37 -0
- data/spec/helpers/bot_context.rb +5 -0
- data/spec/october/environment_spec.rb +28 -0
- data/spec/plugins/hudson/reporter_spec.rb +27 -0
- data/spec/plugins/hudson/test_run_spec.rb +17 -0
- data/spec/plugins/hudson_spec.rb +44 -0
- data/spec/plugins/issues_spec.rb +26 -0
- data/spec/plugins/links_spec.rb +16 -0
- data/spec/plugins/whisper_spec.rb +6 -0
- data/spec/spec_helper.rb +13 -0
- metadata +185 -0
data/Gemfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
source :rubygems
|
2
|
+
|
3
|
+
gem 'cinch'
|
4
|
+
|
5
|
+
gem 'rake', :require => false
|
6
|
+
gem 'activesupport', :require => 'active_support/core_ext'
|
7
|
+
gem 'i18n'
|
8
|
+
|
9
|
+
# debugging
|
10
|
+
group :development do
|
11
|
+
gem 'pry'
|
12
|
+
gem 'pry-nav'
|
13
|
+
gem 'awesome_print'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Redis stuff
|
17
|
+
gem 'redis'
|
18
|
+
gem 'hiredis'
|
19
|
+
gem 'redis-namespace'
|
20
|
+
gem 'redis-objects', :require => 'redis/objects'
|
21
|
+
|
22
|
+
# http stuff
|
23
|
+
gem 'typhoeus'
|
24
|
+
|
25
|
+
# issues stuff - https://github.com/peter-murach/github/
|
26
|
+
gem 'github_api'
|
27
|
+
|
28
|
+
gem 'json'
|
29
|
+
gem 'nokogiri'
|
30
|
+
gem 'curb'
|
31
|
+
|
32
|
+
group :test do
|
33
|
+
gem 'rspec'
|
34
|
+
gem 'fakefs', :require => 'fakefs/safe'
|
35
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# October
|
2
|
+
[](http://travis-ci.org/#!/mikz/october)
|
3
|
+
|
4
|
+
IRC bot build on [Cinch framework](https://github.com/cinchrb/cinch) with some additional stuff like persistence layer od configuration in yml.
|
5
|
+
|
6
|
+
## Plugins
|
7
|
+
|
8
|
+
October provides some sugar for regular Cinch plugins such as redis persistence and help command.
|
9
|
+
|
10
|
+
|
11
|
+
## TODO
|
12
|
+
|
13
|
+
* Spec
|
14
|
+
* Moar features!
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
namespace :gem do
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
end
|
4
|
+
|
5
|
+
task :integrate do |task|
|
6
|
+
ENV['OCTOBER_ENV'] ||= 'test'
|
7
|
+
exec 'rspec spec'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :environment, :env do |task, args|
|
11
|
+
ENV['OCTOBER_ENV'] ||= args[:env]
|
12
|
+
|
13
|
+
$:.unshift File.dirname(__FILE__)
|
14
|
+
|
15
|
+
require 'boot'
|
16
|
+
require 'october'
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
task :boot, [:env, :console] => :environment do |task, args|
|
21
|
+
@bot = October::Base.new
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Starts IRC server'
|
25
|
+
task :start, [:env, :console] => :boot do |task, args|
|
26
|
+
if args[:console]
|
27
|
+
Cinch::IRC.send :include, October::Debugger
|
28
|
+
end
|
29
|
+
|
30
|
+
@bot.start
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Creates interactive console with Pry'
|
34
|
+
task :console, [:env] => :boot do |task, args|
|
35
|
+
@bot.pry
|
36
|
+
end
|
37
|
+
|
38
|
+
#task :default => :start
|
data/bin/october
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
root = File.expand_path("..", File.dirname(__FILE__))
|
4
|
+
|
5
|
+
# this could be just 'october/daemon' when october will be rubygem
|
6
|
+
require File.expand_path(File.join('lib', 'october', 'watchdog'), root)
|
7
|
+
|
8
|
+
October::Watchdog.new(root, ARGV.shift).loop!
|
data/boot.rb
ADDED
data/lib/october.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
|
3
|
+
module October
|
4
|
+
autoload :Config, 'october/config'
|
5
|
+
autoload :Base, 'october/base'
|
6
|
+
autoload :Environment, 'october/environment'
|
7
|
+
autoload :Redis, 'october/redis'
|
8
|
+
autoload :Debugger, 'october/debugger'
|
9
|
+
autoload :Plugins, 'october/plugins'
|
10
|
+
autoload :Plugin, 'october/plugin'
|
11
|
+
|
12
|
+
def self.root
|
13
|
+
Pathname.new('.').expand_path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/october/base.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'cinch'
|
2
|
+
|
3
|
+
module October
|
4
|
+
class Base < Cinch::Bot
|
5
|
+
|
6
|
+
def self.start
|
7
|
+
new.start
|
8
|
+
end
|
9
|
+
|
10
|
+
include Config
|
11
|
+
include Redis
|
12
|
+
include Plugins.initialize
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super do
|
16
|
+
load_config!
|
17
|
+
|
18
|
+
on :message, "hello" do |m|
|
19
|
+
m.reply "Hello, #{m.user.nick}"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module October
|
2
|
+
module Config
|
3
|
+
extend Environment
|
4
|
+
def load_config!
|
5
|
+
env = Config.configuration('irc.yml')
|
6
|
+
return unless env.present?
|
7
|
+
|
8
|
+
env.each_pair do |key, value|
|
9
|
+
# FIXME: make DRY
|
10
|
+
# FIXME: only one level - bad, only to support SSL nested values for now
|
11
|
+
if value.is_a? Hash
|
12
|
+
subconfig = config.send key.dup
|
13
|
+
value.each_pair do |key, value|
|
14
|
+
subconfig.send key.dup << '=', value
|
15
|
+
end
|
16
|
+
else
|
17
|
+
config.send key.dup << '=', value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
gem 'pry'
|
2
|
+
|
3
|
+
module October
|
4
|
+
module Debugger
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
##
|
7
|
+
# Extends capabilities of Cinch::IRC to
|
8
|
+
# launch debugger after connecting and creating all threads
|
9
|
+
#
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
self.class_eval do
|
14
|
+
if method_defined? :start
|
15
|
+
alias_pry(:start)
|
16
|
+
elsif method_defined? :connect
|
17
|
+
alias_pry(:connect)
|
18
|
+
else
|
19
|
+
raise 'Unsupported version of Cinch'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
module InstanceMethods
|
26
|
+
def init_pry
|
27
|
+
Thread.new do
|
28
|
+
binding.pry
|
29
|
+
Thread.pass
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
def alias_pry(before)
|
37
|
+
class_eval %{
|
38
|
+
|
39
|
+
def #{before}_with_pry
|
40
|
+
init_pry
|
41
|
+
#{before}_without_pry
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method_chain :#{before}, :pry
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module October
|
2
|
+
module Environment
|
3
|
+
class NoSuchEnvironment < StandardError; end
|
4
|
+
|
5
|
+
def load_configuration(file)
|
6
|
+
config = File.join('config', file)
|
7
|
+
return {} unless File.exists?(config)
|
8
|
+
YAML.load_file( config ).with_indifferent_access
|
9
|
+
end
|
10
|
+
|
11
|
+
def environment
|
12
|
+
ENV['OCTOBER_ENV'].presence || 'default'
|
13
|
+
end
|
14
|
+
|
15
|
+
def configuration(file, env = environment)
|
16
|
+
load_configuration(file)[env.to_sym]
|
17
|
+
end
|
18
|
+
|
19
|
+
def configuration!(file, env = environment)
|
20
|
+
configuration(file, env) or raise NoSuchEnvironment.new("No environment #{env} in file #{file}")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'cinch'
|
3
|
+
|
4
|
+
module October
|
5
|
+
module Plugin
|
6
|
+
autoload :Help, 'october/plugin/help'
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include Cinch::Plugin
|
12
|
+
extend Help
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def name
|
17
|
+
to_s.underscore
|
18
|
+
end
|
19
|
+
|
20
|
+
def config
|
21
|
+
October::Plugins.config(name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module October
|
2
|
+
module Plugin
|
3
|
+
module Help
|
4
|
+
@@help = {}
|
5
|
+
|
6
|
+
def self.extended(base)
|
7
|
+
end
|
8
|
+
|
9
|
+
def register_help command, description = nil
|
10
|
+
@@help[command] = description
|
11
|
+
end
|
12
|
+
|
13
|
+
def list_help
|
14
|
+
@@help.map do |command, description|
|
15
|
+
[" !", [command, description].compact.join(' - ')].join
|
16
|
+
end.join("\n")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module October
|
2
|
+
class Plugins < Array
|
3
|
+
extend Environment
|
4
|
+
|
5
|
+
attr_reader :loaded
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@loaded = []
|
9
|
+
import Plugins.configuration('plugins.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
delegate :registered, :configure, :to => :'self.class'
|
13
|
+
|
14
|
+
def import plugins
|
15
|
+
return unless plugins.present?
|
16
|
+
|
17
|
+
plugins = Hash[ plugins.map {|plugin|
|
18
|
+
plugin.respond_to?(:to_a) ? plugin.to_a.flatten(1) : [plugin, {}]
|
19
|
+
}].with_indifferent_access
|
20
|
+
|
21
|
+
names = plugins.keys.map {|name| name.camelize }
|
22
|
+
|
23
|
+
diff = registered.keys & (names - self)
|
24
|
+
push *diff
|
25
|
+
load diff
|
26
|
+
|
27
|
+
self.class.configure(plugins)
|
28
|
+
end
|
29
|
+
|
30
|
+
def imported
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def load new
|
36
|
+
@loaded.push *new.map{ |plugin|
|
37
|
+
require registered[plugin]
|
38
|
+
plugin.constantize
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
module PluginMethods
|
43
|
+
extend ActiveSupport::Concern
|
44
|
+
|
45
|
+
included do
|
46
|
+
attr_reader :plugin_module
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize
|
50
|
+
plugins = Plugins.new
|
51
|
+
super
|
52
|
+
# stupid, really, why so long?
|
53
|
+
self.config.plugins.plugins.push *plugins.loaded
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
class << self
|
59
|
+
|
60
|
+
@@plugins = {}
|
61
|
+
@@configs = {}.with_indifferent_access
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
October.root.join('plugins').
|
65
|
+
each_child(false).
|
66
|
+
each do |file|
|
67
|
+
next unless file.to_s =~ /\.rb$/
|
68
|
+
name = file.basename('.rb').to_s.camelize
|
69
|
+
register name => file
|
70
|
+
end
|
71
|
+
|
72
|
+
PluginMethods
|
73
|
+
end
|
74
|
+
|
75
|
+
def register plugin
|
76
|
+
@@plugins.merge! plugin
|
77
|
+
end
|
78
|
+
|
79
|
+
def config(plugin)
|
80
|
+
@@configs.fetch(plugin, {})
|
81
|
+
end
|
82
|
+
|
83
|
+
def configure(plugin)
|
84
|
+
@@configs.merge! plugin
|
85
|
+
end
|
86
|
+
|
87
|
+
def registered
|
88
|
+
@@plugins
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'redis'
|
2
|
+
require 'hiredis'
|
3
|
+
require 'active_support/core_ext/hash/keys'
|
4
|
+
|
5
|
+
module October
|
6
|
+
module Redis
|
7
|
+
extend Environment
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
return unless config = Redis.configuration('redis.yml')
|
11
|
+
# FIXME: parhaps more options, fetch from redis directly, or pass them all and let redis to handle it?
|
12
|
+
redis = ::Redis.new config.slice :host, :port, :path
|
13
|
+
if config.has_key? :namespace
|
14
|
+
redis = ::Redis::Namespace.new config[:namespace], :redis => redis
|
15
|
+
end
|
16
|
+
redis.incr 'launches'
|
17
|
+
$redis = redis
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|