diff options
| author | jason | 2012-07-21 16:20:21 -0600 |
|---|---|---|
| committer | jason | 2012-07-21 16:20:21 -0600 |
| commit | ecf83c6b4576138d34ee3056db997a66476a3f29 (patch) | |
| tree | 48486ae033e4515cd1144d1ef0a9a433ddbb3b40 | |
| parent | 95413bf63d54eb08ce4fb2dc972559f36551b195 (diff) | |
| download | warmachine-ecf83c6b4576138d34ee3056db997a66476a3f29.tar.gz warmachine-ecf83c6b4576138d34ee3056db997a66476a3f29.zip | |
Added support to dynamically load modules.
| -rw-r--r-- | settings.py | 3 | ||||
| -rw-r--r-- | wmd/actions/__init__.py | 3 | ||||
| -rw-r--r-- | wmd/actions/echo.py | 11 | ||||
| -rw-r--r-- | wmd/actions/modules.py | 56 | ||||
| -rw-r--r-- | wmd/actions/passive/nickserv.py | 4 | ||||
| -rw-r--r-- | wmd/actions/passive/pong.py | 4 | ||||
| -rw-r--r-- | wmd/irc.py | 24 | ||||
| -rw-r--r-- | wmd/parser.py | 3 |
8 files changed, 96 insertions, 12 deletions
diff --git a/settings.py b/settings.py index ec2668f..d6c22a9 100644 --- a/settings.py +++ b/settings.py | |||
| @@ -18,6 +18,9 @@ ADMINS = ('com4',) | |||
| 18 | ACTIONS = ( | 18 | ACTIONS = ( |
| 19 | 'wmd.actions.passive.nickserv.IdentWithNickserv', | 19 | 'wmd.actions.passive.nickserv.IdentWithNickserv', |
| 20 | 'wmd.actions.passive.pong.RespondToPing', | 20 | 'wmd.actions.passive.pong.RespondToPing', |
| 21 | 'wmd.actions.modules.ReloadModule', | ||
| 22 | 'wmd.actions.modules.LoadModule', | ||
| 23 | 'wmd.actions.modules.ListModules', | ||
| 21 | ) | 24 | ) |
| 22 | 25 | ||
| 23 | try: | 26 | try: |
diff --git a/wmd/actions/__init__.py b/wmd/actions/__init__.py index 03cde4c..d0529eb 100644 --- a/wmd/actions/__init__.py +++ b/wmd/actions/__init__.py | |||
| @@ -1,2 +1,3 @@ | |||
| 1 | class Action(object): | 1 | class Action(object): |
| 2 | pass \ No newline at end of file | 2 | def log(self, msg): |
| 3 | print "-> %s: %s" %(self.__class__.__name__, msg) \ No newline at end of file | ||
diff --git a/wmd/actions/echo.py b/wmd/actions/echo.py new file mode 100644 index 0000000..dfaff7f --- /dev/null +++ b/wmd/actions/echo.py | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | from wmd.actions import Action | ||
| 2 | |||
| 3 | import settings | ||
| 4 | |||
| 5 | class EchoAction(Action): | ||
| 6 | def recv_msg(self, irc, obj_data): | ||
| 7 | channel = obj_data.get_username() | ||
| 8 | |||
| 9 | args = obj_data.params.split(" ") | ||
| 10 | if "PRIVMSG" in obj_data.command and settings.NICKNAME in args[1]: | ||
| 11 | irc.privmsg(channel, " ".join(args[2:])) \ No newline at end of file | ||
diff --git a/wmd/actions/modules.py b/wmd/actions/modules.py new file mode 100644 index 0000000..ed55609 --- /dev/null +++ b/wmd/actions/modules.py | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | from wmd.actions import Action | ||
| 2 | |||
| 3 | import settings | ||
| 4 | |||
| 5 | class ReloadModule(Action): | ||
| 6 | def recv_msg(self, irc, obj_data): | ||
| 7 | username = obj_data.get_username() | ||
| 8 | |||
| 9 | if username in settings.ADMINS: | ||
| 10 | args = obj_data.params.split(" ") | ||
| 11 | if "PRIVMSG" in obj_data.command and "RELOAD" in args[1].upper(): | ||
| 12 | module = args[2] | ||
| 13 | if not module in irc.actions: | ||
| 14 | irc.privmsg(username, "Invalid Module: %s") | ||
| 15 | return | ||
| 16 | elif module == self.__class__.__name__: | ||
| 17 | irc.privmsg(username, "Unable to reload self. Try restarting") | ||
| 18 | return | ||
| 19 | module_class = irc.actions[module].__module__ | ||
| 20 | module_path = module_class + '.' + module | ||
| 21 | |||
| 22 | del(irc.actions[module]) | ||
| 23 | irc.load_action(module_path) | ||
| 24 | |||
| 25 | msg = "Reloaded %s" % (module_path,) | ||
| 26 | self.log(msg) | ||
| 27 | irc.privmsg(username, msg) | ||
| 28 | |||
| 29 | class LoadModule(Action): | ||
| 30 | def recv_msg(self, irc, obj_data): | ||
| 31 | username = obj_data.get_username() | ||
| 32 | |||
| 33 | if username in settings.ADMINS: | ||
| 34 | args = obj_data.params.split(" ") | ||
| 35 | if "PRIVMSG" in obj_data.command and "LOAD" in args[1].upper(): | ||
| 36 | module_path = args[2] | ||
| 37 | if module_path in irc.actions: | ||
| 38 | irc.privmsg(username, "Module %s already loaded" % (module_path,)) | ||
| 39 | return | ||
| 40 | #irc.load_action(module_path) | ||
| 41 | |||
| 42 | msg = "Loading %s" % (module_path,) | ||
| 43 | self.log(msg) | ||
| 44 | irc.privmsg(username, msg) | ||
| 45 | return {'load': module_path} | ||
| 46 | |||
| 47 | class ListModules(Action): | ||
| 48 | def recv_msg(self, irc, obj_data): | ||
| 49 | username = obj_data.get_username() | ||
| 50 | |||
| 51 | if username in settings.ADMINS: | ||
| 52 | args = obj_data.params.split(" ") | ||
| 53 | if "PRIVMSG" in obj_data.command and "LIST" in args[1].upper(): | ||
| 54 | for module in irc.actions: | ||
| 55 | msg = module | ||
| 56 | irc.privmsg(username, msg) | ||
diff --git a/wmd/actions/passive/nickserv.py b/wmd/actions/passive/nickserv.py index fa91d5b..e705677 100644 --- a/wmd/actions/passive/nickserv.py +++ b/wmd/actions/passive/nickserv.py | |||
| @@ -14,8 +14,8 @@ class IdentWithNickserv(Action): | |||
| 14 | if 'identify' in msg.lower()\ | 14 | if 'identify' in msg.lower()\ |
| 15 | and not self.logged_in: | 15 | and not self.logged_in: |
| 16 | msg = 'identify %s' % (settings.NICKSERV_PASSWORD) | 16 | msg = 'identify %s' % (settings.NICKSERV_PASSWORD) |
| 17 | print "%s: Logging in..." % self.__class__.__name__ | 17 | self.log("Logging in...") |
| 18 | irc.privmsg(username, msg) | 18 | irc.privmsg(username, msg) |
| 19 | self.logged_in = True | 19 | self.logged_in = True |
| 20 | elif 'are now identified' in msg.lower(): | 20 | elif 'are now identified' in msg.lower(): |
| 21 | print "%s: Logged in." % (self.__class__.__name__) \ No newline at end of file | 21 | self.log("Logged in.") \ No newline at end of file |
diff --git a/wmd/actions/passive/pong.py b/wmd/actions/passive/pong.py index 813147d..19e12a7 100644 --- a/wmd/actions/passive/pong.py +++ b/wmd/actions/passive/pong.py | |||
| @@ -9,6 +9,6 @@ class RespondToPing(Action): | |||
| 9 | server = obj_data.params[1:] | 9 | server = obj_data.params[1:] |
| 10 | else: | 10 | else: |
| 11 | server = obj_data.params | 11 | server = obj_data.params |
| 12 | msg = "-> PONG %s" % server | 12 | msg = "PONG %s" % server |
| 13 | print msg | 13 | self.log(msg) |
| 14 | irc.rawsend(msg) \ No newline at end of file | 14 | irc.rawsend(msg) \ No newline at end of file |
| @@ -14,7 +14,7 @@ class IRC(object): | |||
| 14 | self.nick = nick | 14 | self.nick = nick |
| 15 | self.name = name | 15 | self.name = name |
| 16 | self.port = port | 16 | self.port = port |
| 17 | self.actions = [] | 17 | self.actions = dict() |
| 18 | 18 | ||
| 19 | self.load_actions() | 19 | self.load_actions() |
| 20 | 20 | ||
| @@ -66,7 +66,7 @@ class IRC(object): | |||
| 66 | module_name, class_name = path.rsplit('.', 1) | 66 | module_name, class_name = path.rsplit('.', 1) |
| 67 | module = __import__(module_name, globals(), locals(), [class_name], -1) | 67 | module = __import__(module_name, globals(), locals(), [class_name], -1) |
| 68 | classz = getattr(module, class_name) | 68 | classz = getattr(module, class_name) |
| 69 | self.actions.insert(0, classz()) | 69 | self.actions[class_name] = classz() |
| 70 | 70 | ||
| 71 | def __call__(self, *args, **kwargs): | 71 | def __call__(self, *args, **kwargs): |
| 72 | """ | 72 | """ |
| @@ -82,14 +82,24 @@ class IRC(object): | |||
| 82 | if data[-1] != '\n': | 82 | if data[-1] != '\n': |
| 83 | data = data + self.irc.recv(4096) | 83 | data = data + self.irc.recv(4096) |
| 84 | 84 | ||
| 85 | # For dynamic loading, we have to add to the actions dictionary after we're through looping. Maybe there | ||
| 86 | # are some other cases to use the post_loop_commands | ||
| 85 | for line in data.split('\r\n'): | 87 | for line in data.split('\r\n'): |
| 86 | obj_data = parser.IRCParse(line) | 88 | obj_data = parser.IRCParse(line) |
| 87 | #pass to action handlers here... | 89 | #pass to action handlers here... |
| 88 | if (obj_data.prefix == '') and (obj_data.command == '') and (obj_data.params == ''): | 90 | if (obj_data.prefix == '') and (obj_data.command == '') and (obj_data.params == ''): |
| 89 | continue | 91 | continue |
| 90 | 92 | ||
| 91 | print "!" + obj_data.prefix + "~" + obj_data.command + "~" + obj_data.params | 93 | print "<- " + obj_data.prefix + "~" + obj_data.command + "~" + obj_data.params |
| 92 | for action in self.actions: | 94 | |
| 93 | retval = action.recv_msg(self, obj_data) | 95 | modules_to_load = [] |
| 94 | if retval: | 96 | for plugin_name in self.actions: |
| 95 | self.rawsend(retval) \ No newline at end of file | 97 | retval = self.actions[plugin_name].recv_msg(self, obj_data) |
| 98 | if type(retval) == type(dict()): | ||
| 99 | if retval.has_key('load'): | ||
| 100 | modules_to_load.append(retval['load']) | ||
| 101 | elif type(retval) == type('str is str'): | ||
| 102 | self.rawsend(retval) | ||
| 103 | |||
| 104 | for module in modules_to_load: | ||
| 105 | self.load_action(module) | ||
diff --git a/wmd/parser.py b/wmd/parser.py index 24b965c..f4a704f 100644 --- a/wmd/parser.py +++ b/wmd/parser.py | |||
| @@ -18,6 +18,9 @@ class IRCParse(object): | |||
| 18 | else: | 18 | else: |
| 19 | return False | 19 | return False |
| 20 | 20 | ||
| 21 | def get_channel(self): | ||
| 22 | return self.get_username() | ||
| 23 | |||
| 21 | def _process_data(self, data): | 24 | def _process_data(self, data): |
| 22 | data = data.strip() | 25 | data = data.strip() |
| 23 | 26 | ||