require 'thread'
require 'etc'
+require 'date'
require 'fileutils'
require 'logger'
$logger.datetime_format = $dateformat
$logger.level = $cl_loglevel if defined? $cl_loglevel
$logger.level = 0 if $debug
+$logger_stderr = $logger
$log_queue = Queue.new
$log_thread = nil
# messages originating at the same time, we blank #{who} after the first message
# is output.
# Also, we output strings as-is but for other objects we use pretty_inspect
- case message
- when String
- str = message
- else
- str = message.pretty_inspect rescue '?'
- end
+ message = message.kind_of?(String) ? message : (message.pretty_inspect rescue '?')
qmsg = Array.new
- str.each_line { |l|
+ message.each_line { |l|
qmsg.push [level, l.chomp, who]
who = ' ' * who.size
}
- if level == Logger::Severity::ERROR or level == Logger::Severity::FATAL and not $daemonize
- $stderr.puts str
+ if level >= Logger::Severity::WARN and not $daemonize
+ qmsg.each do |l|
+ $logger_stderr.add(*l)
+ end
end
$log_queue.push qmsg
end
require 'rbot/ircsocket'
require 'rbot/botuser'
require 'rbot/timer'
+require 'rbot/registry'
require 'rbot/plugins'
require 'rbot/message'
require 'rbot/language'
# Main bot class, which manages the various components, receives messages,
# handles them or passes them to plugins, and contains core functionality.
class Bot
- COPYRIGHT_NOTICE = "(c) Tom Gilbert and the rbot development team"
+ COPYRIGHT_NOTICE = "(c) Giuseppe Bilotta and the rbot development team"
SOURCE_URL = "http://ruby-rbot.org"
# the bot's Auth data
attr_reader :auth
# proxies etc as defined by the bot configuration/environment
attr_accessor :httputil
+ # mechanize agent factory
+ attr_accessor :agent
+
+ # loads and opens new registry databases, used by the plugins
+ attr_accessor :registry_factory
+
+ # web service
+ attr_accessor :webservice
+
# server we are connected to
# TODO multiserver
def server
:desc => "The CA file used to verify the SSL connection.",
:wizard => true)
Config.register Config::StringValue.new('server.ssl_ca_path',
- :default => '', :requires_restart => true,
+ :default => default_ssl_ca_path, :requires_restart => true,
:desc => "Alternativly a directory that includes CA PEM files used to verify the SSL connection.",
:wizard => true)
Config.register Config::StringValue.new('server.password',
},
:desc => "Percentage of IRC penalty to consider when sending messages to prevent being disconnected for excess flood. Set to 0 to disable penalty control.")
Config.register Config::StringValue.new('core.db',
- :default => "dbm",
- :wizard => true, :default => "dbm",
- :validate => Proc.new { |v| ["dbm", "daybreak"].include? v },
+ :default => default_db, :store_default => true,
+ :wizard => true,
+ :validate => Proc.new { |v| Registry::formats.include? v },
:requires_restart => true,
- :desc => "DB adaptor to use for storing the plugin data/registries. Options: dbm (included in ruby), daybreak")
+ :desc => "DB adaptor to use for storing the plugin data/registries. Options: " + Registry::formats.join(', '))
@argv = params[:argv]
@run_dir = params[:run_dir] || Dir.pwd
$daemonize = true
end
- case @config["core.db"]
- when "dbm"
- require 'rbot/registry/dbm'
- when "daybreak"
- require 'rbot/registry/daybreak'
- else
- raise _("Unknown DB adaptor: %s") % @config["core.db"]
- end
+ @registry_factory = Registry.new @config['core.db']
+ @registry_factory.migrate_registry_folder(path)
@logfile = @config['log.file']
if @logfile.class!=String || @logfile.empty?
end
end
+ def default_ssl_ca_path
+ file = default_ssl_ca_file
+ File.dirname file if file
+ end
+
+ # Determine if tokyocabinet is installed, if it is use it as a default.
+ def default_db
+ begin
+ require 'tokyocabinet'
+ return 'tc'
+ rescue LoadError
+ return 'dbm'
+ end
+ end
+
def repopulate_botclass_directory
template_dir = File.join Config::datadir, 'templates'
if FileTest.directory? @botclass
end
end
- # call the save method for all of the botmodules
- def save
+ # call the save method for all or the specified botmodule
+ #
+ # :botmodule ::
+ # optional botmodule to save
+ def save(botmodule=nil)
@save_mutex.synchronize do
- @plugins.save
+ @plugins.save(botmodule)
end
end
- # call the rescan method for all of the botmodules
- def rescan
+ # call the rescan method for all or just the specified botmodule
+ #
+ # :botmodule ::
+ # instance of the botmodule to rescan
+ def rescan(botmodule=nil)
debug "\tstopping timer..."
@timer.stop
@save_mutex.synchronize do
- @lang.rescan
- @plugins.rescan
+ # @lang.rescan
+ @plugins.rescan(botmodule)
end
@timer.start
end