[Pymoul-svn] SF.net SVN: pymoul: [295] pymoul/trunk/src/moul
Status: Alpha
Brought to you by:
tiran
From: <ti...@us...> - 2007-05-28 16:53:04
|
Revision: 295 http://pymoul.svn.sourceforge.net/pymoul/?rev=295&view=rev Author: tiran Date: 2007-05-28 09:53:00 -0700 (Mon, 28 May 2007) Log Message: ----------- Switching to a new implementation of the IRC chat relay system Modified Paths: -------------- pymoul/trunk/src/moul/chatrelay/__init__.py pymoul/trunk/src/moul/chatrelay/io.py pymoul/trunk/src/moul/chatrelay/ircclient.py pymoul/trunk/src/moul/file/chatlog.py Added Paths: ----------- pymoul/trunk/src/moul/chatrelay/filter.py pymoul/trunk/src/moul/chatrelay/formatter.py pymoul/trunk/src/moul/chatrelay/interfaces.py pymoul/trunk/src/moul/chatrelay/parser.py Modified: pymoul/trunk/src/moul/chatrelay/__init__.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/__init__.py 2007-05-24 22:50:20 UTC (rev 294) +++ pymoul/trunk/src/moul/chatrelay/__init__.py 2007-05-28 16:53:00 UTC (rev 295) @@ -5,7 +5,7 @@ # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. -# +# # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for Added: pymoul/trunk/src/moul/chatrelay/filter.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/filter.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/filter.py 2007-05-28 16:53:00 UTC (rev 295) @@ -0,0 +1,56 @@ +from zope.interface import implements + +from moul.chatrelay.interfaces import ILineFilter +from moul.chatrelay.interfaces import ISnoopyLineFilter +from moul.file.chatlog import (CHAT_UNKNOWN, CHAT_PRIVMSG, CHAT_PRIVMSGTO, + CHAT_PRIVMSGFROM, CHAT_ACTION, CHAT_ERROR, + CHAT_MSG) + +__all__ = [obj for obj in globals() if ILineFilter.isImplementedBy(obj)] + +class NullFilter(object): + implements(ILineFilter) + name = 'Null filter' + + def filter(self, line, **kwargs): + return line, kwargs + +class HightlightImportantFilter(object): + implements(ILineFilter) + name = 'Highlight important people' + + def filter(self, line, **kwargs): + if kwargs.get('important', False): + kwargs['highlight'] = True + return line, kwargs + +class AbstractMessageFilter(object): + implements(ILineFilter) + name = None + msg_type = None + + def __init__(self): + assert self.msg_type, "No message type applied" + + def filter(self, line, **kwargs): + typ = kwargs.get('type', CHAT_UNKNOWN) + if typ & self.msg_type: + return None, None + return line, kwargs + +class PrivateMessageFilter(AbstractMessageFilter): + name = 'Private message filter' + msg_type = CHAT_PRIVMSG + +class ErrorMessageFilter(AbstractMessageFilter): + name = 'Error message filter' + msg_type = CHAT_ERROR + +class NonImportantFilter(object): + implements(ILineFilter) + name = 'Filter non important' + + def filter(self, line, **kwargs): + if not kwargs.get('important', False): + return None, None + return line, kwargs Property changes on: pymoul/trunk/src/moul/chatrelay/filter.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Added: pymoul/trunk/src/moul/chatrelay/formatter.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/formatter.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/formatter.py 2007-05-28 16:53:00 UTC (rev 295) @@ -0,0 +1,32 @@ +from zope.interface import implements + +from moul.chatrelay.interfaces import IOutputFormatter +from moul.file.chatlog import (CHAT_UNKNOWN, CHAT_PRIVMSG, CHAT_PRIVMSGTO, + CHAT_PRIVMSGFROM, CHAT_ACTION, CHAT_ERROR, + CHAT_MSG) + +__all__ = [obj for obj in globals() if IOutputFormatter.isImplementedBy(obj)] + +class NullFormatter(object): + implements(IOutputFormatter) + name = 'Null formatter' + + def format(self, line, **kwargs): + return line + +class MOULFormatter(object): + implements(IOutputFormatter) + name = 'MOUL formatter' + + def format(self, line, **kwargs): + typ = kwargs.get('type', CHAT_UNKNOWN) + highlight = kwargs.get('highlight', False) + if typ == CHAT_PRIVMSGTO: + line = "-> %s" % line + elif typ == CHAT_PRIVMSGFROM: + line = "<- %s" % line + elif typ == CHAT_ACTION: + line = "* %s" % line + if highlight: + line = "%B%s" % line + return line Property changes on: pymoul/trunk/src/moul/chatrelay/formatter.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Added: pymoul/trunk/src/moul/chatrelay/interfaces.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/interfaces.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/interfaces.py 2007-05-28 16:53:00 UTC (rev 295) @@ -0,0 +1,123 @@ +from zope.interface import Attribute +from zope.interface import Interface + +class IFileAppendWatchService(Interface): + """A service which monitors text files and calls the callback for new lines + """ + + def monitorFile(path, callback, errback=None): + """Monitor a file + + @param path: path to a file + @type path: string + @param callback: callback function(path, line) + @type callback: callable + @param errback: errback function(path, error) + @type errback: callable + """ + + def unmonitorFile(path): + """Stop monitoring files + + @param path: path to a file + @type path: string + """ + + def listFiles(): + """List monitored files + + @return: a list of file names + @rtype: list + """ + +class IInputParser(Interface): + """Parse input data + """ + name = Attribute("name of the parser") + + def parse(line): + """Parse a single line + + @param line: input line + @type line: string + @return: parsed line, dict with additional information + @rtype: (string, dict) + """ + +class ILineFilter(Interface): + """A line filter + """ + name = Attribute("name of the filter") + + def filter(line, **kwargs): + """ + + @param line: the line to filter + @type line: string + @param kwargs: additional information + @return: (filtered line, kwargs) or None, None + @rtype: (string, dict) / None, None + """ + +class ISnoopyLineFilter(ILineFilter): + """A line filter that snoops the ongoing chat in the channel + """ + + def snoop(channel, user, msg): + """ + + @param channel: channel name + @type channel: string + @param user: user name with hostmask + @type user: string + @param msg: message + @type msg: string + @return: None + """ + +class IOutputFormatter(Interface): + """A line formatter + """ + name = Attribute("name of the output formatter") + + def format(line, **kwargs): + """Format a line + + @param line: the line to filter + @type line: string + @param kwargs: additional information + @return: a formatted line + @rtype: string + """ + +class IChatRelay(Interface): + """A chat relay + """ + + def registerInputParser(parser): + """Register the input parser, overriding the old one + + @param parser: an input parser object + @type parser: object providing IInputParser + """ + + def registerOutputFormatter(formatter): + """Register the output formatter, overriding the old one + + @param formatter: an output formatter object + @type formatter: object providing IOutputFormatter + """ + + def registerFilters(*filters): + """ + + @param formatter: an output formatter object + @type formatter: object providing IOutputFormatter + """ + + def removeFilter(name): + """Remove a filter from the list of filters + + @param name: name of the filter + @type name: string + """ Property changes on: pymoul/trunk/src/moul/chatrelay/interfaces.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Modified: pymoul/trunk/src/moul/chatrelay/io.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/io.py 2007-05-24 22:50:20 UTC (rev 294) +++ pymoul/trunk/src/moul/chatrelay/io.py 2007-05-28 16:53:00 UTC (rev 295) @@ -5,7 +5,7 @@ # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. -# +# # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for @@ -34,7 +34,7 @@ class MOULLogFormatter(NullFormatter): """Formatter for MOUL """ - + def __init__(self, skipprivate=False, onlyimportant=False): self.skipprivate = skipprivate self.onlyimportant = onlyimportant @@ -44,7 +44,7 @@ return None typ = getattr(msg, 'typ', CHAT_UNKNOWN) important = getattr(msg, 'important', False) - + if self.onlyimportant and not important: return None if self.skipprivate and typ & CHAT_PRIVMSG: @@ -74,7 +74,7 @@ def open(self): self._fd = open(self._fname, 'r') self._fd.seek(0, 2) # eof - + def close(self): if self._fd: self._fd.close() @@ -85,7 +85,7 @@ @property def isOpen(self): return self._fd is not None - + def _read(self): data = self._fd.read() if not data: @@ -104,7 +104,7 @@ return self._fifo.pop(0) except IndexError: raise StopIteration - + class MessageWriter(object): """Write messages to a channel """ Modified: pymoul/trunk/src/moul/chatrelay/ircclient.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/ircclient.py 2007-05-24 22:50:20 UTC (rev 294) +++ pymoul/trunk/src/moul/chatrelay/ircclient.py 2007-05-28 16:53:00 UTC (rev 295) @@ -5,7 +5,7 @@ # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 2 of the License, or (at your # option) any later version. -# +# # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for @@ -68,7 +68,7 @@ reader = None writer = None interval = 5 - + def __init__(self, nickname, channel, realname=None, username=None, serverpasswd=None, nickpasswd=None, adminpasswd=None): """ @@ -80,7 +80,7 @@ self.password = serverpasswd self.nickpasswd = nickpasswd self.adminpasswd = adminpasswd - + self.loop = LoopingCall(self.checkLogfile) self.identified = [] @@ -95,7 +95,7 @@ def checkLogfile(self): for line in iter(self.reader): self.writer.log(line) - + def start(self): #if not self.reader.isOpen: # return @@ -117,10 +117,10 @@ def joined(self, channel): log.msg("I have joined", channel) - + def left(self, channel): log.msg("I have left", channel) - + def kickedFrom(self, channel, kicker, message): log.msg("I have been kicked from %s by %s: %s" % (channel, kicker, message)) @@ -172,7 +172,7 @@ #self.say(channel, "count %d" % self.counter) #self.counter += 1 - + def reply(self, dest, message): # maybe self.notice(dest, message) instead? self.msg(dest, message) @@ -210,7 +210,7 @@ commands.append(name) commands.sort() return commands - + @usage("help <command> - Give help for <command>") def command_HELP(self, user, reply, args): args = args.split() @@ -272,7 +272,7 @@ readerClass = LogFileReader writerClass = MessageWriter formatter = MOULLogFormatter(skipprivate=False, onlyimportant=False) - + def __init__(self, nickname, channel, realname=None, username=None, serverpasswd=None, nickpasswd=None, adminpasswd=None): """ @@ -289,7 +289,7 @@ d = self.__dict__.copy() del d['p'] return d - + def shutdown(self): self.shuttingDown = True if self.p: Added: pymoul/trunk/src/moul/chatrelay/parser.py =================================================================== --- pymoul/trunk/src/moul/chatrelay/parser.py (rev 0) +++ pymoul/trunk/src/moul/chatrelay/parser.py 2007-05-28 16:53:00 UTC (rev 295) @@ -0,0 +1,27 @@ +from zope.interface import implements + +from moul.file.chatlog import ChatlogParser + +from moul.chatrelay.interfaces import IInputParser + +__all__ = [obj for obj in globals() if IInputParser.isImplementedBy(obj)] + +class NullParser(object): + implements(IInputParser) + name = 'Null parser' + + def __init__(self, *args, **kwargs): + pass + + def parse(self, line): + return line, {} + +class MOULChatlogParser(ChatlogParser): + implements(IInputParser) + name = 'MOUL chatlog parser' + + def __init__(self, year): + self.setYear(year) + + def setYear(self, year): + self._year = int(year) Property changes on: pymoul/trunk/src/moul/chatrelay/parser.py ___________________________________________________________________ Name: svn:keywords + 'Id Revision' Name: svn:eol-style + native Modified: pymoul/trunk/src/moul/file/chatlog.py =================================================================== --- pymoul/trunk/src/moul/file/chatlog.py 2007-05-24 22:50:20 UTC (rev 294) +++ pymoul/trunk/src/moul/file/chatlog.py 2007-05-28 16:53:00 UTC (rev 295) @@ -53,17 +53,9 @@ CHAT_ACTION = 1 << 6 # users -USER_CYAN = [ - 'gregbert', 'greydragon', 'Rand Miller', 'ResEng B. Mathias', - 'ResEng B.Dreschel', 'ResEng C. Lambert', 'ResEng KJohnson', - 'ResEng 102', 'ResEng 233', - ] -USER_DRC = [ - 'Cate Alexander', 'Dr. Kodama', 'Marie Sutherland', 'Michael Engberg', - 'Victor Laxman', 'Wheely', 'Douglas Sharper', 'Phil Henderson', - 'Nick White' - ] - +USER_CYAN = ['gregbert', 'greydragon'] +USER_DRC = ['Marie Sutherland', 'Douglas Sharper', 'Nick White', + 'Dr. Kodama', 'Victor Laxman', 'Michael Engberg'] USER_IMPORTANT = USER_CYAN + USER_DRC RE_FLAGS = re.LOCALE @@ -357,7 +349,7 @@ New idea, new design """ - def __init__(self, iterable, year=2007): + def __init__(self, iterable=[], year=2007): self._iterable = iterable self._year = year # XXX @@ -366,58 +358,42 @@ if mo is None: return ChatLine(line, (1970, 1, 1, 0, 0, 0), CHAT_UNKNOWN) d = mo.groupdict() - date = (self._year, int(d['M']), int(d['D']), - int(d['h']), int(d['m']), int(d['s'])) - typ = CHAT_UNKNOWN + dt = (self._year, int(d['M']), int(d['D']), + int(d['h']), int(d['m']), int(d['s'])) msg = d['msg'] - info = {} - important = False + info = {'type' : CHAT_UNKNOWN, 'datetime' : dt, 'important' : False} if len(d['space']) == 2: - typ = CHAT_MSG mo = MSG_RE.match(msg) if mo is None: - return ChatLine(msg, dte, CHAT_UNKNOWN) - info = mo.groupdict() + return msg, info + info['type'] = CHAT_MSG + info.update(mo.groupdict()) else: if msg == CHATLOG_START: - typ = CHAT_START + info['type'] = CHAT_START elif msg == CHATLOG_STOP: - typ = CHAT_STOP + info['type'] = CHAT_STOP else: for t, r in ((CHAT_PRIVMSGFROM, PRIVMSGFROM_RE), (CHAT_PRIVMSGTO, PRIVMSGTO_RE), (CHAT_ERROR, ERROR_RE)): mo = r.match(msg) if mo: - typ = t - info = mo.groupdict() + info['type'] = t + info.update(mo.groupdict()) break - if typ == CHAT_UNKNOWN: # XXX check this - typ = CHAT_ACTION + if info['type'] == CHAT_UNKNOWN: # XXX check this + info['type'] = CHAT_ACTION for user in USER_IMPORTANT: if user in msg: - important = True + info['important'] = True user = info.get('user', None) if user: if user in USER_IMPORTANT: - important = True - return ChatLine(msg, date, typ, important, info) + info['important'] = True + return msg, info def __iter__(self): for line in self._iterable: yield self.parse(line) - -class ChatLine(unicode): - __slots__ = ('datetime', 'typ', 'important', 'info') - - def __new__(cls, ustr, datetime, typ=None, important=False, info={}): - self = unicode.__new__(cls, ustr) - self.datetime = datetime - self.typ = typ - self.important = important - self.info = info - return self - - def asDatetime(self): - return datetime(*self.date) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |