Initial commit. Uploading Velasco v1.1

This commit is contained in:
vylion 2017-09-19 13:00:56 +02:00
commit cb33edc3cd
6 changed files with 293 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
chatlogs/*

Binary file not shown.

Binary file not shown.

58
chatlog.py Normal file
View file

@ -0,0 +1,58 @@
#!/usr/bin/env python3
from markov import *
class Chatlog(object):
def __init__(self, ident, chattype, title, msgs=None, freq=None):
if msgs is not None:
self.msgs = msgs
else:
self.msgs = []
self.id = str(ident)
self.type = chattype
self.title = title
if freq is None:
if "group" in chattype:
freq = 20
#elif chattype is "private":
else:
freq = 5
self.freq = freq
def add_msg(self, message):
msg = message.split()
msg.append("!kvl")
self.msgs.append(msg)
def get_markov_gen(self):
msgs = []
for m in self.msgs:
msgs.append(' '.join(m))
text = ' '.join(msgs)
self.gen = Markov(text)
def speak(self):
self.get_markov_gen()
return self.gen.generate_markov_text()
def get_count(self):
return len(self.msgs)
def set_freq(self, freq):
self.freq = freq
def to_txt(self):
lines = [self.id]
lines.append(self.type)
lines.append(self.title)
lines.append(str(self.freq))
for m in self.msgs:
lines.append(' '.join(m))
return '\n'.join(lines)
def from_txt(text):
lines = text.splitlines()
msgs = []
for m in lines[4:]:
msgs.append(m.split())
return Chatlog(lines[0], lines[1], lines[2], msgs, int(lines[3]))

50
markov.py Normal file
View file

@ -0,0 +1,50 @@
#!/usr/bin/env python3
import random
class Markov(object):
def __init__(self, text=None):
self.cache = {}
self.words = []
if text is None:
text = ""
self.words = text.split()
self.word_size = len(self.words)
self.database()
def triples(self):
""" Generates triples from the given data string. So if our string were
"What a lovely day", we'd generate (What, a, lovely) and then
(a, lovely, day).
"""
if len(self.words) < 3:
return
for i in range(len(self.words) - 2):
yield (self.words[i], self.words[i+1], self.words[i+2])
def database(self):
for w1, w2, w3 in self.triples():
key = (w1, w2)
if key in self.cache:
self.cache[key].append(w3)
else:
self.cache[key] = [w3]
def generate_markov_text(self, size=50):
seed = random.randint(0, self.word_size-3)
seed_word, next_word = self.words[seed], self.words[seed+1]
while "!kvl" in seed_word:
seed = random.randint(0, self.word_size-3)
seed_word, next_word = self.words[seed], self.words[seed+1]
w1, w2 = seed_word, next_word
gen_words = []
for i in range(size):
gen_words.append(w1)
if "!kvl" in w2 or not (w1, w2) in self.cache:
print("Generated text")
break
else:
w1, w2 = w2, random.choice(self.cache[(w1, w2)])
return ' '.join(gen_words)

184
velasco.py Executable file
View file

@ -0,0 +1,184 @@
#!/usr/bin/env python3
import sys, os
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
from chatlog import *
import logging
import argparse
# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
chatlogs = {}
disabled = {}
GUILLERMO_ID = 8379173
def wake(bot):
directory = os.fsencode("chatlogs/")
for file in os.listdir(directory):
filename = os.fsdecode(file)
if filename.endswith(".txt"):
chat = loadchat("chatlogs/" + filename)
chatlogs[chat.id] = chat
print("loaded chat " + chat.id)
continue
else:
continue
"""
for c in chatlogs:
try:
bot.sendMessage(chatlogs[c].id, "Good morning. I just woke up")
except:
pass
#del chatlogs[c]
"""
def start(bot, update):
update.message.reply_text('cowabunga')
def savechat(chatlog):
open_file = open('chatlogs/' + chatlog.id + '.txt', 'w')
open_file.write(chatlog.to_txt())
open_file.close()
def loadchat(path):
open_file = open(path, 'r')
chat = Chatlog.from_txt(open_file.read())
open_file.close()
return chat
def help(bot, update):
update.message.reply_text("""I answer to the following commands:
/start - I say hi.
/about - What I'm about.
/help - I send this message.
/count - I tell you how many messages from this chat I remember.
/freq - Change the frequency of both my messages and the times I save my learned vocabulary.
""")
def about(bot, update):
update.message.reply_text('I am yet another Markov Bot experiment. I read everything you type to me and then spit back nonsensical messages that look like yours')
def echo(bot, update):
update.message.reply_text(update.message.text)
def error(bot, update, error):
logger.warn('Update "%s" caused error "%s"' % (update, error))
def get_chatname(chat):
if chat.title is not None:
return chat.title
elif chat.first_name is not None:
if chat.last_name is not None:
return chat.first_name + " " + chat.last_name
else:
return chat.first_name
else:
return ""
def read(bot, update):
global chatlogs
ident = str(update.message.chat.id)
if not ident in chatlogs:
chat = update.message.chat
title = get_chatname(chat)
chatlog = Chatlog(chat.id, chat.type, title)
else:
chatlog = chatlogs[ident]
chatlog.add_msg(update.message.text)
if chatlog.get_count()%chatlog.freq == 0:
msg = chatlog.speak()
bot.sendMessage(chatlog.id, msg)
savechat(chatlog)
chatlogs[chatlog.id] = chatlog
def get_chatlogs(bot, update):
global GUILLERMO_ID
if update.message.chat.id is GUILLERMO_ID:
m = "I have these chatlogs:"
for c in chatlogs:
m += "\n" + chatlogs[c].id + " " + chatlogs[c].title
bot.sendMessage(GUILLERMO_ID, m)
def get_count(bot, update):
ident = str(update.message.chat.id)
reply = "I remember "
if ident in chatlogs:
reply += str(chatlogs[ident].get_count())
else:
reply += "no"
reply += " messages."
update.message.reply_text(reply)
def set_freq(bot, update):
ident = str(update.message.chat.id)
if not ident in chatlogs:
chat = update.message.chat
title = get_chatname(chat)
chatlog = Chatlog(chat.id, chat.type, title)
chatlogs[chatlog.id] = chatlog
if not len(update.message.text.split()) > 1:
reply = "Current frequency is " + str(chatlogs[ident].freq)
else:
try:
value = update.message.text.split()[1]
value = int(value)
chatlogs[ident].set_freq(value)
reply = "Frequency of speaking set to " + str(value)
except:
reply = "Format was confusing; requency not changed from " + str(chatlogs[ident].freq)
update.message.reply_text(reply)
def stop(bot, update):
chatlog = chatlogs[update.message.chat.id]
del chatlogs[chatlog.id]
os.remove("chatlogs/" + chatlog.id + ".txt")
print("I got blocked. Removed user " + chatlog.id)
def main():
parser = argparse.ArgumentParser(description='A Telegram markovbot.')
parser.add_argument('token', metavar='TOKEN', help='The Bot Token to work with the Telegram Bot API')
args = parser.parse_args()
# Create the EventHandler and pass it your bot's token.
updater = Updater(args.token)
# Get the dispatcher to register handlers
dp = updater.dispatcher
# on different commands - answer in Telegram
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("about", about))
dp.add_handler(CommandHandler("help", help))
dp.add_handler(CommandHandler("count", get_count))
dp.add_handler(CommandHandler("freq", set_freq))
dp.add_handler(CommandHandler("list", get_chatlogs))
dp.add_handler(CommandHandler("stop", stop))
# on noncommand i.e message - echo the message on Telegram
# dp.add_handler(MessageHandler(Filters.text, echo))
dp.add_handler(MessageHandler(Filters.text, read))
# chatlog all errors
dp.add_error_handler(error)
wake(updater.bot)
# Start the Bot
updater.start_polling()
# Run the bot until you press Ctrl-C or the process receives SIGINT,
# SIGTERM or SIGABRT. This should be used most of the time, since
# start_polling() is non-blocking and will stop the bot gracefully.
updater.idle()
if __name__ == '__main__':
main()