ForwardXMPP/forwardxmpp/config.py
2020-04-20 10:01:22 -04:00

105 lines
3.4 KiB
Python

import collections
import configparser
import logging
import re
import slixmpp
logger = logging.getLogger('forwardxmpp.config')
Forward = collections.namedtuple('Forward', ('from_re', 'to_jid', 'body_fmt'))
class Config(configparser.ConfigParser):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
bot_section = self.setdefault('Bot', {})
bot_section.setdefault('loglevel', 'warning')
bot_section.setdefault('max_retry_wait', '300')
def read_paths(self, paths_seq, encoding=None):
for path in paths_seq:
try:
with path.open(encoding=encoding) as source:
self.read_file(source)
except OSError as error:
logger.error("error reading %s: %s", path, error.strerror)
else:
yield path
def ready(self):
retval = True
if not self['Bot'].get('jid'):
logger.error("Bot configuration missing jid")
retval = False
if self['Bot'].get('password') is None:
logger.error("Bot configuration missing password")
retval = False
if not any(self._forward_sections()):
logger.error("no forwarding sections found in configuration")
retval = False
if self.get_loglevel(-1) == -1:
logger.error("invalid loglevel setting %r", self['Bot']['loglevel'])
retval = False
if self.get_max_retry_wait(-1) == -1:
logger.error("invalid max_retry_wait setting %r", self['Bot']['max_retry_wait'])
retval = False
return retval
def bot_jid(self):
retval = slixmpp.JID(self['Bot']['jid'])
if not retval.resource:
retval.resource = 'ForwardXMPP'
return retval
def bot_password(self):
return self['Bot']['password']
def bot_nick(self):
try:
return self['Bot']['nickname']
except KeyError:
return self.bot_jid().user
def _forward_sections(self):
for skey in self.sections():
if skey.startswith('Forward '):
yield skey, self[skey]
def forwards(self):
re_cache = {}
for key, section in self._forward_sections():
try:
from_re = re_cache[section['from']]
except KeyError:
from_re = re.compile(section['from'])
re_cache[section['from']] = from_re
value = Forward(
from_re,
slixmpp.JID(section['to']),
section.get('format', "Forwarded message from {from.full}: {body}"),
)
yield (key, value)
def get_loglevel(self, fallback=None):
loglevel_s = self['Bot'].get('loglevel', 'warning')
try:
retval = getattr(logging, loglevel_s.upper())
except (AttributeError, TypeError, ValueError):
if fallback is None:
raise
else:
return fallback
else:
return retval
def get_max_retry_wait(self, fallback=None):
try:
retval = float(self['Bot'].get('max_retry_wait', 300))
if retval < 5:
raise ValueError("max_retry_wait {} too low".format(retval))
except ValueError:
if fallback is None:
raise
else:
retval = fallback
return retval