Compare commits

..
117 Commits
Author SHA1 Message Date
Davte c1f4abc541 Specify encoding in send_part_of_text_file function
(cherry picked from commit ec747bef1d)
2024-02-14 19:31:17 +01:00
Davte c4a822e45d Compliance with bot API 6.8 and 6.9
Added the method `unpinAllGeneralForumTopicMessages` (6.8).

Added the new administrator privileges `can_post_stories`, `can_edit_stories` and `can_delete_stories` to the class `ChatAdministratorRights` and to the method `promoteChatMember` (6.9).
2023-11-12 11:55:03 +01:00
Davte 6b4a95be36 Method to add table columns if missing 2023-08-23 18:23:32 +02:00
Davte beaf3f8516 Allow non-null standard output and/or error pipe to be passed to aio_subprocess_shell function 2023-08-23 17:17:55 +02:00
Davte fc1f087d4a When answering inline queries, prevent invalid InlineQueryResultsButton instantiation
(cherry picked from commit eab81b065d)
2023-08-07 20:19:50 +02:00
Davte aeac4aea52 Better variable regex: accept only one decimal separator in float numbers
(cherry picked from commit 51a77c695b)
2023-07-25 18:58:45 +02:00
Davte 5ab22909cf Whitespace 2023-07-25 16:42:26 +02:00
Davte 9094955812 Config command implemented, allowing administrators to add variables to configuration files 2023-07-25 16:25:56 +02:00
Davte 173783e154 Moved join_path function to utilities module 2023-07-25 16:24:18 +02:00
Davte 92a986d090 Catch up with branch main (v 2.9.1) 2023-07-25 16:23:21 +02:00
Davte 3e6e364336 Compliance with Telegram Bot API 6.5 2023-02-03 21:40:09 +01:00
Davte f0a4c914e4 Compliance with Telegram Bot API 6.4 2023-01-06 10:30:25 +01:00
Davte 80a1440e75 Make the regex dot match any character at all, including a newline, when cleaning HTML strings (so multiline tag bodies are allowed, as they are in Telegram HTML markdown). 2022-12-26 14:12:23 +01:00
Davte b978022658 HTML parse_mode check upgraded.
All supported tags permitted, malformed tags replaced with escaped characters
2022-12-12 22:45:08 +01:00
Davte 50f561e7f9 Method to add a table and its columns to and ObjectWithDatabase 2022-12-10 18:46:29 +01:00
Davte a9b785f49d Compliance with Telegram Bot API 6.3 2022-12-08 16:19:45 +01:00
Davte b7d08ab2ba When admin A requests profile picture of user B, send B's picture and not A's. 2022-12-06 22:18:35 +01:00
Davte d362ec496b Browse users via /auth command 2022-12-05 22:04:59 +01:00
Davte 0bfc1e157b Working on users browsing via /auth command 2022-12-04 22:13:48 +01:00
Davte bc40957b27 Syntax-breaking typo 2022-10-12 14:19:46 +02:00
Davte 45117610f9 Bug fix: use a unique loop 2022-10-12 14:01:10 +02:00
Davte f91661927e Bug fix: use a unique loop 2022-10-12 13:34:01 +02:00
Davte 12f3a2cc73 Bug fix: asyncio.run cannot take asyncio.gather as coroutine 2022-10-12 13:31:23 +02:00
Davte 25abb80343 Bug fix: no running loop, need to create a new one. 2022-10-12 13:26:03 +02:00
Davte 76ea65a660 asyncio get_event_loop method is being deprecated; use new_event_loop / get_running_loop and asyncio.run instead
Major version change because it may not be backward-compatible
2022-10-12 13:24:40 +02:00
Davte e254dbf42a send_document method should not require a chat_id since it can be passed an update object 2020-12-20 20:30:49 +01:00
Davte b7b91a65ea send_photo method should not require a chat_id since it can be passed an update object 2020-12-11 08:21:57 +01:00
Davte abebff43d9 Avoid relative import statements 2020-11-19 15:18:50 +01:00
Davte a460f71b69 Items in __all__ must be str, not module 2020-11-19 14:37:33 +01:00
Davte 6ad5ec2865 Document can be None if document_path is provided 2020-11-19 12:32:50 +01:00
Davte cfae729270 Do not log chardet INFO and DEBUG levels 2020-11-16 23:05:24 +01:00
Davte dc9c2a7b14 Compliance with Telegram Bot API 5.0 and improved type hinting for API methods. 2020-11-16 22:54:25 +01:00
Davte a3cc676432 Identify edited methods (new or deprecated parameters) in addition to new methods. 2020-11-16 20:51:27 +01:00
Davte 15a7a58537 Version number 2020-11-15 21:35:45 +01:00
Davte ea30fd39cf Import statements refactored 2020-11-15 21:34:26 +01:00
Davte a5cabdd102 web should not be imported from aiohttp; use aiohttp.web instead 2020-11-15 20:55:22 +01:00
Davte 89fa73d1a5 Store user profile pictures in bot database and show them in authorization panel 2020-10-07 16:22:51 +02:00
Davte 4b22658bf5 MySQL compatibility: specify VARCHAR length
`db.types.string` becomes now `db.types.string(n)`
`db.types.text` is the wrong type to use (text blobs)
2020-10-07 16:19:03 +02:00
Davte bce8cff3cf Pass all information to command handler when using /start 2020-09-26 19:28:03 +02:00
Davte ea07aa47cf Make general_handler handle photo updates 2020-09-05 10:35:52 +02:00
Davte d49bab54ca Updated examples 2020-08-23 14:21:37 +02:00
Davte 83d01e4da9 Remove argument parameter from parser decorator 2020-08-23 14:07:51 +02:00
Davte 59dde0d25e In text message handler, make available both lowered and original text and inspect condition parameters 2020-08-23 14:03:42 +02:00
Davte 713f4ffd0e Accept language directly 2020-08-20 15:50:53 +02:00
Davte 51bc95332f General handler implemented and applied to contact updates 2020-08-17 23:52:16 +02:00
Davte 92758d923c Document handlers implemented 2020-08-16 15:17:09 +02:00
Davte 946e2a881f Declare packenv variable 2020-07-19 16:17:39 +02:00
Davte 0f4d31892f Prevent globbing and word splitting 2020-07-19 16:11:00 +02:00
Davte c4eaa0b9db Update default help messages with given ones, instead of replacing them 2020-07-17 09:48:52 +02:00
Davte 21214feb0a In default keyboard, show only buttons for commands the user is authorized to call 2020-07-16 10:05:28 +02:00
Davte f7ee5b71a1 Prevent decoding None objects 2020-07-15 13:16:21 +02:00
Davte fb58c0239d Async function to run shell commands 2020-07-15 13:11:04 +02:00
Davte c848bfc228 Script to merge split files 2020-06-22 22:53:25 +02:00
Davte f823057cbe Split outgoing documents bigger than 50 MB and send chunks 2020-06-22 20:30:03 +02:00
Davte d7a1acd23b Typos 2020-06-20 15:44:26 +02:00
Davte 70053c9279 Send error message if database could not be sent - new version 2020-06-20 15:34:39 +02:00
Davte 1c76c7d797 Send error message if database could not be sent 2020-06-20 15:31:42 +02:00
Davte dfffbff7c6 Merge 2020-06-20 15:20:22 +02:00
Davte a4b1ed09a2 longest_cooldown_timedelta property defined 2020-06-20 15:18:13 +02:00
Davte a1bd681cbf Merge 2020-06-20 15:16:46 +02:00
Davte 9c57677320 Accept both updates and raw_updates in maintenance exception criteria 2020-05-21 15:32:04 +02:00
Davte 956e982157 Pass to handlers the parameters they take and preserve update_id 2020-05-21 14:55:32 +02:00
Davte 4bd10894a8 Merge branch 'master' into develop 2020-05-19 15:21:02 +02:00
Davte 89a9863510 Send long text messages as files 2020-05-19 15:12:38 +02:00
Davte ed36e53a28 Consider _ as a digit when prettifying expressions 2020-05-19 15:11:58 +02:00
Davte 8977e0fbc3 Shorten buffer time for calculation sessions 2020-05-19 14:04:02 +02:00
Davte cf7e0c740b Redundant escape 2020-05-19 13:59:15 +02:00
Davte 12b18cff58 Prettify expressions removing whitespace around newlines and adjusting whitespace around parentheses 2020-05-19 12:53:20 +02:00
Davte 3160723aa7 TypeError bug fixed 2020-05-18 22:25:30 +02:00
Davte 8e2feb5ac2 Prevent message is not modified exceptions 2020-05-18 22:08:10 +02:00
Davte cbc7424a97 Prettify expressions 2020-05-18 19:31:26 +02:00
Davte 1e7c384b6d Multilanguage message in version command
(cherry picked from commit a7fd054106)
2020-05-18 18:58:23 +02:00
Davte 7cc2e02f47 Remove whitespace at the end of the expression after del button is pressed 2020-05-18 18:50:21 +02:00
Davte 6315c0dcc2 Track input via message of algebraic expressions as well as input via buttons. 2020-05-18 18:33:40 +02:00
Davte f06c525f5b Merged branch master 2020-05-18 15:09:05 +02:00
Davte ea5c63c1f8 Finished working on calc command 2020-05-18 15:04:18 +02:00
Davte ea549b63c8 Working on calc command 2020-05-18 13:04:19 +02:00
Davte e63b0f9265 Working on calc command 2020-05-18 12:42:04 +02:00
Davte cb9310437f Working on calc button 2020-05-17 19:45:39 +02:00
Davte 5bc58dd7d5 Working on calc button 2020-05-16 15:51:49 +02:00
Davte 5d35579e10 Working on /calc command 2020-05-15 19:48:04 +02:00
Davte b0132e0b30 /when command implemented 2020-05-14 22:18:21 +02:00
Davte 49ecee63d0 /info command implemented 2020-05-14 21:58:38 +02:00
Davte 273eda2b67 /ping command implemented
/length command returns characters in text message even, not only in reply
2020-05-14 20:25:29 +02:00
Davte b12f653096 Useful tools module added 2020-05-14 18:50:05 +02:00
Davte 05878f3fbd Language-labelled commands are accepted only for selected language. /father uses selected language for commands 2020-05-14 18:49:40 +02:00
Davte c583c3c3b0 Allow language-labelled commands 2020-05-14 15:32:06 +02:00
Davte 2d40903069 Finished working on /version command 2020-05-13 19:44:04 +02:00
Davte 217a445a65 Working on /version command 2020-05-13 15:54:38 +02:00
Davte b68dbe7a07 /ban command implemented 2020-05-13 15:31:59 +02:00
Davte 258ca9f6ef /ban command implemented 2020-05-13 15:31:20 +02:00
Davte 3648a36636 Version 2020-05-13 15:22:37 +02:00
Davte ef99493c7f Finished working on /ban 2020-05-13 15:22:14 +02:00
Davte 841f7f0c8d Working on /ban 2020-05-13 12:47:37 +02:00
Davte 23882e5b3b Implemented button to delete all commands stored by BotFather 2020-05-07 22:52:42 +02:00
Davte 6ba21f0115 Version 2020-05-07 15:29:10 +02:00
Davte ca6dca3cb7 Finished working on /father command 2020-05-07 15:07:45 +02:00
Davte 9072c3abe5 Working on /father command 2020-05-06 23:18:27 +02:00
Davte e74e38c6ae Comment 2020-05-06 15:39:45 +02:00
Davte 7a23045479 New parameters of sendPoll method 2020-05-06 15:33:23 +02:00
Davte 5ef449a542 Temp 2020-05-06 00:44:21 +02:00
Davte a2c83f8d9c Pass language to update handlers 2020-05-06 00:39:23 +02:00
Davte dddaf20ea2 Temp 2020-05-05 23:44:58 +02:00
Davte a828bb5d3c Move functions outside init 2020-05-05 12:29:55 +02:00
Davte 25f5514dff Type hinting
(cherry picked from commit 3896776f0e)
2020-04-28 12:08:01 +02:00
Davte 34f802732b Do not notify package updates too often
(cherry picked from commit ab6a0bc0ad)
2020-04-28 09:48:53 +02:00
Davte f6466b0540 Merge branch 'develop' of ssh://gogs.davte.it:8445/Davte/davtelepot into develop
# Conflicts:
#	davtelepot/__init__.py
2020-04-28 09:48:42 +02:00
Davte 7565df17ba New version
(cherry picked from commit e61d757c1a)
2020-04-28 00:36:28 +02:00
Davte 4be33370b9 Text made more clear
(cherry picked from commit e7274dce07)
2020-04-28 00:27:36 +02:00
Davte cf3f7a88fb Deprecated admin_tools submodule 2020-04-28 00:26:38 +02:00
Davte a4d464da58 Text made more clear 2020-04-27 19:07:10 +02:00
Davte 83c0a91919 Missing whitespace
(cherry picked from commit b107cc105d)
2020-04-27 18:03:24 +02:00
Davte 85a5ce3882 Merge branch 'develop' of ssh://gogs.davte.it:8445/Davte/davtelepot into develop 2020-04-27 17:30:05 +02:00
Davte 77405d2dd3 Merge branch 'master' into develop
# Conflicts:
#	davtelepot/__init__.py
#	davtelepot/administration_tools.py
2020-04-27 14:03:58 +02:00
Davte 1e2316e748 Package update notifier completed 2020-04-27 13:45:25 +02:00
Davte 16014c5a42 Working on package update notifier 2020-04-26 23:30:44 +02:00
Davte f0be5b5ff2 Working on package update notifier 2020-04-26 23:14:10 +02:00
8 changed files with 266 additions and 1730 deletions
-1
View File
@@ -41,7 +41,6 @@ __pycache__/
# Distribution / packaging
.Python
env/
.venv/
build/
develop-eggs/
dist/
+1 -1
View File
@@ -11,7 +11,7 @@ __author__ = "Davide Testa"
__email__ = "davide@davte.it"
__credits__ = ["Marco Origlia", "Nick Lee @Nickoala"]
__license__ = "GNU General Public License v3.0"
__version__ = "2.10.11"
__version__ = "2.9.8"
__maintainer__ = "Davide Testa"
__contact__ = "t.me/davte"
+74 -153
View File
@@ -13,12 +13,10 @@ import asyncio
import datetime
import json
import logging
import platform
import re
import types
from collections import OrderedDict
from importlib.metadata import version as get_package_version_from_metadata
from typing import Union, List, Tuple
# Third party modules
@@ -29,8 +27,8 @@ from davtelepot.messages import default_admin_messages, default_talk_messages
from davtelepot.bot import Bot
from davtelepot.utilities import (
async_wrapper, CachedPage, Confirmator, extract, get_cleaned_text,
get_secure_key, get_user, clean_html_string, line_drawing_unordered_list,
make_button, make_inline_keyboard, remove_html_tags, send_part_of_text_file,
get_user, clean_html_string, line_drawing_unordered_list, make_button,
make_inline_keyboard, remove_html_tags, send_part_of_text_file,
send_csv_file, make_lines_of_buttons, join_path
)
@@ -45,13 +43,6 @@ variable_regex = re.compile(r"(?P<name>[a-zA-Z]\w*)\s*=\s*"
r"\"[^\"]*\")")
def get_package_version(package: types.ModuleType):
"""Get version of given package."""
if hasattr(package, '__version__'):
return package.__version__
return get_package_version_from_metadata(package.__name__)
async def _forward_to(update,
bot: Bot,
sender,
@@ -232,7 +223,7 @@ def get_talk_panel(bot: Bot,
return text, reply_markup
async def talk_command(bot: Bot,
async def _talk_command(bot: Bot,
update,
user_record):
text = get_cleaned_text(
@@ -352,7 +343,7 @@ async def end_session(bot: Bot,
return
async def talk_button(bot: Bot,
async def _talk_button(bot: Bot,
update,
user_record,
data):
@@ -362,7 +353,7 @@ async def talk_button(bot: Bot,
if command == 'search':
bot.set_individual_text_message_handler(
await async_wrapper(
talk_command,
_talk_command,
),
update
)
@@ -435,7 +426,7 @@ async def talk_button(bot: Bot,
return result
async def restart_command(bot: Bot,
async def _restart_command(bot: Bot,
update,
user_record):
with bot.db as db:
@@ -462,7 +453,7 @@ async def restart_command(bot: Bot,
return
async def stop_command(bot: Bot,
async def _stop_command(bot: Bot,
update,
user_record):
text = bot.get_message(
@@ -504,7 +495,7 @@ async def stop_bots(bot: Bot):
return
async def stop_button(bot: Bot,
async def _stop_button(bot: Bot,
update,
user_record,
data: List[Union[int, str]]):
@@ -544,7 +535,7 @@ async def stop_button(bot: Bot,
return result
async def send_bot_database(bot: Bot, user_record: OrderedDict, language: str):
async def _send_bot_database(bot: Bot, user_record: OrderedDict, language: str):
if not all(
[
bot.db_url.endswith('.db'),
@@ -571,7 +562,7 @@ async def send_bot_database(bot: Bot, user_record: OrderedDict, language: str):
)
async def query_command(bot, update, user_record):
async def _query_command(bot, update, user_record):
query = get_cleaned_text(
update,
bot,
@@ -649,7 +640,7 @@ async def query_command(bot, update, user_record):
)
async def query_button(bot, update, user_record, data):
async def _query_button(bot, update, user_record, data):
result, text, reply_markup = '', '', None
command = data[0] if len(data) else 'default'
error_message = bot.get_message(
@@ -686,7 +677,7 @@ async def query_button(bot, update, user_record, data):
return result
async def log_command(bot, update, user_record):
async def _log_command(bot, update, user_record):
if bot.log_file_path is None:
return bot.get_message(
'admin', 'log_command', 'no_log',
@@ -739,7 +730,7 @@ async def log_command(bot, update, user_record):
return
async def errors_command(bot, update, user_record):
async def _errors_command(bot, update, user_record):
# Always send errors log file in private chat
chat_id = update['from']['id']
if bot.errors_file_path is None:
@@ -783,7 +774,7 @@ async def errors_command(bot, update, user_record):
return
async def maintenance_command(bot, update, user_record):
async def _maintenance_command(bot, update, user_record):
maintenance_message = get_cleaned_text(update, bot, ['maintenance'])
if maintenance_message.startswith('{'):
maintenance_message = json.loads(maintenance_message)
@@ -836,8 +827,7 @@ def get_maintenance_exception_criterion(bot, allowed_command):
async def get_last_commit():
"""Get last commit hash and message."""
last_commit_message = None
"""Get last commit hash and davtelepot version."""
try:
_subprocess = await asyncio.create_subprocess_exec(
'git', 'rev-parse', 'HEAD',
@@ -845,22 +835,12 @@ async def get_last_commit():
stderr=asyncio.subprocess.STDOUT
)
stdout, _ = await _subprocess.communicate()
last_commit_hash = stdout.decode().strip()
last_commit = stdout.decode().strip()
except Exception as e:
last_commit_hash = f"{e}"
try:
_subprocess = await asyncio.create_subprocess_exec(
'git', 'log', '--pretty=%B', "-n", "1", last_commit_hash,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT
)
stdout, _ = await _subprocess.communicate()
last_commit_message = stdout.decode().strip()
except Exception:
pass
if last_commit_hash.startswith("fatal: not a git repository"):
last_commit_hash = "-"
return last_commit_hash, last_commit_message
last_commit = f"{e}"
if last_commit.startswith("fatal: not a git repository"):
last_commit = "-"
return last_commit
async def get_new_versions(bot: Bot,
@@ -884,12 +864,7 @@ async def get_new_versions(bot: Bot,
"skipping...")
continue
new_version = web_page['info']['version']
try:
current_version = get_package_version(package)
except TypeError:
current_version = "NA"
logging.error("Could not get current version of "
"package %s", package.__name__)
current_version = package.__version__
notification_record = bot.db['updates_notifications'].find_one(
package=package.__name__,
order_by=['-id'],
@@ -908,21 +883,17 @@ async def get_new_versions(bot: Bot,
return news
async def version_command(bot: Bot, update: dict,
async def _version_command(bot: Bot, update: dict,
user_record: OrderedDict, language: str):
last_commit_hash, last_commit_message = await get_last_commit()
last_commit = await get_last_commit()
text = bot.get_message(
'admin', 'version_command', 'header',
last_commit=last_commit_hash,
last_commit=last_commit,
update=update, user_record=user_record
)
if last_commit_message:
text += "\n<i>" + last_commit_message + "</i>"
text += "\n\n"
text += f'<b>Python: </b> <code>{platform.python_version()}</code>\n'
) + '\n\n'
text += '\n'.join(
f"<b>{package.__name__}</b>: "
f"<code>{get_package_version(package)}</code>"
f"<code>{package.__version__}</code>"
for package in bot.packages
)
temporary_message = await bot.send_message(
@@ -961,15 +932,15 @@ async def notify_new_version(bot: Bot):
Notify admins when last commit and/or davtelepot version change.
"""
last_commit_hash, last_commit_message = await get_last_commit()
last_commit = await get_last_commit()
old_record = bot.db['version_history'].find_one(
order_by=['-id']
)
current_versions = {
f"{package.__name__}_version": get_package_version(package)
f"{package.__name__}_version": package.__version__
for package in bot.packages
}
current_versions['last_commit'] = last_commit_hash
current_versions['last_commit'] = last_commit
if old_record is None:
old_record = dict(
updated_at=datetime.datetime.min,
@@ -992,16 +963,13 @@ async def notify_new_version(bot: Bot):
'admin', 'new_version', 'title',
user_record=admin
) + '\n\n'
if last_commit_hash != old_record['last_commit']:
if last_commit != old_record['last_commit']:
text += bot.get_message(
'admin', 'new_version', 'last_commit',
old_record=old_record,
new_record=current_versions,
user_record=admin
)
if last_commit_message:
text += f"\n<i>{last_commit_message}</i>"
text += "\n\n"
) + '\n\n'
text += '\n'.join(
f"<b>{name[:-len('_version')]}</b>: "
f"<code>{old_record[name]}</code> —> "
@@ -1064,7 +1032,7 @@ async def get_package_updates(bot: Bot,
await asyncio.sleep(monitoring_interval)
async def send_start_messages(bot: Bot):
async def _send_start_messages(bot: Bot):
"""Send restart messages at restart."""
for restart_message in bot.db['restart_messages'].find(sent=None):
asyncio.ensure_future(
@@ -1092,7 +1060,7 @@ async def send_start_messages(bot: Bot):
return
async def load_talking_sessions(bot: Bot):
async def _load_talking_sessions(bot: Bot):
sessions = []
for session in bot.db.query(
"""SELECT *
@@ -1171,7 +1139,7 @@ def get_custom_commands(bot: Bot, language: str = None) -> List[dict]:
)
async def father_command(bot, language):
async def _father_command(bot, language):
modes = [
{
key: (
@@ -1475,12 +1443,12 @@ async def edit_bot_father_settings_via_message(bot: Bot,
return result, text, reply_markup
async def father_button(bot: Bot, user_record: OrderedDict,
async def _father_button(bot: Bot, user_record: OrderedDict,
language: str, data: list):
"""Handle BotFather button.
Operational modes
- main: back to main page (see `father_command`)
- main: back to main page (see _father_command)
- get: show commands stored by @BotFather
- set: edit commands stored by @BotFather
"""
@@ -1574,7 +1542,7 @@ async def father_button(bot: Bot, user_record: OrderedDict,
elif command == 'main':
return dict(
text='',
edit=(await father_command(bot=bot, language=language))
edit=(await _father_command(bot=bot, language=language))
)
elif command == 'set':
stored_commands = await bot.getMyCommands()
@@ -1842,7 +1810,7 @@ async def father_button(bot: Bot, user_record: OrderedDict,
return result
async def config_command(bot: Bot, update: dict,
async def _config_command(bot: Bot, update: dict,
user_record: dict, language: str):
text = get_cleaned_text(
update,
@@ -1876,52 +1844,6 @@ async def config_command(bot: Bot, update: dict,
language=language)
async def become_administrator(bot: Bot, update: dict,
user_record: dict, language: str):
"""When the bot has no administrator, become one providing a token.
The token will be printed to the stdout on the machine running the bot.
"""
if len(bot.administrators) > 0:
return
def _get_message(*args):
return bot.get_message('admin', 'become_admin', *args,
update=update, user_record=user_record,
language=language)
token = get_cleaned_text(update=update, bot=bot,
replace=['become_administrator',
'00become_administrator'],
strip='/ @_')
if token != bot.administration_token:
return _get_message('wrong_token')
with bot.db as db:
db['users'].update({**user_record, 'privileges': 1},
['id'])
return _get_message('success')
async def create_promotion_command(bot: Bot):
"""If bot has no administrators, users can elevate themselves.
To do so, they need to provide a token, that will be printed to the stdout
of the machine running the bot.
"""
await bot.get_me()
if len(bot.administrators) > 0:
return
bot.administration_token = get_secure_key(length=10)
print(f"To become administrator click "
f"https://t.me/{bot.name}?start="
f"00become_administrator_{bot.administration_token}")
@bot.command(command='become_administrator',
authorization_level='everybody',
aliases=['00become_administrator'])
async def _become_administrator(bot, update, user_record, language):
return await become_administrator(bot=bot, update=update,
user_record=user_record,
language=language)
def init(telegram_bot: Bot,
talk_messages: dict = None,
admin_messages: dict = None,
@@ -1985,16 +1907,16 @@ def init(telegram_bot: Bot,
# Tasks to complete before starting bot
@telegram_bot.additional_task(when='BEFORE')
async def _load_talking_sessions():
return await load_talking_sessions(bot=telegram_bot)
async def load_talking_sessions():
return await _load_talking_sessions(bot=telegram_bot)
@telegram_bot.additional_task(when='BEFORE', bot=telegram_bot)
async def notify_version(bot):
return await notify_new_version(bot=bot)
@telegram_bot.additional_task('BEFORE')
async def _send_start_messages():
return await send_start_messages(bot=telegram_bot)
async def send_restart_messages():
return await _send_start_messages(bot=telegram_bot)
# Administration commands
@telegram_bot.command(command='/db',
@@ -2003,8 +1925,8 @@ def init(telegram_bot: Bot,
description=admin_messages[
'db_command']['description'],
authorization_level='admin')
async def _send_bot_database(bot, user_record, language):
return await send_bot_database(bot=bot,
async def send_bot_database(bot, user_record, language):
return await _send_bot_database(bot=bot,
user_record=user_record,
language=language)
@@ -2014,8 +1936,8 @@ def init(telegram_bot: Bot,
description=admin_messages[
'errors_command']['description'],
authorization_level='admin')
async def _errors_command(bot, update, user_record):
return await errors_command(bot, update, user_record)
async def errors_command(bot, update, user_record):
return await _errors_command(bot, update, user_record)
@telegram_bot.command(command='/father',
aliases=[],
@@ -2026,14 +1948,14 @@ def init(telegram_bot: Bot,
if key in ('description', )
},
authorization_level='admin')
async def _father_command(bot, language):
return await father_command(bot=bot, language=language)
async def father_command(bot, language):
return await _father_command(bot=bot, language=language)
@telegram_bot.button(prefix='father:///',
separator='|',
authorization_level='admin')
async def _father_button(bot, user_record, language, data):
return await father_button(bot=bot,
async def query_button(bot, user_record, language, data):
return await _father_button(bot=bot,
user_record=user_record,
language=language,
data=data)
@@ -2044,16 +1966,16 @@ def init(telegram_bot: Bot,
description=admin_messages[
'log_command']['description'],
authorization_level='admin')
async def _log_command(bot, update, user_record):
return await log_command(bot, update, user_record)
async def log_command(bot, update, user_record):
return await _log_command(bot, update, user_record)
@telegram_bot.command(command='/maintenance', aliases=[],
show_in_keyboard=False,
description=admin_messages[
'maintenance_command']['description'],
authorization_level='admin')
async def _maintenance_command(bot, update, user_record):
return await maintenance_command(bot, update, user_record)
async def maintenance_command(bot, update, user_record):
return await _maintenance_command(bot, update, user_record)
@telegram_bot.command(command='/query',
aliases=[],
@@ -2061,16 +1983,16 @@ def init(telegram_bot: Bot,
description=admin_messages[
'query_command']['description'],
authorization_level='admin')
async def _query_command(bot, update, user_record):
return await query_command(bot, update, user_record)
async def query_command(bot, update, user_record):
return await _query_command(bot, update, user_record)
@telegram_bot.button(prefix='db_query:///',
separator='|',
description=admin_messages[
'query_command']['description'],
authorization_level='admin')
async def _query_button(bot, update, user_record, data):
return await query_button(bot, update, user_record, data)
async def query_button(bot, update, user_record, data):
return await _query_button(bot, update, user_record, data)
@telegram_bot.command(command='/restart',
aliases=[],
@@ -2078,8 +2000,8 @@ def init(telegram_bot: Bot,
description=admin_messages[
'restart_command']['description'],
authorization_level='admin')
async def _restart_command(bot, update, user_record):
return await restart_command(bot, update, user_record)
async def restart_command(bot, update, user_record):
return await _restart_command(bot, update, user_record)
@telegram_bot.command(command='/select',
aliases=[],
@@ -2087,8 +2009,8 @@ def init(telegram_bot: Bot,
description=admin_messages[
'select_command']['description'],
authorization_level='admin')
async def _select_command(bot, update, user_record):
return await query_command(bot, update, user_record)
async def select_command(bot, update, user_record):
return await _query_command(bot, update, user_record)
@telegram_bot.command(command='/stop',
aliases=[],
@@ -2096,16 +2018,16 @@ def init(telegram_bot: Bot,
description=admin_messages[
'stop_command']['description'],
authorization_level='admin')
async def _stop_command(bot, update, user_record):
return await stop_command(bot, update, user_record)
async def stop_command(bot, update, user_record):
return await _stop_command(bot, update, user_record)
@telegram_bot.button(prefix='stop:///',
separator='|',
description=admin_messages[
'stop_command']['description'],
authorization_level='admin')
async def _stop_button(bot, update, user_record, data):
return await stop_button(bot, update, user_record, data)
async def stop_button(bot, update, user_record, data):
return await _stop_button(bot, update, user_record, data)
@telegram_bot.command(command='/talk',
aliases=[],
@@ -2113,14 +2035,14 @@ def init(telegram_bot: Bot,
description=admin_messages[
'talk_command']['description'],
authorization_level='admin')
async def _talk_command(bot, update, user_record):
return await talk_command(bot, update, user_record)
async def talk_command(bot, update, user_record):
return await _talk_command(bot, update, user_record)
@telegram_bot.button(prefix='talk:///',
separator='|',
authorization_level='admin')
async def _talk_button(bot, update, user_record, data):
return await talk_button(bot, update, user_record, data)
async def talk_button(bot, update, user_record, data):
return await _talk_button(bot, update, user_record, data)
@telegram_bot.command(command='/version',
aliases=[],
@@ -2131,8 +2053,8 @@ def init(telegram_bot: Bot,
},
show_in_keyboard=False,
authorization_level='admin')
async def _version_command(bot, update, user_record, language):
return await version_command(bot=bot,
async def version_command(bot, update, user_record, language):
return await _version_command(bot=bot,
update=update,
user_record=user_record,
language=language)
@@ -2146,9 +2068,8 @@ def init(telegram_bot: Bot,
},
show_in_keyboard=False,
authorization_level='admin')
async def _config_command(bot, update, user_record, language):
return await config_command(bot=bot,
async def config_command(bot, update, user_record, language):
return await _config_command(bot=bot,
update=update,
user_record=user_record,
language=language)
asyncio.ensure_future(create_promotion_command(bot=telegram_bot))
+85 -1354
View File
File diff suppressed because it is too large Load Diff
+3 -5
View File
@@ -25,7 +25,6 @@ class TelegramApiMethod(object):
'Boolean': "bool",
'Integer': "int",
'Integer or String': "Union[int, str]",
'Array of Integer': "List[str]",
'String': "str",
}
"""Telegram bot API method."""
@@ -56,15 +55,14 @@ class TelegramApiMethod(object):
for n, paragraph in enumerate(self.description.replace('.', '.\n').split('\n')):
additional_indentation = 0
if n == 0 and paragraph.startswith(redundant_string):
paragraph = (paragraph[len(redundant_string)].upper()
+ paragraph[len(redundant_string)+1:])
paragraph = paragraph[len(redundant_string)].upper() + paragraph[len(redundant_string)+1:]
for word in paragraph.split(' '):
if len(current_line) + len(word) > 80 - indentation - additional_indentation:
additional_indentation = max(additional_indentation, 4)
result += f"{current_line.strip()}\n{' ' * additional_indentation}"
current_line = ""
current_line += f"{word} "
if len(current_line) > 0:
if len(current_line):
result += f"{current_line.strip()}\n"
current_line = ""
if n == 0:
@@ -205,7 +203,7 @@ async def print_api_methods(filename=None,
)
)
if output_file:
with open(output_file, 'w', encoding="utf-8") as file:
with open(output_file, 'w') as file:
if new_methods:
file.write(
"from typing import List, Union\n"
+71 -174
View File
@@ -2,6 +2,34 @@
camelCase methods mirror API directly, while snake_case ones act as middleware
someway.
Usage
```
import sys
from davtelepot.bot import Bot
from data.passwords import my_token, my_other_token
long_polling_bot = Bot(token=my_token, database_url='my_db')
webhook_bot = Bot(token=my_other_token, hostname='example.com',
certificate='path/to/certificate.pem',
database_url='my_other_db')
@long_polling_bot.command('/foo')
async def foo_command(bot, update, user_record, language):
return "Bar!"
@webhook_bot.command('/bar')
async def bar_command(bot, update, user_record, language):
return "Foo!"
exit_state = Bot.run(
local_host='127.0.0.5',
port=8552
)
sys.exit(exit_state)
```
"""
# Standard library modules
@@ -21,9 +49,7 @@ from typing import Callable, List, Union, Dict
import aiohttp.web
# Project modules
from davtelepot.api import (
LinkPreviewOptions, ReplyParameters, TelegramBot, TelegramError
)
from davtelepot.api import TelegramBot, TelegramError
from davtelepot.database import ObjectWithDatabase
from davtelepot.languages import MultiLanguageObject
from davtelepot.messages import davtelepot_messages
@@ -78,10 +104,10 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
_errors_file_path = None
_documents_max_dimension = 50 * 1000 * 1000 # 50 MB
def __init__(self,
token, hostname='', certificate=None,
max_connections=40, allowed_updates=None,
database_url='bot.db', api_url: str = None):
def __init__(
self, token, hostname='', certificate=None, max_connections=40,
allowed_updates=None, database_url='bot.db'
):
"""Init a bot instance.
token : str
@@ -99,7 +125,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
# Append `self` to class list of instances
self.__class__.bots.append(self)
# Call superclasses constructors with proper arguments
TelegramBot.__init__(self, token, api_url=api_url)
TelegramBot.__init__(self, token)
ObjectWithDatabase.__init__(self, database_url=database_url)
MultiLanguageObject.__init__(self)
self.messages['davtelepot'] = davtelepot_messages
@@ -122,47 +148,12 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
'edited_message': self.edited_message_handler,
'channel_post': self.channel_post_handler,
'edited_channel_post': self.edited_channel_post_handler,
'business_connection': self.get_update_handler(
update_type='business_connection'
),
'business_message': self.get_update_handler(
update_type='business_message'
),
'edited_business_message': self.get_update_handler(
update_type='edited_business_message'
),
'deleted_business_messages': self.get_update_handler(
update_type='deleted_business_messages'
),
'message_reaction': self.get_update_handler(
update_type='message_reaction'
),
'message_reaction_count': self.get_update_handler(
update_type='message_reaction_count'
),
'inline_query': self.inline_query_handler,
'chosen_inline_result': self.chosen_inline_result_handler,
'callback_query': self.callback_query_handler,
'shipping_query': self.shipping_query_handler,
'pre_checkout_query': self.pre_checkout_query_handler,
'purchased_paid_media': self.get_update_handler(
update_type='purchased_paid_media'
),
'poll': self.poll_handler,
'poll_answer': self.get_update_handler(
update_type='poll_answer'
),
'my_chat_member': self.get_update_handler(
update_type='my_chat_member'
),
'chat_member': self.get_update_handler( update_type='chat_member' ),
'chat_join_request': self.get_update_handler(
update_type='chat_join_request'
),
'chat_boost': self.get_update_handler( update_type='chat_boost' ),
'removed_chat_boost': self.get_update_handler(
update_type='removed_chat_boost'
),
}
# Different message update types need different handlers
self.message_handlers = {
@@ -256,8 +247,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
self.Role = None
self.packages = [sys.modules['davtelepot']]
self._documents_max_dimension = None
self._getting_me = False
self._got_me = False
# Add `users` table with its fields if missing
if 'users' not in self.db.tables:
table = self.db.create_table(
@@ -717,18 +706,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
)
return
def get_update_handler(self, update_type: str):
"""Get update handler for `update_type`."""
bot = self
async def handler(update, user_record, language=None):
"""Handle update message of type `update_type`"""
logging.info(
"The following update was received: %s\n"
"However, this `%s` handler does nothing yet.",
update, update_type
)
return handler
async def edited_channel_post_handler(self, update, user_record, language=None):
"""Handle Telegram `edited_channel_post` update."""
logging.info(
@@ -1342,21 +1319,19 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
async def send_message(self, chat_id: Union[int, str] = None,
text: str = None,
message_thread_id: int = None,
entities: List[dict] = None,
parse_mode: str = 'HTML',
link_preview_options: LinkPreviewOptions = None,
disable_notification: bool = None,
message_thread_id: int = None,
protect_content: bool = None,
disable_web_page_preview: bool = None,
disable_notification: bool = None,
reply_to_message_id: int = None,
allow_sending_without_reply: bool = None,
reply_markup=None,
update: dict = None,
reply_to_update: bool = False,
send_default_keyboard: bool = True,
user_record: OrderedDict = None,
reply_parameters: ReplyParameters = None,
reply_markup=None):
user_record: OrderedDict = None):
"""Send text via message(s).
This method wraps lower-level `TelegramBot.sendMessage` method.
@@ -1377,10 +1352,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
user_record = self.db['users'].find_one(telegram_id=chat_id)
if reply_to_update and 'message_id' in update:
reply_to_message_id = update['message_id']
if disable_web_page_preview:
if link_preview_options is None:
link_preview_options = LinkPreviewOptions()
link_preview_options['is_disabled'] = True
if (
send_default_keyboard
and reply_markup is None
@@ -1424,27 +1395,19 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
limit=self.__class__.TELEGRAM_MESSAGES_MAX_LEN - 100,
parse_mode=parse_mode
)
if reply_to_message_id:
if reply_parameters is None:
reply_parameters = ReplyParameters(message_id=reply_to_message_id)
reply_parameters['message_id'] = reply_to_message_id
if allow_sending_without_reply:
reply_parameters['allow_sending_without_reply'] = allow_sending_without_reply
if reply_to_update and 'chat' in update and 'id' in update['chat']:
if update['chat']['id'] != chat_id:
reply_parameters['chat_id'] = update['chat']['id']
for text_chunk, is_last in text_chunks:
_reply_markup = (reply_markup if is_last else None)
sent_message_update = await self.sendMessage(
chat_id=chat_id,
text=text_chunk,
message_thread_id=message_thread_id,
parse_mode=parse_mode,
entities=entities,
link_preview_options=link_preview_options,
disable_notification=disable_notification,
message_thread_id=message_thread_id,
protect_content=protect_content,
reply_parameters=reply_parameters,
disable_web_page_preview=disable_web_page_preview,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=_reply_markup
)
return sent_message_update
@@ -1468,7 +1431,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
parse_mode: str = 'HTML',
entities: List[dict] = None,
disable_web_page_preview: bool = None,
link_preview_options: LinkPreviewOptions = None,
allow_sending_without_reply: bool = None,
reply_markup=None,
update: dict = None):
@@ -1501,10 +1463,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
)
):
if i == 0:
if disable_web_page_preview:
if link_preview_options is None:
link_preview_options = LinkPreviewOptions()
link_preview_options['is_disabled'] = True
edited_message = await self.editMessageText(
text=text_chunk,
chat_id=chat_id,
@@ -1512,7 +1470,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
inline_message_id=inline_message_id,
parse_mode=parse_mode,
entities=entities,
link_preview_options=link_preview_options,
disable_web_page_preview=disable_web_page_preview,
reply_markup=(reply_markup if is_last else None)
)
if chat_id is None:
@@ -1618,7 +1576,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
reply_markup=None,
update: dict = None,
reply_to_update: bool = False,
reply_parameters: ReplyParameters = None,
send_default_keyboard: bool = True,
use_stored_file_id: bool = True):
"""Send photos.
@@ -1642,15 +1599,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
chat_id = self.get_chat_id(update)
if reply_to_update and 'message_id' in update:
reply_to_message_id = update['message_id']
if reply_to_message_id:
if reply_parameters is None:
reply_parameters = ReplyParameters(message_id=reply_to_message_id)
reply_parameters['message_id'] = reply_to_message_id
if allow_sending_without_reply:
reply_parameters['allow_sending_without_reply'] = allow_sending_without_reply
if reply_to_update and 'chat' in update and 'id' in update['chat']:
if update['chat']['id'] != chat_id:
reply_parameters['chat_id'] = update['chat']['id']
if (
send_default_keyboard
and reply_markup is None
@@ -1704,7 +1652,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
parse_mode=parse_mode,
caption_entities=caption_entities,
disable_notification=disable_notification,
reply_parameters=reply_parameters,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=reply_markup
)
if isinstance(sent_update, Exception):
@@ -1752,7 +1701,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
reply_markup=None,
update: dict = None,
reply_to_update: bool = False,
reply_parameters: ReplyParameters = None,
send_default_keyboard: bool = True,
use_stored_file_id: bool = True):
"""Send audio files.
@@ -1776,15 +1724,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
chat_id = self.get_chat_id(update)
if reply_to_update and 'message_id' in update:
reply_to_message_id = update['message_id']
if reply_to_message_id:
if reply_parameters is None:
reply_parameters = ReplyParameters(message_id=reply_to_message_id)
reply_parameters['message_id'] = reply_to_message_id
if allow_sending_without_reply:
reply_parameters['allow_sending_without_reply'] = allow_sending_without_reply
if reply_to_update and 'chat' in update and 'id' in update['chat']:
if update['chat']['id'] != chat_id:
reply_parameters['chat_id'] = update['chat']['id']
if (
send_default_keyboard
and reply_markup is None
@@ -1842,7 +1781,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
title=title,
thumbnail=thumbnail,
disable_notification=disable_notification,
reply_parameters=reply_parameters,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=reply_markup
)
if isinstance(sent_update, Exception):
@@ -1886,7 +1826,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
reply_markup=None,
update: dict = None,
reply_to_update: bool = False,
reply_parameters: ReplyParameters = None,
send_default_keyboard: bool = True,
use_stored_file_id: bool = True):
"""Send voice messages.
@@ -1910,15 +1849,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
chat_id = self.get_chat_id(update)
if reply_to_update and 'message_id' in update:
reply_to_message_id = update['message_id']
if reply_to_message_id:
if reply_parameters is None:
reply_parameters = ReplyParameters(message_id=reply_to_message_id)
reply_parameters['message_id'] = reply_to_message_id
if allow_sending_without_reply:
reply_parameters['allow_sending_without_reply'] = allow_sending_without_reply
if reply_to_update and 'chat' in update and 'id' in update['chat']:
if update['chat']['id'] != chat_id:
reply_parameters['chat_id'] = update['chat']['id']
if (
send_default_keyboard
and reply_markup is None
@@ -1973,7 +1903,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
caption_entities=caption_entities,
duration=duration,
disable_notification=disable_notification,
reply_parameters=reply_parameters,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=reply_markup
)
if isinstance(sent_update, Exception):
@@ -2020,7 +1951,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
document_name: str = None,
update: dict = None,
reply_to_update: bool = False,
reply_parameters: ReplyParameters = None,
send_default_keyboard: bool = True,
use_stored_file_id: bool = False):
"""Send a document.
@@ -2053,15 +1983,6 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
return
if reply_to_update and 'message_id' in update:
reply_to_message_id = update['message_id']
if reply_to_message_id:
if reply_parameters is None:
reply_parameters = ReplyParameters(message_id=reply_to_message_id)
reply_parameters['message_id'] = reply_to_message_id
if allow_sending_without_reply:
reply_parameters['allow_sending_without_reply'] = allow_sending_without_reply
if reply_to_update and 'chat' in update and 'id' in update['chat']:
if update['chat']['id'] != chat_id:
reply_parameters['chat_id'] = update['chat']['id']
if chat_id > 0:
user_record = self.db['users'].find_one(telegram_id=chat_id)
language = self.get_language(update=update, user_record=user_record)
@@ -2140,7 +2061,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
caption=caption,
parse_mode=parse_mode,
disable_notification=disable_notification,
reply_parameters=reply_parameters,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
update=update,
reply_to_update=reply_to_update,
@@ -2171,7 +2092,8 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
caption_entities=caption_entities,
disable_content_type_detection=disable_content_type_detection,
disable_notification=disable_notification,
reply_parameters=reply_parameters,
reply_to_message_id=reply_to_message_id,
allow_sending_without_reply=allow_sending_without_reply,
reply_markup=reply_markup
)
if isinstance(sent_update, Exception):
@@ -2205,8 +2127,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
return sent_update
async def download_file(self, file_id,
file_name=None, path=None,
prevent_overwriting: bool = False):
file_name=None, path=None):
"""Given a telegram `file_id`, download the related file.
Telegram may not preserve the original file name and MIME type: the
@@ -2216,35 +2137,26 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
file = await self.getFile(file_id=file_id)
if file is None or isinstance(file, Exception):
logging.error(f"{file}")
return file
if self.api_url == 'https://api.telegram.org':
return
file_bytes = await async_get(
url=(
f"{self.api_url}/file/"
f"https://api.telegram.org/file/"
f"bot{self.token}/"
f"{file['file_path']}"
),
mode='raw'
)
path = path or self.path
if file_name is None:
while file_name is None:
file_name = get_secure_key(length=10)
file_complete_path = os.path.join(path, file_name)
if prevent_overwriting:
while os.path.exists(file_complete_path):
file_complete_path = file_complete_path + '1'
if os.path.exists(f"{path}/{file_name}"):
file_name = None
try:
with open(file_complete_path, 'wb') as local_file:
with open(f"{path}/{file_name}", 'wb') as local_file:
local_file.write(file_bytes)
except Exception as e:
logging.error(f"File download failed due to {e}")
return e
else:
file_complete_path = file['file_path']
return dict(file_id=file_id,
file_name=file_name,
path=path,
file_complete_path=file_complete_path)
return
def translate_inline_query_answer_result(self, record,
update=None, user_record=None):
@@ -2853,7 +2765,9 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
"""
if not callable(condition):
raise TypeError(
f'Condition {condition.__name__} is not a callable'
'Condition {c} is not a callable'.format(
c=condition.__name__
)
)
def query_decorator(handler):
@@ -3194,41 +3108,26 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
Restart bots if bot can't be got.
"""
for _ in range(60):
if not self._getting_me:
break
await asyncio.sleep(0.5)
else:
raise TimeoutError("Getting bot information was in progress but "
"did not make it in 30 seconds...")
if self._got_me:
return
self._getting_me = True
try:
me = await self.getMe()
if isinstance(me, Exception):
raise me
if me is None:
raise TypeError('getMe returned None')
elif me is None:
raise Exception('getMe returned None')
self._name = me["username"]
self._telegram_id = me['id']
except Exception as e:
logging.error(
"API getMe method failed, information about this bot could "
"not be retrieved. Restarting in 5 minutes...\n\n"
"Error information:\n%s", e
f"API getMe method failed, information about this bot could "
f"not be retrieved. Restarting in 5 minutes...\n\n"
f"Error information:\n{e}"
)
self._getting_me = False
await asyncio.sleep(5*60)
if self._got_me:
return
self.__class__.stop(
message="Information about this bot could not be retrieved.\n"
"Restarting...",
final_state=65
)
self._getting_me = False
self._got_me = True
def setup(self):
"""Make bot ask for updates and handle responses."""
@@ -3243,11 +3142,9 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
async def close_sessions(self):
"""Close open sessions."""
for session_name in list(self.sessions.keys()):
session = self.sessions[session_name]
for session_name, session in self.sessions.items():
if not session.closed:
await session.close()
del self.sessions[session_name]
async def send_one_message(self, *args, **kwargs):
sent_message = await self.send_message(*args, **kwargs)
@@ -3598,7 +3495,7 @@ class Bot(TelegramBot, ObjectWithDatabase, MultiLanguageObject):
Each bot will receive updates via long polling or webhook according to
its initialization parameters.
A single aiohttp.web.Application instance will be run (cls.app) on
local_host:port, and it may serve custom-defined routes as well.
local_host:port and it may serve custom-defined routes as well.
"""
if local_host is not None:
cls.local_host = local_host
-10
View File
@@ -22,16 +22,6 @@ davtelepot_messages = {
}
default_admin_messages = {
'become_admin': {
'success': {
'en': "🎉 You are now administrator! 👑",
'it': "🎉 Ora hai diritti di amministrazione! 👑",
},
'wrong_token': {
'en': "❌ Wrong token 🚷",
'it': "❌ Password errata 🚷",
},
},
'cancel': {
'button': {
'en': "↩️ Cancel",
+1 -1
View File
@@ -51,7 +51,7 @@ setuptools.setup(
license=find_information("license", "davtelepot", "__init__.py"),
long_description=long_description,
long_description_content_type="text/markdown",
url="https://gitea.davte.it/davte/davtelepot",
url="https://gogs.davte.it/davte/davtelepot",
packages=setuptools.find_packages(),
platforms=['any'],
install_requires=[