|
- from telegram.ext import Updater, MessageHandler, Filters, CallbackContext, CommandHandler
- from telegram import Update, InputMediaPhoto
- import json
- import sys
- import io
- import logging
- from PIL import Image
- import random
-
- from mwt import MWT
-
- submissions = {}
- names = {}
- polls = {}
- poll_options = {}
- status = {}
-
- @MWT(timeout=60*60)
- def get_admin_ids(bot, chat_id):
- """Returns a list of admin IDs for a given chat. Results are cached for 1 hour."""
- return [admin.user.id for admin in bot.get_chat_administrators(chat_id)]
-
- def ensure_admin(func):
- def wrapper(update, context, *args, **kwargs):
- chat_id = update.effective_chat.id
- user_id = update.effective_user.id
- if user_id in get_admin_ids(context.bot, chat_id):
- return func(update, context, *args, **kwargs)
- return wrapper
-
- def ensure_chat(func):
- def wrapper(update, *args, **kwargs):
- chat_id = update.effective_chat.id
- if chat_id not in submissions:
- submissions[chat_id] = {}
- names[chat_id] = {}
- status[chat_id] = "closed"
- polls[chat_id] = {}
- poll_options[chat_id] = []
- print("Added chat: ", chat_id)
- return func(update, *args, **kwargs)
- return wrapper
-
- def ensure_user(func):
- def wrapper(update, *args, **kwargs):
- chat_id = update.effective_chat.id
- user_id = update.effective_user.id
- if user_id not in submissions[chat_id]:
- names[chat_id][user_id] = update.effective_user.first_name
- print("Added user: ", user_id, " - ", update.effective_user.first_name)
- return func(update, *args, **kwargs)
- return wrapper
-
- def update_name(func):
- def wrapper(update, *args, **kwargs):
- chat_id = update.effective_chat.id
- user_id = update.effective_user.id
- if user_id not in submissions[update.effective_chat.id]:
- names[chat_id][user_id] = update.effective_user.first_name
- print("Got name for ", user_id, ": ", update.effective_user.first_name)
- return func(update, *args, **kwargs)
- return wrapper
-
- def ensure_closed(func):
- def wrapper(update, context, *args, **kwargs):
- chat_id = update.effective_chat.id
- if status[chat_id] == "closed":
- return func(update, context, *args, **kwargs)
- else:
- context.bot.send_message(chat_id=chat_id, text="I need to be closed to do that. I'm currently: " + status[chat_id])
- return wrapper
-
- def ensure_open(func):
- def wrapper(update, context, *args, **kwargs):
- chat_id = update.effective_chat.id
- if status[chat_id] == "open":
- return func(update, context, *args, **kwargs)
- else:
- context.bot.send_message(chat_id=chat_id, text="I need to be open to do that. I'm currently: " + status[chat_id])
- return wrapper
-
- def ensure_polling(func):
- def wrapper(update, context, *args, **kwargs):
- chat_id = update.effective_chat.id
- if status[chat_id] == "polling":
- return func(update, context, *args, **kwargs)
- else:
- context.bot.send_message(chat_id=chat_id, text="I need to be polling to do that. I'm currently: " + status[chat_id])
- return wrapper
-
- @ensure_chat
- @ensure_user
- @update_name
- @ensure_open
- def accept_photo(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- user_id = update.effective_user.id
- file_id = update.message.photo[-1].file_id
- submissions[chat_id][user_id] = file_id
- print(file_id)
-
- @ensure_chat
- @ensure_admin
- @ensure_closed
- def open_submissions(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- submissions[chat_id] = {}
- context.bot.send_message(chat_id=chat_id, text="Send your images as a reply to this post.")
- status[chat_id] = "open"
-
- @ensure_chat
- @ensure_admin
- @ensure_open
- def start_poll(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- status[chat_id] = "polling"
- poll_options[chat_id] = []
-
- users = list(submissions[chat_id].keys())
-
- print("Users with submissions: ", users)
-
- chosen_users = random.sample(users, k=min(len(users), 10))
-
- options = []
- chosen = []
-
- for index, user_id in enumerate(chosen_users):
- options.append(str(index+1) + ": " + names[chat_id][user_id])
- chosen.append(submissions[chat_id][user_id])
- poll_options[chat_id].append(user_id)
-
- if len(chosen) == 0:
- context.bot.send_message(chat_id=chat_id, text="There were no submissions.")
- status[chat_id] = "closed"
- elif len(chosen) == 1:
- context.bot.send_photo(chat_id=chat_id, photo=chosen[0])
- context.bot.send_message(chat_id=chat_id, text="There was only one submission. " + options[0] + " is the winner.")
- status[chat_id] = "closed"
- else:
- input_media = list(map(lambda pair: InputMediaPhoto(pair[1], caption=pair[0]), zip(options, chosen)))
- context.bot.send_media_group(chat_id=chat_id, media=input_media)
-
- polls[chat_id] = context.bot.send_poll(chat_id=chat_id, options = options, question="Pick an icon").message_id
-
- @ensure_chat
- @ensure_admin
- @ensure_polling
- def decide_poll(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- status[chat_id] = "closed"
-
- result = context.bot.stop_poll(chat_id=chat_id, message_id=polls[chat_id])
-
- votes = -1
- winners = []
-
- for index, option in enumerate(result.options):
- if option.voter_count > votes:
- winners = []
- if option.voter_count >= votes:
- winners.append(index)
- votes = option.voter_count
-
- winner = random.choice(winners)
- winner_id = poll_options[chat_id][winner]
- winner_name = names[chat_id][winner_id]
- winner_photo = submissions[chat_id][winner_id]
-
- context.bot.send_message(chat_id=chat_id, text="The winner was " + winner_name)
- context.bot.send_photo(chat_id=chat_id, photo=winner_photo)
-
- @ensure_chat
- @ensure_admin
- def cancel(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- status[chat_id] = "closed"
- submissions[chat_id] = {}
- del polls[chat_id]
-
- @ensure_chat
- def show_status(update: Update, context: CallbackContext):
- chat_id = update.effective_chat.id
- if status[chat_id] == "closed":
- context.bot.send_message(chat_id=chat_id, text="I am currently closed.")
- elif status[chat_id] == "open":
- context.bot.send_message(chat_id=chat_id, text=f"I am currently open for submissions. There are {len(submissions[chat_id])} submissions.")
- elif status[chat_id] == "polling":
- context.bot.send_message(chat_id=chat_id, text="I am currently polling.")
-
-
- if __name__ == "__main__":
- try:
- config = json.load(open("config.json", "r", encoding="utf-8"))
- except:
- logging.error("Couldn't read the config!")
- sys.exit(1)
-
- updater = Updater(token=config["token"], use_context=True)
- dispatcher = updater.dispatcher
-
- dispatcher.add_handler(MessageHandler(Filters.photo, accept_photo))
- dispatcher.add_handler(CommandHandler("open", open_submissions))
- dispatcher.add_handler(CommandHandler("poll", start_poll))
- dispatcher.add_handler(CommandHandler("decide", decide_poll))
- dispatcher.add_handler(CommandHandler("cancel", cancel))
- dispatcher.add_handler(CommandHandler("status", show_status))
-
-
- updater.start_polling()
- updater.idle()
|