mirror of
https://gitlab.com/vylion/velascobot.git
synced 2025-04-19 21:46:35 +02:00
Initial commit. Uploading Velasco v1.1
This commit is contained in:
commit
cb33edc3cd
6 changed files with 293 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
chatlogs/*
|
BIN
__pycache__/chatlog.cpython-36.pyc
Normal file
BIN
__pycache__/chatlog.cpython-36.pyc
Normal file
Binary file not shown.
BIN
__pycache__/markov.cpython-36.pyc
Normal file
BIN
__pycache__/markov.cpython-36.pyc
Normal file
Binary file not shown.
58
chatlog.py
Normal file
58
chatlog.py
Normal 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
50
markov.py
Normal 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
184
velasco.py
Executable 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()
|
Loading…
Reference in a new issue