mirror of
https://gitlab.com/vylion/velascobot.git
synced 2025-04-19 13:36:36 +02:00
Velasco 1.6
- Added ability to change Velasco's probability to answer replies to his messages, per chat - Rewritten save-to-file functions for slightly more readability, and rewritten load-from-file functions accordingly
This commit is contained in:
parent
14a92ef0f3
commit
7de67c0238
3 changed files with 81 additions and 18 deletions
49
chatlog.py
49
chatlog.py
|
@ -3,7 +3,7 @@
|
|||
from markov import *
|
||||
|
||||
class Chatlog(object):
|
||||
def __init__(self, ident, chattype, title, text=None, freq=None):
|
||||
def __init__(self, ident, chattype, title, text=None, freq=None, answer=0.5):
|
||||
self.id = str(ident)
|
||||
self.type = chattype
|
||||
self.title = title
|
||||
|
@ -18,6 +18,7 @@ class Chatlog(object):
|
|||
self.count = len(text)
|
||||
else:
|
||||
self.count = 0
|
||||
self.answer = answer
|
||||
self.gen = Markov(text)
|
||||
|
||||
def set_title(self, title):
|
||||
|
@ -31,6 +32,15 @@ class Chatlog(object):
|
|||
self.freq = freq
|
||||
return self.freq
|
||||
|
||||
def set_answer_freq(self, freq):
|
||||
if freq > 1:
|
||||
self.answer = 1
|
||||
elif freq < 0:
|
||||
self.answer = 0
|
||||
else:
|
||||
self.answer = freq
|
||||
return self.answer
|
||||
|
||||
def add_msg(self, message):
|
||||
self.gen.add_text(message + " !kvl")
|
||||
self.count += 1
|
||||
|
@ -41,19 +51,36 @@ class Chatlog(object):
|
|||
def get_count(self):
|
||||
return self.count
|
||||
|
||||
def answering(self, rand):
|
||||
if self.answer == 1:
|
||||
return True
|
||||
elif self.answer == 0:
|
||||
return False
|
||||
return rand <= self.answer
|
||||
|
||||
def to_txt(self):
|
||||
lines = [self.id]
|
||||
lines.append(self.type)
|
||||
lines.append(self.title)
|
||||
lines.append(str(self.freq))
|
||||
lines.append("dict:")
|
||||
lines.append(str(self.count))
|
||||
lines = ["DICT=v2"]
|
||||
lines.append("CHAT_ID=" + self.id)
|
||||
lines.append("CHAT_TYPE=" + self.type)
|
||||
lines.append("CHAT_NAME=" + self.title)
|
||||
lines.append("MESSAGE_FREQ=" + str(self.freq))
|
||||
lines.append("ANSWER_FREQ=" + str(self.answer))
|
||||
lines.append("WORD_COUNT=" + str(self.count))
|
||||
lines.append("WORD_DICT=")
|
||||
txt = '\n'.join(lines)
|
||||
return txt + '\n' + self.gen.to_json()
|
||||
|
||||
def from_txt(text):
|
||||
lines = text.splitlines()
|
||||
if(lines[4] == "dict:"):
|
||||
if(parse_line(lines[0]) == "v2"):
|
||||
new_log = Chatlog(parse_line(lines[1]), parse_line(lines[2]), parse_line(lines[3]), None, int(parse_line(lines[4])), float(parse_line(lines[5])))
|
||||
new_log.count = int(parse_line(lines[6]))
|
||||
cache = '\n'.join(lines[8:])
|
||||
new_log.gen = Markov.from_json(cache)
|
||||
if new_log.count < 0:
|
||||
new_log.count = new_log.gen.new_count()
|
||||
return new_log
|
||||
elif(lines[4] == "dict:"):
|
||||
new_log = Chatlog(lines[0], lines[1], lines[2], None, int(lines[3]))
|
||||
new_log.count = int(lines[5])
|
||||
cache = '\n'.join(lines[6:])
|
||||
|
@ -64,6 +91,12 @@ class Chatlog(object):
|
|||
else:
|
||||
return Chatlog(lines[0], lines[1], lines[2], lines[4:], int(lines[3]))
|
||||
|
||||
def parse_line(line):
|
||||
s = line.split('=')
|
||||
if len(s) < 2:
|
||||
return ""
|
||||
return s[1]
|
||||
|
||||
def fuse_with(chatlog):
|
||||
self.count += chatlog.count
|
||||
self.gen.fuse_with(chatlog.gen)
|
||||
|
|
|
@ -58,7 +58,8 @@ class Markov(object):
|
|||
return Markov(string, True)
|
||||
|
||||
def add_text(self, text):
|
||||
words = trim_and_split(HEAD + " " + text)
|
||||
words = [HEAD]
|
||||
words.extend(trim_and_split(text))
|
||||
self.database(words)
|
||||
|
||||
def database(self, wordlist):
|
||||
|
@ -81,7 +82,7 @@ class Markov(object):
|
|||
for i in range(size):
|
||||
gen_words.append(w1)
|
||||
if w2 == TAIL or not getkey(w1, w2) in self.cache:
|
||||
print("Generated text")
|
||||
# print("Generated text")
|
||||
break
|
||||
else:
|
||||
w1, w2 = w2, random.choice(self.cache[getkey(w1, w2)])
|
||||
|
|
45
velasco.py
45
velasco.py
|
@ -9,7 +9,7 @@ import argparse
|
|||
import random
|
||||
|
||||
# Enable logging
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s - velascobot',
|
||||
level=logging.INFO)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -55,7 +55,10 @@ def savechat(chatlog):
|
|||
|
||||
def loadchat(path):
|
||||
open_file = open(path, 'r')
|
||||
chat = Chatlog.from_txt(open_file.read())
|
||||
try:
|
||||
chat = Chatlog.from_txt(open_file.read())
|
||||
except:
|
||||
pass
|
||||
open_file.close()
|
||||
return chat
|
||||
|
||||
|
@ -67,8 +70,9 @@ def help(bot, update):
|
|||
/explain - I explain how I work.
|
||||
/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. (Maximum of 100000)
|
||||
/freq - Change the frequency of my messages. (Maximum of 100000)
|
||||
/speak - Forces me to speak.
|
||||
/answer - Change the probability to answer to a reply. (Decimal between 0 and 1)
|
||||
""")
|
||||
|
||||
def about(bot, update):
|
||||
|
@ -78,7 +82,7 @@ def explain(bot, update):
|
|||
update.message.reply_text('I decompose every message I read in groups of 3 consecutive words, so for each consecutive pair I save the word that can follow them. I then use this to make my own messages. At first I will only repeat your messages because for each 2 words I will have very few possible following words.\n\nI also separate my vocabulary by chats, so anything I learn in one chat I will only say in that chat. For privacy, you know. Also, I save my vocabulary in the form of a json dictionary, so no logs are kept.\n\nMy default frequency in private chats is one message of mine from each 2 messages received, and in group chats it\'s 10 messages I read for each message I send.')
|
||||
|
||||
def echo(bot, update):
|
||||
text = update.message.text.split(None, 2)
|
||||
text = update.message.text.split(None, maxsplit=1)
|
||||
if len(text) > 1:
|
||||
text = text[1]
|
||||
chatlog.add_msg(text)
|
||||
|
@ -109,7 +113,8 @@ def read(bot, update):
|
|||
chatlog = chatlogs[ident]
|
||||
chatlog.add_msg(update.message.text)
|
||||
replied = update.message.reply_to_message
|
||||
if (replied is not None) and (replied.from_user.name == "@velascobot") and (random.random() <= 0.5):
|
||||
if (replied is not None) and (replied.from_user.name == "@velascobot") and chatlog.answering(random.random()):
|
||||
print("They're talking to me, I'm answering back")
|
||||
msg = chatlog.speak()
|
||||
update.message.reply_text(msg)
|
||||
if random.random() <= REPT_CHANCE:
|
||||
|
@ -119,10 +124,13 @@ def read(bot, update):
|
|||
msg = chatlog.speak()
|
||||
try:
|
||||
if random.random() <= REPL_CHANCE:
|
||||
print("I made a reply")
|
||||
update.message.reply_text(msg)
|
||||
else:
|
||||
print("I sent a message")
|
||||
bot.sendMessage(chatlog.id, msg)
|
||||
if random.random() <= REPT_CHANCE:
|
||||
print("And a followup")
|
||||
msg = chatlog.speak()
|
||||
bot.sendMessage(chatlog.id, msg)
|
||||
except TimedOut:
|
||||
|
@ -194,12 +202,32 @@ def set_freq(bot, update):
|
|||
reply = "Format was confusing; frequency not changed from " + str(chatlogs[ident].freq)
|
||||
update.message.reply_text(reply)
|
||||
|
||||
def set_answer_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 answer probability is " + str(chatlogs[ident].answer)
|
||||
else:
|
||||
try:
|
||||
value = update.message.text.split()[1]
|
||||
value = float(value)
|
||||
value = chatlogs[ident].set_answer_freq(value)
|
||||
reply = "Probability of answering set to " + str(value)
|
||||
savechat(chatlogs[ident])
|
||||
except:
|
||||
reply = "Format was confusing; answer probability not changed from " + str(chatlogs[ident].answer)
|
||||
update.message.reply_text(reply)
|
||||
|
||||
def stop(bot, update):
|
||||
global ADMIN_ID
|
||||
chatlog = chatlogs[update.message.chat.id]
|
||||
del chatlogs[chatlog.id]
|
||||
os.remove(LOG_DIR + chatlog.id + LOG_EXT)
|
||||
print("I got blocked. Removed user " + chatlog.id)
|
||||
#del chatlogs[chatlog.id]
|
||||
#os.remove(LOG_DIR + chatlog.id + LOG_EXT)
|
||||
print("I got blocked by user " + chatlog.id)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='A Telegram markov bot.')
|
||||
|
@ -226,6 +254,7 @@ def main():
|
|||
dp.add_handler(CommandHandler("id", get_id))
|
||||
dp.add_handler(CommandHandler("stop", stop))
|
||||
dp.add_handler(CommandHandler("speak", speak))
|
||||
dp.add_handler(CommandHandler("answer", set_answer_freq))
|
||||
|
||||
# on noncommand i.e message - echo the message on Telegram
|
||||
# dp.add_handler(MessageHandler(Filters.text, echo))
|
||||
|
|
Loading…
Reference in a new issue