mirror of
https://github.com/MuRuLOSE/limoka.git
synced 2026-06-16 14:34:17 +02:00
375 lines
14 KiB
Python
375 lines
14 KiB
Python
# █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
|
||
# █▀█ █ █ █ █▀█ █▀▄ █
|
||
# © Copyright 2022
|
||
# https://t.me/hikariatama
|
||
#
|
||
# 🔒 Licensed under the GNU AGPLv3
|
||
# 🌐 https://www.gnu.org/licenses/agpl-3.0.html
|
||
|
||
# meta desc: Simplifies the interaction with @leomatchbot - Rejects slag, allows you to create filters by age, cities, blacklisted words.
|
||
# meta pic: https://static.dan.tatar/leomatch_icon.png
|
||
# meta banner: https://mods.hikariatama.ru/badges/leomatch.jpg
|
||
# meta developer: @hikarimods
|
||
# requires: russian-names
|
||
# scope: hikka_only
|
||
# scope: hikka_min 1.3.0
|
||
|
||
__version__ = (2, 0, 3)
|
||
|
||
import asyncio
|
||
import logging
|
||
import re
|
||
import time
|
||
from typing import Iterable, Optional
|
||
|
||
from russian_names import RussianNames
|
||
from telethon.tl.types import Message
|
||
|
||
from .. import loader, utils
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@loader.tds
|
||
class LeomatchMod(loader.Module):
|
||
"""Simplifies the interaction with @leomatchbot - Rejects slag, allows you to create filters by age, cities, blacklisted words. Check .config for more info"""
|
||
|
||
strings = {"name": "Leomatch"}
|
||
|
||
strings_ru = {
|
||
"_cls_doc": (
|
||
"Упрощает взаимодействие с @leomatchbot - отклоняет шлак, позволяет"
|
||
" создавать фильтры по возрасту, городам, черному списку слов. Загляни в"
|
||
" .config для подробной информации"
|
||
),
|
||
}
|
||
|
||
_last_decline = 0
|
||
_queue = []
|
||
_groups = {}
|
||
|
||
def __init__(self):
|
||
self.config = loader.ModuleConfig(
|
||
loader.ConfigValue(
|
||
"min_age",
|
||
0,
|
||
(
|
||
"Минимальный возраст собеседника - будет автоматически отклонять"
|
||
" всех, кто младше"
|
||
),
|
||
validator=loader.validators.Integer(minimum=0),
|
||
),
|
||
loader.ConfigValue(
|
||
"max_age",
|
||
100,
|
||
(
|
||
"Максимальный возраст собеседника - будет автоматически отклонять"
|
||
" всех, кто старше"
|
||
),
|
||
validator=loader.validators.Integer(minimum=0),
|
||
),
|
||
loader.ConfigValue(
|
||
"blacklist_cities",
|
||
[],
|
||
(
|
||
"Список городов, пользователи из которых будут автоматически"
|
||
" отклоняться"
|
||
),
|
||
validator=loader.validators.Series(),
|
||
),
|
||
loader.ConfigValue(
|
||
"whitelist_cities",
|
||
[],
|
||
(
|
||
"Список городов для белого списка. Пользователи из других городов"
|
||
" будут автоматически отклоняться"
|
||
),
|
||
validator=loader.validators.Series(),
|
||
),
|
||
loader.ConfigValue(
|
||
"blacklist_words",
|
||
[],
|
||
(
|
||
"Если в анкете пользователя есть слово из этого списка, она будет"
|
||
" автоматически отклонена"
|
||
),
|
||
validator=loader.validators.Series(),
|
||
),
|
||
loader.ConfigValue(
|
||
"whitelist_words",
|
||
[],
|
||
(
|
||
"Если в анкете пользователя есть нет слов из этого списка, она"
|
||
" будет автоматически отклонена"
|
||
),
|
||
validator=loader.validators.Series(),
|
||
),
|
||
loader.ConfigValue(
|
||
"decline_slag",
|
||
True,
|
||
"Отклонять ли шлак (Подпишитесь на наш ТикТок и др.)",
|
||
validator=loader.validators.Boolean(),
|
||
),
|
||
loader.ConfigValue(
|
||
"enable",
|
||
True,
|
||
"Включить ли модуль",
|
||
validator=loader.validators.Boolean(),
|
||
),
|
||
loader.ConfigValue(
|
||
"minimal_len",
|
||
0,
|
||
"Минимальное количество слов в анкете",
|
||
validator=loader.validators.Integer(minimum=0),
|
||
),
|
||
loader.ConfigValue(
|
||
"log",
|
||
True,
|
||
"Отправлять в логи информацию о причинах отклонения анкет",
|
||
validator=loader.validators.Boolean(),
|
||
),
|
||
loader.ConfigValue(
|
||
"delay",
|
||
5,
|
||
"Задержка между автоматическим отклонением анкет",
|
||
validator=loader.validators.Integer(minimum=3),
|
||
),
|
||
loader.ConfigValue(
|
||
"no_female",
|
||
False,
|
||
"Автоматически отклонять девушек",
|
||
validator=loader.validators.Boolean(),
|
||
),
|
||
loader.ConfigValue(
|
||
"no_male",
|
||
False,
|
||
"Автоматически отклонять парней",
|
||
validator=loader.validators.Boolean(),
|
||
),
|
||
)
|
||
|
||
async def client_ready(self):
|
||
names = RussianNames()
|
||
await utils.run_sync(names._fill_base)
|
||
|
||
self.female_names = map(lambda x: x.lower(), names._base["woman"]["name"])
|
||
self.male_names = map(lambda x: x.lower(), names._base["man"]["name"])
|
||
|
||
@loader.loop(interval=1, autostart=True)
|
||
async def loop(self):
|
||
if not self._queue:
|
||
return
|
||
|
||
if self._last_decline + self.config["delay"] > time.time():
|
||
await asyncio.sleep(self._last_decline + self.config["delay"] - time.time())
|
||
|
||
self._last_decline = time.time()
|
||
|
||
log, answer = self._queue.pop(0)
|
||
|
||
async with self._client.conversation(1234060895) as conv:
|
||
m = await conv.send_message(answer)
|
||
await conv.get_response()
|
||
|
||
await m.delete()
|
||
|
||
if self.config["log"] and log:
|
||
logger.info(log)
|
||
|
||
async def _decline(
|
||
self,
|
||
message: Message,
|
||
log: Optional[str] = None,
|
||
answer: Optional[str] = "👎",
|
||
):
|
||
for m in [message] + (
|
||
[m for m in self._groups[message.grouped_id]]
|
||
if message.grouped_id and message.grouped_id in self._groups
|
||
else []
|
||
):
|
||
await m.delete()
|
||
|
||
self._queue += [(log, answer)]
|
||
|
||
@staticmethod
|
||
def _in(needle: str, haystack: Iterable, alter: str) -> bool:
|
||
"""
|
||
Checks for occurence of needle in haystack using smart method
|
||
:param needle: string to search for
|
||
:param haystack: iterable to search in
|
||
:param alter: string to search in if needle is not a one word
|
||
:return: True if needle is found in haystack, False otherwise
|
||
"""
|
||
return (
|
||
True
|
||
if needle.strip().lower() in map(lambda x: x.lower().strip(), haystack)
|
||
else " " in needle and needle.strip().lower() in alter.lower()
|
||
)
|
||
|
||
@loader.watcher(chat_id=1234060895, out=True)
|
||
async def out_watcher(self, _):
|
||
if self._queue:
|
||
self._queue = []
|
||
logger.info("Останавливаюсь, т.к. ты отправил сообщение")
|
||
return
|
||
|
||
@loader.watcher("in", from_id=1234060895)
|
||
async def watcher(self, message: Message):
|
||
if not self.config["enable"]:
|
||
return
|
||
|
||
if (
|
||
"Пригласи друзей и получи больше" in message.raw_text
|
||
and "Твоя статистика" not in message.raw_text
|
||
):
|
||
self._queue = []
|
||
logger.info("Останавливаюсь, т.к. закончились доступные лайки")
|
||
return
|
||
|
||
if message.grouped_id:
|
||
self._groups.setdefault(message.grouped_id, []).append(message)
|
||
|
||
if self.config["decline_slag"] and (
|
||
(
|
||
"Подпишись на канал Дайвинчика" in message.raw_text
|
||
and "https://t.me/leoday" in message.text
|
||
)
|
||
or (
|
||
"Бот не запрашивает личные данные и не идентифицирует пользователей по"
|
||
" паспортным данным"
|
||
in message.raw_text
|
||
)
|
||
or (
|
||
"хочешь больше просмотров в TikTok?" in message.raw_text
|
||
and "tiktok.com/tag/дайвинчик" in message.raw_text
|
||
)
|
||
or (
|
||
"Пришли свое расположение и увидишь анкеты рядом с тобой"
|
||
in message.raw_text
|
||
)
|
||
):
|
||
await self._decline(
|
||
message,
|
||
"Отклонил какой-то шлак",
|
||
"Продолжить просмотр анкет",
|
||
)
|
||
return
|
||
|
||
if self.config["decline_slag"] and message.raw_text == "Это все, идем дальше?":
|
||
await self._decline(
|
||
message,
|
||
"Автоматически продолжаю просмотр анкет",
|
||
"Смотреть анкеты",
|
||
)
|
||
return
|
||
|
||
if (
|
||
message.raw_text.count(",") < 2
|
||
or message.raw_text.startswith("Кому-то понравилась твоя анкета:")
|
||
or "Отлично! Надеюсь хорошо проведете время ;) Начинай общаться"
|
||
in message.raw_text
|
||
):
|
||
return
|
||
|
||
words = re.sub(
|
||
r" {2,}",
|
||
" ",
|
||
"".join(
|
||
(
|
||
symbol
|
||
if symbol
|
||
in "abcdefghijklmnopqrstuvwxyzёйцукенгшщзхъфывапролджэячсмитьбю1234567890 "
|
||
else " "
|
||
)
|
||
for symbol in (
|
||
""
|
||
if len(message.raw_text.lower().split(",", maxsplit=2)) < 3
|
||
or "–" not in message.raw_text
|
||
else message.raw_text.lower()
|
||
.split(",", maxsplit=2)[2]
|
||
.split("–")[1]
|
||
)
|
||
),
|
||
).split()
|
||
|
||
user = (
|
||
message.raw_text.split("–")[0].strip()
|
||
if "–" in message.raw_text
|
||
else message.raw_text
|
||
)
|
||
|
||
user_name = user.split(",")[0].strip().lower()
|
||
if (
|
||
self.config["no_female"]
|
||
and user_name in self.female_names
|
||
or self.config["no_male"]
|
||
and user_name in self.male_names
|
||
):
|
||
await self._decline(message, f"{user} отклонен по несовпадению пола")
|
||
|
||
if self.config["minimal_len"] and len(list(words)) < self.config["minimal_len"]:
|
||
await self._decline(
|
||
message,
|
||
f"{user} отклонен из-за слишком короткой анкеты",
|
||
)
|
||
return
|
||
|
||
if (
|
||
self.config["blacklist_cities"]
|
||
and len(message.raw_text.split(",")) >= 3
|
||
and message.raw_text.split(",")[2].split()[0].lower().strip()
|
||
in map(lambda x: x.lower().strip(), self.config["blacklist_cities"])
|
||
):
|
||
await self._decline(
|
||
message,
|
||
f"{user} отклонен из-за наличия города в черном списке",
|
||
)
|
||
return
|
||
|
||
if (
|
||
self.config["whitelist_cities"]
|
||
and len(message.raw_text.split(",")) >= 3
|
||
and message.raw_text.split(",")[2].split()[0].lower().strip()
|
||
not in map(lambda x: x.lower().strip(), self.config["whitelist_cities"])
|
||
):
|
||
await self._decline(
|
||
message,
|
||
f"{user} отклонен из-за отсутствия города в белом списке",
|
||
)
|
||
return
|
||
|
||
if self.config["blacklist_words"] and any(
|
||
self._in(word, words, message.raw_text)
|
||
for word in self.config["blacklist_words"]
|
||
):
|
||
await self._decline(message, f"{user} отклонен из-за слов в черном списке")
|
||
return
|
||
|
||
if self.config["whitelist_words"] and not any(
|
||
self._in(word, words, message.raw_text)
|
||
for word in self.config["whitelist_words"]
|
||
):
|
||
await self._decline(
|
||
message,
|
||
f"{user} отклонен из-за отсутствия в анкете слов из белого списка",
|
||
)
|
||
return
|
||
|
||
if (
|
||
self.config["min_age"]
|
||
and len(message.raw_text.split(",")) >= 2
|
||
and message.raw_text.split(",")[1].strip().isdigit()
|
||
and int(message.raw_text.split(",")[1].strip()) < self.config["min_age"]
|
||
):
|
||
await self._decline(message, f"{user} отклонен из-за младшего возраста")
|
||
return
|
||
|
||
if (
|
||
self.config["max_age"]
|
||
and len(message.raw_text.split(",")) >= 2
|
||
and message.raw_text.split(",")[1].strip().isdigit()
|
||
and int(message.raw_text.split(",")[1].strip()) > self.config["max_age"]
|
||
):
|
||
await self._decline(message, f"{user} отклонен из-за старшего возраста")
|
||
return
|