Browse Source

add full support for tales and anecdotes

- /addatale command can be used to add a new tale/anecdote to the database
  the tale is saved after three unique users have upvoted it
- /tellatale command can be used to pick a story to tell at random
bluehood 7 years ago
parent
commit
6ffb37ab30
3 changed files with 126 additions and 10 deletions
  1. 10 2
      LCMbot.py
  2. 0 8
      handlers.py
  3. 116 0
      tale_handler.py

+ 10 - 2
LCMbot.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
-from telegram.ext import Updater, CommandHandler, MessageHandler
+from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters,
+                          CallbackQueryHandler)
 import handlers as hnd
+from tale_handler import TaleHandler
 
 
 def main():
@@ -13,8 +15,14 @@ def main():
     dp.add_handler(CommandHandler('checkwebsite', hnd.is_web_up))
     dp.add_handler(CommandHandler('vietnam', hnd.vietnam))
     dp.add_handler(CommandHandler('sellyourmother', hnd.sell_your_mother))
-    dp.add_handler(CommandHandler('storytime', hnd.tell_a_tale))
     dp.add_handler(CommandHandler('abuse150', hnd.abuse_150))
+
+    tale_handler = TaleHandler()
+    dp.add_handler(CommandHandler('addatale', tale_handler.prompt_user))
+    dp.add_handler(MessageHandler([Filters.text], tale_handler.handle_new_tale))
+    dp.add_handler(CallbackQueryHandler(tale_handler.save_tale))
+    dp.add_handler(CommandHandler('tellatale', tale_handler.tell_a_tale))
+
     dp.add_error_handler(hnd.error)
     # dp.add_handler(MessageHandler([], hnd.print_msg_info))
 

+ 0 - 8
handlers.py

@@ -47,14 +47,6 @@ def sell_your_mother(bot, update):
                   caption='cit. Mandelli')
 
 
-def tell_a_tale(bot, update):
-    """ Tell a story about LCM """
-    stories = [ 'Non conosco ancora nessuna storia. \
-Clona il mio repo e insegnamene qualcuna!' ]
-    story = np.random.choice(stories)
-    bot.sendMessage(chat_id=update.message.chat_id, text=story)
-
-
 def print_msg_info(bot, update):
     """Print all message info to console - useful for debugging purposes"""
     print update.message

+ 116 - 0
tale_handler.py

@@ -0,0 +1,116 @@
+# -*- 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_to_message_id=update.message.message_id,
+            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_to_message_id=tale_msg.message_id,
+          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 voter.id == t.author.id:
+            # authors cannot upvote their own story
+            bot.answer_callback_query(
+                callback_query_id=query.id,
+                text=voter.first_name + ' '
+                    'tried to upvote their own tale...classic')
+        if voter.id in t.upvoters_id:
+            bot.answer_callback_query(
+                callback_query_id=query.id,
+                text=voter.first_name + ' upvoted...again')
+        else:
+            t.upvoters_id.append(voter.id)
+            t.upvotes += 1
+            bot.answer_callback_query(
+                callback_query_id=query.id,
+                text=voter.first_name + ' upvoted the tale')
+            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'] + ":")
+            msg.reply_text(text=t['tale'])