summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2007-11-04 01:23:21 +0000
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2007-11-04 01:23:21 +0000
commit96733ef02eace65d3d58bc53426e400abbc72f3e (patch)
tree8321567cc6fb3e293dce58aaea13b450b074934b
parent3082ad5836b0babea7db5cde2eac1f59c3fdd667 (diff)
factoids plugin: Factoid and FactoidList classes
-rw-r--r--data/rbot/plugins/factoids.rb100
1 files changed, 90 insertions, 10 deletions
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 })