from abc import ABC, abstractmethod from pathlib import Path from wiki_postbot.interfaces.mediawiki import Wiki from wiki_postbot.logger import init_logger from wiki_postbot.patterns.wikilink import Wikilink from typing import TYPE_CHECKING, List if TYPE_CHECKING: from logging import Logger class Client(ABC): """ Metaclass for different clients (things that receive inputs like discord/slack messages) pending some actual formalization of the concepts in this library (like idk what do we call the wiki, a sink? idk) Subclasses must implement all the abstract methods (that is, i guess, the definition of abstract methods) but may do whatever other logic they need to do to handle messages, eg. discord bot subclasses """ def __init__( self, wiki:Wiki, name: str = "wikibot_client", log_dir: Path = Path('/var/log/wikibot'), ): super(Client, self).__init__() self._wiki = None self.wiki = wiki self.name = name self.log_dir = Path(log_dir) self.logger = self._init_logger(name=self.name, log_dir=self.log_dir) # -------------------------------------------------- # abstract methods # -------------------------------------------------- # @abstractmethod # def _react_progress(self, message): # """React to a message indicating that we are processing it""" # pass # @abstractmethod # def _react_complete(self, message): # """React to a message indicating that we have completed processing it""" # pass # @abstractmethod # def _react_error(self, message): # """React to a message indicating there was some error""" @abstractmethod def parse_wikilinks(self, message) -> List[Wikilink]: """Parse a given message, returning the wikilinks it contains""" @abstractmethod def handle_wikilinks(self, message, wl: List[Wikilink]): """Handle the message with wikilinks, most likely by posting it to the wiki!""" # -------------------------------------------------- # Properties # -------------------------------------------------- @property def wiki(self) -> Wiki: return self._wiki @wiki.setter def wiki(self, wiki: Wiki): if wiki.sess is None: raise RuntimeError("Wiki client is not logged in! Login before passing to client") self._wiki = wiki # -------------------------------------------------- # Private methods # -------------------------------------------------- def _init_logger(self, name:str, log_dir:Path) -> 'Logger': # Try and make log directory, if we cant, it should fail. log_dir.mkdir(exist_ok=True) logger = init_logger(name=name, basedir=log_dir) return logger