109 lines
3.6 KiB
Python
109 lines
3.6 KiB
Python
import asyncio
|
||
import re
|
||
from datetime import datetime
|
||
|
||
from pyrogram import Client
|
||
from pyrogram.types import Message, InputMedia, InputMediaPhoto
|
||
|
||
from bot import config
|
||
from bot.loader import app1
|
||
|
||
from random import randint
|
||
|
||
|
||
NUMBER_POSTS = 20
|
||
|
||
|
||
def get_number_posts():
|
||
global NUMBER_POSTS
|
||
return NUMBER_POSTS
|
||
|
||
|
||
def set_number_posts(x: int):
|
||
global NUMBER_POSTS
|
||
NUMBER_POSTS = x
|
||
|
||
|
||
async def sending():
|
||
"""
|
||
Функция для пересылки по расписанию.
|
||
"""
|
||
await forwards_to_chats(config.rent_channel_id, config.sell_channel_id, config.groups_for_rent, get_number_posts())
|
||
# await forwards_to_chats(config.sell_channel_id, config.groups_for_sell, get_number_posts())
|
||
|
||
|
||
# contains date: client: media groups
|
||
class DailyAlbums:
|
||
todays_albums = set()
|
||
|
||
@classmethod
|
||
def add_album(cls, client: Client, media_group_id: int):
|
||
album_key = (client.api_id, datetime.now().strftime('%d.%m.%Y'), media_group_id)
|
||
cls.todays_albums.add(album_key)
|
||
|
||
@classmethod
|
||
def contains_album(cls, client: Client, media_group_id: int) -> bool:
|
||
album_key = (client.api_id, datetime.now().strftime('%d.%m.%Y'), media_group_id)
|
||
return album_key in cls.todays_albums
|
||
|
||
|
||
async def fetch_posts(chat_id: int, daily_albums: DailyAlbums, limit: int):
|
||
"""
|
||
Получает посты из чата, проверяя, что они ещё не находятся в daily_albums.
|
||
"""
|
||
posts = []
|
||
async for post in app1.get_chat_history(chat_id=chat_id, limit=200):
|
||
if post.media_group_id and post.caption and not daily_albums.contains_album(app1, post.media_group_id):
|
||
posts.append(post)
|
||
daily_albums.add_album(app1, post.media_group_id)
|
||
if len(posts) >= limit:
|
||
break
|
||
await asyncio.sleep(0.1)
|
||
return posts
|
||
|
||
|
||
async def forwards_to_chats(rent_channel_id: int, sell_channel_id: int, groups: list[str], limit: int):
|
||
"""
|
||
Пересылает посты из rent_channel_id и sell_channel_id в группы.
|
||
"""
|
||
if not groups:
|
||
return
|
||
|
||
daily_albums = DailyAlbums()
|
||
messages = await fetch_posts(rent_channel_id, daily_albums, limit)
|
||
messages2 = await fetch_posts(sell_channel_id, daily_albums, limit)
|
||
|
||
all_messages = messages + messages2
|
||
for i in range(min(limit, len(all_messages))):
|
||
await forward_post(app1, all_messages[i], groups)
|
||
await asyncio.sleep(config.spam_interval)
|
||
|
||
|
||
def is_valid_time_format(time_str):
|
||
"""Проверяют строку на формат HH:MM"""
|
||
time_pattern = re.compile(r'^[0-2][0-9]:[0-5][0-9]$')
|
||
return bool(time_pattern.match(time_str))
|
||
|
||
|
||
def check_stop_sign(message: Message):
|
||
return "⛔️" in str(message.caption) or "⛔️" in str(message.text)
|
||
|
||
|
||
async def forward_post(client: Client, message: Message, groups: list[int, str]):
|
||
# === СТОП ЗНАК ===
|
||
if check_stop_sign(message) or not (message.caption or message.text):
|
||
return
|
||
# ===============================
|
||
for spam_group in groups:
|
||
group_id, reply_id = (spam_group, None) if '_' not in str(spam_group) else list(
|
||
map(int, str(spam_group).split('_')))
|
||
try:
|
||
if message.media_group_id:
|
||
await client.copy_media_group(chat_id=group_id, from_chat_id=message.chat.id, message_id=message.id,
|
||
reply_to_message_id=reply_id)
|
||
else:
|
||
await message.copy(group_id, reply_to_message_id=reply_id)
|
||
except Exception as e:
|
||
print(f"Ошибка: {e}\n\nГруппа: {group_id}\n\n-----------------------\n\n")
|
||
await asyncio.sleep(2)
|