Skip to content

Commit

Permalink
feat(/import): select keep custom title or not
Browse files Browse the repository at this point in the history
Signed-off-by: Rongrong <15956627+Rongronggg9@users.noreply.github.com>
Rongronggg9 committed Mar 3, 2022
1 parent 67bf87a commit f23ea49
Showing 7 changed files with 94 additions and 17 deletions.
18 changes: 17 additions & 1 deletion src/command/customization.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
from telethon import events, Button
from telethon.tl.patched import Message

from . import inner
from . import inner, misc
from .utils import command_gatekeeper, parse_sub_customization_callback_data, parse_callback_data_with_page
from src import db
from src.i18n import i18n
@@ -171,3 +171,19 @@ async def callback_activate_or_deactivate_sub(event: events.CallbackQuery.Event,
await event.answer('ERROR: ' + i18n[lang]['subscription_not_exist'], alert=True)
return
await callback_get_activate_or_deactivate_page.__wrapped__(event, activate, lang=lang, page=page)


@command_gatekeeper(only_manager=False)
async def callback_del_subs_title(event: events.CallbackQuery.Event,
*_,
**__): # callback data: del_subs_title={id_start}-{id_end}|{id_start}-{id_end}|...
user_id = event.chat_id
id_ranges_str = event.data.decode().strip().split('=')[-1].split('|')
subs = []
for id_range_str in id_ranges_str:
id_range = id_range_str.split('-')
id_start = int(id_range[0])
id_end = int(id_range[1])
subs.extend(await db.Sub.filter(user_id=user_id, id__range=(id_start, id_end)).all())
await inner.customization.del_subs_title(subs)
await misc.callback_del_buttons.__wrapped__(event)
8 changes: 8 additions & 0 deletions src/command/inner/customization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations
from typing import Union, Optional
from collections.abc import Iterable

from telethon import Button
from telethon.tl.types import KeyboardButtonCallback
@@ -194,3 +195,10 @@ async def set_sub_exhaustive_option(sub: db.Sub, option: str) -> db.Sub:
sub.style = sub.style + 1 if sub.style < valid_values[-1] else valid_values[0]
await sub.save()
return sub

async def del_subs_title(subs: Union[Iterable[db.Sub], db.Sub]) -> int:
if isinstance(subs, db.Sub):
subs = (subs,)
for sub in subs:
sub.title = None
return await db.Sub.bulk_update(subs, ['title'])
2 changes: 1 addition & 1 deletion src/command/inner/sub.py
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ async def subs(user_id: int,
feed_urls: Sequence[Union[str, tuple[str, str]]],
lang: Optional[str] = None,
bypass_url_filter: bool = False) \
-> Optional[dict[str, Union[dict[str, Union[int, str, db.Sub, None]], str]]]:
-> Optional[dict[str, Union[tuple[dict[str, Union[int, str, db.Sub, None]], ...], str, int]]]:
if not feed_urls:
return None

21 changes: 15 additions & 6 deletions src/command/misc.py
Original file line number Diff line number Diff line change
@@ -57,12 +57,6 @@ async def cmd_version(event: Union[events.NewMessage.Event, Message], *_, **__):
await event.respond(env.VERSION)


# bypassing command gatekeeper
async def callback_null(event: events.CallbackQuery.Event): # callback data = null
await event.answer(cache_time=3600)
raise events.StopPropagation


@command_gatekeeper(only_manager=False)
async def callback_cancel(event: events.CallbackQuery.Event,
*_,
@@ -85,3 +79,18 @@ async def callback_get_group_migration_help(event: events.CallbackQuery.Event,
return
msg, buttons = get_group_migration_help_msg(lang)
await event.edit(msg, buttons=buttons, parse_mode='html')


# bypassing command gatekeeper
async def callback_null(event: events.CallbackQuery.Event): # callback data = null
await event.answer(cache_time=3600)
raise events.StopPropagation


@command_gatekeeper(only_manager=False)
async def callback_del_buttons(event: events.CallbackQuery.Event,
*_,
**__): # callback data = del_buttons
msg = await event.get_message()
await event.answer(cache_time=3600)
await msg.edit(buttons=None)
51 changes: 45 additions & 6 deletions src/command/opml.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
from telethon.tl import types
from telethon.tl.patched import Message

from src import env
from src import env, db
from src.i18n import i18n
from . import inner
from .utils import command_gatekeeper, logger, send_success_and_failure_msg
@@ -33,26 +33,65 @@ async def cmd_export(event: Union[events.NewMessage.Event, Message], *_, lang: O

@command_gatekeeper(only_manager=False, timeout=300)
async def opml_import(event: Union[events.NewMessage.Event, Message], *_, lang: Optional[str] = None, **__):
user_id = event.chat_id
reply_message: Message = await event.get_reply_message()
if not (event.is_private or event.is_channel and not event.is_group) and reply_message.sender_id != env.bot_id:
return # must reply to the bot in a group to import opml
try:
opml_file = await event.download_media(file=bytes)
except Exception as e:
await event.reply('ERROR: ' + i18n[lang]['fetch_file_failed'])
logger.warning(f'Failed to get opml file from {event.chat_id}: ', exc_info=e)
logger.warning(f'Failed to get opml file from {user_id}: ', exc_info=e)
return

reply: Message = await event.reply(i18n[lang]['processing'] + '\n' + i18n[lang]['opml_import_processing'])
logger.info(f'Got an opml file from {event.chat_id}')
logger.info(f'Got an opml file from {user_id}')

opml_d = listparser.parse(opml_file.decode())
if not opml_d.feeds:
await reply.edit('ERROR: ' + i18n[lang]['opml_parse_error'])
return

import_result = await inner.sub.subs(event.chat_id,
import_result = await inner.sub.subs(user_id,
tuple((feed.url, feed.title) for feed in opml_d.feeds),
lang=lang)
logger.info(f'Imported feed(s) for {event.chat_id}')
await send_success_and_failure_msg(reply, **import_result, lang=lang, edit=True)
logger.info(f'Imported feed(s) for {user_id}')
msg = await send_success_and_failure_msg(reply, **import_result, lang=lang, edit=True)

subs = tuple(sub_d['sub'] for sub_d in import_result['sub_d_l'] if sub_d['sub'])
if subs:
if not sum(sub.title is not None for sub in subs):
return # no subscription set custom title
sub_ids: list[int] = sorted(sub.id for sub in subs if sub.id)
sub_ranges: list[tuple[int, int]] = []
curr_start = sub_ids[0]
while sub_ids:
curr_id = sub_ids.pop(0)
if not sub_ids:
sub_ranges.append((curr_start if curr_start else curr_id, curr_id))
break
next_id = sub_ids[0]
if next_id == curr_id + 1 or next_id == curr_id:
continue
elif sum(sub.title is not None for sub in subs
if sub.id in range(curr_start, curr_id + 1)): # if any sub has custom title
subs_between_w_title_count = await db.Sub.filter(user_id=user_id,
id__in=(curr_id + 1, next_id - 1),
title__not_isnull=True).count()
if not subs_between_w_title_count:
continue
sub_ranges.append((curr_start, curr_id))
curr_start = next_id
else:
curr_start = next_id

if not sub_ranges:
return # no subscription set custom title

button_data = f'del_subs_title=' + '|'.join(f'{start}-{end}' for start, end in sub_ranges)
if len(button_data) <= 64: # Telegram API limit
button = [
[Button.inline(i18n[lang]['delete_subs_title_button'], button_data)],
[Button.inline(i18n[lang]['keep_subs_title_button'], 'del_buttons')],
]
await msg.edit(text=msg.text, buttons=button)
7 changes: 4 additions & 3 deletions src/command/utils.py
Original file line number Diff line number Diff line change
@@ -491,7 +491,7 @@ async def send_success_and_failure_msg(message: Union[Message, events.NewMessage
*_,
lang: Optional[str] = None,
edit: bool = False,
**__):
**__) -> Union[Message, events.NewMessage.Event, events.CallbackQuery.Event]:
for i in range(4):
success_msg_short = (
success_msg.split('\n', 1)[0] + '\n'
@@ -531,8 +531,9 @@ async def send_success_and_failure_msg(message: Union[Message, events.NewMessage
)

try:
await (message.edit(msg_html, parse_mode='html') if edit else message.respond(msg_html, parse_mode='html'))
return
msg = await (message.edit(msg_html, parse_mode='html') if edit
else message.respond(msg_html, parse_mode='html'))
return msg if msg is not None else message
except (EntitiesTooLongError, MessageTooLongError) as e:
if i < 3:
continue
4 changes: 4 additions & 0 deletions telegramRSSbot.py
Original file line number Diff line number Diff line change
@@ -132,6 +132,8 @@ async def pre():
bot.add_event_handler(command.administration.cmd_set_option,
events.NewMessage(pattern='/set_option'))
# callback query handler
bot.add_event_handler(command.misc.callback_del_buttons, # delete buttons
events.CallbackQuery(data='del_buttons'))
bot.add_event_handler(command.misc.callback_null, # null callback query
events.CallbackQuery(data='null'))
bot.add_event_handler(command.misc.callback_cancel,
@@ -166,6 +168,8 @@ async def pre():
events.CallbackQuery(pattern=r'^set(=\d+(,\w+(,\w+)?)?)?(\|\d+)?$'))
bot.add_event_handler(command.customization.cmd_set_or_callback_get_set_page,
events.CallbackQuery(pattern=r'^get_set_page|\d+$'))
bot.add_event_handler(command.customization.callback_del_subs_title,
events.CallbackQuery(pattern=r'^del_subs_title=(\d+-\d+\|)*(\d+-\d+)$'))
# being added to a group handler
bot.add_event_handler(command.misc.cmd_start,
command.utils.AddedToGroupAction())

0 comments on commit f23ea49

Please sign in to comment.