Skip to content

Instantly share code, notes, and snippets.

@robotlolita
Created February 5, 2011 17:18
Show Gist options
  • Save robotlolita/812610 to your computer and use it in GitHub Desktop.
Save robotlolita/812610 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
#!/usr/bin/python
from collections import defaultdict
class Eventful(object):
"""Any class that can respond to events.
"""
def __init__(self):
self.listeners = defaultdict(list)
def listen(self, event, callback):
"""Listens to an event
"""
self.listeners[event].append(callback)
def deafen(self, event, callback):
"""Stop listening to an event
"""
self.listeners[event].remove(callback)
def post(self, kind, **kwargs):
"""Post a new event. When the application has some time, it'll process
them and call the right functions that are waiting for them.
"""
kwargs['kind'] = kind
for callback in self.listeners[kind]:
callback(kwargs)
class HelpHandler(Eventful):
"""Displays help to the user.
"""
def __init__(self, parent):
super(HelpHandler, self).__init__()
self.topics = {}
self.parent = parent
self.register("help", self.help_out)
self.listen("on_help_summary", self.help_summary)
def add_topic(self, command, handler):
"""Adds the topic to the database.
"""
self.topics[command] = handler.__doc__
def short_doc(self, doc):
"""Returns a short documentation for listing.
"""
doc = doc.splitlines()[0].strip()
if len(doc) > 60:
doc = doc[:57] + "..."
return doc
def help_summary(self, evt):
"""Summarizes topics.
"""
print "Available commands:"
for topic, doc in self.topics.iteritems():
doc = self.short_doc(doc)
print " %s — %s" % (topic, doc)
print ""
def help_out(self, evt):
"""This helpful message.
"""
arg = evt['arg']
if arg:
if arg in self.topics:
print ":: %s ::\n%s" % (arg, self.topics[arg])
else:
print "Sorry, no help for %s" % arg
else:
self.post("on_help_summary")
def register(self, command, handler):
"""Registers a command as a listener and adds to the topics.
"""
self.add_topic(command, handler)
self.parent.listen("on_" + command, handler)
class Wierd(Eventful):
"""Wierd commands.
"""
def __init__(self, parent):
super(Wierd, self).__init__()
self.parent = parent
self.parent.helper.register("cat", self.cat)
self.parent.longcat.listen("on_longcat_too_long", self.long_indeed)
def long_indeed(self, evt):
"""Indeed too long.
"""
print "Long indeed."
def cat(self, evt):
"""Prints things to stdout.
Try `cat lol' and `cat long' out :3
"""
arg = evt['arg']
if arg == "lol":
print "Science just created a new LOLcat!"
if arg == "long":
self.parent.longcat.post("on_longcat")
class Longcat(Eventful):
"""Long cat is LOOOOOOOOOOOOOOOONG.
"""
def __init__(self, parent):
super(Longcat, self).__init__()
self.parent = parent
self.listen("on_longcat", self.print_cat)
def print_cat(self, evt):
"""Prints a longcat.
"""
print "Long cat is l%s..." % ("o" * 500)
self.post("on_longcat_too_long")
class InputHandler(Eventful):
"""Handles the user's input.
"""
def __init__(self):
super(InputHandler, self).__init__()
self.active = True
self.helper = HelpHandler(self)
self.longcat = Longcat(self)
self.wierd = Wierd(self)
self.listen("on_input_received", self.handle_input)
self.listen("on_missing_cmd", self.say_what)
self.helper.register("quit", self.quit)
def say_what(self, evt):
"""Called when the handler doesn't understand a command.
"""
print "Sorry, but what do you mean by %s" % evt['cmd']
def quit(self, evt):
"""Quits the handler.
"""
self.active = False
def handle_input(self, evt):
"""Handles the user input.
"""
command, sep, arg = evt['cmd'].partition(' ')
self.post('on_%s' % command, arg=arg, cmd=command)
def post(self, kind, **kwargs):
if kind not in self.listeners:
self.post("on_missing_cmd", **kwargs)
else:
super(InputHandler, self).post(kind, **kwargs)
def main():
handler = InputHandler()
while handler.active:
command = raw_input('> ')
handler.post('on_input_received', cmd=command)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment