Refactoring: step 1
- пакет app переименован в src - файл БД теперь должен лежать в data - удалена папка коммандс, все команды вынесены в модуль коммандс или админ_коммандс - нет импортов в ините - убраны все импорты * - теперь в .env можно указать use_reminder="FALSE", тогда не будет стартовать ремайндер - можно указать урл для Правил - в конфиге теперь только конфиг -то, что из енва получаем - константы теперь лежат отдельно - добавлены явные return там, где не было - бот и вебхук разнесены отдельно - при старте проверяем, что Правила доступны - добавлено еще логирование
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
from .commands import service
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
from urllib.request import urlopen
|
|
||||||
|
|
||||||
|
|
||||||
def my_ip():
|
|
||||||
ip_service = "https://icanhazip.com"
|
|
||||||
ip = urlopen(
|
|
||||||
ip_service,
|
|
||||||
)
|
|
||||||
return ip.read().decode("utf-8")
|
|
||||||
|
|
||||||
|
|
||||||
def me(message):
|
|
||||||
msg = f"<b>Telegram ID:</b> <code>{message.from_user.id}</code>\n\
|
|
||||||
├ <b>Is bot:</b> {message.from_user.is_bot}\n\
|
|
||||||
├ <b>First name:</b> {message.from_user.first_name}\n"
|
|
||||||
if message.from_user.last_name:
|
|
||||||
msg += f" ├ <b>Last name:</b> {message.from_user.last_name}\n"
|
|
||||||
if message.from_user.username:
|
|
||||||
msg += f" ├ <b>Username:</b> {message.from_user.username}\n"
|
|
||||||
msg += f" ├ <b>Language code:</b> {message.from_user.language_code}\n"
|
|
||||||
if message.from_user.is_premium is True:
|
|
||||||
msg += f" ├ <b>Is Premium</b>: ⭐️\n"
|
|
||||||
else:
|
|
||||||
msg += f" ├ <b>Is Premium</b>: No\n"
|
|
||||||
msg += f" ├ <b>Chat ID:</b> {message.chat.id}"
|
|
||||||
|
|
||||||
return msg
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
""" Send User's info. """
|
|
||||||
import shelve
|
|
||||||
import logging
|
|
||||||
from . import report
|
|
||||||
from .config import DATA
|
|
||||||
from urllib import parse
|
|
||||||
from telebot import types
|
|
||||||
|
|
||||||
|
|
||||||
def represent_as_get(message: types.Message):
|
|
||||||
return parse.quote_plus(detect_args(message))
|
|
||||||
|
|
||||||
|
|
||||||
def detect_args(message: types.Message):
|
|
||||||
if message.reply_to_message and message.reply_to_message.text:
|
|
||||||
if len(message.text.split()) == 1:
|
|
||||||
return message.reply_to_message.text
|
|
||||||
else:
|
|
||||||
return " ".join(message.text.split()[1:])
|
|
||||||
else:
|
|
||||||
if len(message.text.split()) > 1:
|
|
||||||
return " ".join(message.text.split()[1:])
|
|
||||||
|
|
||||||
|
|
||||||
def update_stats(message: types.Message):
|
|
||||||
with shelve.open(f"{DATA}{message.chat.id}", writeback=True) as s:
|
|
||||||
if "Messages" not in s:
|
|
||||||
report.reset_report_stats(message.chat.id)
|
|
||||||
|
|
||||||
if message.from_user.id not in s["Messages"]:
|
|
||||||
s["Messages"][message.from_user.id] = {
|
|
||||||
"User": message.from_user,
|
|
||||||
"Count": 1,
|
|
||||||
}
|
|
||||||
logging.info(
|
|
||||||
f"[{message.chat.title[:10]}] [{message.from_user.id}] {message.from_user.first_name}"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
s["Messages"][message.from_user.id]["Count"] += 1
|
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
""" Service commands for Admin purposes. """
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from telebot import logger
|
|
||||||
from datetime import datetime as dt
|
from datetime import datetime as dt
|
||||||
from ..models import Chat, Quote, session
|
|
||||||
from ..config import bot, ADMIN_ID, types
|
from telebot import types, logger
|
||||||
from .. import reminder
|
|
||||||
from .. import report
|
from .constants import ADMIN_ID, LOGGING_LEVEL_DEBUG, LOGGING_LEVEL_INFO
|
||||||
from ..filters import is_admin, is_white
|
from .filters import is_white, is_admin
|
||||||
from .get import me, my_ip
|
from .helpers import me, my_ip
|
||||||
|
from .models import Chat, Quote, session
|
||||||
|
from .reminder import remind, print_get_jobs, create_report_text
|
||||||
|
from .report import reset_report_stats
|
||||||
|
from .robot import bot
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(commands=["me"])
|
@bot.message_handler(commands=["me"])
|
||||||
async def command_me(message):
|
async def send_me(message):
|
||||||
"""Send info about user and chat id [Service]."""
|
"""Send info about user and chat id [Service]."""
|
||||||
await bot.send_message(message.chat.id, me(message))
|
await bot.send_message(message.chat.id, me(message))
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ async def remind_manually(message):
|
|||||||
except ValueError as ve:
|
except ValueError as ve:
|
||||||
await bot.send_message(message.chat.id, f"Не удалось разобрать дату!\n{ve}")
|
await bot.send_message(message.chat.id, f"Не удалось разобрать дату!\n{ve}")
|
||||||
else:
|
else:
|
||||||
await reminder.remind(message.chat.id, today)
|
await remind(message.chat.id, today)
|
||||||
else:
|
else:
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
@@ -44,45 +45,34 @@ async def remind_manually(message):
|
|||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_admin, commands=["jobs"])
|
@bot.message_handler(func=is_admin, commands=["jobs"])
|
||||||
async def list_jobs(message):
|
async def list_jobs(_message):
|
||||||
"""List all the jobs in schedule."""
|
"""List all the jobs in schedule."""
|
||||||
await bot.send_message(ADMIN_ID, reminder.print_get_jobs())
|
await bot.send_message(ADMIN_ID, print_get_jobs())
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_admin, commands=["stats"])
|
@bot.message_handler(func=is_admin, commands=["stats"])
|
||||||
async def send_stats(message: types.Message):
|
async def send_stats(message: types.Message):
|
||||||
if len(message.text.split()) == 1:
|
if len(message.text.split()) == 1:
|
||||||
rep = report.create_report_text(message.chat.id)
|
rep = create_report_text(message.chat.id)
|
||||||
if rep:
|
if rep:
|
||||||
await bot.send_message(message.chat.id, rep)
|
await bot.send_message(message.chat.id, rep)
|
||||||
else:
|
else:
|
||||||
await bot.send_message(message.chat.id, report.create_report_text(message.text.split()[-1]))
|
await bot.send_message(message.chat.id, create_report_text(message.text.split()[-1]))
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_admin, commands=["reset_stats"], chat_types=["supergroup", "group"])
|
@bot.message_handler(func=is_admin, commands=["reset_stats"], chat_types=["supergroup", "group"])
|
||||||
async def send_stats(message: types.Message):
|
async def send_stats(message: types.Message):
|
||||||
logging.warning("reset_stats")
|
logging.warning("reset_stats")
|
||||||
report.reset_report_stats(message.chat.id)
|
reset_report_stats(message.chat.id)
|
||||||
await bot.send_message(message.chat.id, report.reset_report_stats(message.chat.id))
|
await bot.send_message(message.chat.id, reset_report_stats(message.chat.id))
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_white, commands=["enable_stan"], chat_types=["supergroup", "group"])
|
@bot.message_handler(func=is_white, commands=["enable_stan"], chat_types=["supergroup", "group"])
|
||||||
async def enable_stan(message: types.Message):
|
async def enable_stan(message: types.Message):
|
||||||
"""Add group to database."""
|
"""Add group to database."""
|
||||||
|
logging.info(f"[{message.chat.title}] [{message.from_user.id}] {message.from_user.username}: {message.text}")
|
||||||
logging.info(
|
|
||||||
f"[{message.chat.title}] [{message.from_user.id}] {message.from_user.username}: {message.text}"
|
|
||||||
)
|
|
||||||
if not session.query(Chat.id).filter(Chat.chat_id == message.chat.id).first():
|
if not session.query(Chat.id).filter(Chat.chat_id == message.chat.id).first():
|
||||||
session.add(
|
session.add(Chat(chat_id=message.chat.id, title=message.chat.title, antispam=1, report=0, reminder=1))
|
||||||
Chat(
|
|
||||||
chat_id=message.chat.id,
|
|
||||||
title=message.chat.title,
|
|
||||||
antispam=1,
|
|
||||||
report=0,
|
|
||||||
reminder=1,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
session.commit()
|
session.commit()
|
||||||
await bot.send_message(
|
await bot.send_message(
|
||||||
message.chat.id,
|
message.chat.id,
|
||||||
@@ -100,10 +90,7 @@ async def disable_stan(message: types.Message):
|
|||||||
chat = session.query(Chat).filter_by(chat_id=message.chat.id).first()
|
chat = session.query(Chat).filter_by(chat_id=message.chat.id).first()
|
||||||
session.delete(chat)
|
session.delete(chat)
|
||||||
session.commit()
|
session.commit()
|
||||||
await bot.send_message(
|
await bot.send_message(message.chat.id, f"Группа {message.chat.title} и все связанные с ней цитаты удалёны!")
|
||||||
message.chat.id,
|
|
||||||
f"Группа {message.chat.title} и все связанные с ней цитаты удалёны!",
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
await bot.send_message(message.chat.id, "Отказ. Этой группы нет в БД.")
|
await bot.send_message(message.chat.id, "Отказ. Этой группы нет в БД.")
|
||||||
|
|
||||||
@@ -130,21 +117,17 @@ async def set_antispam_report_reminder(message: types.Message):
|
|||||||
await bot.send_message(message.chat.id, f"""Настройки обновлены. Проверить: /get_group_info""")
|
await bot.send_message(message.chat.id, f"""Настройки обновлены. Проверить: /get_group_info""")
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(
|
@bot.message_handler(func=is_white, commands=["get_quotes"], chat_types=["supergroup", "group"])
|
||||||
func=is_white, commands=["get_quotes"], chat_types=["supergroup", "group"]
|
|
||||||
)
|
|
||||||
async def get_quotes(message: types.Message):
|
async def get_quotes(message: types.Message):
|
||||||
logging.info(f"[{message.chat.id}] {message.from_user.first_name} {message.text}.")
|
logging.info(f"[{message.chat.id}] {message.from_user.first_name} {message.text}.")
|
||||||
quotes = session.query(Quote.text).filter(Quote.chat_id == message.chat.id).all()
|
quotes = session.query(Quote.text).filter(Quote.chat_id == message.chat.id).all()
|
||||||
if quotes:
|
if quotes:
|
||||||
text = f"Количество цитат: {len(session.query(Quote).filter(Quote.chat_id == message.chat.id).all())}\n\
|
length = len(session.query(Quote).filter(Quote.chat_id == message.chat.id).all())
|
||||||
Последние добавленные\n\n"
|
text = f"Количество цитат: {length}\n\Последние добавленные\n\n"
|
||||||
text += "\n".join(f"· {quote[0]}" for quote in quotes[-10:])
|
text += "\n".join(f"· {quote[0]}" for quote in quotes[-10:])
|
||||||
await bot.send_message(message.chat.id, f"{text}")
|
await bot.send_message(message.chat.id, f"{text}")
|
||||||
else:
|
else:
|
||||||
await bot.send_message(
|
await bot.send_message(message.chat.id, f"Цитаты отсутствуют. Подробнее: /get_group_info")
|
||||||
message.chat.id, f"Цитаты отсутствуют. Подробнее: /get_group_info"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_white, commands=["get_group_info"], chat_types=["supergroup", "group"])
|
@bot.message_handler(func=is_white, commands=["get_group_info"], chat_types=["supergroup", "group"])
|
||||||
@@ -172,8 +155,8 @@ ID группы: {group.chat_id}
|
|||||||
async def set_logging_level(message: types.Message):
|
async def set_logging_level(message: types.Message):
|
||||||
args = message.text.split()
|
args = message.text.split()
|
||||||
if args[-1] == '10':
|
if args[-1] == '10':
|
||||||
logger.setLevel(10) # DEBUG
|
logger.setLevel(LOGGING_LEVEL_DEBUG)
|
||||||
logging.info("[LEVEL] Установлен уровень DEBUG")
|
logging.info("[LEVEL] Установлен уровень DEBUG")
|
||||||
else:
|
else:
|
||||||
logger.setLevel(20) # INFO
|
logger.setLevel(LOGGING_LEVEL_INFO)
|
||||||
logging.info("[LEVEL] Установлен уровень INFO")
|
logging.info("[LEVEL] Установлен уровень INFO")
|
||||||
@@ -1,11 +1,23 @@
|
|||||||
|
import logging
|
||||||
|
import logging.handlers
|
||||||
import shelve
|
import shelve
|
||||||
|
|
||||||
from . import stan
|
from telebot import types
|
||||||
from . import rules
|
|
||||||
|
|
||||||
|
from .constants import DATA, LOG_COMM, FAQ, LIB, RULES, RUS, RUS_ENG_TABLE, ENG_RUS_TABLE, PYTHONCHATRU, ZEN
|
||||||
|
from .filters import in_spam_list, in_caption_spam_list, in_delete_list, is_admin
|
||||||
from .helpers import represent_as_get, detect_args, update_stats
|
from .helpers import represent_as_get, detect_args, update_stats
|
||||||
from .filters import *
|
from .admin_commands import bot
|
||||||
from .config import *
|
from .rules import fetch_rule
|
||||||
|
from .stan import act, speak
|
||||||
|
|
||||||
|
|
||||||
|
async def send_or_reply(message: types.Message, answer, **kwargs):
|
||||||
|
if message.reply_to_message:
|
||||||
|
await bot.reply_to(message.reply_to_message, answer, **kwargs)
|
||||||
|
else:
|
||||||
|
await bot.send_message(message.chat.id, answer, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
""" [ ANTISPAM ] """
|
""" [ ANTISPAM ] """
|
||||||
|
|
||||||
@@ -16,8 +28,8 @@ async def moderate_messages(message: types.Message):
|
|||||||
"""Ban user and delete their message."""
|
"""Ban user and delete their message."""
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
await bot.ban_chat_member(message.chat.id, message.from_user.id)
|
await bot.ban_chat_member(message.chat.id, message.from_user.id)
|
||||||
with shelve.open(f"{DATA}{message.chat.id}") as s:
|
with shelve.open(f"{DATA}{message.chat.id}") as shelve_db:
|
||||||
s["Banned"] += 1
|
shelve_db["Banned"] += 1
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=in_caption_spam_list, content_types=["video"], chat_types=["supergroup", "group"])
|
@bot.message_handler(func=in_caption_spam_list, content_types=["video"], chat_types=["supergroup", "group"])
|
||||||
@@ -25,8 +37,8 @@ async def catch_videos(message: types.Message):
|
|||||||
"""Catch offensive videos"""
|
"""Catch offensive videos"""
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
await bot.ban_chat_member(message.chat.id, message.from_user.id)
|
await bot.ban_chat_member(message.chat.id, message.from_user.id)
|
||||||
with shelve.open(f"{DATA}{message.chat.id}") as s:
|
with shelve.open(f"{DATA}{message.chat.id}") as shelve_db:
|
||||||
s["Banned"] += 1
|
shelve_db["Banned"] += 1
|
||||||
|
|
||||||
|
|
||||||
@bot.edited_message_handler(func=in_delete_list, chat_types=["supergroup", "group"])
|
@bot.edited_message_handler(func=in_delete_list, chat_types=["supergroup", "group"])
|
||||||
@@ -34,8 +46,8 @@ async def catch_videos(message: types.Message):
|
|||||||
async def delete_message(message: types.Message):
|
async def delete_message(message: types.Message):
|
||||||
"""Delete unwanted message."""
|
"""Delete unwanted message."""
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
with shelve.open(f"{DATA}{message.chat.id}") as s:
|
with shelve.open(f"{DATA}{message.chat.id}") as shelve_db:
|
||||||
s["Deleted"] += 1
|
shelve_db["Deleted"] += 1
|
||||||
|
|
||||||
|
|
||||||
""" [ COMMANDS ] """
|
""" [ COMMANDS ] """
|
||||||
@@ -58,7 +70,7 @@ async def send_rules(message: types.Message):
|
|||||||
if len(args) > 1 and args[-1].isdigit() and 0 < int(args[-1]):
|
if len(args) > 1 and args[-1].isdigit() and 0 < int(args[-1]):
|
||||||
await send_or_reply(
|
await send_or_reply(
|
||||||
message,
|
message,
|
||||||
f"<b>Правило {args[-1]}</b>\n<i>{rules.fetch_rule(args[-1])}</i>",
|
f"<b>Правило {args[-1]}</b>\n<i>{fetch_rule(args[-1])}</i>",
|
||||||
reply_markup=markup,
|
reply_markup=markup,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -164,7 +176,7 @@ async def stan_speak(message: types.Message):
|
|||||||
message.text,
|
message.text,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await bot.send_message(message.chat.id, stan.speak(0, message.chat.id), parse_mode='Markdown')
|
await bot.send_message(message.chat.id, speak(0, message.chat.id), parse_mode='Markdown')
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
|
|
||||||
|
|
||||||
@@ -180,10 +192,7 @@ async def send_tsya(message: types.Message):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(
|
markup.add(types.InlineKeyboardButton("🧑🏼🎓 Читать правило", url="https://tsya.ru/"), row_width=1)
|
||||||
types.InlineKeyboardButton("🧑🏼🎓 Читать правило", url="https://tsya.ru/"),
|
|
||||||
row_width=1,
|
|
||||||
)
|
|
||||||
await send_or_reply(message, "<i>-тся</i> и <i>-ться</i> в глаголах", reply_markup=markup)
|
await send_or_reply(message, "<i>-тся</i> и <i>-ться</i> в глаголах", reply_markup=markup)
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
|
|
||||||
@@ -200,10 +209,7 @@ async def send_nometa(message: types.Message):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(
|
markup.add(types.InlineKeyboardButton("❓ nometa.xyz", url="https://nometa.xyz/ru.html"), row_width=1)
|
||||||
types.InlineKeyboardButton("❓ nometa.xyz", url="https://nometa.xyz/ru.html"),
|
|
||||||
row_width=1,
|
|
||||||
)
|
|
||||||
await send_or_reply(
|
await send_or_reply(
|
||||||
message,
|
message,
|
||||||
"""Не задавай мета-вопросов вроде:
|
"""Не задавай мета-вопросов вроде:
|
||||||
@@ -229,13 +235,8 @@ async def send_neprivet(message: types.Message):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(
|
markup.add(types.InlineKeyboardButton("👋 Непривет", url="https://neprivet.com/"), row_width=1)
|
||||||
types.InlineKeyboardButton("👋 Непривет", url="https://neprivet.com/"),
|
await send_or_reply(message, "Пожалуйста, не пишите просто «Привет» в чате.", reply_markup=markup)
|
||||||
row_width=1,
|
|
||||||
)
|
|
||||||
await send_or_reply(
|
|
||||||
message, "Пожалуйста, не пишите просто «Привет» в чате.", reply_markup=markup
|
|
||||||
)
|
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
|
|
||||||
|
|
||||||
@@ -282,8 +283,7 @@ async def google_it(message: types.Message):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
query = f"<i>{detect_args(message)}</i>"
|
query = f"<i>{detect_args(message)}</i>"
|
||||||
get_query = "https://www.google.com/search?q=" + represent_as_get(message)
|
get_query = f"https://www.google.com/search?q={represent_as_get(message)}"
|
||||||
|
|
||||||
markup = types.InlineKeyboardMarkup()
|
markup = types.InlineKeyboardMarkup()
|
||||||
markup.add(types.InlineKeyboardButton("🔍 Google Поиск", url=get_query), row_width=1)
|
markup.add(types.InlineKeyboardButton("🔍 Google Поиск", url=get_query), row_width=1)
|
||||||
await send_or_reply(message, f"<i>Ищем «{query}»...</i>", reply_markup=markup)
|
await send_or_reply(message, f"<i>Ищем «{query}»...</i>", reply_markup=markup)
|
||||||
@@ -360,22 +360,9 @@ async def default_query(inline_query):
|
|||||||
""" [ COUNTER ] """
|
""" [ COUNTER ] """
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(content_types=["text", "sticker", "photo", "animation", "video", "audio", "document", ],
|
@bot.message_handler(content_types=["text", "sticker", "photo", "animation", "video", "audio", "document"],
|
||||||
chat_types=["supergroup", "group"])
|
chat_types=["supergroup", "group"])
|
||||||
async def handle_msg(message: types.Message):
|
async def handle_msg(message: types.Message):
|
||||||
"""Count messages, Stan."""
|
"""Count messages, Stan."""
|
||||||
update_stats(message)
|
update_stats(message)
|
||||||
await stan.act(message)
|
await act(message)
|
||||||
|
|
||||||
|
|
||||||
""" [ WEBHOOK ] """
|
|
||||||
|
|
||||||
|
|
||||||
@app.post(f"/bot{TOKEN}/")
|
|
||||||
async def webhook(update: dict):
|
|
||||||
"""Parse POST requests from Telegram."""
|
|
||||||
if update:
|
|
||||||
update = telebot.types.Update.de_json(update)
|
|
||||||
await bot.process_new_updates([update])
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from urllib.error import URLError
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from telebot import logger
|
||||||
|
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
TOKEN = os.environ.get("LUTZPYBOT")
|
||||||
|
if not TOKEN:
|
||||||
|
raise LookupError("LUTZPYBOT (token) has not been found in .env")
|
||||||
|
|
||||||
|
WHITEIDS = {int(i) for i in os.environ.get("whiteids").split(",")}
|
||||||
|
ROLLBACK = {int(i) for i in os.environ.get("rollback").split(",")}
|
||||||
|
USE_REMINDER = os.environ.get("use_reminder", "TRUE") == "TRUE"
|
||||||
|
|
||||||
|
RULES_URL = os.environ.get("rules_url", "https://telegra.ph/pythonchatru-07-07")
|
||||||
|
try:
|
||||||
|
assert urlopen(RULES_URL).status == 200
|
||||||
|
except (URLError, AssertionError):
|
||||||
|
raise LookupError(f"LUTZPYBOT rules url({RULES_URL}) is not reachable")
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
@@ -1,40 +1,15 @@
|
|||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import logging
|
|
||||||
|
|
||||||
import telebot.types
|
from telebot import types
|
||||||
from fastapi import FastAPI
|
|
||||||
from telebot.async_telebot import AsyncTeleBot
|
|
||||||
from telebot import logger, types
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
|
|
||||||
logger.setLevel(logging.ERROR)
|
|
||||||
|
|
||||||
logging.warning("[START] Stan")
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
TOKEN = os.environ.get("LUTZPYBOT")
|
|
||||||
if not TOKEN:
|
|
||||||
raise LookupError("LUTZPYBOT (token) has not been found in .env")
|
|
||||||
|
|
||||||
bot = AsyncTeleBot(
|
|
||||||
TOKEN,
|
|
||||||
"HTML",
|
|
||||||
disable_web_page_preview=True,
|
|
||||||
allow_sending_without_reply=True,
|
|
||||||
colorful_logs=True,
|
|
||||||
)
|
|
||||||
LOG_TEXT = "[%s] %s: %s"
|
LOG_TEXT = "[%s] %s: %s"
|
||||||
LOG_COMM = "[%s] [%s] %s: %s"
|
LOG_COMM = "[%s] [%s] %s: %s"
|
||||||
app = FastAPI(docs=None, redoc_url=None)
|
LOGGING_LEVEL_DEBUG = 10
|
||||||
|
LOGGING_LEVEL_INFO = 20
|
||||||
DATA = "data/chat"
|
DATA = "data/chat"
|
||||||
|
|
||||||
ADMIN_ID = 280887861 # Rykov7
|
ADMIN_ID = 280887861 # Rykov7
|
||||||
PYTHONCHATRU = -1001338616632 # pythonchatru
|
PYTHONCHATRU = -1001338616632 # pythonchatru
|
||||||
|
|
||||||
URL_RX = re.compile(r"\w+\.\w+/(\+)?\w+")
|
URL_RX = re.compile(r"\w+\.\w+/(\+)?\w+")
|
||||||
ALLOWED_WORDS = [
|
ALLOWED_WORDS = [
|
||||||
"paste",
|
"paste",
|
||||||
@@ -61,20 +36,13 @@ ALLOWED_WORDS = [
|
|||||||
"jetbrains",
|
"jetbrains",
|
||||||
]
|
]
|
||||||
|
|
||||||
WHITEIDS = {int(i) for i in os.environ.get("whiteids").split(",")}
|
|
||||||
ROLLBACK = {int(i) for i in os.environ.get("rollback").split(",")}
|
|
||||||
|
|
||||||
RUS = """ёйцукенгшщзхъфывапролджэячсмитьбю.Ё!"№;%:?ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"""
|
RUS = """ёйцукенгшщзхъфывапролджэячсмитьбю.Ё!"№;%:?ЙЦУКЕНГШЩЗХЪ/ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,"""
|
||||||
ENG = """`qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?"""
|
ENG = """`qwertyuiop[]asdfghjkl;'zxcvbnm,./~!@#$%^&QWERTYUIOP{}|ASDFGHJKL:"ZXCVBNM<>?"""
|
||||||
RUS_ENG_TABLE = str.maketrans(RUS, ENG)
|
RUS_ENG_TABLE = str.maketrans(RUS, ENG)
|
||||||
ENG_RUS_TABLE = str.maketrans(ENG, RUS)
|
ENG_RUS_TABLE = str.maketrans(ENG, RUS)
|
||||||
|
|
||||||
RULES = types.InlineKeyboardButton(
|
RULES = types.InlineKeyboardButton("🟡 Правила чата", url="https://telegra.ph/pythonchatru-07-07")
|
||||||
"🟡 Правила чата", url="https://telegra.ph/pythonchatru-07-07"
|
FAQ = types.InlineKeyboardButton("🔵 Частые вопросы", url="https://telegra.ph/faq-10-07-4")
|
||||||
)
|
|
||||||
FAQ = types.InlineKeyboardButton(
|
|
||||||
"🔵 Частые вопросы", url="https://telegra.ph/faq-10-07-4"
|
|
||||||
)
|
|
||||||
LIB = types.InlineKeyboardButton("📚 Книги", url="https://telegra.ph/what-to-read-10-06")
|
LIB = types.InlineKeyboardButton("📚 Книги", url="https://telegra.ph/what-to-read-10-06")
|
||||||
|
|
||||||
SPAM = {"me.sv/", "tg.sv/", "goo.by/", "go.sv/", "intim.video/", "uclck.ru/", 'раб0т',
|
SPAM = {"me.sv/", "tg.sv/", "goo.by/", "go.sv/", "intim.video/", "uclck.ru/", 'раб0т',
|
||||||
@@ -88,6 +56,7 @@ SPAM = {"me.sv/", "tg.sv/", "goo.by/", "go.sv/", "intim.video/", "uclck.ru/", '
|
|||||||
'P2P', 'Идет набор', 'в лс', 'нaбop', 'комaндy', 'kpuпт', 'бupж', '💰', 'пишитe', '💸',
|
'P2P', 'Идет набор', 'в лс', 'нaбop', 'комaндy', 'kpuпт', 'бupж', '💰', 'пишитe', '💸',
|
||||||
'$ в неделю', 'обучаю с нуля', 'доходы для всех', 'по трейдингу', 'фальшивые рубли', '‼️',
|
'$ в неделю', 'обучаю с нуля', 'доходы для всех', 'по трейдингу', 'фальшивые рубли', '‼️',
|
||||||
'зароботку', 'Набuраю', 'цuфр', 'Обучу вас', 'прuб', 'остались курсы', 'Crypt', 'kр', 'рu'}
|
'зароботку', 'Набuраю', 'цuфр', 'Обучу вас', 'прuб', 'остались курсы', 'Crypt', 'kр', 'рu'}
|
||||||
|
|
||||||
NON_GRATA = {"дудар", "хауди", "dudar"}
|
NON_GRATA = {"дудар", "хауди", "dudar"}
|
||||||
BAN_WORDS = {"GREEN"}
|
BAN_WORDS = {"GREEN"}
|
||||||
|
|
||||||
@@ -1,20 +1,23 @@
|
|||||||
import logging.handlers
|
import logging.handlers
|
||||||
|
|
||||||
from .models import session
|
from telebot import types
|
||||||
|
|
||||||
|
from .config import WHITEIDS
|
||||||
|
from .constants import BAN_WORDS, LOG_COMM, SPAM, ALLOWED_WORDS, URL_RX, NON_GRATA, ADMIN_ID
|
||||||
from .models import Chat
|
from .models import Chat
|
||||||
from .config import *
|
from .models import session
|
||||||
|
|
||||||
|
|
||||||
def in_spam_list(message: types.Message) -> bool:
|
def in_spam_list(message: types.Message) -> bool:
|
||||||
"""Check for mentioning unwanted persons in text."""
|
"""Check for mentioning unwanted persons in text."""
|
||||||
antispam_is_enabled = session.query(Chat.antispam).filter_by(chat_id=message.chat.id).first()[0]
|
antispam_is_enabled = session.query(Chat.antispam).filter_by(chat_id=message.chat.id).first()[0]
|
||||||
if message.from_user.id not in WHITEIDS and antispam_is_enabled:
|
from_user_id, title, from_user_name = message.from_user.id, message.chat.title, message.from_user.first_name
|
||||||
|
if from_user_id not in WHITEIDS and antispam_is_enabled:
|
||||||
for text in SPAM:
|
for text in SPAM:
|
||||||
if text.casefold() in message.text.casefold():
|
if text.casefold() in message.text.casefold():
|
||||||
logging.info(
|
logging.info("!BAN!" + LOG_COMM % (title, from_user_id, from_user_name, message.text))
|
||||||
"!BAN!" + LOG_COMM % (
|
|
||||||
message.chat.title, message.from_user.id, message.from_user.first_name, message.text))
|
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def in_caption_spam_list(message: types.Message) -> bool:
|
def in_caption_spam_list(message: types.Message) -> bool:
|
||||||
@@ -24,6 +27,7 @@ def in_caption_spam_list(message: types.Message) -> bool:
|
|||||||
logging.info("!BAN!" + LOG_COMM % (
|
logging.info("!BAN!" + LOG_COMM % (
|
||||||
message.chat.title, message.from_user.id, message.from_user.first_name, message.video.file_name))
|
message.chat.title, message.from_user.id, message.from_user.first_name, message.video.file_name))
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def in_not_allowed(word_list, msg):
|
def in_not_allowed(word_list, msg):
|
||||||
@@ -36,21 +40,17 @@ def in_not_allowed(word_list, msg):
|
|||||||
def in_delete_list(message: types.Message) -> bool:
|
def in_delete_list(message: types.Message) -> bool:
|
||||||
"""Check for URLs in message and delete."""
|
"""Check for URLs in message and delete."""
|
||||||
antispam_is_enabled = session.query(Chat.antispam).filter_by(chat_id=message.chat.id).first()[0]
|
antispam_is_enabled = session.query(Chat.antispam).filter_by(chat_id=message.chat.id).first()[0]
|
||||||
if message.from_user.id not in WHITEIDS and antispam_is_enabled:
|
from_user_id, title, from_user_name = message.from_user.id, message.chat.title, message.from_user.first_name
|
||||||
if URL_RX.search(message.text) and in_not_allowed(
|
if from_user_id not in WHITEIDS and antispam_is_enabled:
|
||||||
ALLOWED_WORDS, message.text
|
if URL_RX.search(message.text) and in_not_allowed(ALLOWED_WORDS, message.text):
|
||||||
):
|
logging.info(f"[DELETE] [{title}] [{from_user_id}] {from_user_name}: {message.text}")
|
||||||
logging.info(
|
|
||||||
f"[DELETE] [{message.chat.title}] [{message.from_user.id}] {message.from_user.first_name}: {message.text}"
|
|
||||||
)
|
|
||||||
return True
|
return True
|
||||||
if message.entities:
|
if message.entities:
|
||||||
for entity in message.entities:
|
for entity in message.entities:
|
||||||
if entity.url and in_not_allowed(ALLOWED_WORDS, entity.url):
|
if entity.url and in_not_allowed(ALLOWED_WORDS, entity.url):
|
||||||
logging.info(
|
logging.info(f"[DELETE] [{title}] [{from_user_id}] {from_user_name}: [entity] {message.text}")
|
||||||
f"[DELETE] [{message.chat.title}] [{message.from_user.id}] {message.from_user.first_name}: [entity] {message.text}"
|
|
||||||
)
|
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_nongrata(type_message: types.Message) -> bool:
|
def is_nongrata(type_message: types.Message) -> bool:
|
||||||
@@ -58,6 +58,7 @@ def is_nongrata(type_message: types.Message) -> bool:
|
|||||||
for phrase in NON_GRATA:
|
for phrase in NON_GRATA:
|
||||||
if phrase in type_message.text.casefold():
|
if phrase in type_message.text.casefold():
|
||||||
return True
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_admin(message: types.Message) -> bool:
|
def is_admin(message: types.Message) -> bool:
|
||||||
@@ -66,10 +67,3 @@ def is_admin(message: types.Message) -> bool:
|
|||||||
|
|
||||||
def is_white(message: types.Message) -> bool:
|
def is_white(message: types.Message) -> bool:
|
||||||
return message.from_user.id in WHITEIDS
|
return message.from_user.id in WHITEIDS
|
||||||
|
|
||||||
|
|
||||||
async def send_or_reply(m: types.Message, answer, **kwargs):
|
|
||||||
if m.reply_to_message:
|
|
||||||
await bot.reply_to(m.reply_to_message, answer, **kwargs)
|
|
||||||
else:
|
|
||||||
await bot.send_message(m.chat.id, answer, **kwargs)
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
""" Send User's info. """
|
||||||
|
import logging
|
||||||
|
import shelve
|
||||||
|
from pathlib import Path
|
||||||
|
from urllib import parse
|
||||||
|
from urllib.request import urlopen
|
||||||
|
|
||||||
|
from telebot import types
|
||||||
|
|
||||||
|
from .constants import DATA
|
||||||
|
from .report import reset_report_stats
|
||||||
|
|
||||||
|
|
||||||
|
def my_ip():
|
||||||
|
ip_service = "https://icanhazip.com"
|
||||||
|
ip = urlopen(ip_service)
|
||||||
|
return ip.read().decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def me(message: types.Message):
|
||||||
|
msg = f"<b>Telegram ID:</b> <code>{message.from_user.id}</code>\n\
|
||||||
|
├ <b>Is bot:</b> {message.from_user.is_bot}\n\
|
||||||
|
├ <b>First name:</b> {message.from_user.first_name}\n"
|
||||||
|
if message.from_user.last_name:
|
||||||
|
msg += f" ├ <b>Last name:</b> {message.from_user.last_name}\n"
|
||||||
|
if message.from_user.username:
|
||||||
|
msg += f" ├ <b>Username:</b> {message.from_user.username}\n"
|
||||||
|
msg += f" ├ <b>Language code:</b> {message.from_user.language_code}\n"
|
||||||
|
if message.from_user.is_premium is True:
|
||||||
|
msg += f" ├ <b>Is Premium</b>: ⭐️\n"
|
||||||
|
else:
|
||||||
|
msg += f" ├ <b>Is Premium</b>: No\n"
|
||||||
|
msg += f" ├ <b>Chat ID:</b> {message.chat.id}"
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def represent_as_get(message: types.Message):
|
||||||
|
return parse.quote_plus(detect_args(message))
|
||||||
|
|
||||||
|
|
||||||
|
def detect_args(message: types.Message):
|
||||||
|
if message.reply_to_message and message.reply_to_message.text:
|
||||||
|
if len(message.text.split()) == 1:
|
||||||
|
return message.reply_to_message.text
|
||||||
|
else:
|
||||||
|
return " ".join(message.text.split()[1:])
|
||||||
|
else:
|
||||||
|
if len(message.text.split()) > 1:
|
||||||
|
return " ".join(message.text.split()[1:])
|
||||||
|
|
||||||
|
|
||||||
|
def update_stats(message: types.Message):
|
||||||
|
if not Path(f"{DATA}{message.chat.id}").exists():
|
||||||
|
reset_report_stats(message.chat.id)
|
||||||
|
with shelve.open(f"{DATA}{message.chat.id}", writeback=True) as shelve_db:
|
||||||
|
if "Messages" not in shelve_db:
|
||||||
|
reset_report_stats(message.chat.id)
|
||||||
|
if message.from_user.id not in shelve_db["Messages"]:
|
||||||
|
shelve_db["Messages"][message.from_user.id] = {"User": message.from_user, "Count": 1}
|
||||||
|
logging.info(f"[{message.chat.title[:10]}] [{message.from_user.id}] {message.from_user.first_name}")
|
||||||
|
else:
|
||||||
|
shelve_db["Messages"][message.from_user.id]["Count"] += 1
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
import os
|
from pathlib import Path
|
||||||
|
|
||||||
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey
|
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey
|
||||||
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import relationship, declarative_base, sessionmaker
|
from sqlalchemy.orm import relationship, declarative_base, sessionmaker
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
basedir = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
engine = create_engine('sqlite:///' + os.path.join(basedir, 'db/db.sqlite'))
|
root = Path(__file__).parent.parent
|
||||||
|
data_folder = root / "data"
|
||||||
|
db_path = data_folder / "db.sqlite"
|
||||||
|
engine = create_engine(f'sqlite:///{db_path}')
|
||||||
|
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
Session = sessionmaker(bind=engine)
|
Session = sessionmaker(bind=engine)
|
||||||
session = Session()
|
session = Session()
|
||||||
|
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
""" Schedule holidays. """
|
""" Schedule holidays. """
|
||||||
from schedule import repeat, every, get_jobs, run_pending
|
|
||||||
import time
|
|
||||||
from threading import Thread
|
|
||||||
from datetime import datetime as dt
|
|
||||||
import csv
|
import csv
|
||||||
from .config import PYTHONCHATRU, TOKEN
|
import logging
|
||||||
from . import report
|
import time
|
||||||
|
from datetime import datetime as dt
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
from schedule import repeat, every, get_jobs, run_pending
|
||||||
from telebot import TeleBot
|
from telebot import TeleBot
|
||||||
|
|
||||||
# We need synchronous instance of bot here as we use synchronous library 'schedule' in a separate thread.
|
from .config import TOKEN, USE_REMINDER
|
||||||
bot = TeleBot(TOKEN, "HTML", disable_web_page_preview=True, allow_sending_without_reply=True)
|
from .constants import PYTHONCHATRU
|
||||||
|
from .report import create_report_text, reset_report_stats
|
||||||
|
|
||||||
|
if USE_REMINDER:
|
||||||
|
logging.debug("Starts reminder!!!")
|
||||||
|
# We need synchronous instance of bot here as we use synchronous library 'schedule' in a separate thread.
|
||||||
|
bot = TeleBot(TOKEN, "HTML", disable_web_page_preview=True, allow_sending_without_reply=True)
|
||||||
|
else:
|
||||||
|
bot = None
|
||||||
|
|
||||||
|
|
||||||
def scheduler():
|
def scheduler():
|
||||||
@@ -42,10 +50,10 @@ def remind(chat_to_repeat, today):
|
|||||||
@repeat(every().day.at("06:00"), PYTHONCHATRU)
|
@repeat(every().day.at("06:00"), PYTHONCHATRU)
|
||||||
def stat_report(chat_to_repeat):
|
def stat_report(chat_to_repeat):
|
||||||
"""Everyday group statistic info."""
|
"""Everyday group statistic info."""
|
||||||
rep = report.create_report_text(PYTHONCHATRU)
|
rep = create_report_text(PYTHONCHATRU)
|
||||||
if rep:
|
if rep:
|
||||||
bot.send_message(chat_to_repeat, rep)
|
bot.send_message(chat_to_repeat, rep)
|
||||||
report.reset_report_stats(PYTHONCHATRU)
|
reset_report_stats(PYTHONCHATRU)
|
||||||
|
|
||||||
|
|
||||||
def print_get_jobs():
|
def print_get_jobs():
|
||||||
@@ -58,4 +66,5 @@ def print_get_jobs():
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
Thread(target=scheduler).start()
|
if USE_REMINDER:
|
||||||
|
Thread(target=scheduler).start()
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import html
|
import html
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import shelve
|
import shelve
|
||||||
import os
|
|
||||||
from .config import DATA, ROLLBACK
|
from .config import ROLLBACK
|
||||||
|
from .constants import DATA
|
||||||
|
|
||||||
|
|
||||||
def create_report_text(chat_id):
|
def create_report_text(chat_id):
|
||||||
@@ -44,7 +46,7 @@ def create_report_text(chat_id):
|
|||||||
if s["Banned"]:
|
if s["Banned"]:
|
||||||
report += f"""
|
report += f"""
|
||||||
<b> Криптоидов поймано:</b> {s['Banned']}
|
<b> Криптоидов поймано:</b> {s['Banned']}
|
||||||
└ [ {s['Banned']*current_spammer_face} ]
|
└ [ {s['Banned'] * current_spammer_face} ]
|
||||||
"""
|
"""
|
||||||
return report
|
return report
|
||||||
else:
|
else:
|
||||||
@@ -52,12 +54,12 @@ def create_report_text(chat_id):
|
|||||||
|
|
||||||
|
|
||||||
def reset_report_stats(chat_id):
|
def reset_report_stats(chat_id):
|
||||||
with shelve.open(f"{DATA}{chat_id}") as s:
|
with shelve.open(f"{DATA}{chat_id}") as shelve_db:
|
||||||
s["Messages"] = {}
|
shelve_db["Messages"] = {}
|
||||||
s["Banned"] = 0
|
shelve_db["Banned"] = 0
|
||||||
s["Deleted"] = 0
|
shelve_db["Deleted"] = 0
|
||||||
return f"""Chat ID: {chat_id}
|
return f"""Chat ID: {chat_id}
|
||||||
|
|
||||||
{s['Messages']=}
|
{shelve_db['Messages']=}
|
||||||
{s['Banned']=}
|
{shelve_db['Banned']=}
|
||||||
{s['Deleted']=}"""
|
{shelve_db['Deleted']=}"""
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from telebot.async_telebot import AsyncTeleBot
|
||||||
|
|
||||||
|
from .config import TOKEN
|
||||||
|
|
||||||
|
logging.warning("[START] Stan")
|
||||||
|
bot = AsyncTeleBot(
|
||||||
|
TOKEN,
|
||||||
|
"HTML",
|
||||||
|
disable_web_page_preview=True,
|
||||||
|
allow_sending_without_reply=True,
|
||||||
|
colorful_logs=True,
|
||||||
|
)
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
from bs4 import BeautifulSoup
|
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
html = BeautifulSoup(urlopen("https://telegra.ph/pythonchatru-07-07"), "lxml")
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
from .config import RULES_URL
|
||||||
|
|
||||||
|
html = BeautifulSoup(urlopen(RULES_URL), "lxml")
|
||||||
|
|
||||||
|
|
||||||
def fetch_rule(li):
|
def fetch_rule(li):
|
||||||
@@ -4,11 +4,14 @@ import html
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
from sqlalchemy import delete
|
from sqlalchemy import delete
|
||||||
|
from telebot import types
|
||||||
|
|
||||||
from .config import bot, types
|
|
||||||
from .filters import is_white, is_nongrata
|
from .filters import is_white, is_nongrata
|
||||||
from .models import session
|
|
||||||
from .models import Quote
|
from .models import Quote
|
||||||
|
from .models import session
|
||||||
|
from .robot import bot
|
||||||
|
|
||||||
|
TYPING_TIMEOUT = 0.13 / 4 # Reading time is quarter of the same text writing time
|
||||||
|
|
||||||
|
|
||||||
def speak(chance_of, group_id):
|
def speak(chance_of, group_id):
|
||||||
@@ -20,7 +23,7 @@ def speak(chance_of, group_id):
|
|||||||
async def send_quote(after_sec, message, quote):
|
async def send_quote(after_sec, message, quote):
|
||||||
"""Pretend Reading, pretend Typing, send."""
|
"""Pretend Reading, pretend Typing, send."""
|
||||||
if message.text:
|
if message.text:
|
||||||
await asyncio.sleep(len(message.text) * 0.13 / 4) # Reading time is quarter of the same text writing time
|
await asyncio.sleep(len(message.text) * TYPING_TIMEOUT)
|
||||||
await bot.send_chat_action(message.chat.id, action="typing")
|
await bot.send_chat_action(message.chat.id, action="typing")
|
||||||
await asyncio.sleep(after_sec) # Typing time
|
await asyncio.sleep(after_sec) # Typing time
|
||||||
await bot.send_message(message.chat.id, html.escape(quote))
|
await bot.send_message(message.chat.id, html.escape(quote))
|
||||||
@@ -29,7 +32,7 @@ async def send_quote(after_sec, message, quote):
|
|||||||
async def act(message: types.Message):
|
async def act(message: types.Message):
|
||||||
quote = speak(50, message.chat.id)
|
quote = speak(50, message.chat.id)
|
||||||
if quote:
|
if quote:
|
||||||
await send_quote(len(quote) * 0.13, message, quote )
|
await send_quote(len(quote) * 0.13, message, quote)
|
||||||
|
|
||||||
|
|
||||||
@bot.message_handler(func=is_white, commands=["add"])
|
@bot.message_handler(func=is_white, commands=["add"])
|
||||||
@@ -39,8 +42,7 @@ async def add_stan_quote(message: types.Message):
|
|||||||
if quote not in [i[0] for i in session.query(Quote.text).filter(Quote.chat_id == message.chat.id).all()]:
|
if quote not in [i[0] for i in session.query(Quote.text).filter(Quote.chat_id == message.chat.id).all()]:
|
||||||
session.add(Quote(chat_id=message.chat.id, text=quote.replace("\n", " ")))
|
session.add(Quote(chat_id=message.chat.id, text=quote.replace("\n", " ")))
|
||||||
session.commit()
|
session.commit()
|
||||||
await bot.send_message(message.chat.id, "➕\n └ " + quote.replace("\n", " "),
|
await bot.send_message(message.chat.id, "➕\n └ " + quote.replace("\n", " "), parse_mode='Markdown')
|
||||||
parse_mode='Markdown')
|
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
else:
|
else:
|
||||||
await bot.send_message(message.chat.id, f"⛔️ Не добавил, есть токое\n └ {quote}", parse_mode='Markdown')
|
await bot.send_message(message.chat.id, f"⛔️ Не добавил, есть токое\n └ {quote}", parse_mode='Markdown')
|
||||||
@@ -49,13 +51,11 @@ async def add_stan_quote(message: types.Message):
|
|||||||
@bot.message_handler(func=is_white, commands=["remove"])
|
@bot.message_handler(func=is_white, commands=["remove"])
|
||||||
async def remove_stan_quote(message: types.Message):
|
async def remove_stan_quote(message: types.Message):
|
||||||
if message.reply_to_message and message.reply_to_message.text:
|
if message.reply_to_message and message.reply_to_message.text:
|
||||||
|
|
||||||
quote = message.reply_to_message.text
|
quote = message.reply_to_message.text
|
||||||
already_exist = session.query(Quote.text).filter_by(text=quote, chat_id=message.chat.id).first()
|
already_exist = session.query(Quote.text).filter_by(text=quote, chat_id=message.chat.id).first()
|
||||||
if already_exist:
|
if already_exist:
|
||||||
session.execute(delete(Quote).filter_by(text=quote, chat_id=message.chat.id))
|
session.execute(delete(Quote).filter_by(text=quote, chat_id=message.chat.id))
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
await bot.send_message(message.chat.id, f"➖ \n └ {quote}", parse_mode='Markdown')
|
await bot.send_message(message.chat.id, f"➖ \n └ {quote}", parse_mode='Markdown')
|
||||||
await bot.delete_message(message.chat.id, message.id)
|
await bot.delete_message(message.chat.id, message.id)
|
||||||
else:
|
else:
|
||||||
@@ -65,4 +65,4 @@ async def remove_stan_quote(message: types.Message):
|
|||||||
@bot.message_handler(func=is_nongrata)
|
@bot.message_handler(func=is_nongrata)
|
||||||
async def tease_nongrata(message: types.Message):
|
async def tease_nongrata(message: types.Message):
|
||||||
"""Reply to non grata mentions."""
|
"""Reply to non grata mentions."""
|
||||||
await bot.reply_to(message, f"у нас тут таких не любят")
|
await bot.reply_to(message, "у нас тут таких не любят")
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
import telebot
|
||||||
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from .commands import bot
|
||||||
|
from .config import TOKEN
|
||||||
|
|
||||||
|
logging.warning("[START] Webhook server")
|
||||||
|
app = FastAPI(docs=None, redoc_url=None)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post(f"/bot{TOKEN}/")
|
||||||
|
async def webhook(update: dict):
|
||||||
|
"""Parse POST requests from Telegram."""
|
||||||
|
if update:
|
||||||
|
update = telebot.types.Update.de_json(update)
|
||||||
|
await bot.process_new_updates([update])
|
||||||
|
else:
|
||||||
|
return None
|
||||||
Reference in New Issue
Block a user