1
0
mirror of https://github.com/eternnoir/pyTelegramBotAPI.git synced 2023-08-10 21:12:57 +03:00

Merge pull request #1422 from Badiboy/master

Code base cleanup
This commit is contained in:
Badiboy 2022-01-25 10:27:10 +03:00 committed by GitHub
commit 8d49d22074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 53 additions and 98 deletions

View File

@ -20,7 +20,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.6','3.7','3.8','3.9', 'pypy-3.6', 'pypy-3.7' ] #'pypy-3.8', 'pypy-3.9' NOT SUPPORTED NOW
python-version: [ '3.6','3.7','3.8','3.9', 'pypy-3.7', 'pypy-3.8' ] #'pypy-3.9' NOT SUPPORTED NOW
name: ${{ matrix.python-version }} and tests
steps:
- uses: actions/checkout@v2

View File

@ -9,7 +9,7 @@ import telebot
from telebot import types
# Initialize bot with your token
bot = telebot.TeleBot(TOKEN)
bot = telebot.TeleBot('TOKEN')
# The `users` variable is needed to contain chat ids that are either in the search or in the active dialog, like {chat_id, chat_id}
users = {}
@ -47,7 +47,7 @@ def find(message: types.Message):
if message.chat.id not in users:
bot.send_message(message.chat.id, 'Finding...')
if freeid == None:
if freeid is None:
freeid = message.chat.id
else:
# Question:

View File

@ -1,9 +1,8 @@
import telebot
from telebot import asyncio_filters
from telebot.async_telebot import AsyncTeleBot
# list of storages, you can use any storage
from telebot.asyncio_storage import StateRedisStorage,StateMemoryStorage,StatePickleStorage
from telebot.asyncio_storage import StateMemoryStorage
# new feature for states.
from telebot.asyncio_handler_backends import State, StatesGroup

View File

@ -1,6 +1,5 @@
# Just a little example of middleware handlers
import telebot
from telebot.asyncio_handler_backends import BaseMiddleware
from telebot.async_telebot import AsyncTeleBot
from telebot.async_telebot import CancelUpdate

View File

@ -4,7 +4,7 @@ from telebot import custom_filters
from telebot.handler_backends import State, StatesGroup #States
# States storage
from telebot.storage import StateRedisStorage, StatePickleStorage, StateMemoryStorage
from telebot.storage import StateMemoryStorage
# Beginning from version 4.4.0+, we support storages.

View File

@ -18,7 +18,6 @@ def send_welcome(message):
def beep(chat_id) -> None:
"""Send the beep message."""
bot.send_message(chat_id, text='Beep!')
return schedule.CancelJob # Run a job once
@bot.message_handler(commands=['set'])

View File

@ -5,6 +5,7 @@
# Documenation to Tornado: http://tornadoweb.org
import signal
from typing import Optional, Awaitable
import tornado.httpserver
import tornado.ioloop
@ -33,12 +34,18 @@ bot = telebot.TeleBot(API_TOKEN)
class Root(tornado.web.RequestHandler):
def data_received(self, chunk: bytes) -> Optional[Awaitable[None]]:
pass
def get(self):
self.write("Hi! This is webhook example!")
self.finish()
class webhook_serv(tornado.web.RequestHandler):
class WebhookServ(tornado.web.RequestHandler):
def data_received(self, chunk: bytes) -> Optional[Awaitable[None]]:
pass
def get(self):
self.write("What are you doing here?")
self.finish()
@ -93,7 +100,7 @@ tornado.options.parse_command_line()
signal.signal(signal.SIGINT, signal_handler)
application = tornado.web.Application([
(r"/", Root),
(r"/" + WEBHOOK_SECRET, webhook_serv)
(r"/" + WEBHOOK_SECRET, WebhookServ)
])
http_server = tornado.httpserver.HTTPServer(application, ssl_options={

View File

@ -9,7 +9,7 @@ import time
import traceback
from typing import Any, Callable, List, Optional, Union
# this imports are used to avoid circular import error
# these imports are used to avoid circular import error
import telebot.util
import telebot.types
@ -33,13 +33,11 @@ from telebot.handler_backends import MemoryHandlerBackend, FileHandlerBackend
from telebot.custom_filters import SimpleCustomFilter, AdvancedCustomFilter
REPLY_MARKUP_TYPES = Union[
types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup,
types.ReplyKeyboardRemove, types.ForceReply]
"""
Module : telebot
"""
@ -156,7 +154,6 @@ class TeleBot:
:param parse_mode: default parse_mode
:return: Telebot object.
"""
self.token = token
self.parse_mode = parse_mode
self.update_listener = []
@ -196,7 +193,6 @@ class TeleBot:
self.current_states = state_storage
if apihelper.ENABLE_MIDDLEWARE:
self.typed_middleware_handlers = {
'message': [],
@ -251,8 +247,7 @@ class TeleBot:
:param filename: Filename of saving file
"""
self.current_states = StatePickleStorage(filename=filename)
self.current_states = StatePickleStorage(file_path=filename)
self.current_states.create_dir()
def enable_save_reply_handlers(self, delay=120, filename="./.handler-saves/reply.save"):
@ -519,7 +514,6 @@ class TeleBot:
self.process_new_chat_member(new_chat_members)
if chat_join_request:
self.process_new_chat_join_request(chat_join_request)
def process_new_messages(self, new_messages):
self._notify_next_handlers(new_messages)
@ -590,7 +584,6 @@ class TeleBot:
for listener in self.update_listener:
self._exec_task(listener, new_messages)
def infinity_polling(self, timeout: int=20, skip_pending: bool=False, long_polling_timeout: int=20, logger_level=logging.ERROR,
allowed_updates: Optional[List[str]]=None, *args, **kwargs):
"""
@ -778,7 +771,7 @@ class TeleBot:
logger.info('Stopped polling.')
def _exec_task(self, task, *args, **kwargs):
if kwargs.get('task_type') == 'handler':
if kwargs and kwargs.get('task_type') == 'handler':
pass_bot = kwargs.get('pass_bot')
kwargs.pop('pass_bot')
kwargs.pop('task_type')
@ -956,7 +949,6 @@ class TeleBot:
"""
Use this method to send text messages.
Warning: Do not send more than about 4000 characters each message, otherwise you'll risk an HTTP 414 error.
If you must send more than 4000 characters,
use the `split_string` or `smart_split` function in util.py.
@ -1419,7 +1411,6 @@ class TeleBot:
allow_sending_without_reply, protect_content)
return [types.Message.de_json(msg) for msg in result]
# TODO: Rewrite this method like in API.
def send_location(
self, chat_id: Union[int, str],
@ -1434,8 +1425,6 @@ class TeleBot:
proximity_alert_radius: Optional[int]=None,
allow_sending_without_reply: Optional[bool]=None,
protect_content: Optional[bool]=None) -> types.Message:
"""
Use this method to send point on the map.
:param chat_id:
@ -1735,7 +1724,6 @@ class TeleBot:
:return: True on success.
"""
return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
def ban_chat_sender_chat(self, chat_id: Union[int, str], sender_chat_id: Union[int, str]) -> bool:
"""
@ -1767,7 +1755,6 @@ class TeleBot:
"""
return apihelper.unban_chat_sender_chat(self.token, chat_id, sender_chat_id)
def set_chat_permissions(
self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool:
"""
@ -2262,7 +2249,6 @@ class TeleBot:
:param protect_content:
:return:
"""
if isinstance(question, types.Poll):
raise RuntimeError("The send_poll signature was changed, please see send_poll function details.")
@ -2445,7 +2431,6 @@ class TeleBot:
self.token, user_id, name, title, emojis, png_sticker, tgs_sticker,
contains_masks, mask_position)
def add_sticker_to_set(
self, user_id: int, name: str, emojis: str,
png_sticker: Optional[Union[Any, str]]=None,
@ -2466,7 +2451,6 @@ class TeleBot:
return apihelper.add_sticker_to_set(
self.token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position)
def set_sticker_position_in_set(self, sticker: str, position: int) -> bool:
"""
Use this method to move a sticker in a set created by the bot to a specific position . Returns True on success.
@ -2542,8 +2526,9 @@ class TeleBot:
def set_state(self, user_id: int, state: Union[int, str], chat_id: int=None) -> None:
"""
Sets a new state of a user.
:param chat_id:
:param user_id:
:param state: new state. can be string or integer.
:param chat_id:
"""
if chat_id is None:
chat_id = user_id
@ -2557,10 +2542,12 @@ class TeleBot:
"""
if chat_id is None:
chat_id = user_id
self.current_states.reset_data(chat_id, user_id)
def delete_state(self, user_id: int, chat_id: int=None) -> None:
"""
Delete the current state of a user.
:param user_id:
:param chat_id:
:return:
"""
@ -2576,6 +2563,7 @@ class TeleBot:
def get_state(self, user_id: int, chat_id: int=None) -> Optional[Union[int, str]]:
"""
Get current state of a user.
:param user_id:
:param chat_id:
:return: state of a user
"""
@ -2586,6 +2574,7 @@ class TeleBot:
def add_data(self, user_id: int, chat_id:int=None, **kwargs):
"""
Add data to states.
:param user_id:
:param chat_id:
"""
if chat_id is None:
@ -2655,8 +2644,8 @@ class TeleBot:
need_pop = True
self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
if need_pop:
new_messages.pop(i) # removing message that was detected with next_step_handler
# removing message that was detected with next_step_handler
new_messages.pop(i)
@staticmethod
def _build_handler_dict(handler, pass_bot=False, **filters):
@ -2697,9 +2686,7 @@ class TeleBot:
print(update.update_id)
:param update_types: Optional list of update types that can be passed into the middleware handler.
"""
def decorator(handler):
self.add_middleware_handler(handler, update_types)
return handler
@ -2737,10 +2724,9 @@ class TeleBot:
bot.register_middleware_handler(print_channel_post_text, update_types=['channel_post', 'edited_channel_post'])
:param callback:
:param update_types: Optional list of update types that can be passed into the middleware handler.
"""
self.add_middleware_handler(callback, update_types)
def message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
@ -2782,7 +2768,6 @@ class TeleBot:
:param content_types: Supported message content types. Must be a list. Defaults to ['text'].
:param chat_types: list of chat types
"""
if content_types is None:
content_types = ["text"]
@ -2856,7 +2841,6 @@ class TeleBot:
:param kwargs:
:return:
"""
if content_types is None:
content_types = ["text"]
@ -3065,7 +3049,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_inline_handler(handler_dict)
@ -3099,7 +3082,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_chosen_inline_handler(handler_dict)
@ -3133,7 +3115,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_callback_query_handler(handler_dict)
@ -3167,7 +3148,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_shipping_query_handler(handler_dict)
@ -3201,7 +3181,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_pre_checkout_query_handler(handler_dict)
@ -3235,7 +3214,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_poll_handler(handler_dict)
@ -3269,7 +3247,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_poll_answer_handler(handler_dict)
@ -3303,7 +3280,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_my_chat_member_handler(handler_dict)
@ -3337,7 +3313,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_chat_member_handler(handler_dict)
@ -3371,7 +3346,6 @@ class TeleBot:
:param kwargs:
:return:
"""
def decorator(handler):
handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
self.add_chat_join_request_handler(handler_dict)
@ -3429,14 +3403,6 @@ class TeleBot:
:param message: Message to test
:return: True if filter conforms
"""
# test_cases = {
# 'content_types': lambda msg: msg.content_type in filter_value,
# 'regexp': lambda msg: msg.content_type == 'text' and re.search(filter_value, msg.text, re.IGNORECASE),
# 'commands': lambda msg: msg.content_type == 'text' and util.extract_command(msg.text) in filter_value,
# 'func': lambda msg: filter_value(msg)
# }
# return test_cases.get(message_filter, lambda msg: False)(message)
if message_filter == 'content_types':
return message.content_type in filter_value
elif message_filter == 'regexp':
@ -3478,8 +3444,3 @@ class TeleBot:
if self._test_message_handler(message_handler, message):
self._exec_task(message_handler['function'], message, pass_bot=message_handler['pass_bot'], task_type='handler')
break

View File

@ -3,7 +3,6 @@ from datetime import datetime
import logging
import re
import sys
import time
import traceback
from typing import Any, List, Optional, Union
@ -22,17 +21,14 @@ from telebot import logger
from telebot import util, types, asyncio_helper
import asyncio
from telebot import asyncio_handler_backends
from telebot import asyncio_filters
REPLY_MARKUP_TYPES = Union[
types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup,
types.ReplyKeyboardRemove, types.ForceReply]
"""
Module : telebot
"""
@ -42,7 +38,6 @@ class Handler:
"""
Class for (next step|reply) handlers
"""
def __init__(self, callback, *args, **kwargs):
self.callback = callback
self.args = args
@ -310,7 +305,6 @@ class AsyncTeleBot:
return
except asyncio.CancelledError:
return
except asyncio_helper.RequestTimeout as e:
logger.error(str(e))
if non_stop:
@ -318,16 +312,12 @@ class AsyncTeleBot:
continue
else:
return
except asyncio_helper.ApiTelegramException as e:
logger.error(str(e))
if non_stop:
continue
else:
break
except KeyboardInterrupt:
return
except Exception as e:
logger.error('Cause exception while getting updates.')
if non_stop:
@ -335,14 +325,12 @@ class AsyncTeleBot:
await asyncio.sleep(3)
continue
else:
raise e
raise e
finally:
self._polling = False
await self.close_session()
logger.warning('Polling is stopped.')
def _loop_create_task(self, coro):
return asyncio.create_task(coro)
@ -357,8 +345,7 @@ class AsyncTeleBot:
for message in messages:
middleware = await self.process_middlewares(message, update_type)
tasks.append(self._run_middlewares_and_handlers(handlers, message, middleware))
asyncio.gather(*tasks)
await asyncio.gather(*tasks)
async def _run_middlewares_and_handlers(self, handlers, message, middleware):
handler_error = None
@ -790,6 +777,7 @@ class AsyncTeleBot:
def register_edited_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, chat_types=None, pass_bot=False, **kwargs):
"""
Registers edited message handler.
:param pass_bot:
:param callback: function to be called
:param content_types: list of content_types
:param commands: list of commands
@ -861,6 +849,7 @@ class AsyncTeleBot:
def register_channel_post_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, pass_bot=False, **kwargs):
"""
Registers channel post message handler.
:param pass_bot:
:param callback: function to be called
:param content_types: list of content_types
:param commands: list of commands
@ -929,6 +918,7 @@ class AsyncTeleBot:
def register_edited_channel_post_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, pass_bot=False, **kwargs):
"""
Registers edited channel post message handler.
:param pass_bot:
:param callback: function to be called
:param content_types: list of content_types
:param commands: list of commands
@ -979,6 +969,7 @@ class AsyncTeleBot:
def register_inline_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers inline handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1012,6 +1003,7 @@ class AsyncTeleBot:
def register_chosen_inline_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers chosen inline handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1045,6 +1037,7 @@ class AsyncTeleBot:
def register_callback_query_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers callback query handler..
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1078,6 +1071,7 @@ class AsyncTeleBot:
def register_shipping_query_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers shipping query handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1111,6 +1105,7 @@ class AsyncTeleBot:
def register_pre_checkout_query_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers pre-checkout request handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1144,6 +1139,7 @@ class AsyncTeleBot:
def register_poll_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers poll handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1177,6 +1173,7 @@ class AsyncTeleBot:
def register_poll_answer_handler(self, callback, func, pass_bot=False, **kwargs):
"""
Registers poll answer handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1210,6 +1207,7 @@ class AsyncTeleBot:
def register_my_chat_member_handler(self, callback, func=None, pass_bot=False, **kwargs):
"""
Registers my chat member handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1243,6 +1241,7 @@ class AsyncTeleBot:
def register_chat_member_handler(self, callback, func=None, pass_bot=False, **kwargs):
"""
Registers chat member handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1276,6 +1275,7 @@ class AsyncTeleBot:
def register_chat_join_request_handler(self, callback, func=None, pass_bot=False, **kwargs):
"""
Registers chat join request handler.
:param pass_bot:
:param callback: function to be called
:param func:
:return: decorated function
@ -1403,7 +1403,7 @@ class AsyncTeleBot:
"""
Alternative for delete_webhook but uses set_webhook
"""
self.set_webhook()
await self.set_webhook()
async def get_webhook_info(self, timeout=None):
"""
@ -3061,6 +3061,7 @@ class AsyncTeleBot:
async def set_state(self, user_id: int, state: str, chat_id: int=None):
"""
Sets a new state of a user.
:param user_id:
:param chat_id:
:param state: new state. can be string or integer.
"""
@ -3081,6 +3082,7 @@ class AsyncTeleBot:
async def delete_state(self, user_id: int, chat_id:int=None):
"""
Delete the current state of a user.
:param user_id:
:param chat_id:
:return:
"""
@ -3096,6 +3098,7 @@ class AsyncTeleBot:
async def get_state(self, user_id, chat_id: int=None):
"""
Get current state of a user.
:param user_id:
:param chat_id:
:return: state of a user
"""
@ -3106,6 +3109,7 @@ class AsyncTeleBot:
async def add_data(self, user_id: int, chat_id: int=None, **kwargs):
"""
Add data to states.
:param user_id:
:param chat_id:
"""
if not chat_id:

View File

@ -1,8 +1,3 @@
import os
import pickle
class BaseMiddleware:
"""
Base class for middleware.
@ -32,4 +27,3 @@ class StatesGroup:
if not name.startswith('__') and not callable(value) and isinstance(value, State):
# change value of that variable
value.name = ':'.join((cls.__name__, name))

View File

@ -43,6 +43,7 @@ class SessionManager:
if self.session.closed:
self.session = await self.create_session()
# noinspection PyProtectedMember
if not self.session._loop.is_running():
await self.session.close()
self.session = await self.create_session()

View File

@ -43,11 +43,10 @@ class StateStorageBase:
async def get_state(self, chat_id, user_id):
raise NotImplementedError
async def save(chat_id, user_id, data):
async def save(self, chat_id, user_id, data):
raise NotImplementedError
class StateContext:
"""
Class for data.

View File

@ -1,4 +1,3 @@
from pickle import FALSE
from telebot.asyncio_storage.base_storage import StateStorageBase, StateContext
import json
@ -93,7 +92,6 @@ class StateRedisStorage(StateStorageBase):
return True
return False
async def get_value(self, chat_id, user_id, key):
"""
Get value for a data of a user in a chat.
@ -105,7 +103,6 @@ class StateRedisStorage(StateStorageBase):
if key in response[user_id]['data']:
return response[user_id]['data'][key]
return None
async def get_state(self, chat_id, user_id):
"""
@ -119,7 +116,6 @@ class StateRedisStorage(StateStorageBase):
return None
async def get_data(self, chat_id, user_id):
"""
Get data of particular user in a particular chat.
@ -131,7 +127,6 @@ class StateRedisStorage(StateStorageBase):
return response[user_id]['data']
return None
async def reset_data(self, chat_id, user_id):
"""
Reset data of a user in a chat.
@ -144,9 +139,6 @@ class StateRedisStorage(StateStorageBase):
await self.set_record(chat_id, response)
return True
async def set_data(self, chat_id, user_id, key, value):
"""
Set data without interactive data.
@ -175,4 +167,3 @@ class StateRedisStorage(StateStorageBase):
response[user_id]['data'] = dict(data, **response[user_id]['data'])
await self.set_record(chat_id, response)
return True

View File

@ -42,7 +42,7 @@ class StateStorageBase:
def get_state(self, chat_id, user_id):
raise NotImplementedError
def save(chat_id, user_id, data):
def save(self, chat_id, user_id, data):
raise NotImplementedError

View File

@ -6,6 +6,7 @@ import pickle
class StatePickleStorage(StateStorageBase):
# noinspection PyMissingConstructor
def __init__(self, file_path="./.state-save/states.pkl") -> None:
self.file_path = file_path
self.create_dir()
@ -109,4 +110,4 @@ class StatePickleStorage(StateStorageBase):
def save(self, chat_id, user_id, data):
self.data[chat_id][user_id]['data'] = data
self.update_data()
self.update_data()

View File

@ -4,7 +4,6 @@ import re
import string
import threading
import traceback
import warnings
from typing import Any, Callable, List, Dict, Optional, Union
# noinspection PyPep8Naming
@ -408,6 +407,7 @@ def OrEvent(*events):
def busy_wait():
while not or_event.is_set():
# noinspection PyProtectedMember
or_event._wait(3)
for e in events:

View File

@ -1,3 +1,3 @@
# Versions should comply with PEP440.
# This line is parsed in setup.py:
__version__ = '4.3.1'
__version__ = '4.4.0'