[Home] [Downloads] [Search] [Help/forum]

Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Python
. . -> [Subject]  addxml.lua


It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Posted by Isthiriel   (113 posts)  [Biography] bio
Date Thu 27 Dec 2007 03:20 PM (UTC)

Amended on Thu 27 Dec 2007 03:47 PM (UTC) by Isthiriel

It took longer than I expected, but a Python addxml.lua equivalent. :)

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'

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

    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'
            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:
        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':
                self.__setattr__(k, v)
        if attr in self.valid_attribs:
            if isinstance(val, bool):
                if val:
                    val = 'y'
                    val = 'n'
            self.data[attr] = str(val)
        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]
        raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, attr))
[Go to top] top

Posted by Isthiriel   (113 posts)  [Biography] bio
Date Reply #1 on Thu 27 Dec 2007 03:21 PM (UTC)

Amended on Thu 27 Dec 2007 03:48 PM (UTC) by Isthiriel

And then the actual information about triggers/aliases/timers:

class XMLTrigger(XMLObject):
    magic_data = (0, 'triggers', 'trigger')
    valid_attribs = [
        'back_colour', 'bold', 'clipboard_arg', 'colour_change_type',
        'custom_colour', 'enabled', 'expand_variables', 'group',
        'ignore_case', 'inverse', 'italic', 'keep_evaluating',
        'lines_to_match', 'lowercase_wildcard', 'make_bold', 'make_italic',
        'make_underline', 'match', 'match_back_colour', 'match_bold',
        'match_inverse', 'match_italic', 'match_text_colour',
        'match_underline', 'multi_line', 'name', 'omit_from_log',
        'omit_from_output', 'one_shot', 'other_back_colour',
        'other_text_colour', 'regexp', 'repeat', 'script', 'send',
        'send_to', 'sequence', 'sound', 'sound_if_inactive',
        'temporary', 'text_colour', 'user', 'variable',
    valid_flags = {
        eEnabled: 'enabled',
        eOmitFromLog: 'omit_from_log',
        eOmitFromOutput: 'omit_from_output',
        eKeepEvaluating: 'keep_evaluating',
        eIgnoreCase: 'ignore_case',
        eTriggerRegularExpression: 'regexp',
        eExpandVariables: 'expand_variables',
        eLowercaseWildcard: 'lowercase_wildcard',
        eTemporary: 'temporary',

class XMLAlias(XMLObject):
    magic_data = (1, 'aliases', 'alias')
    valid_attribs = [
        'echo_alias', 'enabled', 'expand_variables', 'group', 'ignore_case',
        'keep_evaluating', 'match', 'menu', 'name', 'omit_from_command_history',
        'omit_from_log', 'omit_from_output', 'one_shot', 'regexp', 'script',
        'send', 'send_to', 'sequence', 'temporary', 'user', 'variable',
    valid_flags = {
        eEnabled: 'enabled',
        eIgnoreAliasCase: 'ignore_case',
        eOmitFromLogFile: 'omit_from_log',
        eAliasRegularExpression: 'regexp',
        eExpandVariables: 'expand_variables',
        eAliasMenu: 'menu',
        eTemporary: 'temporary',

class XMLTimer(XMLObject):
    magic_data = (2, 'timers', 'timer')
    valid_attribs = [
        'active_closed', 'at_time', 'enabled', 'group', 'hour', 'minute', 'name',
        'offset_hour', 'offset_minute', 'offset_second', 'omit_from_log',
        'omit_from_output', 'one_shot', 'script', 'second', 'send', 'send_to',
        'temporary', 'variable',
    valid_flags = {
        eEnabled: 'enabled',
        eAtTime: 'at_time',
        eOneShot: 'one_shot',
        eActiveWhenClosed: 'active_closed',
        eTemporary: 'temporary',

class XMLMacro(XMLObject):
    magic_data = (3, 'macros', 'macro')
    # crippled due to lack of information
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum

[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]