Skip to content

Instantly share code, notes, and snippets.

@Tishka17
Created January 7, 2020 20:28
Show Gist options
  • Save Tishka17/5a651a6ae0d2272db35e16768e84da30 to your computer and use it in GitHub Desktop.
Save Tishka17/5a651a6ae0d2272db35e16768e84da30 to your computer and use it in GitHub Desktop.
from functools import partial
from logging import getLogger
from typing import Callable, Tuple, List, Optional
from vk_api import VkApi
from vk_api.longpoll import VkEventType, Event, VkLongPoll
from repo import Repository, UserState
Handler = Callable[[VkApi, Event, UserState], UserState]
Checker = Callable[[Event, UserState], bool]
def check_text(text: str, event: Event, state: UserState) -> bool:
return text == event.text
class Dispatcher:
def __init__(self, default_handler: Optional[Handler] = None):
self.handlers: List[Tuple[Checker, Handler]] = []
self.default_handler = default_handler
def get_handler(self, event: Event, state: UserState) -> Optional[Handler]:
for checker, handler in self.handlers:
if checker(event, state):
return handler
return self.default_handler
def add_handler(self, checker: Checker, handler: Handler) -> None:
self.handlers.append((checker, handler))
def add_text_handler(self, text: str, handler: Handler):
# noinspection PyTypeChecker
self.add_handler(partial(check_text, text), handler)
class Bot:
__logger = getLogger(__name__)
def __init__(self, repo: Repository, dispatcher: Dispatcher, vk_api: VkApi):
self.repo = repo
self.dispatcher = dispatcher
self.vk_api = vk_api
def _handle_message(self, event: Event):
if not (event.type == VkEventType.MESSAGE_NEW and event.to_me and event.text):
return
self.__logger.debug("Processing message: (%s) %s", event.user_id, event.text)
state = self.repo.get_state(event.user_id)
handler = self.dispatcher.get_handler(event, state)
if handler:
state = handler(self.vk_api, event, state)
self.repo.set_state(event.user_id, state)
def run(self):
self.__logger.info("Start polling")
long_poll = VkLongPoll(self.vk_api)
for event in long_poll.listen():
try:
self._handle_message(event)
except Exception:
self.__logger.exception("Error during message handling: %s", event)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment