From 96733ef02eace65d3d58bc53426e400abbc72f3e Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Sun, 4 Nov 2007 01:23:21 +0000 Subject: factoids plugin: Factoid and FactoidList classes --- data/rbot/plugins/factoids.rb | 100 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 10 deletions(-) (limited to 'data/rbot/plugins/factoids.rb') diff --git a/data/rbot/plugins/factoids.rb b/data/rbot/plugins/factoids.rb index 3110bd11..eee1dfaa 100644 --- a/data/rbot/plugins/factoids.rb +++ b/data/rbot/plugins/factoids.rb @@ -10,26 +10,99 @@ # Store (and retrieve) unstructured one-sentence factoids class FactoidsPlugin < Plugin + + class Factoid + def initialize(hash) + @hash = hash.reject { |k, val| val.nil? or val.empty? rescue false } + raise ArgumentError, "no fact!" unless @hash[:fact] + if String === @hash[:when] + @hash[:when] = Time.parse @hash[:when] + end + end + + def to_s + @hash[:fact] + end + + def [](*args) + @hash[*args] + end + + def to_hsh + return @hash + end + end + + class FactoidList < ArrayOf + def initialize(ar=[]) + super(Factoid, ar) + end + + def index(f) + fact = f.to_s + return if fact.empty? + self.map { |f| f[:fact] }.index(fact) + end + + def delete(f) + idx = index(f) + return unless idx + self.delete_at(idx) + end + + def grep(x) + self.find_all { |f| + x === f[:fact] + } + end + end + def initialize super # TODO config @dir = File.join(@bot.botclass,"factoids") - @fname = File.join(@dir,"factoids.rbot") - if File.exist?(@fname) - @factoids = File.readlines(@fname) - @factoids.each { |l| l.chomp! } - else - # A Set, maybe? - @factoids = Array.new + @filename = "factoids.rbot" + @factoids = FactoidList.new + read_factfile + @changed = false + end + + def read_factfile(name=@filename,dir=@dir) + fname = File.join(dir,name) + if File.exist?(fname) + factoids = File.readlines(fname) + return if factoids.empty? + firstline = factoids.shift + pattern = firstline.chomp.split(" | ") + if pattern.length == 1 and pattern.first != "fact" + factoids.unshift(firstline) + factoids.each { |f| + @factoids << Factoid.new( :fact => f.chomp ) + } + else + pattern.map! { |p| p.intern } + raise ArgumentError, "fact must be the last field" unless pattern.last == :fact + factoids.each { |f| + ar = f.chomp.split(" | ", pattern.length) + @factoids << Factoid.new(Hash[*([pattern, ar].transpose.flatten)]) + } + end end end def save + return unless @changed Dir.mkdir(@dir) unless FileTest.directory?(@dir) - Utils.safe_save(@fname) do |file| - file.puts @factoids + fname = File.join(@dir,@filename) + ar = ["when | who | where | fact"] + @factoids.each { |f| + ar << "%s | %s | %s | %s" % [ f[:when], f[:who], f[:where], f[:fact]] + } + Utils.safe_save(fname) do |file| + file.puts ar end + @changed = false end def help(plugin, topic="") @@ -37,11 +110,17 @@ class FactoidsPlugin < Plugin end def learn(m, params) - factoid = params[:stuff].to_s + factoid = Factoid.new( + :fact => params[:stuff].to_s, + :when => Time.now, + :who => m.source.fullform, + :where => m.channel.to_s + ) if @factoids.index(factoid) m.reply _("I already know that %{factoid}" % { :factoid => factoid }) else @factoids << factoid + @changed = true m.okay end end @@ -49,6 +128,7 @@ class FactoidsPlugin < Plugin def forget(m, params) factoid = params[:stuff].to_s if @factoids.delete(factoid) + @changed = true m.okay else m.reply _("I didn't know that %{factoid}" % { :factoid => factoid }) -- cgit v1.2.3