From 85729441ece622ac346a0e51d99db5f5a6edaca1 Mon Sep 17 00:00:00 2001 From: Steven Haussmann Date: Wed, 1 Jul 2020 11:04:14 -0400 Subject: [PATCH] Set the bot up to receive images --- .gitignore | 152 ++++++++++++++++++++++++++++++++++++++++++ .vscode/settings.json | 3 + icon-poller.py | 98 +++++++++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 icon-poller.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56d3761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,152 @@ +config.json + +# Created by https://www.toptal.com/developers/gitignore/api/python,virtualenv +# Edit at https://www.toptal.com/developers/gitignore?templates=python,virtualenv + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +### VirtualEnv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json + +# End of https://www.toptal.com/developers/gitignore/api/python,virtualenv \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..84a192c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "venv\\Scripts\\python.exe" +} \ No newline at end of file diff --git a/icon-poller.py b/icon-poller.py new file mode 100644 index 0000000..06230a9 --- /dev/null +++ b/icon-poller.py @@ -0,0 +1,98 @@ +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 + +submissions = {} +names = {} +status = {} + +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] = {} + 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_open(func): + def wrapper(update, *args, **kwargs): + chat_id = update.effective_chat.id + if status[chat_id] == "open": + return func(update, *args, **kwargs) + 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_user +def echo(update: Update, context: CallbackContext): + context.bot.send_message(chat_id=update.effective_chat.id, text="Hi.") + updater.stop() + +@ensure_chat +def open_submissions(update: Update, context: CallbackContext): + chat_id = update.effective_chat.id + context.bot.send_message(chat_id=update.effective_chat.id, text="Send me your images pls.") + status[chat_id] = "open" + +@ensure_chat +def show_submissions(update: Update, context: CallbackContext): + chat_id = update.effective_chat.id + options = list(map(lambda file_id: InputMediaPhoto(file_id), submissions[chat_id].values())) + chosen = random.choices(options, k=min(len(options), 10)) + context.bot.send_media_group(chat_id=chat_id, media=[chosen[0]]) + + +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("show", show_submissions)) + + updater.start_polling() + updater.idle() \ No newline at end of file