예제 #1
0
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)
예제 #2
0
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])
            ]
        ]))
예제 #3
0
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)
예제 #4
0
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])]
        ]))
예제 #5
0
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])]
        ]))
예제 #6
0
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])]
    ]))
예제 #7
0
    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
예제 #8
0
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])
            ]
        ]))
예제 #9
0
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()))
예제 #10
0
async def settings(_, message: Message):
    await message.reply_text(settings_text,
                             reply_markup=Keyboard(
                                 get_settings_menu_buttons()))
예제 #11
0
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()