Created
February 5, 2011 17:18
-
-
Save robotlolita/812610 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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