commit 205b373fbdc2247f5f69befa932d7e6ad9dce32a Author: bakatrouble Date: Tue Nov 20 22:51:15 2018 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7255c4a --- /dev/null +++ b/.gitignore @@ -0,0 +1,168 @@ + +### Python template +# 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/ +*.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/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# 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/ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..9d9b523 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,28 @@ + + + + + sqlite.xerial + true + org.sqlite.JDBC + jdbc:sqlite:$PROJECT_DIR$/db.sqlite3 + + + + + + file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.20.1.1/sqlite-jdbc-3.20.1.1.jar + + + file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.20.1.1/xerial-sqlite-license.txt + + + file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/sqlite-jdbc-3.16.1.jar + + + file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.16.1/xerial-sqlite-license.txt + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..52a93e4 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.idea/lono.iml b/.idea/lono.iml new file mode 100644 index 0000000..6711606 --- /dev/null +++ b/.idea/lono.iml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..9a28146 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..53b0268 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..fcfe779 --- /dev/null +++ b/main.py @@ -0,0 +1,103 @@ +from html import escape +from random import random +from time import sleep + +from telegram.error import Unauthorized, TelegramError +from telegram.ext import Updater, CommandHandler, MessageHandler, Filters +from telegram import Message, Update + +from models import Subscriber + +queue = [] + + +def go_away(bot, update: Update): + Subscriber(user_id=str(update.message.chat_id)) + update.message.reply_text('Вы были добавлены') + # update.message.reply_text('Пожалуйста, обратитесь к @lono_contactbot') + + +def unsubscribe(bot, update: Update): + Subscriber.deleteBy(user_id=str(update.message.chat_id)) + update.message.reply_text('Вы были отписаны от бота. Обратитесь к @lono_contactbot за добавлением обратно.') + # update.message.reply_text('Пожалуйста, обратитесь к @lono_contactbot') + + +def msg(bot, update: Update): + queue.append(update.message) + + +def task_queue(bot, job): + if not queue: + return + m = queue.pop(0) + current_chat = str(m.chat_id) + uids = set(s.user_id for s in Subscriber.select()) + if current_chat not in uids: + # return m.reply_text('Пожалуйста, обратитесь к @lono_contactbot') + Subscriber(user_id=current_chat) + m.reply_text('Вы были добавлены') + + try: + uids.remove(current_chat) + except KeyError: + pass + + for uid in uids: + sleep(.05) + try: + if m.forward_from or m.forward_from_chat or m.forward_from_message_id or m.forward_signature: + m.forward(f'{uid}') + elif hasattr(m, 'audio') and m.audio: + a = m.audio + bot.send_audio(f'{uid}', a.file_id, a.duration, a.performer, a.title, m.caption_html, parse_mode='html') + elif hasattr(m, 'document') and m.document: + d = m.document + bot.send_document(f'{uid}', d.file_id, d.file_name, m.caption_html, parse_mode='html') + elif hasattr(m, 'photo') and m.photo: + p = m.photo + bot.send_photo(f'{uid}', p[-1].file_id, m.caption_html, parse_mode='html') + elif hasattr(m, 'sticker') and m.sticker: + s = m.sticker + bot.send_sticker(f'{uid}', s.file_id) + elif hasattr(m, 'video') and m.video: + v = m.video + bot.send_video(f'{uid}', v.file_id, v.duration, m.caption_html, parse_mode='html') + elif hasattr(m, 'voice') and m.voice: + v = m.voice + bot.send_voice(f'{uid}', v.file_id, v.duration, m.caption_html, parse_mode='html') + elif hasattr(m, 'video_note') and m.video_note: + vn = m.video_note + bot.send_video_note(f'{uid}', vn.file_id, vn.duration, vn.length) + elif hasattr(m, 'contact') and m.contact: + c = m.contact + bot.send_contact(f'{uid}', c.phone_number, c.first_name, c.last_name) + elif hasattr(m, 'location') and m.location: + l = m.location + bot.send_location(f'{uid}', l.latitude, l.longitude) + elif hasattr(m, 'venue') and m.venue: + v = m.venue + bot.send_venue(f'{uid}', v.location.latitude, v.location.longitude, v.title, v.address, v.foursquare_id) + elif hasattr(m, 'text') and m.text: + txt = m.text_html + if txt.startswith('!sign') or txt.startswith('/sign'): + txt = txt[5:] + f'\n\n____________\n' \ + f'by {escape(m.from_user.full_name)}' + bot.send_message(f'{uid}', txt, 'html') + except Unauthorized: + Subscriber.deleteBy(user_id=uid) + except TelegramError: + pass + + +updater = Updater('450146961:AAGt5QRp3jS5wcHVIZOLxmqyO55iOVf6gpY', workers=4) +updater.job_queue.run_repeating(task_queue, .04) + +updater.dispatcher.add_handler(CommandHandler('start', go_away)) +updater.dispatcher.add_handler(CommandHandler('stop', unsubscribe)) +updater.dispatcher.add_handler(MessageHandler(Filters.all, msg)) + + +if __name__ == '__main__': + updater.start_polling() + updater.idle() diff --git a/models.py b/models.py new file mode 100644 index 0000000..c6ec0e9 --- /dev/null +++ b/models.py @@ -0,0 +1,10 @@ +from sqlobject import * + +sqlhub.processConnection = connectionForURI('sqlite:db.sqlite3') + + +class Subscriber(SQLObject): + user_id = StringCol(length=32) + + +Subscriber.createTable(ifNotExists=True)