async def _navigate(message: Message, user_id: int, offset=0): documents, keyboard = get_documents_range( channels, offset, filters=channels_admin_filter(user_id), nav=lambda c, o: f"{c}_admins_nav_{user_id}_{o}") if not keyboard: keyboard = Keyboard([]) for d in documents: if d.get('scheduling').get('in_queue') is True: name, channel_id = [d.get(k) for k in ("name", "channel_id")] keyboard.inline_keyboard.append([ custom_btn(f"❌ {name}", _PREFIX, ["rm", user_id, channel_id, offset]) ]) if len(keyboard.inline_keyboard) == 0: keyboard = None fmt_channels = format_documents_list(documents.rewind(), _format_channel_info) await message.edit_text( admin_of_these_channels.format(channels=fmt_channels), reply_markup=keyboard)
async def select_forward_time(_, callback_query: CallbackQuery): await callback_query.answer() channel_id, msg_id, start, end = map( int, callback_query.data.rsplit('_', 4)[1:]) time_keyboard = select_double_time_keyboard(_PREFIX, start, end, ['set', channel_id, msg_id]) fmt_text = select_time_range.format( general_start=options("time_range_start"), general_end=options("time_range_end"), start=fmt_mins(start), end=fmt_mins(end)) await callback_query.message.edit_text( fmt_text, reply_markup=Keyboard([ select_double_time_header(), *time_keyboard, [ confirm_btn(_PREFIX, ['confirm', channel_id, msg_id, start, end]) ] ]))
async def _navigate(message: Message, offset=0): documents, keyboard = get_documents_range(channels, offset) if not keyboard: keyboard = Keyboard([]) keyboard.inline_keyboard.extend([*map(list, chunk(( custom_btn(d.get("name"), _PREFIX, ['info', d.get('channel_id'), offset, 1]) for d in documents), 2))]) fmt_channels = format_documents_list(documents.rewind(), _format_channel_info) await message.edit_text(channels_list.format(channels=fmt_channels), reply_markup=keyboard)
async def settings_forward_network_delta_set(_, callback_query: CallbackQuery): await callback_query.answer() value = int(callback_query.data.rsplit('_', 1)[1]) args = callback_query.data.split('_')[1:4] time_keyboard = select_time_keyboard(_PREFIX, value, args, _DELTA_BUTTONS) fmt_text = select_network_delta.format( network_delta=fmt_time_duration(value)) await callback_query.message.edit_text( fmt_text, reply_markup=Keyboard([ *time_keyboard, [confirm_btn(_PREFIX, [*args[:-1], 'confirm', value])] ]))
async def settings_forward_time_range_set(_, callback_query: CallbackQuery): await callback_query.answer() start, end = map(int, callback_query.data.rsplit('_', 2)[1:]) args = callback_query.data.split('_')[1:4] time_keyboard = select_double_time_keyboard(_PREFIX, start, end, args) fmt_text = select_time_range.format(start=fmt_mins(start), end=fmt_mins(end)) await callback_query.message.edit_text( fmt_text, reply_markup=Keyboard([ select_double_time_header(), *time_keyboard, [confirm_btn(_PREFIX, ['forward', 'tr', 'confirm', start, end])] ]))
async def get_channel_info(client: Client, callback_query: CallbackQuery): await callback_query.answer() channel_id, back_offset, can_update_admins = map(int, callback_query.data.rsplit('_', 3)[1:]) channel = channels.find_one({"channel_id": channel_id}) if not bool(can_update_admins): administrators = filter(lambda member: not (member.user.is_deleted or member.user.is_bot), await client.get_chat_members(channel_id, filter=Filters.ADMINISTRATORS)) channels.find_one_and_update({"channel_id": channel_id}, {"$set": {"administrators": list(map(lambda m: m.user.id, administrators))}}) await callback_query.message.edit_text(_format_channel_info(channel, True), reply_markup=Keyboard([ [custom_btn(update_admins_text, _PREFIX, ['info', channel_id, back_offset, 0]) if can_update_admins else dummy_btn(cant_update_admins_text)], [custom_btn(go_back, _PREFIX, ['nav', back_offset])] ]))
def _check(): collection_filter = {"scheduling.in_queue": True} collection_sort = [("scheduling.time_to", pymongo.ASCENDING), ("last_send", pymongo.ASCENDING)] documents_number: int = channels.count_documents(collection_filter) if documents_number == 0: return start_mins, end_mins = options("time_range_start") or 0, options( "time_range_end") or MINUTES_PER_DAY datetime_now = dt.utcnow() today = datetime_now.date() start, end = map( lambda minutes: dt.combine(today, t.min) + timedelta( minutes=minutes), (start_mins, end_mins)) if not PeriodicMongoTask._can_send(start, end, datetime_now): return queue_documents: List[Dict] = list( channels.find(collection_filter, sort=collection_sort)) for document in queue_documents: scheduling = document.get('scheduling') channel_start_mins, channel_end_mins = scheduling.get( "time_from"), scheduling.get("time_to") channel_start, channel_end = map( lambda minutes: dt.combine(today, t.min) + timedelta( minutes=minutes), (channel_start_mins, channel_end_mins)) if PeriodicMongoTask._can_send(channel_start or start, channel_end or end, datetime_now): to_be_sent = document break else: return channel_id, message_id = to_be_sent.get("channel_id"), to_be_sent.get( "scheduling").get("message_id") sent_message: Union[Message, List[Message]] = telegram.forward_messages( network, channel_id, message_id) channels.update_one(to_be_sent, { "$set": { "last_send": datetime_now, "scheduling": { "in_queue": False } } }) channel_username, msg_id = sent_message.chat.username, sent_message.message_id reply_markup = None if channel_username: reply_markup = Keyboard([[ Button(go_to_the_message, url=f"https://t.me/{channel_username}/{msg_id}") ]]) for administrator_id in to_be_sent.get("administrators"): try: telegram.send_message(administrator_id, successfully_forwarded, reply_markup=reply_markup) except RPCError: pass
async def forward(_, message: Message): tg_channel = message.forward_from_chat if not tg_channel or tg_channel.type != "channel": return await message.reply_text(not_a_channel) doc_channel: Optional[Dict] = channels.find_one( {"channel_id": tg_channel.id}) if doc_channel is None: return await message.reply_text(not_part_of_the_network) try: channel_admins: List[ChatMember] = await tg_channel.get_members( filter=Filters.ADMINISTRATORS) except RPCError: return await message.reply_text(im_not_an_admin) if message.from_user.id not in map(lambda a: a.user.id, channel_admins): return await message.reply_text(youre_not_an_admin) last_send: datetime = doc_channel.get("last_send") or datetime.min delta: int = doc_channel.get("delta") or options("channels_delta") diff: timedelta = datetime.utcnow() - last_send if diff.total_seconds() < delta: return await message.reply_text( not_allowed_until.format( fmt_time(last_send + timedelta(seconds=delta)))) if doc_channel.get("scheduling").get("in_queue"): return await message.reply_text(already_in_queue) sent_message, start, end = await message.reply_text(loading), options( "time_range_start"), options("time_range_end") channel_id, msg_id = tg_channel.id, message.forward_from_message_id time_keyboard = select_double_time_keyboard(_PREFIX, start, end, ['set', channel_id, msg_id]) fmt_text = select_time_range.format( **{ k: fmt_mins(v) for k, v in { "start": start, "end": end, "general_start": start, "general_end": end }.items() }) await sent_message.edit_text( fmt_text, reply_markup=Keyboard([ select_double_time_header(), *time_keyboard, [ confirm_btn(_PREFIX, ['confirm', channel_id, msg_id, start, end]) ] ]))
async def settings_menu(_, callback_query: CallbackQuery): await callback_query.answer() await callback_query.message.edit_text(settings_text, reply_markup=Keyboard( get_settings_menu_buttons()))
async def settings(_, message: Message): await message.reply_text(settings_text, reply_markup=Keyboard( get_settings_menu_buttons()))
select_channels_delta = "\ Gli amministratori dei canali possono inviare nuovi messaggi ogni: <b>{channels_delta}</b>" not_allowed = "\ Non sei amministratore del bot" already_in_queue = "\ Spiacente, un messaggio è già in coda per l'invio." back_to_menu = "\ Torna al menu" settings_ok = lambda msg: msg.edit_text( text="Salvato", reply_markup=Keyboard([[custom_btn(back_to_menu, _PREFIX, ["menu"])]])) @telegram.on_message(filters.private & filters.command(["settings", "impostazioni"]) & custom_filters.is_admin) async def settings(_, message: Message): await message.reply_text(settings_text, reply_markup=Keyboard( get_settings_menu_buttons())) @telegram.on_callback_query(_path("menu")) async def settings_menu(_, callback_query: CallbackQuery): await callback_query.answer()