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)
|