"""
# EyeRCBot | Glitch
# Written by croxis
# As is. If it somehow removes your root directory, it isn't my fault.
"""
CONFIG_VERSION = 21
DATABASE_VERSION = 1
# Version marker changes
# 1.0 -- Default
# 1.1 -- USER --> USERS
# 1.2 -- Plugin system now handles exceptions which are written to log without killing the whole bot
# 1.3 -- We now pass the bot instance to the plugins
# 1.4 -- More organized code. Bot responds in manner it was communicated in
# 2.0 -- Twisted library backend. This is for AMAZEMENT!
# 3.0 -- Python 3!
# 3.1 -- Asynchat powered backend
# 3.2
# 3.3 -- Moving to decorators for plugin api
# 3.4 -- Added decorator for adding function to the messenger
# 3.5 -- Switching to requests
# 4.0 -- Httplib2 removed. HAS_CONFIG removed. alias and event maps removed
# 4.1 -- Now using https://github.com/goldsmith/Wikipedia for wikipedia requests
# 4.2 -- Now using feedparser for the feed plugin
# 5.0 -- Switched to asyncio
# 5.2 -- Wsgi and flask support
# 6.0 -- Mongo mongo mongo!
# 6.1 -- Updated apscheduler to 3.x
# 6.2 -- Stats (to some degree)
# 6.3 -- Webchat
# 6.4 -- Katawa's karma plugin
# 6.5 -- GeoIp localized and separate plugin.
# 6.6 -- Database schema version support
# Version string: Rewrite, New core feature or plugin, bug fix
VERSION = 6, 6, 0
import asyncio
import logging
import logging.handlers
import signal
import yaml
from apscheduler.schedulers.asyncio import AsyncIOScheduler
config = {}
# Memory is a generic volatile dict for whatever the bot is trying to track
# that may span plugins.
# This is not very secure as any plugin can access it and conflicts can arise.
# If the plugin does not need to share the data, then store that information
# within the plugin.
memory = {}
scheduler = AsyncIOScheduler()
loop = asyncio.get_event_loop()
log = logging.getLogger(__name__)
LOG_LEVELS = {'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL}
from . import messenger
from . import database
from . import plugins
[docs]def get_nick(server):
"""Return the bot nick of a given server.
:param server:
"""
if server not in config['servers']:
return ''
return config['servers'][server]['nick']
[docs]def init(conf):
"""Bot setup and run forever.
:param conf:
"""
for key, value in conf.items():
config[key] = value
log.setLevel(LOG_LEVELS[config["logs"]])
log_path = (config["basedir"] +
config["logdir"] +
config["name"] + '.log')
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
stream = logging.StreamHandler()
stream.setFormatter(formatter)
log.addHandler(stream)
handler = logging.handlers.TimedRotatingFileHandler(
log_path, when='D', backupCount=7)
handler.setFormatter(formatter)
log.addHandler(handler)
log.info('Logging handlers added.')
database.init(conf['name'], config['database']['hostname'], config['database']['port'])
# Import done here for db initialization timings. Make more pythonic?
from .import network
scheduler.start()
messenger.send('load all plugins')
messenger.send('connect all')
messenger.send('start all')
log.info("Entering main loop")
loop.add_signal_handler(signal.SIGHUP, SIGHUP)
loop.add_signal_handler(signal.SIGINT, SIGINT)
loop.run_forever()
@messenger.add('quitAll')
def stop(message=''):
loop.stop()
def SIGHUP():
# send('quitAll')
# self.quit('HUP')
# time.sleep(1)
# try:
# self.protocol.transport.close()
# finally:
pass
def SIGINT():
# send('quitAll')
# self.notify('SIGINT')
# if getattr(self, 'protocol', None):
# self.quit('INT')
# time.sleep(1)
# self.loop.stop()
loop.stop()
[docs]def save_config():
"""
Write bot configuration to file.
"""
with open('bot.yaml', 'w') as stream:
yaml.dump(config, stream)
log.info("Configuration saved")