Created
July 1, 2014 23:05
-
-
Save FestivalBobcats/35587c736ded6d9c7a28 to your computer and use it in GitHub Desktop.
Quinky (GroupMe haiku bot)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'json' | |
require 'typhoeus' | |
require 'ansi' | |
ACCESS_TOKEN = # | |
GROUP_ID = # | |
def register_bot(name, avatar_url=nil) | |
url = "https://api.groupme.com/v3/bots?token=#{ACCESS_TOKEN}" | |
body = { | |
bot: { | |
name: name, | |
group_id: GROUP_ID, | |
avatar_url: avatar_url | |
} | |
}.to_json | |
resp = Typhoeus.post(url, body: body) | |
JSON.parse(resp.body)['response']['bot']['bot_id'] | |
end | |
def post_as_bot(bot_id, opts) | |
url = "https://api.groupme.com/v3/bots/post?token=#{ACCESS_TOKEN}" | |
body = { | |
bot_id: bot_id | |
}.merge(opts).to_json | |
Typhoeus.post(url, body: body) | |
end | |
def get_messages(size) | |
messages = [] | |
last_msg_id = nil | |
while messages.size < size | |
print '.'.ansi(:magenta) | |
url = "https://api.groupme.com/v3/groups/#{GROUP_ID}/messages?token=#{ACCESS_TOKEN}" | |
args = [url] | |
args << {body: {before_id: last_msg_id}} if last_msg_id | |
resp = Typhoeus.get(*args) | |
msgs = JSON.parse(resp.body)['response']['messages'] | |
last_msg_id = msgs[-1]['id'] | |
messages += msgs.map {|m| m['text'] } | |
end | |
messages | |
end | |
def count_syllables(word) | |
word.downcase! | |
return 1 if word.length <= 3 | |
word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '') | |
word.sub!(/^y/, '') | |
word.scan(/[aeiouy]{1,2}/).size | |
end | |
def get_most_recent_words | |
recent_msgs = get_messages(1_500) | |
recent_msgs.join(' ').split(/[\.\/ \n]+/i).select {|w| w[/[a-z]{2,}/i] }.reject {|w| w[/[^[a-zA-Z]]{3,}/] }.map do |word| | |
word.gsub(/(\W{2,}|[^a-zA-Z0-9]\z|\A[^a-zA-Z0-9])/, '').downcase | |
end | |
end | |
def make_gibberish_haiku | |
all_words = get_most_recent_words | |
word_syllable_count = all_words.reduce({}) do |hash, word| | |
hash[word] ||= count_syllables(word.dup) | |
hash | |
end | |
all_syl_counts = word_syllable_count.values | |
max_syl_per_word = all_syl_counts.select {|v| all_syl_counts.select {|vv| vv == v }.size > 3 }.max | |
words_used = [] | |
lines = [5, 7, 5].map do |s| | |
word_syllables_this_line = [] | |
loop do | |
print '.'.ansi(:green) | |
sum = word_syllables_this_line.inject(:+) || 0 | |
ws = [(1..s).to_a.shuffle.first, max_syl_per_word].min | |
if sum + ws > s | |
next | |
# elsif sum + ws == s && word_syllables_this_line[-1] == 1 && ws == 1 | |
# word_syllables_this_line << 2 | |
# break | |
# elsif (s - (sum + ws)) == 1 # don't end with 1 syllable | |
# | |
# if ws == 1 | |
# word_syllables_this_line.pop | |
# word_syllables_this_line << 2 | |
# | |
# break | |
# else # just make the one syllable come first | |
# word_syllables_this_line << 1 | |
# word_syllables_this_line << ws | |
# break | |
# end | |
# | |
# next | |
elsif sum + ws == s | |
word_syllables_this_line << ws | |
break | |
else # < s | |
word_syllables_this_line << ws | |
end | |
end | |
words = word_syllables_this_line.map do |ws| | |
begin | |
print '.'.ansi(:red) | |
word = word_syllable_count.to_a.shuffle.find {|k, v| v == ws }[0] | |
if words_used.select {|w| w == word }.size >= 1 \ | |
|| words_used.last == word \ | |
|| word.size == 1 | |
raise "Retry" | |
end | |
words_used << word | |
word | |
rescue | |
retry | |
end | |
end | |
words.join(' ') | |
end | |
lines.join("\n") | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment