123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- # -*- coding: utf-8 -*-
- import numpy as np
- from telegram import (ForceReply, InlineKeyboardMarkup, InlineKeyboardButton,
- Chat)
- import redis
- class Tale:
- def __init__(self, text, msg_id, author):
- self.text = text
- self.msg_id = msg_id
- self.author = author
- self.upvotes = 0
- self.upvoters_id = []
- class TaleHandler:
- """Helper class to handle storage and retrieval of tales via Telegram"""
- def __init__(self):
- self.db = redis.StrictRedis()
- self.cur_authors = [] # list of tuples (user_id, prompt_msg_id)
- self.cur_tales = [] # list of Tale objects (tales to be added to db)
- def prompt_user(self, bot, update):
- """Prompt user to tell a tale. It will be added to database if upvoted
- at least three times
- """
- if update.message.chat.type != Chat.GROUP:
- update.message.reply_text(text='We need to be in a group chat to '
- 'add a new tale or anecdote!')
- return
- user = update.message.from_user
- prompt_msg = update.message.reply_text(
- text='Ok, %s, tell me your story!' % user.first_name,
- reply_markup=ForceReply(selective=True))
- self.cur_authors.append((user.id, prompt_msg.message_id))
- def handle_new_tale(self, bot, update):
- """Start the upvoting procedure when a new tale is received"""
- tale_msg = update.message
- author = tale_msg.from_user
- reply_to_msg = tale_msg.reply_to_message
- reply_to_id = reply_to_msg.message_id if reply_to_msg is not None else 0
- if (author.id, reply_to_id) not in self.cur_authors:
- # this is not a tale. do nothing
- return
- self.cur_authors.remove((author.id, reply_to_id))
- t = Tale(text=tale_msg.text,
- msg_id=tale_msg.message_id,
- author=author)
- self.cur_tales.append(t)
- thumb_up = u'\U0001F44D'
- b = InlineKeyboardButton(thumb_up + ' 0', callback_data=str(t.msg_id))
- keyboard = InlineKeyboardMarkup([[b]])
- tale_msg.reply_text(
- text='Alright, I need three upvotes to add this tale to my database',
- reply_markup=keyboard)
- def save_tale(self, bot, update):
- """Add tale to db when upvoted three times"""
- query = update.callback_query
- voter = query.from_user
- # retrieve tale
- t = filter(lambda t: t.msg_id == int(query.data), self.cur_tales)
- if len(t) == 0:
- # could not find this tale. this should never happen
- # TODO log an error
- return
- t = t[0]
- if voter.id == t.author.id:
- # authors cannot upvote their own story
- bot.answer_callback_query(
- callback_query_id=query.id,
- text="Nope, can't upvote your own tale")
- elif voter.id in t.upvoters_id:
- bot.answer_callback_query(
- callback_query_id=query.id,
- text='One upvote per person, sorry')
- else:
- t.upvoters_id.append(voter.id)
- t.upvotes += 1
- bot.answer_callback_query(
- callback_query_id=query.id,
- text='Upvote registered')
- if t.upvotes == 3:
- n_tale = self.db.incr('n_tales')
- self.db.hset(str(n_tale), 'author', t.author.first_name)
- self.db.hset(str(n_tale), 'tale', t.text)
- bot.editMessageText(chat_id=query.message.chat_id,
- message_id=query.message.message_id,
- text='Tale saved to database')
- else:
- thumb_up = u'\U0001F44D'
- button = InlineKeyboardButton(thumb_up + str(t.upvotes),
- callback_data=query.data)
- keyboard = InlineKeyboardMarkup([[button]])
- bot.editMessageText(chat_id=query.message.chat_id,
- message_id=query.message.message_id,
- text=query.message.text,
- reply_markup=keyboard)
- def tell_a_tale(self, bot, update):
- """Tell a tale about LCM"""
- msg = update.message
- n_tales = self.db.get('n_tales')
- if not n_tales:
- text = ("I don't know any tales or anecdotes about LCM yet. "
- 'Teach me one using the /addatale command!')
- msg.reply_text(text=text)
- else:
- rnd_tale = str(np.random.randint(1, int(n_tales) + 1))
- t = self.db.hgetall(rnd_tale)
- msg.reply_text(text="This one's from " + t['author'] + ":",
- quote=False)
- msg.reply_text(text=t['tale'], quote=False)
|