It took longer than I expected, but a Python addxml.lua equivalent. :)
Some use cases:
The close-to-lua syntax:
More OO:
Or rather than using a bitvector, you can set flags individually:
You retrieve current xml by the get() methods on the XMLTrigger, XMLAlias and XMLTimer classes:
Which you can modify as above:
... Hmm. I could also make it so you can use |= and &= to mask the current flags, but that would be something for another day.
First the magic part:
Some use cases:
The close-to-lua syntax:
x = XMLTimer('GetEntity', { 'second': 0.1, 'enabled': True, 'one_shot': 'y', }).add()
More OO:
x = XMLTimer('GetEntity')
x.set_flags(eEnabled | eOneShot | eActiveWhenClosed | eTemporary)
x.second = 0.1
x.script = 'OnEmptyTimer'
x.add()
Or rather than using a bitvector, you can set flags individually:
x.enabled = True
x.one_shot = 'y'
You retrieve current xml by the get() methods on the XMLTrigger, XMLAlias and XMLTimer classes:
x = XMLTimer.get('GetEntity')
Which you can modify as above:
x.one_shot = True
x.second = 20
x.add() # send the changes back to MUSHclient
... Hmm. I could also make it so you can use |= and &= to mask the current flags, but that would be something for another day.
First the magic part:
# ---------------------------------------------------------
# Python version of addxml.lua
# -- See: http://www.gammon.com.au/forum/?id=7123
# ---------------------------------------------------------
import xml.etree.ElementTree as et
eXmlTrigger = 0
eXmlAlias = 1
eXmlTimer = 2
eXmlMacro = 3
eXmlSendMUD = 0 # send to MUD
eXmlSendCommand = 1 # put in command window
eXmlSendOutput = 2 # display in output window
eXmlSendStatus = 3 # put in status line
eXmlSendNotepadNew = 4 # new notepad
eXmlSendNotepadAppend = 5 # append to notepad
eXmlSendLog = 6 # put in log file
eXmlSendNotepadReplace = 7 # replace notepad
eXmlSendQueue = 8 # queue it
eXmlSendVariable = 9 # set a variable
eXmlSendReparseCommand = 10 # re-parse as command
eXmlSendSpeedwalk = 11 # send to MUD as speedwalk
eXmlSendScript = 12 # send to script engine
eXmlSendImmediate = 13 # send without queuing
eXmlSendScriptOmit = 14 # send to script engine - after omitting from output (triggers)
class XMLObject(object):
magic_data = None
def __init__(self, name, data=None, send=None):
assert self.magic_data != None
assert name
self.__dict__['data'] = { 'name': name, 'send': '', }
self.data = data
if send:
self.data['send'] = send
@classmethod
def get(klass, name):
assert klass.magic_data != None
xml = world.ExportXML(klass.magic_data[0], name)
assert xml != ''
root = et.XML(xml)
body = root.find(".//%s" % klass.magic_data[2])
data = body.attrib
send = root.find(".//send")
if send:
data['send'] = send.text
r = klass(name, data)
return r
def set_flags(self, flags):
for k, v in self.valid_flags.iteritems():
if flags & k:
self.data[v] = 'y'
continue
self.data[v] = 'n'
def get_flags(self):
flags = 0
for k, v in self.valid_flags.iteritems():
if self.data.has_key(v) and self.data[v] == 'y':
flags |= k
return flags
def add(self, note_xml=False):
assert self.magic_data != None
data = self.data
root = et.Element(self.magic_data[1])
text = data['send']
del data['send']
body = et.SubElement(root, self.magic_data[2], data)
data['send'] = text
send = et.SubElement(body, 'send')
send.text = data['send']
xml = et.tostring(root)
if note_xml:
world.Note(xml)
assert 1 == world.ImportXML(xml)
# Force script entry-point resolution
if self.magic_data[0] < 3 and \
data.has_key('name') and data['name'] and \
data.has_key('script') and data['script']:
s = "world.Set%sOption(data['name'], 'script', data['script'])"
exec s % self.magic_data[2].capitalize()
def __getattr__(self, attr):
if attr in self.valid_attribs:
return self.data[attr]
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, attr))
def __setattr__(self, attr, val):
if attr == 'name':
raise AttributeError("Cannot modify name of '%s'" % self.__class__.__name__)
if attr == 'data':
if not isinstance(val, dict):
raise AttributeError("'%s' expected dict to be assigned to 'data'" % self.__class__.__name__)
for k, v in val.iteritems():
if k == 'name':
continue
self.__setattr__(k, v)
return
if attr in self.valid_attribs:
if isinstance(val, bool):
if val:
val = 'y'
else:
val = 'n'
self.data[attr] = str(val)
return
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, attr))
def __delattr__(self, attr):
if attr == 'name':
raise AttributeError("Cannot modify name of '%s'" % self.__class__.__name__)
if attr in self.valid_attribs:
del self.data[attr]
return
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, attr))