Source code for glitch

"""
# 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")