#!/usr/bin/python
# Upgrade script for CtrlProxy
# Copyright (C) 2005-2006 Jelmer Vernooij <jelmer@samba.org>
import optparse
import sys
import os
from xml.dom import minidom, Node
class UnknownTagError(StandardError):
def __init__(self,tag):
StandardError.__init__(self, 'Unknown tag: %s' % tag.nodeName)
class Channel:
def __init__(self, name=None):
self.name = name
self.autojoin = False
self.key = None
class Network:
def __init__(self, name=None):
self.name = name
self.nick = None
self.fullname = None
self.username = None
self.autoconnect = None
self.channels = {}
self.servers = []
class Plugin:
def __init__(self, name=None, autoload=True, config=None):
if name.startswith('lib'):
name = name[3:]
self.name = name
self.config = config
self.autoload = autoload
class Config:
def __init__(self):
self.plugins = {}
self.networks = {}
self.listeners = []
self.autosend_lines = []
self.nickserv_nicks = []
def has_plugin(self, name):
return self.plugins.has_key(name)
class OldConfigFile(Config):
def _parsePlugin(self,node):
plugin = Plugin(name=node.attributes['file'].value, config=node.childNodes)
if node.attributes.has_key('autoload') and \
node.attributes['autoload'].value == "1":
plugin.autoload = True
if plugin.name == 'nickserv':
for cn in node.childNodes:
if cn.nodeName == 'nick':
self.nickserv_nicks.append(cn.attributes)
plugin.config = None
if plugin.name == 'autosend':
for cn in node.childNodes:
if cn.nodeName == 'nick':
self.autosend_lines.append({
'network': cn.attributes['network'].name,
'data': cn.toxml()})
plugin.config = None
if plugin.name == 'listener':
for cn in node.childNodes:
if cn.nodeName == 'listen':
self.listeners.append(cn.attributes)
plugin.config = None
self.plugins[plugin.name] = plugin
def _parsePlugins(self,node):
for cn in node.childNodes:
if cn.nodeName == 'plugin':
self._parsePlugin(cn)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
def _parseServer(self,node,serverpass):
return node.attributes #FIXME
def _parseServers(self,node,serverpass):
servers = []
for cn in node.childNodes:
if cn.nodeName == 'ipv4' or cn.nodeName == 'ipv6' \
or cn.nodeName == 'pipe' or cn.nodeName == 'server':
servers.append(self._parseServer(cn,serverpass))
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
def _parseChannel(self,node):
channel = Channel()
channel.name = node.attributes['name'].value
if node.attributes.has_key('autojoin') or \
node.attributes['autojoin'].value == '1':
channel.autojoin = True
if node.attributes.has_key('key'):
channel.key = node.attributes['key'].value
return channel
def _parseNickserv(self,name,node):
for cn in node.childNodes:
if cn.nodeName == 'nick' or cn.nodeName == 'nickserv':
nick = {
'network': name,
'password': cn.attributes['password'].value
}
if cn.attributes.has_key('nick'):
nick['nick'] = cn.attributes['nick'].value
elif cn.attributes.has_key('name'):
nick['nick'] = cn.attributes['name'].value
self.nickserv_nicks.append(nick)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
def _parseListeners(self,name,clientpass,node):
for cn in node.childNodes:
if cn.nodeName == 'ipv4' or cn.nodeName == 'ipv6':
listener = {'network': name }
if not clientpass is None:
listener['password'] = clientpass
if cn.attributes.has_key('port'):
listener['port'] = cn.attributes['port'].value
if cn.attributes.has_key('password'):
listener['password'] = cn.attributes['password'].value
if cn.attributes.has_key('bind'):
listener['bind'] = cn.attributes['bind'].value
if cn.attributes.has_key('ssl'):
listener['ssl'] = cn.attributes['ssl'].value
self.listeners.append(listener)
elif cn.nodeName == 'pipe':
listener = {'network': name }
if not clientpass is None:
listener['password'] = clientpass
listener['path'] = cn.attributes['path'].value
if cn.attributes.has_key('password'):
listener['password'] = cn.attributes['password'].value
self.listeners.append(listener)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
def _parseNetwork(self,node):
network = Network()
client_pass = None
serverpass = None
if node.attributes.has_key('name'):
network.name = node.attributes['name'].value
else:
self.nameless_index += 1
network.name = "nameless%d" % self.nameless_index
if node.attributes.has_key('client_pass'):
client_pass = node.attributes['client_pass'].value
if node.attributes.has_key('nick'):
network.nick = node.attributes['nick'].value
if node.attributes.has_key('fullname'):
network.fullname = node.attributes['fullname'].value
if node.attributes.has_key('password'):
serverpass = node.attributes['password'].value
if node.attributes.has_key('autoconnect') and \
node.attributes['autoconnect'].value == "1":
network.autoconnect = True
if node.attributes.has_key('username'):
network.username = node.attributes['username'].value
for cn in node.childNodes:
if cn.nodeName == 'servers':
network.servers.append(self._parseServers(cn,serverpass))
elif cn.nodeName == 'channel':
channel = self._parseChannel(cn)
network.channels[channel.name] = channel
elif cn.nodeName == 'program':
network.program_path = cn.toxml()
elif cn.nodeName == 'virtual':
network.virtual_type = cn.attributes['type'].value
elif cn.nodeName == 'listen':
self._parseListeners(network.name, client_pass, cn)
elif cn.nodeName == 'autosend':
self.autosend_lines = {'network': network.name,
'data': cn.toxml()}
elif cn.nodeName == 'nickserv':
self._parseNickserv(network.name, cn)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
self.networks[network.name] = network
def _parseNetworks(self,node):
for cn in node.childNodes:
if cn.nodeName == 'network':
self._parseNetwork(cn)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
def __init__(self,filename):
Config.__init__(self)
self.doc = minidom.parse(filename)
node = self.doc.documentElement
self.nameless_index = 0
if node.nodeName != 'ctrlproxy':
raise UnknownTagError(cn)
for cn in node.childNodes:
if cn.nodeName == 'networks':
self._parseNetworks(cn)
elif cn.nodeName == 'plugins':
self._parsePlugins(cn)
elif cn.nodeType == Node.ELEMENT_NODE:
raise UnknownTagError(cn)
if len(sys.argv) > 1:
oldfilename = sys.argv[1]
else:
oldfilename = os.path.join(os.getenv('HOME'), ".ctrlproxyrc")
try:
oldfile = OldConfigFile(oldfilename)
except IOError, e:
print "%s" % (e)
print "Usage: %s [PATH-TO-CTRLPROXYRC]" % sys.argv[0]
sys.exit(1)
class IniFile(object):
def __init__(self,dict={}):
self.conf = dict
def write(self):
if self.conf.has_key('global'):
self.print_section("global")
del self.conf["global"]
for section in self.conf:
print
self.print_section(section)
def print_section(self,section):
print "[%s]" % section
for var in self.conf[section]:
print "%s = %s" % (var, self.conf[section][var])
conf = IniFile({'global':{'autoconnect':""}})
networks = {}
listeners = IniFile()
warnings = []
def convert_report_time(plugin,conf):
conf.conf['global']['report-time'] = 'true'
def convert_motd_file(plugin,conf):
conf.conf["global"]["motd-file"] = 'FIXME'
def convert_linestack_file(plugin,conf):
conf.conf["global"]["linestack"] = "file"
def convert_ctcp(plugin,conf):
# Now integrated
pass
def convert_strip(plugin,conf):
# Now integrated
pass
def convert_repl_lastdisconnect(plugin,conf):
conf.conf["global"]["replication"] = "lastdisconnect"
def convert_repl_none(plugin,conf):
conf.conf["global"]["replication"] = "none"
def convert_admin(plugin,conf):
conf.conf["admin"] = {}
def convert_log_irssi(plugin,conf):
conf.conf["log-irssi"] = {}
for cn in plugin.config:
if cn.nodeName == "logfile":
conf.conf["log-irssi"]["logfile"] = cn.toxml()
def convert_log_custom(plugin,conf):
conf.conf["log-custom"] = {}
for cn in plugin.config:
conf.conf["log-custom"][cn.nodeName] = cn.toxml()
def convert_nickserv(plugin,conf):
conf.conf["nickserv"] = {}
def convert_auto_away(plugin,conf):
conf.conf["auto-away"] = {}
for cn in plugin.config:
if cn.nodeName == 'message':
conf.conf['auto-away']['message'] = cn.toxml()
if cn.attributes.has_key('time'):
conf.conf['auto-away']['time'] = cn.attributes['time'].value
elif cn.nodeName == 'only_noclient':
conf.conf['auto-away']['only_noclient'] = cn.toxml()
def convert_socket(plugin,conf):
# Now integrated
for cn in plugin.config:
if cn.nodeName == "sslcertfile":
conf.conf['global']['certfile'] = cn.toxml()
elif cn.nodeName == "sslkeyfile":
conf.conf['global']['keyfile'] = cn.toxml()
elif cn.nodeName == "sslcafile":
conf.conf['global']['cafile'] = cn.toxml()
def convert_stats(plugin,conf):
warnings.append("stats module is no longer supported")
def convert_linestack_memory(plugin,conf):
conf.conf['global']['linestack'] = 'file'
def convert_repl_command(plugin,conf):
# Now integrated
pass
def convert_repl_memory(plugin,conf):
conf.conf['global']['linestack'] = 'file'
conf.conf['global']['replication'] = 'simple'
def convert_antiflood(plugin,conf):
conf.conf['antiflood'] = {}
def convert_repl_highlight(plugin,conf):
conf.conf['global']['replication'] = 'highlight'
matches = []
for cn in plugin.config:
if cn.nodeName == 'match':
matches.append(cn.toxml())
conf.conf['global']['matches'] = ",".join(matches)
def convert_repl_simple(plugin,conf):
conf.conf['global']['replication'] = 'simple'
convert_plugin = {
'report_time': convert_report_time,
'motd_file': convert_motd_file,
'linestack_file': convert_linestack_file,
'ctcp': convert_ctcp,
'strip': convert_strip,
'repl_none': convert_repl_none,
'admin': convert_admin,
'nickserv': convert_nickserv,
'log_irssi': convert_log_irssi,
'log_custom': convert_log_custom,
'stats': convert_stats,
'socket': convert_socket,
'auto_away': convert_auto_away,
'linestack_memory': convert_linestack_memory,
'repl_command': convert_repl_command,
'repl_memory': convert_repl_memory,
'repl_lastdisconnect': convert_repl_lastdisconnect,
'antiflood': convert_antiflood,
'repl_highlight': convert_repl_highlight,
'repl_simple': convert_repl_simple,
'auto-away': convert_auto_away,
}
if oldfile.autosend_lines:
warnings.append("autosend data is no longer reported")
for plugin in oldfile.plugins.keys():
convert_plugin[plugin](oldfile.plugins[plugin],conf)
del oldfile.plugins[plugin]
for net in oldfile.networks.keys():
oldnet = oldfile.networks[net]
networks[net] = IniFile({'global':{}})
if oldnet.nick:
networks[net].conf['global']['nick'] = oldnet.nick
if oldnet.fullname:
networks[net].conf['global']['fullname'] = oldnet.fullname
if oldnet.username:
networks[net].conf['global']['username'] = oldnet.username
if oldnet.autoconnect:
conf.conf['global']['autoconnect'] += "%s;" % oldnet.name
for ch in oldnet.channels:
oldch = oldnet.channels[ch]
networks[net].conf[ch] = {}
if oldch.key:
networks[net].conf[ch]['key'] = oldch.key
if oldch.autojoin:
networks[net].conf[ch]['autojoin'] = oldch.autojoin
del oldfile.networks[net]
for l in oldfile.listeners:
key = l['port']
if l.has_key('bind'):
key = "%s:%d" % (l['bind'], l['port'])
listeners.conf[key] = {}
if l.has_key('network'):
listeners.conf[key]['network'] = l['network']
if l.has_key('password'):
listeners.conf[key]['password'] = l['password']
if l.has_key('ssl'):
listeners.conf[key]['ssl'] = l['ssl']
conf.write()
#for i in networks:
# print i
# networks[i].write()
def write_nickserv_file():
for entry in oldfile.nickserv_nicks:
if entry.has_key('network'):
entry['network'] = "*"
print "%s\t%s\t%s" % (entry['nick'], entry['password'], entry['network'])
#listeners.write()
print "Warnings:"
for w in warnings:
print w
syntax highlighted by Code2HTML, v. 0.9.1