mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Update util.py
- Removed function `unix_time` - Added function `escape` - Added function `user_link` - Added function `quick_markup` - Added some type hints
This commit is contained in:
parent
9a6ddce8df
commit
ed5e5e5077
121
telebot/util.py
121
telebot/util.py
@ -6,10 +6,11 @@ import threading
|
|||||||
import traceback
|
import traceback
|
||||||
import warnings
|
import warnings
|
||||||
import functools
|
import functools
|
||||||
import time
|
from typing import Any, List, Dict
|
||||||
|
|
||||||
import queue as Queue
|
import queue as Queue
|
||||||
import logging
|
import logging
|
||||||
|
from telebot import types
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
@ -187,7 +188,7 @@ def pil_image_to_file(image, extension='JPEG', quality='web_low'):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError('PIL module is not imported')
|
raise RuntimeError('PIL module is not imported')
|
||||||
|
|
||||||
def is_command(text):
|
def is_command(text: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if `text` is a command. Telegram chat commands start with the '/' character.
|
Checks if `text` is a command. Telegram chat commands start with the '/' character.
|
||||||
:param text: Text to check.
|
:param text: Text to check.
|
||||||
@ -197,7 +198,7 @@ def is_command(text):
|
|||||||
return text.startswith('/')
|
return text.startswith('/')
|
||||||
|
|
||||||
|
|
||||||
def extract_command(text):
|
def extract_command(text: str) -> str:
|
||||||
"""
|
"""
|
||||||
Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
|
Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
|
||||||
If `text` is not a command, this function returns None.
|
If `text` is not a command, this function returns None.
|
||||||
@ -215,26 +216,24 @@ def extract_command(text):
|
|||||||
return text.split()[0].split('@')[0][1:] if is_command(text) else None
|
return text.split()[0].split('@')[0][1:] if is_command(text) else None
|
||||||
|
|
||||||
|
|
||||||
def unix_time(seconds=0, minutes=0, hours=0, days=0):
|
def extract_arguments(text: str) -> str:
|
||||||
"""
|
"""
|
||||||
Returns UNIX time + given paramenters
|
Returns the argument after the command.
|
||||||
This is useful to restrict or kick a chat member. Just use it as parameter `until_date`.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
bot.kick_chat_member(chat_id, user_id, until_date=unix_time(days=1)): bans a chat member for 1 day
|
|
||||||
bot.kick_chat_member(chat_id, user_id, until_date=unix_time(seconds=45)): bans a chat member for 45 seconds
|
|
||||||
|
|
||||||
:param seconds: how many seconds from now
|
Examples:
|
||||||
:param minutes: how many minutes from now
|
extract_arguments("/get name"): 'name'
|
||||||
:param hours: how many hours from now
|
extract_arguments("/get"): ''
|
||||||
:param days: how many days from now
|
extract_arguments("/get@botName name"): 'name'
|
||||||
:return: UNIX time
|
|
||||||
|
:param text: String to extract the arguments from a command
|
||||||
|
:return: the arguments if `text` is a command (according to is_command), else None.
|
||||||
"""
|
"""
|
||||||
t = seconds + (60 * minutes) + (3600 * hours) + (86400 * days)
|
regexp = re.compile(r"/\w*(@\w*)*\s*([\s\S]*)",re.IGNORECASE)
|
||||||
return (int(t + time.time()))
|
result = regexp.match(text)
|
||||||
|
return result.group(2) if is_command(text) else None
|
||||||
|
|
||||||
|
|
||||||
def split_string(text, chars_per_string):
|
def split_string(text: str, chars_per_string: int) -> List[str]:
|
||||||
"""
|
"""
|
||||||
Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
|
Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
|
||||||
This is very useful for splitting one giant message into multiples.
|
This is very useful for splitting one giant message into multiples.
|
||||||
@ -246,7 +245,7 @@ def split_string(text, chars_per_string):
|
|||||||
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
|
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
|
||||||
|
|
||||||
|
|
||||||
def smart_split(text, chars_per_string=MAX_MESSAGE_LENGTH):
|
def smart_split(text: str, chars_per_string: int=MAX_MESSAGE_LENGTH) -> List[str]:
|
||||||
f"""
|
f"""
|
||||||
Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
|
Splits one string into multiple strings, with a maximum amount of `chars_per_string` characters per string.
|
||||||
This is very useful for splitting one giant message into multiples.
|
This is very useful for splitting one giant message into multiples.
|
||||||
@ -257,7 +256,7 @@ def smart_split(text, chars_per_string=MAX_MESSAGE_LENGTH):
|
|||||||
:param chars_per_string: The number of maximum characters per part the text is split to.
|
:param chars_per_string: The number of maximum characters per part the text is split to.
|
||||||
:return: The splitted text as a list of strings.
|
:return: The splitted text as a list of strings.
|
||||||
"""
|
"""
|
||||||
def _text_before_last(substr):
|
def _text_before_last(substr: str) -> str:
|
||||||
return substr.join(part.split(substr)[:-1]) + substr
|
return substr.join(part.split(substr)[:-1]) + substr
|
||||||
|
|
||||||
if chars_per_string > MAX_MESSAGE_LENGTH: chars_per_string = MAX_MESSAGE_LENGTH
|
if chars_per_string > MAX_MESSAGE_LENGTH: chars_per_string = MAX_MESSAGE_LENGTH
|
||||||
@ -277,6 +276,72 @@ def smart_split(text, chars_per_string=MAX_MESSAGE_LENGTH):
|
|||||||
parts.append(part)
|
parts.append(part)
|
||||||
text = text[len(part):]
|
text = text[len(part):]
|
||||||
|
|
||||||
|
|
||||||
|
def escape(text: str) -> str:
|
||||||
|
"""
|
||||||
|
Replaces the following chars in `text` ('&' with '&', '<' with '<' and '>' with '>').
|
||||||
|
|
||||||
|
:param text: the text to escape
|
||||||
|
:return: the escaped text
|
||||||
|
"""
|
||||||
|
chars = {"&": "&", "<": "<", ">": ">"}
|
||||||
|
for old, new in chars.items(): text = text.replace(old, new)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def user_link(user: types.User, include_id: bool=False) -> str:
|
||||||
|
"""
|
||||||
|
Returns an HTML user link. This is useful for reports.
|
||||||
|
Attention: Don't forget to set parse_mode to 'HTML'!
|
||||||
|
|
||||||
|
Example:
|
||||||
|
bot.send_message(your_user_id, user_link(message.from_user) + ' startet the bot!', parse_mode='HTML')
|
||||||
|
|
||||||
|
:param user: the user (not the user_id)
|
||||||
|
:param include_id: include the user_id
|
||||||
|
:return: HTML user link
|
||||||
|
"""
|
||||||
|
name = escape(user.first_name)
|
||||||
|
return (f"<a href='tg://user?id={user.id}'>{name}</a>"
|
||||||
|
+ f" (<pre>{user.id}</pre>)" if include_id else "")
|
||||||
|
|
||||||
|
|
||||||
|
def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.InlineKeyboardMarkup:
|
||||||
|
"""
|
||||||
|
Returns a reply markup from a dict in this format: {'text': kwargs}
|
||||||
|
This is useful to avoid always typing 'btn1 = InlineKeyboardButton(...)' 'btn2 = InlineKeyboardButton(...)'
|
||||||
|
|
||||||
|
Example:
|
||||||
|
quick_markup({
|
||||||
|
'Twitter': {'url': 'https://twitter.com'},
|
||||||
|
'Facebook': {'url': 'https://facebook.com'},
|
||||||
|
'Back': {'callback_data': 'whatever'}
|
||||||
|
}, row_width=2):
|
||||||
|
returns an InlineKeyboardMarkup with two buttons in a row, one leading to Twitter, the other to facebook
|
||||||
|
and a back button below
|
||||||
|
|
||||||
|
kwargs can be:
|
||||||
|
{
|
||||||
|
'url': None,
|
||||||
|
'callback_data': None,
|
||||||
|
'switch_inline_query': None,
|
||||||
|
'switch_inline_query_current_chat': None,
|
||||||
|
'callback_game': None,
|
||||||
|
'pay': None,
|
||||||
|
'login_url': None
|
||||||
|
}
|
||||||
|
|
||||||
|
:param values: a dict containing all buttons to create in this format: {text: kwargs} {str:}
|
||||||
|
:return: InlineKeyboardMarkup
|
||||||
|
"""
|
||||||
|
markup = types.InlineKeyboardMarkup(row_width=row_width)
|
||||||
|
buttons = []
|
||||||
|
for text, kwargs in values.items():
|
||||||
|
buttons.append(types.InlineKeyboardButton(text=text, **kwargs))
|
||||||
|
markup.add(*buttons)
|
||||||
|
return markup
|
||||||
|
|
||||||
|
|
||||||
# CREDITS TO http://stackoverflow.com/questions/12317940#answer-12320352
|
# CREDITS TO http://stackoverflow.com/questions/12317940#answer-12320352
|
||||||
def or_set(self):
|
def or_set(self):
|
||||||
self._set()
|
self._set()
|
||||||
@ -317,22 +382,6 @@ def OrEvent(*events):
|
|||||||
changed()
|
changed()
|
||||||
return or_event
|
return or_event
|
||||||
|
|
||||||
def extract_arguments(text):
|
|
||||||
"""
|
|
||||||
Returns the argument after the command.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
extract_arguments("/get name"): 'name'
|
|
||||||
extract_arguments("/get"): ''
|
|
||||||
extract_arguments("/get@botName name"): 'name'
|
|
||||||
|
|
||||||
:param text: String to extract the arguments from a command
|
|
||||||
:return: the arguments if `text` is a command (according to is_command), else None.
|
|
||||||
"""
|
|
||||||
regexp = re.compile(r"/\w*(@\w*)*\s*([\s\S]*)",re.IGNORECASE)
|
|
||||||
result = regexp.match(text)
|
|
||||||
return result.group(2) if is_command(text) else None
|
|
||||||
|
|
||||||
|
|
||||||
def per_thread(key, construct_value, reset=False):
|
def per_thread(key, construct_value, reset=False):
|
||||||
if reset or not hasattr(thread_local, key):
|
if reset or not hasattr(thread_local, key):
|
||||||
|
Loading…
Reference in New Issue
Block a user