2016-03-23 02:30:28 +00:00
|
|
|
require 'cinch'
|
|
|
|
require 'open-uri'
|
|
|
|
require_relative '../classes/Util.rb'
|
|
|
|
require_relative '../classes/Markov.rb'
|
|
|
|
class Markovian
|
|
|
|
include Cinch::Plugin
|
|
|
|
include Hooks::ACLHook
|
|
|
|
include Util::PluginHelper
|
|
|
|
set :prefix, /^:/
|
|
|
|
@clist = %w{markov}
|
2016-07-27 20:52:33 +00:00
|
|
|
@@commands["markov"] = ":markov <length> <seed>- generates a markov chain of <length> words, starting with optional word <seed>"
|
2016-03-24 21:08:58 +00:00
|
|
|
match /markov (\d+)( \w+)?/, method: :markov
|
2016-03-24 06:59:38 +00:00
|
|
|
match /markov$/, method: :markov
|
2016-03-23 02:30:28 +00:00
|
|
|
listen_to :channel
|
|
|
|
|
|
|
|
def listen(m)
|
|
|
|
text = m.message
|
|
|
|
return if m.message.match /^:/
|
|
|
|
user = m.user.nick
|
|
|
|
#puts "Markovian\n\t#{user}: #{text}"
|
|
|
|
mkv = Markovin8or.new(2)
|
2016-07-27 20:52:33 +00:00
|
|
|
db = Util::Util.instance.getCollection("markov","ngrams")
|
|
|
|
re = /[^a-z0-9' ]/i
|
|
|
|
text = text.gsub(re, " ").gsub(/ {2,}/, " ")
|
|
|
|
puts "text: #{text}"
|
|
|
|
chains = mkv.chain(text)
|
|
|
|
mkvs = mkv.mongoize
|
|
|
|
mkvs.each { |hash|
|
|
|
|
#next if hash["head"] == nil
|
|
|
|
#hash["user"] = user
|
|
|
|
#hash["server"] = Util::Util.instance.hton(m.bot.config.server)
|
2016-03-23 02:30:28 +00:00
|
|
|
#p hash
|
2016-07-27 20:52:33 +00:00
|
|
|
if(db.find({head: hash[:head]}).count > 0)
|
|
|
|
#puts "#{hash[:head]} found"
|
|
|
|
hash[:tails].each { |tail|
|
|
|
|
if(tail != nil)
|
|
|
|
db.update_one(
|
|
|
|
{head: hash[:head]},
|
|
|
|
{'$push' =>
|
|
|
|
{ tails: tail
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#puts "#{hash[:head]} not found (#{hash[:tails].inspect})"
|
|
|
|
val = db.insert_one(hash)
|
|
|
|
end
|
2016-03-23 02:30:28 +00:00
|
|
|
#p val
|
|
|
|
if(val)
|
|
|
|
#puts "success :: #{hash}"
|
|
|
|
else
|
|
|
|
#puts "failure :: #{hash}"
|
|
|
|
end
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-03-24 21:08:58 +00:00
|
|
|
def markov(m,length=nil, seed=nil)
|
|
|
|
out = start(m,length == nil ? length : length.to_i, seed)
|
2016-03-24 06:59:38 +00:00
|
|
|
puts "markov out:\n\t#{out}"
|
2016-03-23 02:30:28 +00:00
|
|
|
m.reply(out)
|
|
|
|
|
|
|
|
end
|
|
|
|
def getRandomRow(seed = nil)
|
|
|
|
db = Util::Util.instance.getCollection("markov","ngrams")
|
|
|
|
ret = []
|
|
|
|
if(seed == nil)
|
2016-07-27 20:52:33 +00:00
|
|
|
cnt = db.find().count()
|
|
|
|
ret = db.find().limit(-1).skip(rand(cnt)).to_a.shift
|
2016-03-23 02:30:28 +00:00
|
|
|
else
|
|
|
|
ret = getRow(seed)
|
|
|
|
end
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
2016-03-24 21:08:58 +00:00
|
|
|
def start(m,words=nil, seed=nil)
|
2016-03-23 02:30:28 +00:00
|
|
|
db = Util::Util.instance.getCollection("markov","ngrams")
|
|
|
|
res = ""
|
2016-03-24 06:59:38 +00:00
|
|
|
if(words == nil)
|
|
|
|
words = (4+rand(24).to_i)
|
|
|
|
end
|
2016-07-27 20:52:33 +00:00
|
|
|
words = words > 32 ? 32 : words
|
|
|
|
#puts "begin markov chainsaw"
|
|
|
|
#puts "start.count: #{words}, start.seed: #{seed}"
|
2016-03-24 21:08:58 +00:00
|
|
|
seed.strip! if seed != nil
|
2016-03-23 02:30:28 +00:00
|
|
|
out = ""
|
2016-07-27 20:52:33 +00:00
|
|
|
if(seed.match(/ /))
|
|
|
|
a = seed.split(/ /)
|
|
|
|
seed = a.pop
|
|
|
|
out = a.join(" ") << " "
|
|
|
|
end
|
|
|
|
|
2016-03-23 02:30:28 +00:00
|
|
|
i = 0
|
2016-03-24 21:08:58 +00:00
|
|
|
head = ""
|
2016-07-27 20:52:33 +00:00
|
|
|
tails = []
|
2016-03-23 02:30:28 +00:00
|
|
|
while i < words
|
|
|
|
#puts i
|
2016-07-27 20:52:33 +00:00
|
|
|
|
|
|
|
loop do
|
|
|
|
row = getRandomRow(seed)
|
|
|
|
#puts "new row #{row.inspect}"
|
2016-03-24 21:08:58 +00:00
|
|
|
head = row[:head]
|
2016-07-27 20:52:33 +00:00
|
|
|
tails = row[:tails]
|
|
|
|
test = row == nil or !row.key?(:head) or row[:head] == nil or row[:head] == "" or tails == nil
|
|
|
|
# puts "new row: #{row.inspect}"
|
|
|
|
break if !test
|
|
|
|
# puts "heaheahea"
|
2016-03-24 21:08:58 +00:00
|
|
|
end
|
2016-07-27 20:52:33 +00:00
|
|
|
tail = tails[rand(tails.count())]
|
2016-03-23 02:30:28 +00:00
|
|
|
#next if n == nil
|
|
|
|
#puts "\t#{head} -> #{n}"
|
|
|
|
out += "#{head} "
|
2016-07-27 20:52:33 +00:00
|
|
|
seed = tail
|
2016-03-23 02:30:28 +00:00
|
|
|
#puts "\trow: "
|
2016-03-24 06:59:38 +00:00
|
|
|
#p row
|
2016-03-23 02:30:28 +00:00
|
|
|
#puts "out: #{out}"
|
|
|
|
i+=1
|
|
|
|
end
|
|
|
|
#puts "end markov chainsaw"
|
|
|
|
out.gsub! /\r?\n/, ""
|
|
|
|
return out
|
|
|
|
end
|
|
|
|
def getRow(head)
|
|
|
|
db = Util::Util.instance.getCollection("markov","ngrams")
|
2016-03-24 21:08:58 +00:00
|
|
|
res = db.find({'head' => head}).to_a
|
2016-07-27 20:52:33 +00:00
|
|
|
return res[0]
|
2016-03-23 02:30:28 +00:00
|
|
|
end
|
|
|
|
end
|