-
Notifications
You must be signed in to change notification settings - Fork 4
/
boop.rb
127 lines (89 loc) · 3.29 KB
/
boop.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# TODO
#
# - convert/filter out HTML entities like "
# - add a callback to prime the chains when the bot is ready, and do this in a thread.
class Boop < CampfireBot::Plugin
# Markov chain implementation courtesy of http://blog.segment7.net/articles/2006/02/25/markov-chain
on_message /.*/, :listen
on_command 'speak', :random_chatter
on_command 'prime_chains', :load_transcripts
def initialize
@phrases = Hash.new { |hash, key| hash[key] = [] } # phrase => next-word possibilities
@word_count = 0
end
def listen(msg)
add_line(msg[:message])
end
def random_chatter(msg)
puts "random_chatter"
msg.speak(generate_line)
end
def focused_chatter(msg)
end
def load_transcripts(msg)
msg.speak("Filling my brain with transcripts...")
puts "available transcripts - #{bot.room.available_transcripts.to_yaml}"
bot.room.available_transcripts.to_a.each do |date|
puts "loading transcript #{date}"
transcript = bot.room.transcript(date)
transcript.each do |message|
puts "message: #{message[:message]}"
filtered_text = strip_message(message)
filtered_text.split("\n").each { |line| add_line(line) unless line.blank? }
filtered_text.split("\n").each { |line| puts "ACCEPTED: " + line unless line.blank? }
end
end
msg.speak("Primed!")
end
private
def add_line(line)
words = line.scan(/\S+/)
@word_count += words.length
words.each_with_index do |word, index|
phrase = words[index, phrase_length] # current phrase
@phrases[phrase] << words[index + phrase_length] # next possibility
end
end
def generate_line
# our seed phrase
# phrase = words[0, phrase_length]
phrase = [random_word]
output = []
@word_count.times do
# grab all possibilities for our state
options = @phrases[phrase]
# add the first word to our output and discard
output << phrase.shift
# select at random and add it to our phrase
phrase.push(options.rand)
# the last phrase of the input text will map to an empty array of
# possibilities so exit cleanly.
break if phrase.compact.empty? # all out of words
end
# return our output
output.join(' ')
end
def random_word
@phrases.keys.rand.first
end
# amount of state (order-k)
def phrase_length
1
end
def strip_message(msg)
str = msg[:message].to_s
return '' if str.blank?
# return nothing if the line is a bot command
return '' if str[0..0] == '!' || str =~ Regexp.new("^#{bot.config['nickname']},", Regexp::IGNORECASE)
# and get rid of the messages that are generated by the campfire system itself
return '' if str =~ /has (entered|left) the room/
# keep the contents of the pastes, but strip out the 'view paste' link.
str.gsub!(/<a href=.*?>View paste<\/a>/, '')
# also get rid of the stuff spoken by the bot
return '' if msg[:person] == bot.config['nickname']
# now strip out all image tags completely
str.gsub!(/<img\s.*?\/>/, '')
# and now strip out all other html tags, leaving their contents intact
str.gsub(/<\/?[^>]*>/, "")
end
end