telekit 2.5.0b1__tar.gz → 2.5.0b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. {telekit-2.5.0b1 → telekit-2.5.0b2}/PKG-INFO +10 -2
  2. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/__init__.py +5 -1
  3. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chain_base.py +0 -1
  4. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_handler.py +10 -1
  5. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_init.py +2 -0
  6. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_inline_buttons.py +26 -23
  7. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_version.py +1 -1
  8. telekit-2.5.0b2/telekit/chat.py +59 -0
  9. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/debug.py +1 -0
  10. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/utils.py +22 -19
  11. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit.egg-info/PKG-INFO +10 -2
  12. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit.egg-info/SOURCES.txt +1 -0
  13. {telekit-2.5.0b1 → telekit-2.5.0b2}/LICENSE +0 -0
  14. {telekit-2.5.0b1 → telekit-2.5.0b2}/README.md +0 -0
  15. {telekit-2.5.0b1 → telekit-2.5.0b2}/setup.cfg +0 -0
  16. {telekit-2.5.0b1 → telekit-2.5.0b2}/setup.py +0 -0
  17. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_buildtext/__init__.py +0 -0
  18. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_buildtext/formatter.py +0 -0
  19. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_buildtext/styles.py +0 -0
  20. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_callback_query_handler.py +0 -0
  21. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chain.py +0 -0
  22. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chain_entry_logic.py +0 -0
  23. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chain_inline_keyboards_logic.py +0 -0
  24. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chapters/__init__.py +0 -0
  25. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_chapters/chapters.py +0 -0
  26. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_inline_keyboard.py +0 -0
  27. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_input_handler.py +0 -0
  28. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_logger.py +0 -0
  29. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_on.py +0 -0
  30. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_reply_keyboard.py +0 -0
  31. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_snapvault/__init__.py +0 -0
  32. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_snapvault/snapcode.py +0 -0
  33. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_snapvault/snapvault.py +0 -0
  34. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_state.py +0 -0
  35. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/__init__.py +0 -0
  36. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/mixin.py +0 -0
  37. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/__init__.py +0 -0
  38. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/builder.py +0 -0
  39. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/canvas_parser.py +0 -0
  40. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/lexer.py +0 -0
  41. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/nodes.py +0 -0
  42. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/parser.py +0 -0
  43. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/parser/token.py +0 -0
  44. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/telekit_dsl.py +0 -0
  45. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_telekit_dsl/telekit_orm.py +0 -0
  46. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_timeout.py +0 -0
  47. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_trait.py +0 -0
  48. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/_user.py +0 -0
  49. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/dices.py +0 -0
  50. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/__init__.py +0 -0
  51. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/__init__.py +0 -0
  52. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/calendar.py +0 -0
  53. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/complete_hotel.py +0 -0
  54. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/counter.py +0 -0
  55. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/dsl.py +0 -0
  56. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/entry.py +0 -0
  57. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/faq.py +0 -0
  58. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/hotel.py +0 -0
  59. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/on_text.py +0 -0
  60. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/pages.py +0 -0
  61. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/pyapi.py +0 -0
  62. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/qr.py +0 -0
  63. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/quiz.py +0 -0
  64. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/spells.py +0 -0
  65. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/start.py +0 -0
  66. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_handlers/text_document.py +0 -0
  67. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/example/example_server.py +0 -0
  68. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/inline_buttons.py +0 -0
  69. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/parameters.py +0 -0
  70. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/reply_buttons.py +0 -0
  71. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/scheduler.py +0 -0
  72. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/senders.py +0 -0
  73. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/server.py +0 -0
  74. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/styles.py +0 -0
  75. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/traits/__init__.py +0 -0
  76. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/traits/calendar_pick.py +0 -0
  77. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/traits/paginated_choice.py +0 -0
  78. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/traits/track_handoff_origin.py +0 -0
  79. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit/types.py +0 -0
  80. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit.egg-info/dependency_links.txt +0 -0
  81. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit.egg-info/requires.txt +0 -0
  82. {telekit-2.5.0b1 → telekit-2.5.0b2}/telekit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: telekit
3
- Version: 2.5.0b1
3
+ Version: 2.5.0b2
4
4
  Summary: Declarative, developer-friendly library for building Telegram bots
5
5
  Home-page: https://github.com/Romashkaa/telekit
6
6
  Author: romashka
@@ -477,7 +477,7 @@ It tries to make Telegram bot development easier.
477
477
 
478
478
  ---
479
479
 
480
- # Changes in version 2.5.0b1
480
+ # Changes in version 2.5.0b2
481
481
 
482
482
  ### v2.5.0`b0`
483
483
  - Added support for t-strings (PEP 750, Python 3.14+) in `TextEntity`.
@@ -493,3 +493,11 @@ It tries to make Telegram bot development easier.
493
493
  - `add_contact` — adds a `ContactButton`.
494
494
  - `add_user_link` — adds a `UserLinkButton`.
495
495
  - `add_bot_link` — adds a `BotLinkButton`.
496
+
497
+ ### v2.5.0`b2`
498
+ - Added the `escape` parameter to `telekit.utils.*`:
499
+ - `make_user_link`
500
+ - `make_bot_link`
501
+ - `Handler.handlers_dict` now excludes private handlers (classes whose names start with `_`).
502
+ - Added `Debug.duplicate_handler_warnings` to warn about duplicate handler names during initialization.
503
+ - Added `Handler.chat` object (BETA)
@@ -30,6 +30,7 @@ from ._user import User
30
30
  from ._telekit_dsl.telekit_dsl import TelekitDSL
31
31
  from ._telekit_dsl.mixin import DSLHandler, InstanceDSLHandler
32
32
  from ._logger import enable_file_logging
33
+ from .chat import Chat
33
34
 
34
35
  from . import senders
35
36
  from . import types
@@ -41,6 +42,7 @@ from . import utils
41
42
  from . import traits
42
43
  from . import debug
43
44
  from . import scheduler
45
+ from . import chat
44
46
 
45
47
  Styles = styles.Styles
46
48
 
@@ -56,11 +58,13 @@ __all__ = [
56
58
  "inline_buttons",
57
59
  "dices",
58
60
  "scheduler",
61
+ "chat",
59
62
 
60
63
  "Styles",
61
64
  "User",
62
65
 
63
- "Server",
66
+ "Server",
67
+ "Chat",
64
68
  "Chain",
65
69
  "Trait",
66
70
  "Handler",
@@ -18,7 +18,6 @@
18
18
  #
19
19
 
20
20
  # Standard library
21
- import inspect
22
21
  from typing import Callable
23
22
 
24
23
  # Third-party packages
@@ -27,8 +27,9 @@ library = logger.library
27
27
  from ._chain import Chain
28
28
  from ._callback_query_handler import CallbackQueryHandler
29
29
  from ._user import User
30
+ from .chat import Chat
30
31
  from ._on import On
31
- from . import senders
32
+ from .debug import Debug
32
33
 
33
34
  class Handler:
34
35
 
@@ -40,6 +41,7 @@ class Handler:
40
41
 
41
42
  # Instance Attributes
42
43
  user: User
44
+ chat: Chat
43
45
  chain: Chain
44
46
  message: Message
45
47
 
@@ -74,6 +76,12 @@ class Handler:
74
76
  handler.on = On(handler, bot)
75
77
  handler.init_handler()
76
78
 
79
+ if handler.__name__.startswith("_"):
80
+ continue
81
+
82
+ if handler.__name__ in cls.handlers_dict and Debug.duplicate_handler_warnings:
83
+ library.warning("Multiple handlers are named 'StartHandler'. Only the last registered handler is available through Handler.handlers_dict.")
84
+
77
85
  cls.handlers_dict[handler.__name__] = handler
78
86
 
79
87
  @classmethod
@@ -99,6 +107,7 @@ class Handler:
99
107
  def __init__(self, message: Message):
100
108
  self.message: Message = message
101
109
  self.user = User(self.message)
110
+ self.chat = Chat(self.message.chat.id, self.message.message_thread_id)
102
111
  self.new_chain()
103
112
 
104
113
  def handle(self) -> Any:
@@ -25,6 +25,7 @@ from ._inline_buttons import InlineButton
25
25
  from ._user import User
26
26
  from .senders import BaseSender
27
27
  from ._state import TelekitState
28
+ from .chat import Chat
28
29
 
29
30
  import telebot
30
31
 
@@ -33,6 +34,7 @@ __all__ = ["init"]
33
34
  def init(bot: telebot.TeleBot) -> None:
34
35
  TelekitState._init(bot)
35
36
  BaseSender._init(bot)
37
+ Chat._init(bot)
36
38
  Handler._init(bot)
37
39
  Chain._init(bot)
38
40
  InputHandler._init(bot)
@@ -166,7 +166,7 @@ class LinkButton(InlineButton):
166
166
  :param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
167
167
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
168
168
  You can also pass these as string values: "danger", "success", "primary".
169
- If omitted, an app-specific default style is used.
169
+ If omitted, an client-specific default style is used.
170
170
  :type style: `str`
171
171
 
172
172
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -197,16 +197,17 @@ class ContactButton(LinkButton):
197
197
  :type user_id: :class:`str` | :class:`int`
198
198
  :param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
199
199
  enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
200
- ``"primary"`` (blue). Defaults to the app-specific style if omitted.
200
+ ``"primary"`` (blue). Defaults to the client-specific style if omitted.
201
201
  :type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
202
202
  :param kwargs: Additional keyword arguments forwarded to
203
203
  :class:`~telekit.types.InlineKeyboardButton`.
204
204
  """
205
205
  def __init__(self, user_id: str | int, *, style: str | None | ButtonStyle = None, **kwargs):
206
- self._url = telekit.utils.make_mention(user_id)
207
-
208
- self._style = self._normalize_style(style)
209
- self._kwargs = kwargs
206
+ super().__init__(
207
+ url=telekit.utils.make_mention(user_id),
208
+ style=style,
209
+ **kwargs
210
+ )
210
211
 
211
212
  class UserLinkButton(LinkButton):
212
213
  """
@@ -221,16 +222,17 @@ class UserLinkButton(LinkButton):
221
222
  :type text: :class:`str` | ``None``
222
223
  :param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
223
224
  enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
224
- ``"primary"`` (blue). Defaults to the app-specific style if omitted.
225
+ ``"primary"`` (blue). Defaults to the client-specific style if omitted.
225
226
  :type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
226
227
  :param kwargs: Additional keyword arguments forwarded to
227
228
  :class:`~telekit.types.InlineKeyboardButton`.
228
229
  """
229
230
  def __init__(self, username: str, text: str | None = None, *, style: str | None | ButtonStyle = None, **kwargs):
230
- self._url = telekit.utils.make_user_link(username, text)
231
-
232
- self._style = self._normalize_style(style)
233
- self._kwargs = kwargs
231
+ super().__init__(
232
+ url=telekit.utils.make_user_link(username, text),
233
+ style=style,
234
+ **kwargs
235
+ )
234
236
 
235
237
  class BotLinkButton(LinkButton):
236
238
  """
@@ -245,16 +247,17 @@ class BotLinkButton(LinkButton):
245
247
  :type start: :class:`str` | ``None``
246
248
  :param style: Visual style of the button. Accepts a :class:`~telekit.types.ButtonStyle`
247
249
  enum value or its string equivalent: ``"danger"`` (red), ``"success"`` (green),
248
- ``"primary"`` (blue). Defaults to the app-specific style if omitted.
250
+ ``"primary"`` (blue). Defaults to the client-specific style if omitted.
249
251
  :type style: :class:`~telekit.types.ButtonStyle` | :class:`str` | ``None``
250
252
  :param kwargs: Additional keyword arguments forwarded to
251
253
  :class:`~telekit.types.InlineKeyboardButton`.
252
254
  """
253
255
  def __init__(self, botname: str, start: str | None = None, *, style: str | None | ButtonStyle = None, **kwargs):
254
- self._url = telekit.utils.make_bot_link(botname, start)
255
-
256
- self._style = self._normalize_style(style)
257
- self._kwargs = kwargs
256
+ super().__init__(
257
+ url=telekit.utils.make_bot_link(botname, start),
258
+ style=style,
259
+ **kwargs
260
+ )
258
261
 
259
262
  class WebAppButton(InlineButton):
260
263
  """
@@ -266,7 +269,7 @@ class WebAppButton(InlineButton):
266
269
  :param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
267
270
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
268
271
  You can also pass these as string values: "danger", "success", "primary".
269
- If omitted, an app-specific default style is used.
272
+ If omitted, an client-specific default style is used.
270
273
  :type style: `str`
271
274
 
272
275
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -295,7 +298,7 @@ class CopyTextButton(InlineButton):
295
298
  :param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
296
299
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
297
300
  You can also pass these as string values: "danger", "success", "primary".
298
- If omitted, an app-specific default style is used.
301
+ If omitted, an client-specific default style is used.
299
302
  :type style: `str`
300
303
 
301
304
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -335,7 +338,7 @@ class SuggestButton(InlineButton):
335
338
  :param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
336
339
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
337
340
  You can also pass these as string values: "danger", "success", "primary".
338
- If omitted, an app-specific default style is used.
341
+ If omitted, an client-specific default style is used.
339
342
  :type style: `str`
340
343
 
341
344
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -388,7 +391,7 @@ class CallbackButton(InlineButton):
388
391
  :param style: Style of the button. Must be one of `telekit.types.ButtonStyle.DANGER` (red),
389
392
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
390
393
  You can also pass these as string values: "danger", "success", "primary".
391
- If omitted, an app-specific default style is used.
394
+ If omitted, an client-specific default style is used.
392
395
  :type style: `str`
393
396
 
394
397
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -581,7 +584,7 @@ class AlertButton(AnswerButton):
581
584
  :param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
582
585
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
583
586
  You can also pass these as string values: "danger", "success", "primary".
584
- If omitted, an app-specific default style is used.
587
+ If omitted, an client-specific default style is used.
585
588
  :type style: `str | ButtonStyle | None`
586
589
 
587
590
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -631,7 +634,7 @@ class NotificationButton(AnswerButton):
631
634
  :param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
632
635
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
633
636
  You can also pass these as string values: "danger", "success", "primary".
634
- If omitted, an app-specific default style is used.
637
+ If omitted, an client-specific default style is used.
635
638
  :type style: `str | ButtonStyle | None`
636
639
 
637
640
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -696,7 +699,7 @@ class InvokeButton(CallbackButton):
696
699
  :param style: Style of the button. Must be one of `ButtonStyle.DANGER` (red),
697
700
  `*.SUCCESS` (green) or `*.PRIMARY` (blue).
698
701
  You can also pass these as string values: "danger", "success", "primary".
699
- If omitted, an app-specific default style is used.
702
+ If omitted, an client-specific default style is used.
700
703
  :type style: `str | ButtonStyle | None`
701
704
 
702
705
  :param kwargs: Additional keyword arguments passed directly to `InlineKeyboardButton`.
@@ -3,4 +3,4 @@
3
3
  # PyPI history: https://pypi.org/project/telekit/#history
4
4
  # ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
5
5
 
6
- __version__ = "2.5.0b1"
6
+ __version__ = "2.5.0b2"
@@ -0,0 +1,59 @@
1
+ from typing import Any
2
+
3
+ from telebot import TeleBot
4
+ from telebot.types import Message
5
+
6
+ import telekit
7
+ from telekit.styles import TextEntity, Escape, Raw, Group, Bold, Italic
8
+ from ._logger import _library
9
+
10
+ __all__ = ['Chat']
11
+
12
+ class Chat:
13
+
14
+ bot: TeleBot
15
+
16
+ @classmethod
17
+ def _init(cls, bot: TeleBot):
18
+ """
19
+ Initializes the bot instance for the class.
20
+ """
21
+ cls.bot = bot
22
+
23
+ def __init__(self, chat_id: int, thread_id: int | None = None, previous_user_message: Message | None = None) -> None:
24
+ self.id = chat_id
25
+ self.thread_id = thread_id
26
+ self.previous_user_message = previous_user_message
27
+
28
+ def _get_base_params(self) -> dict[str, Any]:
29
+ return {
30
+ "chat_id": self.id,
31
+ "parse_mode": "html",
32
+ "message_thread_id": self.thread_id
33
+ }
34
+
35
+ def answer(self, text: str | TextEntity):
36
+ """
37
+ Sends a text message to the chat.
38
+
39
+ Returns:
40
+ Message | None: The sent message or None if sending failed.
41
+ """
42
+ if not isinstance(text, TextEntity):
43
+ text = Escape(text)
44
+
45
+ try:
46
+ return self.bot.send_message(
47
+ chat_id = self.id,
48
+ message_thread_id = self.thread_id,
49
+ text = text.html,
50
+ parse_mode = "html",
51
+ )
52
+ except Exception as exception:
53
+ text.debug("html")
54
+ _library.warning(f"^^^ [chat.answer]: Failed to answer (chat_id={self.id}; thread_id={self.thread_id}): {exception}")
55
+ return None
56
+
57
+
58
+
59
+
@@ -2,6 +2,7 @@ class Debug:
2
2
  timeout_warnings: bool = False
3
3
  deletion_warnings: bool = False
4
4
  callback_query_tracing: bool = False
5
+ duplicate_handler_warnings: bool = True
5
6
 
6
7
  @classmethod
7
8
  def set_all(cls, value: bool) -> None:
@@ -322,8 +322,20 @@ def compose_keyboard(
322
322
  # Link Generating
323
323
  # ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
324
324
 
325
- def make_bot_link(botname: str, start: str | None = None) -> str:
326
- """Return a t.me link to a bot.
325
+ def make_mention(user_id: int | str) -> str:
326
+ """
327
+ Creates a Telegram mention link by user ID.
328
+
329
+ Examples::
330
+
331
+ make_mention(123456789)
332
+ >>> 'tg://user?id=123456789'
333
+ """
334
+ return f"tg://user?id={user_id}"
335
+
336
+ def make_bot_link(botname: str, start: str | None = None, escape: bool = True) -> str:
337
+ """
338
+ Return a t.me link to a bot.
327
339
 
328
340
  >>> make_bot_link("UserNameOfBot")
329
341
  "https://t.me/UserNameOfBot"
@@ -341,22 +353,12 @@ def make_bot_link(botname: str, start: str | None = None) -> str:
341
353
  botname = botname.lstrip("@")
342
354
  if start is None:
343
355
  return f"https://t.me/{botname}"
344
- encoded_start = quote(start, safe="")
356
+ encoded_start = quote(start, safe="") if escape else start
345
357
  return f"https://t.me/{botname}?start={encoded_start}"
346
358
 
347
- def make_mention(user_id: int | str) -> str:
359
+ def make_user_link(username: str, text: str | None = None, escape: bool = True) -> str:
348
360
  """
349
- Creates a Telegram mention link by user ID.
350
-
351
- Examples::
352
-
353
- make_mention(123456789)
354
- >>> 'tg://user?id=123456789'
355
- """
356
- return f"tg://user?id={user_id}"
357
-
358
- def make_user_link(username: str, text: str | None = None) -> str:
359
- """Return a t.me link to a user.
361
+ Return a t.me link to a user.
360
362
 
361
363
  >>> make_user_link("UserName")
362
364
  "https://t.me/UserName"
@@ -374,7 +376,7 @@ def make_user_link(username: str, text: str | None = None) -> str:
374
376
  username = username.lstrip("@")
375
377
  if text is None:
376
378
  return f"https://t.me/{username}"
377
- encoded_text = quote(text, safe="")
379
+ encoded_text = quote(text, safe="") if escape else text
378
380
  return f"https://t.me/{username}?text={encoded_text}"
379
381
 
380
382
  def make_qrcode(
@@ -395,7 +397,8 @@ def make_qrcode(
395
397
  caption_font_size: int | None = None,
396
398
  caption_font_color: str | None = None,
397
399
  ) -> str:
398
- """Return a QuickChart URL that renders a QR code.
400
+ """
401
+ Return a QuickChart URL that renders a QR code.
399
402
 
400
403
  >>> make_qrcode("https://example.com")
401
404
  'https://quickchart.io/qr?text=https%3A%2F%2Fexample.com'
@@ -438,9 +441,9 @@ def make_qrcode(
438
441
  if margin is not None:
439
442
  params["margin"] = margin
440
443
  if dark is not None:
441
- params["dark"] = dark
444
+ params["dark"] = dark.lstrip("#")
442
445
  if light is not None:
443
- params["light"] = light
446
+ params["light"] = light.lstrip("#")
444
447
  if ec_level is not None:
445
448
  params["ecLevel"] = ec_level
446
449
  if format is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: telekit
3
- Version: 2.5.0b1
3
+ Version: 2.5.0b2
4
4
  Summary: Declarative, developer-friendly library for building Telegram bots
5
5
  Home-page: https://github.com/Romashkaa/telekit
6
6
  Author: romashka
@@ -477,7 +477,7 @@ It tries to make Telegram bot development easier.
477
477
 
478
478
  ---
479
479
 
480
- # Changes in version 2.5.0b1
480
+ # Changes in version 2.5.0b2
481
481
 
482
482
  ### v2.5.0`b0`
483
483
  - Added support for t-strings (PEP 750, Python 3.14+) in `TextEntity`.
@@ -493,3 +493,11 @@ It tries to make Telegram bot development easier.
493
493
  - `add_contact` — adds a `ContactButton`.
494
494
  - `add_user_link` — adds a `UserLinkButton`.
495
495
  - `add_bot_link` — adds a `BotLinkButton`.
496
+
497
+ ### v2.5.0`b2`
498
+ - Added the `escape` parameter to `telekit.utils.*`:
499
+ - `make_user_link`
500
+ - `make_bot_link`
501
+ - `Handler.handlers_dict` now excludes private handlers (classes whose names start with `_`).
502
+ - Added `Debug.duplicate_handler_warnings` to warn about duplicate handler names during initialization.
503
+ - Added `Handler.chat` object (BETA)
@@ -21,6 +21,7 @@ telekit/_timeout.py
21
21
  telekit/_trait.py
22
22
  telekit/_user.py
23
23
  telekit/_version.py
24
+ telekit/chat.py
24
25
  telekit/debug.py
25
26
  telekit/dices.py
26
27
  telekit/inline_buttons.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes