telekit 2.5.0b3__tar.gz → 2.5.1__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.
- {telekit-2.5.0b3 → telekit-2.5.1}/PKG-INFO +29 -23
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_handler.py +1 -1
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_version.py +1 -1
- telekit-2.5.1/telekit/chat.py +101 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/on_text.py +20 -15
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/traits/calendar_pick.py +180 -195
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/utils.py +176 -111
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit.egg-info/PKG-INFO +29 -23
- telekit-2.5.0b3/telekit/chat.py +0 -59
- {telekit-2.5.0b3 → telekit-2.5.1}/LICENSE +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/README.md +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/setup.cfg +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/setup.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_buildtext/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_buildtext/formatter.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_buildtext/styles.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_callback_query_handler.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chain.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chain_base.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chain_entry_logic.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chain_inline_keyboards_logic.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chapters/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_chapters/chapters.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_init.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_inline_buttons.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_inline_keyboard.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_input_handler.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_logger.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_on.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_reply_keyboard.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_snapvault/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_snapvault/snapcode.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_snapvault/snapvault.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_state.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/mixin.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/builder.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/canvas_parser.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/lexer.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/nodes.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/parser.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/parser/token.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/telekit_dsl.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_telekit_dsl/telekit_orm.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_text_builder.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_timeout.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_trait.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/_user.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/debug.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/dices.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/article.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/calendar.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/complete_hotel.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/counter.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/dsl.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/entry.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/faq.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/hotel.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/pages.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/pyapi.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/qr.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/quiz.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/spells.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/start.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/style.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_handlers/text_document.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/example/example_server.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/html_text.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/inline_buttons.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/parameters.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/reply_buttons.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/scheduler.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/senders.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/server.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/styles.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/traits/__init__.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/traits/paginated_choice.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/traits/paginated_text.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/traits/track_handoff_origin.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit/types.py +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit.egg-info/SOURCES.txt +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit.egg-info/dependency_links.txt +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/telekit.egg-info/requires.txt +0 -0
- {telekit-2.5.0b3 → telekit-2.5.1}/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.
|
|
3
|
+
Version: 2.5.1
|
|
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,30 +477,13 @@ It tries to make Telegram bot development easier.
|
|
|
477
477
|
|
|
478
478
|
---
|
|
479
479
|
|
|
480
|
-
# Changes in version 2.5.
|
|
480
|
+
# Changes in version 2.5.1
|
|
481
481
|
|
|
482
|
-
### v2.5.
|
|
483
|
-
-
|
|
484
|
-
|
|
485
|
-
### v2.5.0`b1`
|
|
486
|
-
- Added `Sender.send_message` method.
|
|
487
|
-
- Added `utils.make_mention` utility for generating `tg://user?id=` mention links.
|
|
488
|
-
- Added new inline button types to `inline_buttons`:
|
|
489
|
-
- `ContactButton` — mentions a user by Telegram ID via `tg://user?id=`.
|
|
490
|
-
- `UserLinkButton` — opens a user profile by username; supports pre-filled message text.
|
|
491
|
-
- `BotLinkButton` — opens a bot by username; supports deep-link `?start=` payload.
|
|
492
|
-
- Added new methods to `InlineKeyboard`:
|
|
493
|
-
- `add_contact` — adds a `ContactButton`.
|
|
494
|
-
- `add_user_link` — adds a `UserLinkButton`.
|
|
495
|
-
- `add_bot_link` — adds a `BotLinkButton`.
|
|
482
|
+
### v2.5.1 `(bug-fix)`
|
|
483
|
+
- Implement `TelegramMarkdownV2Sanitizer` for improved `MarkdownV2` handling
|
|
496
484
|
|
|
497
|
-
### v2.5.0`
|
|
498
|
-
-
|
|
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)
|
|
485
|
+
### v2.5.0 `(final)`
|
|
486
|
+
- Refactor `CalendarPick` trait to use `set_keyboard`
|
|
504
487
|
|
|
505
488
|
### v2.5.0`b3`
|
|
506
489
|
- Added `utils.Markers` class
|
|
@@ -513,3 +496,26 @@ It tries to make Telegram bot development easier.
|
|
|
513
496
|
- Added styles to `telekit.types`
|
|
514
497
|
- Added `utils.CyclicList`
|
|
515
498
|
- Fixed `_answer_callback_query` to always call `bot.answer_callback_query()`, even without a popup text
|
|
499
|
+
|
|
500
|
+
### v2.5.0`b2`
|
|
501
|
+
- Added the `escape` parameter to `telekit.utils.*`:
|
|
502
|
+
- `make_user_link`
|
|
503
|
+
- `make_bot_link`
|
|
504
|
+
- `Handler.handlers_dict` now excludes private handlers (classes whose names start with `_`).
|
|
505
|
+
- Added `Debug.duplicate_handler_warnings` to warn about duplicate handler names during initialization.
|
|
506
|
+
- Added `Handler.chat` object (BETA)
|
|
507
|
+
|
|
508
|
+
### v2.5.0`b1`
|
|
509
|
+
- Added `Sender.send_message` method.
|
|
510
|
+
- Added `utils.make_mention` utility for generating `tg://user?id=` mention links.
|
|
511
|
+
- Added new inline button types to `inline_buttons`:
|
|
512
|
+
- `ContactButton` — mentions a user by Telegram ID via `tg://user?id=`.
|
|
513
|
+
- `UserLinkButton` — opens a user profile by username; supports pre-filled message text.
|
|
514
|
+
- `BotLinkButton` — opens a bot by username; supports deep-link `?start=` payload.
|
|
515
|
+
- Added new methods to `InlineKeyboard`:
|
|
516
|
+
- `add_contact` — adds a `ContactButton`.
|
|
517
|
+
- `add_user_link` — adds a `UserLinkButton`.
|
|
518
|
+
- `add_bot_link` — adds a `BotLinkButton`.
|
|
519
|
+
|
|
520
|
+
### v2.5.0`b0`
|
|
521
|
+
- Added support for t-strings (PEP 750, Python 3.14+) in `TextEntity`.
|
|
@@ -107,7 +107,7 @@ class Handler:
|
|
|
107
107
|
def __init__(self, message: Message):
|
|
108
108
|
self.message: Message = message
|
|
109
109
|
self.user = User(self.message)
|
|
110
|
-
self.chat = Chat(self.message.chat.id, self.message.message_thread_id)
|
|
110
|
+
self.chat = Chat(self.message.chat.id, self.message.message_thread_id, self.message)
|
|
111
111
|
self.new_chain()
|
|
112
112
|
|
|
113
113
|
def handle(self) -> Any:
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from telebot import TeleBot
|
|
3
|
+
from telebot.types import Message, ReplyParameters
|
|
4
|
+
from telekit.styles import TextEntity, Escape
|
|
5
|
+
from ._logger import _library
|
|
6
|
+
|
|
7
|
+
__all__ = ['Chat']
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Chat:
|
|
11
|
+
bot: TeleBot
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def _init(cls, bot: TeleBot) -> None:
|
|
15
|
+
cls.bot = bot
|
|
16
|
+
|
|
17
|
+
def __init__(self, chat_id: int, thread_id: int | None = None, initial_user_message: Message | None = None) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Represents a chat (or a specific thread within a chat) that messages can be sent to.
|
|
20
|
+
|
|
21
|
+
:param chat_id: The Telegram chat ID.
|
|
22
|
+
:param thread_id: The message thread ID, if the chat is a forum topic.
|
|
23
|
+
Defaults to ``None``.
|
|
24
|
+
:param initial_user_message: The original user message that triggered this chat context,
|
|
25
|
+
used as the target for :meth:`reply`. Defaults to ``None``.
|
|
26
|
+
"""
|
|
27
|
+
self.id = chat_id
|
|
28
|
+
self.thread_id = thread_id
|
|
29
|
+
self.initial_user_message = initial_user_message
|
|
30
|
+
|
|
31
|
+
def _get_base_params(self) -> dict[str, Any]:
|
|
32
|
+
"""
|
|
33
|
+
Builds the base set of parameters shared by outgoing requests.
|
|
34
|
+
|
|
35
|
+
:return: A dictionary with ``chat_id``, ``parse_mode``, and ``message_thread_id``.
|
|
36
|
+
:rtype: dict[str, Any]
|
|
37
|
+
"""
|
|
38
|
+
return {
|
|
39
|
+
"chat_id": self.id,
|
|
40
|
+
"parse_mode": "html",
|
|
41
|
+
"message_thread_id": self.thread_id
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def answer(self, text: str | TextEntity):
|
|
45
|
+
"""
|
|
46
|
+
Sends a simple text message to the chat.
|
|
47
|
+
|
|
48
|
+
:param text: The message content. Plain strings are HTML-escaped automatically;
|
|
49
|
+
pass a ``TextEntity`` (e.g. ``Bold``, ``Italic``) for custom formatting.
|
|
50
|
+
:return: The sent message, or ``None`` if sending failed.
|
|
51
|
+
:rtype: Message | None
|
|
52
|
+
"""
|
|
53
|
+
if not isinstance(text, TextEntity):
|
|
54
|
+
text = Escape(text)
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
return self.bot.send_message(
|
|
58
|
+
chat_id = self.id,
|
|
59
|
+
message_thread_id = self.thread_id,
|
|
60
|
+
text = text.html,
|
|
61
|
+
parse_mode = "html",
|
|
62
|
+
)
|
|
63
|
+
except Exception as exception:
|
|
64
|
+
text.debug("html")
|
|
65
|
+
_library.warning(f"^^^ [chat.answer]: Failed to send message (chat_id={self.id}; thread_id={self.thread_id}): {exception}")
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
def reply(self, text: str | TextEntity):
|
|
69
|
+
"""
|
|
70
|
+
Sends a simple text message to the chat as a reply to the user's initial message.
|
|
71
|
+
|
|
72
|
+
:param text: The message content. Plain strings are HTML-escaped automatically;
|
|
73
|
+
pass a ``TextEntity`` (e.g. ``Bold``, ``Italic``) for custom formatting.
|
|
74
|
+
:return: The sent message, or ``None`` if sending failed.
|
|
75
|
+
:rtype: Message | None
|
|
76
|
+
"""
|
|
77
|
+
if not isinstance(text, TextEntity):
|
|
78
|
+
text = Escape(text)
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
return self.bot.send_message(
|
|
82
|
+
chat_id = self.id,
|
|
83
|
+
message_thread_id = self.thread_id,
|
|
84
|
+
text = text.html,
|
|
85
|
+
parse_mode = "html",
|
|
86
|
+
reply_parameters = self._get_reply_parameters()
|
|
87
|
+
)
|
|
88
|
+
except Exception as exception:
|
|
89
|
+
text.debug("html")
|
|
90
|
+
_library.warning(f"^^^ [chat.reply]: Failed to send message (chat_id={self.id}; thread_id={self.thread_id}, reply_parameters={self._get_reply_parameters()}): {exception}")
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
def _get_reply_parameters(self) -> ReplyParameters | None:
|
|
94
|
+
"""
|
|
95
|
+
Builds reply parameters pointing to the initial user message, if any.
|
|
96
|
+
|
|
97
|
+
:return: ``ReplyParameters`` referencing :attr:`initial_user_message`, or ``None``
|
|
98
|
+
if no initial message was provided.
|
|
99
|
+
:rtype: ReplyParameters | None
|
|
100
|
+
"""
|
|
101
|
+
return ReplyParameters(self.initial_user_message.message_id) if self.initial_user_message else None
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import telekit
|
|
2
2
|
|
|
3
3
|
from telekit.styles import *
|
|
4
|
+
from telekit.types import TextBuilder
|
|
4
5
|
|
|
5
6
|
class OnTextHandler(telekit.Handler):
|
|
6
7
|
|
|
@@ -16,7 +17,14 @@ class OnTextHandler(telekit.Handler):
|
|
|
16
17
|
cls.on.text().invoke(cls.handle)
|
|
17
18
|
|
|
18
19
|
cls.on.command("on_text").invoke(cls.handle)
|
|
19
|
-
|
|
20
|
+
|
|
21
|
+
EXAMPLES = [
|
|
22
|
+
"Name: John. Age: 25",
|
|
23
|
+
"My name is Alice and I am 30 years old",
|
|
24
|
+
"My name is Romashka",
|
|
25
|
+
"I'm 18 years old"
|
|
26
|
+
]
|
|
27
|
+
|
|
20
28
|
# ------------------------------------------
|
|
21
29
|
# Handling Logic
|
|
22
30
|
# ------------------------------------------
|
|
@@ -29,7 +37,7 @@ class OnTextHandler(telekit.Handler):
|
|
|
29
37
|
if not age:
|
|
30
38
|
age = "An unknown number of"
|
|
31
39
|
|
|
32
|
-
self.chain.sender.set_title(
|
|
40
|
+
self.chain.sender.set_title("👋 Hello, ", Italic(name), "!")
|
|
33
41
|
self.chain.sender.set_message(Italic(age), " years is a wonderful stage of life!")
|
|
34
42
|
self.chain.disable_timeout_warnings()
|
|
35
43
|
self.chain.send()
|
|
@@ -37,23 +45,20 @@ class OnTextHandler(telekit.Handler):
|
|
|
37
45
|
# command
|
|
38
46
|
|
|
39
47
|
def handle(self):
|
|
40
|
-
|
|
41
|
-
self.chain.sender.set_message(
|
|
42
|
-
"Try sending any of these example phrases to see the handler in action:\n\n"
|
|
48
|
+
reply = TextBuilder()
|
|
43
49
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"-
|
|
50
|
+
reply.add_bold("💡 Try sending any of these example phrases to see the", Code("on.text"), "in action:", sep=" ")
|
|
51
|
+
reply.spacer()
|
|
52
|
+
for example in self.EXAMPLES:
|
|
53
|
+
reply.add("-", Code(example), sep=" ")
|
|
54
|
+
reply.newln()
|
|
55
|
+
reply.newln()
|
|
56
|
+
reply.add("The bot will respond according to the information you provide")
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
)
|
|
58
|
+
self.chain.sender.set_text(reply)
|
|
51
59
|
self.chain.set_entry_suggestions(
|
|
52
60
|
{
|
|
53
|
-
|
|
54
|
-
"2": "My name is Alice and I am 30 years old",
|
|
55
|
-
"3": "My name is Romashka",
|
|
56
|
-
"4": "I'm 18 years old"
|
|
61
|
+
str(i + 1): example for i, example in enumerate(self.EXAMPLES)
|
|
57
62
|
}, row_width=4
|
|
58
63
|
)
|
|
59
64
|
self.chain.edit()
|