diff options
author | Stefan Hacker <dd0t@users.sourceforge.net> | 2016-03-12 06:41:49 +0300 |
---|---|---|
committer | Stefan Hacker <dd0t@users.sourceforge.net> | 2016-03-12 06:41:49 +0300 |
commit | 5886ca6ccaf5d201514d020554e4a4abbeda8119 (patch) | |
tree | 4d858c8f2f7d5b89eca1ffc8726fcc9733a2e925 | |
parent | 787c83c926108bec81b5c4e667a5d4ce55da373d (diff) |
Remove legacy mumo and refer to new repo instead
-rw-r--r-- | Bots/mumo/README.md | 1 | ||||
-rw-r--r-- | Bots/mumo/mumo.ini | 32 | ||||
-rw-r--r-- | Bots/mumo/mumo.py | 378 |
3 files changed, 1 insertions, 410 deletions
diff --git a/Bots/mumo/README.md b/Bots/mumo/README.md new file mode 100644 index 0000000..fadcf2f --- /dev/null +++ b/Bots/mumo/README.md @@ -0,0 +1 @@ +See https://github.com/mumble-voip/mumo/ diff --git a/Bots/mumo/mumo.ini b/Bots/mumo/mumo.ini deleted file mode 100644 index 82cb974..0000000 --- a/Bots/mumo/mumo.ini +++ /dev/null @@ -1,32 +0,0 @@ -[autoaway] -; Interval in which to check for idle users in seconds (0 = disable auto away) -interval = 0 -; Time after which a user is considered idle in seconds -timeout = 3600 -; Should the script mute idle users -mute = True -; Should the script mute and deafen idle users (overrides mute) -deafen = False -; To which channel should the script move idle users (-1 = disabled) -channel = -1 - -[onjoin] -; Every player will get moved into the channel with this id on connect (-1 = disabled) -movetochannel = -1 - -[murmur] -; ID of the server the script should operate on -server = 1 - -; Ice configuration -[ice] -host = 127.0.0.1 -port = 6502 -slice = Murmur.ice -secret = - -; Logging configuration -[log] -; Available loglevels: 10 = DEBUG (default) | 20 = INFO | 30 = WARNING | 40 = ERROR -level = -file = mumo.log
\ No newline at end of file diff --git a/Bots/mumo/mumo.py b/Bots/mumo/mumo.py deleted file mode 100644 index 4ff529a..0000000 --- a/Bots/mumo/mumo.py +++ /dev/null @@ -1,378 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 - -# Copyright (C) 2010 Stefan Hacker <dd0t@users.sourceforge.net> -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# - Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# - Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# - Neither the name of the Mumble Developers nor the names of its -# contributors may be used to endorse or promote products derived from this -# software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# - -# mumo.py -# -# mumo, the Mumble moderator script can perform a range of common -# tasks on a Mumble server. It connects to Murmur using Ice. -# -# The script can currently perform the following tasks: -# * Auto mute inactive players and move them to an afk channel -# - -import sys -import Ice -import thread -import logging -import ConfigParser -import time - -from logging import (debug, - info, - warning, - error, - critical, - getLogger) -from optparse import OptionParser - -def x2bool(s): - """Helper function to convert strings from the config to bool""" - if isinstance(s, bool): - return s - elif isinstance(s, basestring): - return s.lower() in ['1', 'true'] - raise ValueError() - -# -#--- Default configuration values -# -cfgfile = 'mumo.ini' -default = {'autoaway':(('interval', int, 0), - ('timeout', int, 3600), - ('mute', x2bool, True), - ('deafen', x2bool, False), - ('channel', int, -1)), - 'onjoin':(('movetochannel', int, -1),), - - 'murmur':(('server', int, 1),), - - 'ice':(('host', str, '127.0.0.1'), - ('port', int, 6502), - ('slice', str, 'Murmur.ice'), - ('secret', str, '')), - - 'iceraw':None, - - 'glacier':(('enabled', x2bool, False), - ('user', str, 'mumo'), - ('password', str, 'secret'), - ('host', str, 'localhost'), - ('port', int, '4063')), - - 'log':(('level', int, logging.DEBUG), - ('file', str, 'mumo.log'))} - -# -#--- Helper classes -# -class config(object): - """ - Small abstraction for config loading - """ - - def __init__(self, filename = None, default = None): - if not filename or not default: return - cfg = ConfigParser.ConfigParser() - cfg.optionxform = str - cfg.read(filename) - - for h,v in default.iteritems(): - if not v: - # Output this whole section as a list of raw key/value tuples - try: - self.__dict__[h] = cfg.items(h) - except ConfigParser.NoSectionError: - self.__dict__[h] = [] - else: - self.__dict__[h] = config() - for name, conv, vdefault in v: - try: - self.__dict__[h].__dict__[name] = conv(cfg.get(h, name)) - except (ValueError, ConfigParser.NoSectionError, ConfigParser.NoOptionError): - self.__dict__[h].__dict__[name] = vdefault - -def do_main_program(): - # - #--- Callback implementation - # All of this has to go in here so we can correctly daemonize the tool - # without loosing the file descriptors opened by the Ice module - Ice.loadSlice('', ['-I' + Ice.getSliceDir(), cfg.ice.slice]) - import Murmur - - def UpdateUserAutoAway(server, user, index): - if cfg.autoaway.interval <= 0: return - - update = False - if not user in index and user.idlesecs > cfg.autoaway.timeout: - if cfg.autoaway.deafen \ - and not (user.suppress or user.selfMute or user.mute) \ - and not (user.selfDeaf or user.deaf): - info('autoaway: Mute and deafen user %s (%d / %d)', user.name, user.session, user.userid) - user.deaf = True - update = True - elif cfg.autoaway.mute and not (user.suppress or user.selfMute or user.mute): - info('autoaway: Mute user %s (%d / %d)', user.name, user.session, user.userid) - user.mute = True - update = True - - if cfg.autoaway.channel >= 0 and user.channel != cfg.autoaway.channel: - info('autoaway: Move user %s (%d / %d)', user.name, user.session, user.userid) - user.channel = cfg.autoaway.channel - update = True - - if update: - index.add(user.session) - - elif user.session in index and user.idlesecs < cfg.autoaway.timeout: - index.remove(user.session) - if cfg.autoaway.deafen: - info('autoaway: Unmute and undeafen user %s (%d / %d)', user.name, user.session, user.userid) - user.mute = False - user.deafen = False - update = True - elif cfg.autoaway.mute: - info('autoaway: Unmute user %s (%d / %d)', user.name, user.session, user.userid) - user.mute = False - update = True - - if update: - server.setState(user) - - class mumoApp(Ice.Application): - def run(self, args): - self.shutdownOnInterrupt() - - self.index = set() - - if not self.initializeIceConnection(): - return 1 - - # Figure out what our polling interval will be - interval = cfg.autoaway.interval - - if interval != 0: - # If we have polling tasks perform them - while True: - self.handleAutoAway() - time.sleep(interval) - - else: - # Serve till we are stopped - self.communicator().waitForShutdown() - - if self.interrupted(): - warning('Caught interrupt, shutting down') - - return 0 - - def handleAutoAway(self): - meta = self.meta - server = meta.getServer(cfg.murmur.server) - if server: - for user in server.getUsers().itervalues(): - UpdateUserAutoAway(server, user, self.index) - - - def initializeIceConnection(self): - """ - Establishes the two-way Ice connection and adds the callback to the - configured servers - """ - ice = self.communicator() - - if cfg.ice.secret: - debug('Using shared ice secret') - ice.getImplicitContext().put("secret", cfg.ice.secret) - elif not cfg.glacier.enabled: - warning('Consider using an ice secret to improve security') - - if cfg.glacier.enabled: - #info('Connecting to Glacier2 server (%s:%d)', glacier_host, glacier_port) - error('Glacier support not implemented yet') - #TODO: Implement this - - info('Connecting to Ice server (%s:%d)', cfg.ice.host, cfg.ice.port) - base = ice.stringToProxy('Meta:tcp -h %s -p %d' % (cfg.ice.host, cfg.ice.port)) - try: - meta = Murmur.MetaPrx.checkedCast(base) - except Ice.LocalException, e: - error('Could not connect to Ice server, error %d: %s', e.error, str(e).replace('\n', ' ')) - return False - - adapter = ice.createObjectAdapterWithEndpoints('Callback.Client', 'tcp -h %s' % cfg.ice.host) - adapter.activate() - - try: - server = meta.getServer(cfg.murmur.server) - except Murmur.InvalidSecretException: - error('Invalid ice secret') - return False - - if server: - info('Setting callback for server %d', server.id()) - callbackprx = adapter.addWithUUID(ServerCallback(server, self.index, adapter)) - callback = Murmur.ServerCallbackPrx.uncheckedCast(callbackprx) - server.addCallback(callback) - - self.meta = meta - return True - - class ServerCallback(Murmur.ServerCallback): - def __init__(self, server, index, adapter): - Murmur.ServerCallback.__init__(self) - self.index = index - self.server = server - - def userStateChanged(self, u, current=None): - UpdateUserAutoAway(self.server, u, self.index) - - def userDisconnected(self, u, current=None): - if u.session in self.index: - self.index.remove(u.session) - - def userConnected(self, u, current=None): - if cfg.onjoin.movetochannel >= 0: - info('onjoin: Moving user %s (%d / %d)', u.name, u.session, u.userid) - u.channel = cfg.onjoin.movetochannel - self.server.setState(u) - - def channelCreated(self, c, current=None): pass # Unused callback - def channelRemoved(self, c, current=None): pass - def channelStateChanged(self, c, current=None): pass - - class CustomLogger(Ice.Logger): - """ - Logger implementation to pipe Ice log messages into - out own log - """ - - def __init__(self): - Ice.Logger.__init__(self) - self._log = getLogger("Ice") - - def _print(self, message): - self._log.info(message) - - def trace(self, category, message): - self._log.debug("Trace %s: %s", category, message) - - def warning(self, message): - self._log.warning(message) - - def error(self, message): - self._log.error(message) - - # - #--- Start of authenticator - # - info('Starting mumble moderator script') - initdata = Ice.InitializationData() - initdata.properties = Ice.createProperties([], initdata.properties) - for prop, val in cfg.iceraw: - initdata.properties.setProperty(prop, val) - - initdata.properties.setProperty("Ice.ImplicitContext", "Shared") - initdata.logger = CustomLogger() - - app = mumoApp() - state = app.main(sys.argv[:1], initData = initdata) - info('Shutdown complete') - -# -#--- Start of program -# -if __name__ == '__main__': - # Parse commandline options - parser = OptionParser() - parser.add_option('-i', '--ini', - help = 'load configuration from INI', default = cfgfile) - parser.add_option('-v', '--verbose', action='store_true', dest = 'verbose', - help = 'verbose output [default]', default = True) - parser.add_option('-q', '--quiet', action='store_false', dest = 'verbose', - help = 'only error output') - parser.add_option('-d', '--daemon', action='store_true', dest = 'force_daemon', - help = 'run as daemon', default = False) - parser.add_option('-a', '--app', action='store_true', dest = 'force_app', - help = 'do not run as daemon', default = False) - (option, args) = parser.parse_args() - - if option.force_daemon and option.force_app: - parser.print_help() - sys.exit(1) - - # Load configuration - try: - cfg = config(option.ini, default) - except Exception, e: - print>>sys.stderr, 'Fatal error, could not load config file from "%s"' % cfgfile - sys.exit(1) - - # Initialize logger - if cfg.log.file: - try: - logfile = open(cfg.log.file, 'a') - except IOError, e: - print>>sys.stderr, 'Fatal error, could not open logfile "%s"' % cfg.log.file - sys.exit(1) - else: - logfile = logging.sys.stderr - - - if option.verbose: - level = cfg.log.level - else: - level = logging.ERROR - - logging.basicConfig(level = level, - format='%(asctime)s %(levelname)s %(message)s', - stream = logfile) - - # As the default try to run as daemon. Silently degrade to running as a normal application if this fails - # unless the user explicitly defined what he expected with the -a / -d parameter. - try: - if option.force_app: - raise ImportError # Pretend that we couldn't import the daemon lib - import daemon - except ImportError: - if option.force_daemon: - print>>sys.stderr, 'Fatal error, could not daemonize process due to missing "daemon" library, ' \ - 'please install the missing dependency and restart the script' - sys.exit(1) - do_main_program() - else: - context = daemon.DaemonContext(working_directory = sys.path[0], - stderr = logfile) - context.__enter__() - try: - do_main_program() - finally: - context.__exit__(None, None, None) |