Class: Butler
- Inherits:
-
Object
- Object
- Butler
- Extended by:
- Log::Comfort
- Defined in:
- lib/butler/version.rb,
lib/butler.rb,
lib/butler/dialog.rb,
lib/butler/plugin.rb,
lib/butler/control.rb,
lib/butler/plugins.rb,
lib/butler/service.rb,
lib/butler/session.rb,
lib/butler/debuglog.rb,
lib/butler/irc/user.rb,
lib/butler/services.rb,
lib/butler/irc/topic.rb,
lib/butler/irc/whois.rb,
lib/butler/irc/client.rb,
lib/butler/irc/parser.rb,
lib/butler/irc/socket.rb,
lib/butler/irc/channel.rb,
lib/butler/plugin/more.rb,
lib/butler/remote/user.rb,
lib/butler/irc/hostmask.rb,
lib/butler/irc/userlist.rb,
lib/butler/initialvalues.rb,
lib/butler/remote/server.rb,
lib/butler/plugin/trigger.rb,
lib/butler/irc/channellist.rb,
lib/butler/irc/client/filter.rb,
lib/butler/remote/connection.rb,
lib/butler/irc/parser/command.rb,
lib/butler/plugin/configproxy.rb,
lib/butler/irc/client/listener.rb,
lib/butler/irc/client/listenerlist.rb
Overview
:nodoc:
Defined Under Namespace
Modules: DebugLog, IRC, Remote, Service, VERSION Classes: Control, Dialog, Plugin, Plugins, Services, Session
Constant Summary collapse
- IsGem =
REPLACE: IsGem = false
true
- Structure =
%w[ BOTPATH BOTPATH/access BOTPATH/access/privilege BOTPATH/access/role BOTPATH/access/user BOTPATH/log BOTPATH/plugins BOTPATH/services ].map { |e| [e, 0755] }
- ConfigurationStructure =
first one is the base-directory
%w[ BOTPATH/config connections channels plugins ]
- EmptyConfig =
{ 'remote' => { 'host' => 'localhost', 'port' => 7666, 'active' => false, }, 'logging' => { }, 'owner' => { 'username' => nil, # no owner 'contact' => 'unknown', }, }
Class Attribute Summary collapse
-
.path ⇒ Object
Returns the value of attribute path.
Attributes included from Log::Comfort
Class Method Summary collapse
-
.backup(path, botname, backup) ⇒ Object
creates a backup of all important files of a bot.
-
.create(path, botname, opts = {}) ⇒ Object
creates a new bot.
-
.delete(path, botname) ⇒ Object
deletes a bot.
-
.exists?(path, botname) ⇒ Boolean
tests if a bot named
botname
exists. -
.list(path) ⇒ Object
returns a list with bots.
- .new(*args, &block) ⇒ Object
-
.rename(path, old_name, new_name) ⇒ Object
renames a bot.
-
.start(path, botname, opts = {}, &block) ⇒ Object
start a bot if you provide a block, it will yield the bot instance and you can control it.
- .start_daemon(path, botname, opts = {}, &block) ⇒ Object
- .start_interactive(path, botname, opts, &block) ⇒ Object
- .stop(path, botname) ⇒ Object
- .test_pidfile(path, botname) ⇒ Object
Methods included from Log::Comfort
debug, error, exception, fail, info, log, warn
Class Attribute Details
.path ⇒ Object
Returns the value of attribute path.
28 29 30 |
# File 'lib/butler.rb', line 28 def path @path end |
Class Method Details
.backup(path, botname, backup) ⇒ Object
creates a backup of all important files of a bot
132 133 134 135 136 137 |
# File 'lib/butler.rb', line 132 def backup(path, botname, backup) path ||= @path bot_path = "#{path.bots}/#{botname}" FileUtils.mkdir_p(File.dirname(backup), :mode => 0755) FileUtils.cp_r(bot_path, backup) end |
.create(path, botname, opts = {}) ⇒ Object
creates a new bot
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/butler.rb', line 153 def create(path, botname, opts={}) path ||= @path bot_path = "#{path.bots}/#{botname}" Structure.each { |dir, mode| FileUtils.mkdir_p(dir.sub(/BOTPATH/, bot_path), :mode => mode) } conf = Configuration.new( ConfigurationStructure.first.sub(/BOTPATH/, bot_path), ConfigurationStructure[1..-1] ) EmptyConfig.each { |k,v| conf[k] = v } FileUtils.cp_r(path.plugin_repository, bot_path) FileUtils.cp_r(path.service_repository, bot_path) end |
.delete(path, botname) ⇒ Object
deletes a bot
171 172 173 174 175 |
# File 'lib/butler.rb', line 171 def delete(path, botname) path ||= @path bot_path = "#{path.bots}/#{botname}" FileUtils.rm_r(bot_path) end |
.exists?(path, botname) ⇒ Boolean
tests if a bot named botname
exists
140 141 142 143 144 |
# File 'lib/butler.rb', line 140 def exists?(path, botname) path ||= @path bot_path = "#{path.bots}/#{botname}" File.directory?(bot_path) end |
.list(path) ⇒ Object
returns a list with bots
147 148 149 150 |
# File 'lib/butler.rb', line 147 def list(path) path ||= @path Dir[path.bots+"/*/"].map { |dir| dir[%r{([^/]+)/$}, 1] } end |
.new(*args, &block) ⇒ Object
185 186 187 |
# File 'lib/butler.rb', line 185 def new(*args, &block) Bot.new(*args, &block) end |
.rename(path, old_name, new_name) ⇒ Object
renames a bot
178 179 180 181 182 183 |
# File 'lib/butler.rb', line 178 def rename(path, old_name, new_name) path ||= @path old_bot_path = "#{path.bots}/#{old_name}" new_bot_path = "#{path.bots}/#{new_name}" FileUtils.mv(old_bot_path, new_bot_path) end |
.start(path, botname, opts = {}, &block) ⇒ Object
start a bot if you provide a block, it will yield the bot instance and you can control it. If not, it will enter the Bot#event_loop. options: -:in_dir => path to the directory the bot can be found [Butler.bots] -:daemonize => whether this script should become a deamon or not [true] -…
37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/butler.rb', line 37 def start(path, botname, opts={}, &block) Thread.abort_on_exception = true if $DEBUG path ||= @path butler = nil if opts.delete(:daemonize) then start_daemon(path, botname, opts, &block) else start_interactive(path, botname, opts, &block) end end |
.start_daemon(path, botname, opts = {}, &block) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/butler.rb', line 49 def start_daemon(path, botname, opts={}, &block) butler, pidfile = nil, nil info "Daemonizing" pidfile = test_pidfile(path.run, botname) daemonize(path.base) { } begin File.write(pidfile, $$) butler = Bot.new(path, botname, opts) path = butler.path $stderr = File.open(path.log+"/error.log", "a") $stdout = File.open(path.log+"/out.log", "a") trap("SIGHUP") { butler.quit } butler.output_to_logfiles butler.plugins.load_all butler.login info("Running #{botname} with PID #{$$} as daemon") if block then butler.event_loop(&block) else sleep end rescue SystemExit => e info("Exit, terminating #{botname} (in #{e.backtrace.first}") rescue Exception => e exception(e) else info("EventLoop ended, terminating #{botname}") ensure butler.quit if butler File.delete(pidfile) if pidfile and File.exist?(pidfile) info("Terminated") end end |
.start_interactive(path, botname, opts, &block) ⇒ Object
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/butler.rb', line 79 def start_interactive(path, botname, opts, &block) butler, pidfile = nil, nil pidfile = test_pidfile(path.run, botname) File.write(pidfile, $$) info("Running #{botname} with PID #{$$} interactively") butler = Bot.new(path, botname, opts) butler.plugins.load_all butler.login if block then butler.event_loop(&block) else sleep end rescue SystemExit => e info("Exit #{botname} (in #{e.backtrace.first}") rescue Interrupt => e info("Interrupt, terminating #{botname} (in #{e.backtrace.first}") rescue Exception => e exception(e) ensure File.delete(pidfile) if pidfile and File.exist?(pidfile) butler.quit if butler and butler.connected? info("Terminated") end |
.stop(path, botname) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/butler.rb', line 114 def stop(path, botname) path ||= @path pidfile = "#{path.run}/#{botname}.pid" if File.exist?(pidfile) then pid = File.read(pidfile).to_i begin Process.kill("HUP", pid) rescue Errno::ESRCH; end begin File.delete(pidfile) rescue Errno::ENOENT; end end rescue => e exception(e) nil end |
.test_pidfile(path, botname) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/butler.rb', line 100 def test_pidfile(path, botname) pidfile = "#{path}/#{botname}.pid" FileUtils.mkdir_p(path, :mode => 0755) raise "Can't write to pid-directory (#{path.run})" if !File.writable?(path) if File.exist?(pidfile) && pid = File.read(pidfile) then if pid.empty? then raise "Already a Butler named '#{botname}' starting up" else raise "Already a Butler named '#{botname}' running with PID #{pid.chomp}" end end pidfile end |