Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Python ➜ addxml.lua

addxml.lua

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


Posted by Isthiriel   (113 posts)  Bio
Date Thu 27 Dec 2007 03:20 PM (UTC)

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

Message
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'
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))
Top

Posted by Isthiriel   (113 posts)  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

Message
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
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.


12,294 views.

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

Go to topic:           Search the forum


[Go to top] top

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