Lets you submit and vote on images
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 

176 řádky
6.0 KiB

  1. from telegram.ext import Updater, MessageHandler, Filters, CallbackContext, CommandHandler
  2. from telegram import Update, InputMediaPhoto
  3. import json
  4. import sys
  5. import io
  6. import logging
  7. from PIL import Image
  8. import random
  9. submissions = {}
  10. names = {}
  11. polls = {}
  12. poll_options = {}
  13. status = {}
  14. def ensure_chat(func):
  15. def wrapper(update, *args, **kwargs):
  16. chat_id = update.effective_chat.id
  17. if chat_id not in submissions:
  18. submissions[chat_id] = {}
  19. names[chat_id] = {}
  20. status[chat_id] = "closed"
  21. polls[chat_id] = {}
  22. poll_options[chat_id] = []
  23. print("Added chat: ", chat_id)
  24. return func(update, *args, **kwargs)
  25. return wrapper
  26. def ensure_user(func):
  27. def wrapper(update, *args, **kwargs):
  28. chat_id = update.effective_chat.id
  29. user_id = update.effective_user.id
  30. if user_id not in submissions[chat_id]:
  31. names[chat_id][user_id] = update.effective_user.first_name
  32. print("Added user: ", user_id, " - ", update.effective_user.first_name)
  33. return func(update, *args, **kwargs)
  34. return wrapper
  35. def update_name(func):
  36. def wrapper(update, *args, **kwargs):
  37. chat_id = update.effective_chat.id
  38. user_id = update.effective_user.id
  39. if user_id not in submissions[update.effective_chat.id]:
  40. names[chat_id][user_id] = update.effective_user.first_name
  41. print("Got name for ", user_id, ": ", update.effective_user.first_name)
  42. return func(update, *args, **kwargs)
  43. return wrapper
  44. def ensure_closed(func):
  45. def wrapper(update, context, *args, **kwargs):
  46. chat_id = update.effective_chat.id
  47. if status[chat_id] == "closed":
  48. return func(update, context, *args, **kwargs)
  49. else:
  50. context.bot.send_message(chat_id=chat_id, text="I need to be closed to do that. I'm currently: " + status[chat_id])
  51. return wrapper
  52. def ensure_open(func):
  53. def wrapper(update, context, *args, **kwargs):
  54. chat_id = update.effective_chat.id
  55. if status[chat_id] == "open":
  56. return func(update, context, *args, **kwargs)
  57. else:
  58. context.bot.send_message(chat_id=chat_id, text="I need to be open to do that. I'm currently: " + status[chat_id])
  59. return wrapper
  60. def ensure_polling(func):
  61. def wrapper(update, context, *args, **kwargs):
  62. chat_id = update.effective_chat.id
  63. if status[chat_id] == "polling":
  64. return func(update, context, *args, **kwargs)
  65. else:
  66. context.bot.send_message(chat_id=chat_id, text="I need to be polling to do that. I'm currently: " + status[chat_id])
  67. return wrapper
  68. @ensure_chat
  69. @ensure_user
  70. @update_name
  71. @ensure_open
  72. def accept_photo(update: Update, context: CallbackContext):
  73. chat_id = update.effective_chat.id
  74. user_id = update.effective_user.id
  75. file_id = update.message.photo[-1].file_id
  76. submissions[chat_id][user_id] = file_id
  77. print(file_id)
  78. @ensure_chat
  79. @ensure_closed
  80. def open_submissions(update: Update, context: CallbackContext):
  81. chat_id = update.effective_chat.id
  82. context.bot.send_message(chat_id=chat_id, text="Send your images as a reply to this post.")
  83. status[chat_id] = "open"
  84. @ensure_chat
  85. @ensure_open
  86. def start_poll(update: Update, context: CallbackContext):
  87. chat_id = update.effective_chat.id
  88. status[chat_id] = "polling"
  89. poll_options[chat_id] = []
  90. users = list(submissions[chat_id].keys())
  91. print("Users with submissions: ", users)
  92. chosen_users = random.choices(users, k=min(len(users), 10))
  93. options = []
  94. chosen = []
  95. for user_id in chosen_users:
  96. options.append(names[chat_id][user_id])
  97. chosen.append(submissions[chat_id][user_id])
  98. poll_options[chat_id].append(user_id)
  99. if len(chosen) == 0:
  100. context.bot.send_message(chat_id=chat_id, text="There were no submissions.")
  101. status[chat_id] = "closed"
  102. if len(chosen) == 1:
  103. context.bot.send_photo(chat_id=chat_id, photo=chosen[0])
  104. context.bot.send_message(chat_id=chat_id, text="There was only one submission. " + options[0] + " is the winner.")
  105. status[chat_id] = "closed"
  106. else:
  107. input_media = list(map(lambda file_id: InputMediaPhoto(file_id), chosen))
  108. context.bot.send_media_group(chat_id=chat_id, media=input_media)
  109. polls[chat_id] = context.bot.send_poll(chat_id=chat_id, options = options, question="Pick an icon").message_id
  110. @ensure_chat
  111. @ensure_polling
  112. def decide_poll(update: Update, context: CallbackContext):
  113. chat_id = update.effective_chat.id
  114. status[chat_id] = "closed"
  115. result = context.bot.stop_poll(chat_id=chat_id, message_id=polls[chat_id])
  116. votes = -1
  117. winner = 0
  118. for index, option in enumerate(result.options):
  119. if option.voter_count > votes:
  120. winner = index
  121. votes = option.voter_count
  122. winner_id = poll_options[chat_id][winner]
  123. winner_name = names[chat_id][winner_id]
  124. winner_photo = submissions[chat_id][winner_id]
  125. context.bot.send_message(chat_id=chat_id, text="The winner was " + winner_name)
  126. context.bot.send_photo(chat_id=chat_id, photo=winner_photo)
  127. @ensure_chat
  128. def cancel(update: Update, context: CallbackContext):
  129. chat_id = update.effective_chat.id
  130. status[chat_id] = "closed"
  131. submissions[chat_id] = {}
  132. del polls[chat_id]
  133. if __name__ == "__main__":
  134. try:
  135. config = json.load(open("config.json", "r", encoding="utf-8"))
  136. except:
  137. logging.error("Couldn't read the config!")
  138. sys.exit(1)
  139. updater = Updater(token=config["token"], use_context=True)
  140. dispatcher = updater.dispatcher
  141. dispatcher.add_handler(MessageHandler(Filters.photo, accept_photo))
  142. dispatcher.add_handler(CommandHandler("open", open_submissions))
  143. dispatcher.add_handler(CommandHandler("poll", start_poll))
  144. dispatcher.add_handler(CommandHandler("decide", decide_poll))
  145. dispatcher.add_handler(CommandHandler("cancel", cancel))
  146. updater.start_polling()
  147. updater.idle()