made a siphon module
Benjamin West <[email protected]> Wed, 26 Jan 2005 03:58:13 -0600
| Newsgroups | gmane.comp.games.mud.client.lyntin |
|---|---|
| Message-ID | <[email protected]> |
This will watch for text similar to gag or action. When it finds a match, it will open a file with the name you gave it and start copying mud data to the file until it sees two consecutive newlines. Siphon allows you to capture chunks of data in files for each session. This might come in handy if you are trying to monitor several characters at once. Siphon relevant data from each, and open up xterms to use something like "watch cat *.eq.siphon". That would let you see everyone's eq. Ben
siphon.py
(application/octet-stream, 7.6 KB)
"""
This module implements a siphon feature. It will watch for a match
for a given piece of text and then log everything from that point until
a double newline to a predefined file.
TODO:
* add a siphon now command that just starts siphoning
* fix file header
* add config items
"""
__author__ = "Ben West"
__version__ = ".8"
__date__ = "Wed Jan 26 03:42:16 CST 2005"
__description__ = "A siphon to stick chunks of data into files."
import string
from lyntin import exported, session, ansi, manager, utils
from lyntin.modules import modutils
commands_dict = {}
class SiphonData:
def __init__(self):
self._cues = {}
def addSiphon(self, item, filename):
"""
Add a cue to the dict.
"""
compiled = utils.compile_regexp(item,1)
siphon = {'regex': compiled, 'filename': filename, 'filehandle': 0, 'issiphoning': 0}
self._cues[item] = siphon
def clear(self):
"""
Remove all cues.
"""
self_cues.clear()
def removeSiphon(self, text):
"""
Remove given siphon cue.
Returns a list of tuples of cues that were removed.
"""
badcues = utils.expand_text(text, self._cues.keys())
ret = []
for mem in badcues:
ret.append(mem)
del self._cues[mem]
return ret
def findcue(self, text):
"""
Looks at mud data, starts siphoning we find a cue.
Returns key to the cue.
"""
if len(text) > 0:
for key in self._cues.keys():
if self._cues[key]['regex'].search(text):
return key
def issiphoning(self, item):
"""
Access function to see if we are in the process of siphoning.
"""
return self._cues[item]['issiphoning']
def startSiphon(self, item):
"""
Open a file, store the handle in the dict, note that we've started.
"""
filename = self._cues[item]['filename'] + ".siphon"
#filename = "atest.siphon"
self._cues[item]['filehandle'] = file(filename, "w")
header = "".ljust(6)
header = header.replace(" ", "*", 5)
last = "".rjust(44 - len(self._cues[item]['filename']))
last.replace(" ", "*")
header = header + self._cues[item]['filename'] + " " + last
self._cues[item]['filehandle'].write(header + "\n")
self._cues[item]['issiphoning'] = True
def stopSiphon(self, item):
"""
Close the file, del the handle, and note that we've stopped.
"""
#self._cues[item]['prevnoline'] = False
self._cues[item]['filehandle'].close()
self._cues[item]['filehandle'] = 0
self._cues[item]['issiphoning'] = 0
def siphon(self, text):
"""
siphon, process the text
first ask if we are already siphoning,
if we are, then check to see if this text
has a double newline. If it doesn't have a double
newline, send to file. If it does
have a double newline, stop siphoning, and send it to the
file and close it.
"""
for mem in self._cues.keys():
if self._cues[mem]['issiphoning']:
if text[0] == "\n":
self._cues[mem]['filehandle'].write(text)
self.stopSiphon(mem)
else:
self._cues[mem]['filehandle'].write(text)
item = self.findcue(text)
if item:
self.startSiphon(item)
self._cues[item]['filehandle'].write(text)
def getInfo(self, text=''):
"""
Returns information about the siphons.
"""
data = self._cues.keys()
if text:
data = utils.expand_text(text, data)
data = ["siphon {%s}" % mem for mem in data]
return data
def getSiphonInfoMappings(self):
l = []
for mem in self._cues.keys():
l.append( {"text": mem} )
return l
def getStatus(self):
cues = len(self._cues.keys())
return "%d siphon cue(s)." % (cues)
class SiphonManager(manager.Manager):
def __init__(self):
self._siphondata = {}
def getSiphonData(self, ses):
if not self._siphondata.has_key(ses):
self._siphondata[ses] = SiphonData()
return self._siphondata[ses]
def addSession(self, newsession, basesession=None):
if basesession:
if self._siphondata.has_key(basesession):
bdata = self.getSiphonData(basesession)
ndata = self.getSiphonData(newsession)
for mem in bdata._cues.keys():
ndata.addSiphon(mem, bdata._cues[mem]["filename"])
def persist(self, args):
ses = args["session"]
quiet = args["quiet"]
siphon = self.getSiphonData(ses)
data = siphon.getInfo()
if quiet == 1:
data = [m + " quiet={true}" for m in data]
return data
def clear(self, ses):
if not self._siphondata.has_key(ses):
self._siphondata[ses].clear()
def getInfo(self, ses, text=''):
return self.getSiphonData(ses).getInfo(text)
def getInfoMappings(self, item, ses):
if item != "siphon cues":
raise ValueError("%s is not a valid item for this manager." % item)
if not self._siphondata.has_key(ses):
return []
return self._siphondata.getSiphonInfoMappings()
def getItems(self):
return ["siphon cues"]
def getParameters(self, item):
if item == "siphon cues":
return [ ("text", "The text which serves as a cue to start siphoning text." ) ]
raise ValueError("%s is not a valid item for this manager." % item)
def getStatus(self, ses):
return self.getSiphonData(ses).getStatus()
def removeSession(self, ses):
if self._siphondata.has_key(ses):
del self._siphondata[ses]
def handle_mudfilter(self, args):
"""
mud_filter hook function
first ask if we are already siphoning,
if we are, then check to see if this text
has a double newline. If it doesn't have a double
newline, tuck it away in our storage place. If it does
have a double newline, stop siphoning, and send it to the
file and close it. Note that we stopped siphoning.
"""
ses = args["session"]
mudtext = args["dataadj"]
mudtext = ansi.filter_ansi(mudtext)
if self._siphondata.has_key(ses):
self._siphondata[ses].siphon(mudtext)
return args["dataadj"]
def uncue_cmd(ses, args, input):
"""
Remove a cue.
see also: cue
category: siphons
"""
str = args["str"]
sm = exported.get_manager("siphon")
sd = sm.getSiphonData(ses)
func = sd.removeSiphon
modutils.unsomething_helper(args, func, None, "cue", "cues")
commands_dict["uncue"] = (uncue_cmd, "str= quiet:boolean=false")
def cue_cmd(ses, args, input):
"""
This takes the name of the siphon, and siphons all text from
when this command is called until we see a double newline.
We'll put this text in a file, indicated by the filename
with a .siphon extension. It will automatically create a
header and a footer about 50 characters long based on the
name and filled with "****".
Similar to gag or action or substitute, except that it only
siphons the data and does not modify it in any way.
category: siphons
"""
cuetext = args["item"]
quiet = args["quiet"]
filename = args["name"]
sm = exported.get_manager("siphon")
sd = sm.getSiphonData(ses)
if not cuetext:
data = sd.getInfo()
if not data:
data = ["cue: no siphon cues defined."]
exported.write_message("siphon cues\n" + "\n".join(data), ses)
return
sd.addSiphon(cuetext, filename)
if not quiet:
exported.write_message("siphon cue: {%s} added." % cuetext, ses)
commands_dict["cue"] = (cue_cmd, "item= name:string=~/muds/siphon quiet:boolean=false")
sm = None
def load():
""" Initialize module... """
global sm
modutils.load_commands(commands_dict)
sm = SiphonManager()
exported.add_manager("siphon", sm)
exported.hook_register("mud_filter_hook", sm.handle_mudfilter, 77)
exported.hook_register("write_hook", sm.persist)
def unload():
""" Unload module... """
global sm
modutils.unload_commands(commands_dict.keys())
exported.remove_manager("siphon")
exported.hook_unregister("write_hook", sm.persist)
exported.hook_unregister("mud_filter_hook", sm.handle_mudfilter)
# Local variables:
# mode:python
# py-indent-offset:2
# tab-width:2
# End: