def initialize
super
- @data_path = "#{@bot.botclass}/alias/"
- @data_file = "#{@data_path}/aliases.yaml"
+ @data_path = datafile
+ @data_file = File.join(@data_path, 'aliases.yaml')
# hash of alias => command entries
data = nil
aliases = if File.exist?(@data_file) &&
:default => "",
:desc => "Directory where profile/string dumps are to be stored")
+ def dirname
+ @bot.config['debug.logdir']
+ end
+
def initialize
super
@prev = Hash.new(0)
@curr = Hash.new(0)
@delta = Hash.new(0)
- @file = File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler.log",'w')
+ @file = File.open(datafile("memory_profiler.log"), 'w')
@thread = @bot.timer.add(@bot.config['debug.interval']) {
begin
GC.start
end
if @bot.config['debug.dump_strings']
- File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
+ File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
curr_strings.sort.each do |s|
f.puts s
end
end
end
- File.open("#{@bot.botclass}/#{@bot.config['debug.logdir']}/memory_profiler_strings.log.#{Time.now.to_i}",'w') do |f|
+ File.open(datafile("memory_profiler_strings.log.#{Time.now.to_i}"), 'w') do |f|
curr_strings.sort.each do |s|
f.puts s
end
super
# TODO config
- @dir = File.join(@bot.botclass,"factoids")
+ @dir = datafile
@filename = "factoids.rbot"
@factoids = FactoidList.new
@triggers = Set.new
},
}
- @autoadd_base = "#{@bot.botclass}/azgame/autoadd-"
+ @autoadd_base = datafile "autoadd-"
end
def initialize_wordlist(params)
def fetch_data( m )
# Read the winning messages file
@win_messages = Array.new
- if File.exists? "#{@bot.botclass}/quiz/win_messages"
- IO.foreach("#{@bot.botclass}/quiz/win_messages") { |line| @win_messages << line.chomp }
+ winfile = datafile 'win_messages'
+ if File.exists? winfile
+ IO.foreach(winfile) { |line| @win_messages << line.chomp }
else
warning( "win_messages file not found!" )
# Fill the array with a least one message or code accessing it would fail
m.reply "Failed to download questions from #{p}, ignoring sources"
end
else
- path = "#{@bot.botclass}/quiz/#{p}"
+ path = datafile p
debug "Fetching from #{path}"
# Local data
begin
- datafile = File.new( path, File::RDONLY )
- data << "\n\n" << datafile.read
+ file = File.new( path, File::RDONLY )
+ data << "\n\n" << file.read
rescue
m.reply "Failed to read from local database file #{p}, skipping."
end
if ruleset.has_key?(:wordlist_file)
begin
ruleset[:words] =
- File.new("#{@bot.botclass}/shiritori/#{ruleset[:wordlist_file]}").grep(
+ File.new(datafile ruleset[:wordlist_file]).grep(
ruleset[:listen]) {|l| ruleset[:normalize].call l.chomp}
rescue
raise "unable to load word list"
@registry.set_default(0)
# import if old file format found
- if(File.exist?("#{@bot.botclass}/karma.rbot"))
+ oldkarma = @bot.path 'karma.rbot'
+ if File.exist? oldkarma
log "importing old karma data"
- IO.foreach("#{@bot.botclass}/karma.rbot") do |line|
+ IO.foreach(oldkarma) do |line|
if(line =~ /^(\S+)<=>([\d-]+)$/)
item = $1
karma = $2.to_i
@registry[item] = karma
end
end
- File.delete("#{@bot.botclass}/karma.rbot")
+ File.delete oldkarma
end
end
scan
# import old format keywords into DBHash
- if(File.exist?("#{@bot.botclass}/keywords.rbot"))
+ olds = @bot.path 'keywords.rbot'
+ if File.exist? olds
log "auto importing old keywords.rbot"
- IO.foreach("#{@bot.botclass}/keywords.rbot") do |line|
+ IO.foreach(olds) do |line|
if(line =~ /^(.*?)\s*<=(is|are)?=?>\s*(.*)$/)
lhs = $1
mhs = $2
@keywords[lhs] = Keyword.new(mhs, values).dump
end
end
- File.rename("#{@bot.botclass}/keywords.rbot", "#{@bot.botclass}/keywords.rbot.old")
+ File.rename(olds, olds + ".old")
end
end
# have been added
def scan
# first scan for old DBHash files, and convert them
- Dir["#{@bot.botclass}/keywords/*"].each {|f|
+ Dir[datafile '*'].each {|f|
next unless f =~ /\.db$/
log "upgrading keyword db #{f} (rbot 0.9.5 or prior) database format"
newname = f.gsub(/\.db$/, ".kdb")
- old = BDB::Hash.open f, nil,
- "r+", 0600
- new = BDB::CIBtree.open(newname, nil,
- BDB::CREATE | BDB::EXCL,
- 0600)
+ old = BDB::Hash.open f, nil, "r+", 0600
+ new = BDB::CIBtree.open(newname, nil, BDB::CREATE | BDB::EXCL, 0600)
old.each {|k,v|
new[k] = v
}
}
# then scan for current DBTree files, and load them
- Dir["#{@bot.botclass}/keywords/*"].each {|f|
+ Dir[@bot.path 'keywords', '*'].each {|f|
next unless f =~ /\.kdb$/
hsh = DBTree.new @bot, f, true
key = File.basename(f).gsub(/\.kdb$/, "")
}
# then scan for non DB files, and convert/import them and delete
- Dir["#{@bot.botclass}/keywords/*"].each {|f|
+ Dir[@bot.path 'keywords', '*'].each {|f|
next if f =~ /\.kdb$/
next if f =~ /CVS$/
log "auto converting keywords from #{f}"
# upgrade data files found in old rbot formats to current
def upgrade_data
- if File.exist?("#{@bot.botclass}/keywords.db")
+ olds = @bot.path 'keywords.db'
+ if File.exist? olds
log "upgrading old keywords (rbot 0.9.5 or prior) database format"
- old = BDB::Hash.open "#{@bot.botclass}/keywords.db", nil,
- "r+", 0600
+ old = BDB::Hash.open olds, nil, "r+", 0600
old.each {|k,v|
@keywords[k] = v
}
old.close
@keywords.flush
- File.rename("#{@bot.botclass}/keywords.db", "#{@bot.botclass}/keywords.db.old")
+ File.rename(olds, olds + ".old")
end
- if File.exist?("#{@bot.botclass}/keyword.db")
+ olds.replace(@bot.path 'keyword.db')
+ if File.exist? olds
log "upgrading old keywords (rbot 0.9.9 or prior) database format"
- old = BDB::CIBtree.open "#{@bot.botclass}/keyword.db", nil,
- "r+", 0600
+ old = BDB::CIBtree.open olds, nil, "r+", 0600
old.each {|k,v|
@keywords[k] = v
}
old.close
@keywords.flush
- File.rename("#{@bot.botclass}/keyword.db", "#{@bot.botclass}/keyword.db.old")
+ File.rename(olds, olds + ".old")
end
end
end
def oldsave
- File.open("#{@bot.botclass}/keywords.rbot", "w") do |file|
+ File.open(@bot.path "keywords.rbot", "w") do |file|
@keywords.each do |key, value|
file.puts "#{key}<=#{value.type}=>#{value.dump}"
end
# TODO check factoids config
# also TODO: runtime export
- dir = File.join(@bot.botclass,"factoids")
+ dir = @bot.path 'factoids'
fname = File.join(dir,"keyword_factoids.rbot")
Dir.mkdir(dir) unless FileTest.directory?(dir)
# We may be on an old installation, so on the first run read non-language-specific larts
unless defined?(@oldlart)
- @oldlart = "#{@bot.botclass}/lart/larts"
- @oldpraise = "#{@bot.botclass}/lart/praise"
+ @oldlart = datafile 'larts'
+ @oldpraise = datafile 'praise'
end
- @lartfile.replace "#{@bot.botclass}/lart/larts-#{lang}"
- @praisefile.replace "#{@bot.botclass}/lart/praises-#{lang}"
+ @lartfile.replace(datafile "larts-#{lang}")
+ @praisefile.replace(datafile "praises-#{lang}")
@larts.clear
@praises.clear
if File.exists? @lartfile
def save
return unless @changed
- Dir.mkdir("#{@bot.botclass}/lart") if not FileTest.directory? "#{@bot.botclass}/lart"
- # TODO implement safe saving here too
+ Dir.mkdir(datafile) unless FileTest.directory? datafile
Utils.safe_save(@lartfile) { |file|
file.puts @larts
}
define_structure :Quote, :num, :date, :source, :quote
class QuotePlugin < Plugin
+ def dirname
+ 'quotes'
+ end
+
def initialize
super
@lists = Hash.new
@changed = Hash.new
- Dir["#{@bot.botclass}/quotes/*"].each {|f|
+ Dir[datafile '*'].each {|f|
next if File.directory?(f)
channel = File.basename(f)
@lists[channel] = Array.new if(!@lists.has_key?(channel))
end
def save
- Dir.mkdir("#{@bot.botclass}/quotes") if(!FileTest.directory?("#{@bot.botclass}/quotes"))
+ Dir.mkdir(datafile) unless FileTest.directory? datafile
@lists.each {|channel, quotes|
begin
if @changed[channel]
debug "Writing new quotefile for channel #{channel} ..."
- Utils.safe_save("#{@bot.botclass}/quotes/#{channel}") {|file|
+ Utils.safe_save(datafile channel) {|file|
quotes.compact.each {|q|
file.puts "#{q.num} | #{q.date} | #{q.source} | #{q.quote}"
}
@all_langs = @bot.config['salut.all_languages']
if @all_langs
# Get all available languages
- langs = Dir.new("#{@bot.botclass}/salut").collect {|f|
+ langs = Dir.new(datafile).collect {|f|
f =~ /salut-([^.]+)/ ? $1 : nil
}.compact
langs.each { |lang|
end
def load_lang(lang)
- dir = "#{@bot.botclass}/salut"
+ dir = datafile
if not File.exist?(dir)
Dir.mkdir(dir)
end
- file = "#{@bot.botclass}/salut/salut-#{lang}"
+ file = File.join dir, "salut-#{lang}"
if File.exist?(file)
begin
salutations = Hash.new
end
def save_lang(lang, val)
- fn = "#{@bot.botclass}/salut/salut-#{lang}"
+ fn = datafile "salut-#{lang}"
Utils.safe_save(fn) { |file|
file.puts val.to_yaml
}
return unless @bot
@changed = false
- if(File.exist?("#{@bot.botclass}/conf.yaml"))
+ conf = @bot.path 'conf.yaml'
+ if File.exist? conf
begin
- newconfig = YAML::load_file("#{@bot.botclass}/conf.yaml")
+ newconfig = YAML::load_file conf
newconfig.each { |key, val|
@config[key.to_sym] = val
}
return
end
begin
+ conf = @bot.path 'conf.yaml'
+ fnew = conf + '.new'
debug "Writing new conf.yaml ..."
- File.open("#{@bot.botclass}/conf.yaml.new", "w") do |file|
+ File.open(fnew, "w") do |file|
savehash = {}
@config.each { |key, val|
savehash[key.to_s] = val
file.puts savehash.to_yaml
end
debug "Officializing conf.yaml ..."
- File.rename("#{@bot.botclass}/conf.yaml.new",
- "#{@bot.botclass}/conf.yaml")
+ File.rename(fnew, conf)
@changed = false
rescue => e
error "failed to write configuration file conf.yaml! #{$!}"
def auth_export(m, params)
- exportfile = "#{@bot.botclass}/new-auth.users"
+ exportfile = @bot.path "new-auth.users"
what = params[:things]
has_to = what[-2] == "to"
if has_to
- exportfile = "#{@bot.botclass}/#{what[-1]}"
+ exportfile = @bot.path what[-1]
what.slice!(-2,2)
end
def auth_import(m, params)
- importfile = "#{@bot.botclass}/new-auth.users"
+ importfile = @bot.path "new-auth.users"
what = params[:things]
has_from = what[-2] == "from"
if has_from
- importfile = "#{@bot.botclass}/#{what[-1]}"
+ importfile = @bot.path what[-1]
what.slice!(-2,2)
end
@queue = Queue.new
@thread = Thread.new { loggers_thread }
@logs = Hash.new
- Dir.mkdir("#{@bot.botclass}/logs") unless File.exist?("#{@bot.botclass}/logs")
+ logdir = @bot.path 'logs'
+ Dir.mkdir(logdir) unless File.exist?(logdir)
+ # TODO what shall we do if the logdir couldn't be created? (e.g. it existed as a file)
event_irclog_list_changed(@bot.config['irclog.no_log'], @bot.config['irclog.do_log'])
@fn_format = @bot.config['irclog.filename_format']
end
end
def logfilepath(where_str, now)
- File.join(@bot.botclass, 'logs', now.strftime(@fn_format) % { :where => where_str })
+ @bot.path('logs', now.strftime(@fn_format) % { :where => where_str })
end
protected
def Utils.bot=(b)
debug "initializing utils"
@@bot = b
- @@safe_save_dir = "#{@@bot.botclass}/safe_save"
+ @@safe_save_dir = @@bot.path('safe_save')
end
class Bot
class Wordlist
def self.wordlist_base
- @@wordlist_base ||= File.join(Utils.bot.botclass, 'wordlists')
+ @@wordlist_base ||= Utils.bot.path 'wordlists'
end
def self.get(path, options={})
def initialize(bot, key, absfilename=false)
@bot = bot
@key = key
+ relfilename = @bot.path key
+ relfilename << '.db'
if absfilename && File.exist?(key)
# db already exists, use it
@db = DBHash.open_db(key)
- elsif File.exist?(@bot.botclass + "/#{key}.db")
- # db already exists, use it
- @db = DBHash.open_db(@bot.botclass + "/#{key}.db")
elsif absfilename
# create empty db
@db = DBHash.create_db(key)
+ elsif File.exist? relfilename
+ # db already exists, use it
+ @db = DBHash.open_db relfilename
else
# create empty db
- @db = DBHash.create_db(@bot.botclass + "/#{key}.db")
+ @db = DBHash.create_db relfilename
end
end
@key = key
if @@env.nil?
begin
- @@env = BDB::Env.open("#{@bot.botclass}", BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER, "set_lg_max" => @@lg_max)
+ @@env = BDB::Env.open(@bot.botclass, BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER, "set_lg_max" => @@lg_max)
debug "DBTree: environment opened with max log size #{@@env.conf['lg_max']}"
rescue => e
debug "DBTree: failed to open environment: #{e.pretty_inspect}. Retrying ..."
- @@env = BDB::Env.open("#{@bot.botclass}", BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER)
+ @@env = BDB::Env.open(@bot.botclass, BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER)
end
- #@@env = BDB::Env.open("#{@bot.botclass}", BDB::CREATE | BDB::INIT_MPOOL | BDB::RECOVER)
+ #@@env = BDB::Env.open(@bot.botclass, BDB::CREATE | BDB::INIT_MPOOL | BDB::RECOVER)
end
+ relfilename = @bot.path key
+ relfilename << '.db'
+
if absfilename && File.exist?(key)
# db already exists, use it
@db = DBTree.open_db(key)
elsif absfilename
# create empty db
@db = DBTree.create_db(key)
- elsif File.exist?(@bot.botclass + "/#{key}.db")
+ elsif File.exist? relfilename
# db already exists, use it
- @db = DBTree.open_db(@bot.botclass + "/#{key}.db")
+ @db = DBTree.open_db relfilename
else
# create empty db
- @db = DBTree.create_db(@bot.botclass + "/#{key}.db")
+ @db = DBTree.create_db relfilename
end
end
end
end
+ # Return a path under the current botclass by joining the mentioned
+ # components. The components are automatically converted to String
+ def path(*components)
+ File.join(@botclass, *(components.map {|c| c.to_s}))
+ end
+
def setup_plugins_path
plugdir_default = File.join(Config::datadir, 'plugins')
plugdir_local = File.join(@botclass, 'plugins')
@bot.plugins.mark_priorities_dirty
end
end
+
+ # Directory name to be joined to the botclass to access data files. By
+ # default this is the plugin name itself, but may be overridden, for
+ # example by plugins that share their datafiles or for backwards
+ # compatibilty
+ def dirname
+ name
+ end
+
+ # Filename for a datafile built joining the botclass, plugin dirname and
+ # actual file name
+ def datafile(*fname)
+ @bot.path dirname, *fname
+ end
end
# A CoreBotModule is a BotModule that provides core functionality.
# NB this function is called _early_ in init(), pretty much all you have to
# work with is @bot.botclass.
def upgrade_data
- if File.exist?("#{@bot.botclass}/registry.db")
+ oldreg = @bot.path 'registry.db'
+ newreg = @bot.path 'plugin_registry.db'
+ if File.exist?(oldreg)
log _("upgrading old-style (rbot 0.9.5 or earlier) plugin registry to new format")
- old = BDB::Hash.open("#{@bot.botclass}/registry.db", nil,
- "r+", 0600)
- new = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil,
- BDB::CREATE | BDB::EXCL,
- 0600)
+ old = BDB::Hash.open(oldreg, nil, "r+", 0600)
+ new = BDB::CIBtree.open(newreg, nil, BDB::CREATE | BDB::EXCL, 0600)
old.each {|k,v|
new[k] = v
}
old.close
new.close
- File.rename("#{@bot.botclass}/registry.db", "#{@bot.botclass}/registry.db.old")
+ File.rename(oldreg, oldreg + ".old")
end
end
def upgrade_data2
- if File.exist?("#{@bot.botclass}/plugin_registry.db")
- Dir.mkdir("#{@bot.botclass}/registry") unless File.exist?("#{@bot.botclass}/registry")
- env = BDB::Env.open("#{@bot.botclass}", BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER)# | BDB::TXN_NOSYNC)
+ oldreg = @bot.path 'plugin_registry.db'
+ newdir = @bot.path 'registry'
+ if File.exist?(oldreg)
+ Dir.mkdir(newdir) unless File.exist?(newdir)
+ env = BDB::Env.open(@bot.botclass, BDB::INIT_TRANSACTION | BDB::CREATE | BDB::RECOVER)# | BDB::TXN_NOSYNC)
dbs = Hash.new
log _("upgrading previous (rbot 0.9.9 or earlier) plugin registry to new split format")
- old = BDB::CIBtree.open("#{@bot.botclass}/plugin_registry.db", nil,
- "r+", 0600, "env" => env)
+ old = BDB::CIBtree.open(oldreg, nil, "r+", 0600, "env" => env)
old.each {|k,v|
prefix,key = k.split("/", 2)
prefix.downcase!
dbs[prefix][key] = v
}
old.close
- File.rename("#{@bot.botclass}/plugin_registry.db", "#{@bot.botclass}/plugin_registry.db.old")
+ File.rename(oldreg, oldreg + ".old")
dbs.each {|k,v|
log _("closing db #{k}")
v.close
def initialize(bot, name)
@bot = bot
@name = name.downcase
- @filename = "#{@bot.botclass}/registry/#{@name}"
+ @filename = @bot.path 'registry', @name
dirs = File.dirname(@filename).split("/")
dirs.length.times { |i|
dir = dirs[0,i+1].join("/")+"/"