From bd56910a19d168b7c2758dc1b874ca180c385c15 Mon Sep 17 00:00:00 2001 From: chiri <2alivemafia@gmail.com> Date: Mon, 16 Dec 2024 01:20:15 +0300 Subject: [PATCH 1/2] make `url` optional and add example for `LinkPreview` widget --- example/link_preview.py | 95 +++++++++++++++++++ .../widgets/link_preview/base.py | 5 +- 2 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 example/link_preview.py diff --git a/example/link_preview.py b/example/link_preview.py new file mode 100644 index 00000000..0ea3eed6 --- /dev/null +++ b/example/link_preview.py @@ -0,0 +1,95 @@ +from aiogram import Bot, Dispatcher +from aiogram.filters import Command +from aiogram.filters.state import State, StatesGroup +from aiogram.fsm.storage.memory import MemoryStorage +from aiogram.types import Message + +from aiogram_dialog import ( + Dialog, + DialogManager, + StartMode, + Window, + setup_dialogs, +) +from aiogram_dialog.widgets.kbd import SwitchTo +from aiogram_dialog.widgets.link_preview import LinkPreview +from aiogram_dialog.widgets.text import Const, Format + + +async def photo_getter(**_): + return {"photo_url": "https://nplus1.ru/news/2024/05/23/voyager-1-science-data"} + + +class SG(StatesGroup): + MAIN = State() + IS_DISABLED = State() + SMALL_MEDIA = State() + LARGE_MEDIA = State() + SHOW_ABOVE_TEXT = State() + + +BACK = SwitchTo(Const("back"), "_back", SG.MAIN) + + +dialog = Dialog( + Window( + Format("Default\n{photo_url}"), + SwitchTo( + Const("disable"), "_disable", SG.IS_DISABLED, + ), + SwitchTo( + Const("prefer small media"), "_prefer_small_media", SG.SMALL_MEDIA, + ), + SwitchTo( + Const("prefer large media"), "_prefer_large_media", SG.LARGE_MEDIA, + ), + SwitchTo( + Const("show above text"), "_show_above_text", SG.SHOW_ABOVE_TEXT, + ), + getter=photo_getter, + state=SG.MAIN, + ), + Window( + Format("{photo_url}"), + LinkPreview(is_disabled=True), + BACK, + state=SG.IS_DISABLED, + getter=photo_getter, + ), + Window( + Const("prefer small media"), + LinkPreview(Format("{photo_url}"), prefer_small_media=True), + BACK, + state=SG.SMALL_MEDIA, + getter=photo_getter, + ), + Window( + Const("prefer large media"), + LinkPreview(Format("{photo_url}"), prefer_large_media=True), + BACK, + state=SG.LARGE_MEDIA, + getter=photo_getter, + ), + Window( + Const("show above text"), + LinkPreview(Format("{photo_url}"), show_above_text=True), + BACK, + state=SG.SHOW_ABOVE_TEXT, + getter=photo_getter, + ), +) + +storage = MemoryStorage() +bot = Bot("token") +dp = Dispatcher(storage=storage) +dp.include_router(dialog) +setup_dialogs(dp) + + +@dp.message(Command("start")) +async def start(message: Message, dialog_manager: DialogManager): + await dialog_manager.start(SG.MAIN, mode=StartMode.RESET_STACK) + + +if __name__ == "__main__": + dp.run_polling(bot, skip_updates=True) diff --git a/src/aiogram_dialog/widgets/link_preview/base.py b/src/aiogram_dialog/widgets/link_preview/base.py index ac9f40ef..7a2fe925 100644 --- a/src/aiogram_dialog/widgets/link_preview/base.py +++ b/src/aiogram_dialog/widgets/link_preview/base.py @@ -27,7 +27,7 @@ async def _render_link_preview( class LinkPreview(LinkPreviewBase): def __init__( self, - url: TextWidget, + url: Optional[TextWidget] = None, is_disabled: bool = False, prefer_small_media: bool = False, prefer_large_media: bool = False, @@ -51,9 +51,8 @@ async def render_link_preview( async def _render_link_preview( self, data: dict, manager: DialogManager, ) -> Optional[LinkPreviewOptions]: - url = await self.url.render_text(data, manager) return LinkPreviewOptions( - url=url, + url=await self.url.render_text(data, manager) if self.url else None, is_disabled=self.is_disabled, prefer_small_media=self.prefer_small_media, prefer_large_media=self.prefer_large_media, From 22dd47b63479f12930d1f4c2cefa82d1a8b7f590 Mon Sep 17 00:00:00 2001 From: chiri <2alivemafia@gmail.com> Date: Mon, 16 Dec 2024 02:18:15 +0300 Subject: [PATCH 2/2] add docs to LinkPreview widget --- docs/conf.py | 5 +---- docs/widgets/index.rst | 8 +++++--- docs/widgets/link_preview/example.py | 27 +++++++++++++++++++++++++++ docs/widgets/link_preview/index.rst | 23 +++++++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 docs/widgets/link_preview/example.py create mode 100644 docs/widgets/link_preview/index.rst diff --git a/docs/conf.py b/docs/conf.py index 7a3178ad..c8410d17 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,13 +13,10 @@ # import os # import sys # sys.path.insert(0, os.path.abspath(".")) - -import datetime - # -- Project information ----------------------------------------------------- project = "aiogram-dialog" -copyright = f"{datetime.date.today().year}, Tishka17" +copyright = "%Y, Tishka17" author = "Tishka17" master_doc = "index" diff --git a/docs/widgets/index.rst b/docs/widgets/index.rst index c11c0664..5678ef7a 100644 --- a/docs/widgets/index.rst +++ b/docs/widgets/index.rst @@ -4,13 +4,14 @@ Widgets and Rendering Base information ******************** -Currently there are 4 kinds of widgets: :ref:`texts `, :ref:`keyboards `, -:ref:`input `, :ref:`media` and you can create your own :ref:`widgets`. +Currently there are 5 kinds of widgets: :ref:`texts `, :ref:`keyboards `, +:ref:`input `, :ref:`media`, :ref:`link preview` and you can create your own :ref:`widgets`. * **Texts** used to render text anywhere in dialog. It can be message text, button title and so on. * **Keyboards** represent parts of ``InlineKeyboard`` * **Media** represent media attachment to message * **Input** allows to process incoming messages from user. Is has no representation. +* **Link Preview** used to manage link previews in messages. Widgets can display static (e.g. ``Const``) and dynamic (e.g. ``Format``) content. To use dynamic data you have to set it. See :ref:`passing data `. @@ -37,5 +38,6 @@ Also there are 2 general types: keyboard/index input/index media/index + link_preview/index hiding/index - custom_widgets/index + custom_widgets/index \ No newline at end of file diff --git a/docs/widgets/link_preview/example.py b/docs/widgets/link_preview/example.py new file mode 100644 index 00000000..3f9bbed4 --- /dev/null +++ b/docs/widgets/link_preview/example.py @@ -0,0 +1,27 @@ +from aiogram.filters.state import State, StatesGroup + +from aiogram_dialog import Window +from aiogram_dialog.widgets.link_preview import LinkPreview +from aiogram_dialog.widgets.text import Const + + +class SG(StatesGroup): + MAIN = State() + SECOND = State() + + +window = Window( + Const("https://nplus1.ru/news/2024/05/23/voyager-1-science-data"), + LinkPreview(is_disabled=True), + state=SG.MAIN, +) + +second_window = Window( + Const("some text"), + LinkPreview( + url=Const("https://nplus1.ru/news/2024/05/23/voyager-1-science-data"), + prefer_small_media=True, + show_above_text=True, + ), + state=SG.MAIN, +) diff --git a/docs/widgets/link_preview/index.rst b/docs/widgets/link_preview/index.rst new file mode 100644 index 00000000..0c552bfc --- /dev/null +++ b/docs/widgets/link_preview/index.rst @@ -0,0 +1,23 @@ +.. _link_preview: + +LinkPreview +************* + +The **LinkPreview** widget is used to manage link previews in messages. + +Parameters: + +* ``url``: A ``TextWidget`` with URL to be used in the link preview. If not provided, the first URL found in the message will be used. +* ``is_disabled``: that controls whether the link preview is displayed. If ``True``, the preview will be disabled. +* ``prefer_small_media``: that controls if the media in the link preview should be displayed in a smaller size. Ignored if media size change is not supported. +* ``prefer_large_media``: that controls if the media in the link preview should be enlarged. Ignored if media size change is not supported. +* ``show_above_text``: that specifies whether the link preview should be displayed above the message text. If ``True``, link preview be displayed above the message text. + + +Code example: + +.. literalinclude:: ./example.py + +.. autoclass:: aiogram_dialog.widgets.link_preview.LinkPreview + :special-members: __init__ + :members: render_link_preview, _render_link_preview