diff options
author | Mason Larobina <mason.larobina@gmail.com> | 2009-09-10 22:15:23 +0800 |
---|---|---|
committer | Mason Larobina <mason.larobina@gmail.com> | 2009-09-10 22:15:23 +0800 |
commit | 09cb17496ce37b96898eb6a4246aa9e6603222a8 (patch) | |
tree | 8a469e4781752308c97a35a9a6e67a848af906aa /examples | |
parent | 6e9d1499e263b488336a877fd7b1acbed2551d92 (diff) |
Added listen_from_uzbl_socket added various command line options.
Diffstat (limited to 'examples')
-rwxr-xr-x | examples/data/uzbl/scripts/event_manager.py | 267 |
1 files changed, 223 insertions, 44 deletions
diff --git a/examples/data/uzbl/scripts/event_manager.py b/examples/data/uzbl/scripts/event_manager.py index 7f3ffce..e131306 100755 --- a/examples/data/uzbl/scripts/event_manager.py +++ b/examples/data/uzbl/scripts/event_manager.py @@ -47,6 +47,8 @@ import re import types import socket import pprint +import time +from optparse import OptionParser from traceback import print_exc @@ -70,8 +72,10 @@ DATA_DIR = os.path.join(xdghome('DATA', '.local/share/'), 'uzbl/') # Config dict (NOT the same as the uzbl.config). config = { - 'verbose': True, - 'plugin_dir': "$XDG_DATA_HOME/uzbl/scripts/plugins/" + 'verbose': False, + 'plugin_dir': "$XDG_DATA_HOME/uzbl/scripts/plugins/", + 'plugins_load': [], + 'plugins_ignore': [], } @@ -92,6 +96,12 @@ def echo(msg): sys.stdout.write("%s: %s\n" % (_SCRIPTNAME, msg)) +def error(msg): + '''Prints error messages to stderr.''' + + sys.stderr.write("%s: error: %s\n" % (_SCRIPTNAME, msg)) + + def counter(): '''Generate unique object id's.''' @@ -124,7 +134,7 @@ class PluginManager(dict): self.load_plugins() - def _find_plugins(self): + def _find_all_plugins(self): '''Find all python scripts in plugin dir and return a list of locations and imp moduleinfo's.''' @@ -139,7 +149,7 @@ class PluginManager(dict): return plugins - def _unload_plugin(self, plugin, remove_pyc=True): + def _unload_plugin(self, name, remove_pyc=True): '''Unload specific plugin and remove all waste in sys.modules Notice: manual manipulation of sys.modules is very un-pythonic but I @@ -147,49 +157,47 @@ class PluginManager(dict): this allows us to implement a reload plugins function.''' allmodules = sys.modules.keys() - allrefs = filter(lambda s: s.startswith("%s." % plugin), allmodules) + allrefs = filter(lambda s: s.startswith("%s." % name), allmodules) for ref in allrefs: del sys.modules[ref] - if plugin in sys.modules.keys(): - del sys.modules[plugin] + if name in sys.modules.keys(): + del sys.modules[name] - if plugin in self.keys(): - dict.__delitem__(self, plugin) + if name in self: + del self[name] if remove_pyc: - pyc = os.path.join(self.plugin_dir, '%s.pyc' % plugin) + pyc = os.path.join(self.plugin_dir, '%s.pyc' % name) if os.path.exists(pyc): os.remove(pyc) def load_plugins(self): - pluginlist = self._find_plugins() + if config['plugins_load']: + pluginlist = config['plugins_load'] - for name in pluginlist: - try: - # Make sure the plugin isn't already loaded. - self._unload_plugin(name) + else: + pluginlist = self._find_all_plugins() + for name in config['plugins_ignore']: + if name in pluginlist: + pluginlist.remove(name) - except: - print_exc() + for name in pluginlist: + # Make sure the plugin isn't already loaded. + self._unload_plugin(name) try: moduleinfo = imp.find_module(name, [self.plugin_dir,]) plugin = imp.load_module(name, *moduleinfo) - dict.__setitem__(self, name, plugin) - - # Check it has the init function. - if not hasattr(plugin, 'init'): - raise ImportError('plugin missing main "init" function.') + self[name] = plugin except: - print_exc() - self._unload_plugin(name) + raise - if len(self.keys()): + if self.keys(): echo("loaded plugin(s): %s" % ', '.join(self.keys())) @@ -322,6 +330,7 @@ class UzblInstance(object): self._exports = {} self._config = self.ConfigDict(self.set) self._running = None + self._buffer = '' self._handlers = {} @@ -386,7 +395,37 @@ class UzblInstance(object): plugin.init(self) except: - print_exc() + #print_exc() + raise + + + def _init_uzbl_socket(self, uzbl_socket=None, timeout=None): + '''Store socket location and open socket connection to uzbl socket.''' + + if uzbl_socket is None: + uzbl_socket = self.uzbl_socket + + if not uzbl_socket: + error("no socket location.") + return + + if not os.path.exists(uzbl_socket): + if timeout is None: + error("uzbl socket doesn't exist: %r" % uzbl_socket) + return + + waitlimit = time.time() + timeout + echo("waiting for uzbl socket: %r" % uzbl_socket) + while not os.path.exists(uzbl_socket): + time.sleep(0.25) + if time.time() > waitlimit: + error("timed out waiting for socket: %r" % uzbl_socket) + return + + self.uzbl_socket = uzbl_socket + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.connect(self.uzbl_socket) + self._socket = sock def _flush(self): @@ -403,9 +442,7 @@ class UzblInstance(object): if len(self._socket_cmd_queue) and self.uzbl_socket: if not self._socket and os.path.exists(self.uzbl_socket): - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect(self.uzbl_socket) - self._socket = sock + self._init_uzbl_socket() if self._socket: while len(self._socket_cmd_queue): @@ -485,27 +522,27 @@ class UzblInstance(object): def listen_from_fd(self, fd): - '''Main loop reading event messages from stdin.''' + '''Polls for event messages from fd.''' - self._running = True - while self._running: - try: + try: + self._running = True + while self._running: if select.select([fd,], [], [], 1)[0]: self.read_from_fd(fd) continue self._flush() - except KeyboardInterrupt: - self._running = False - print + except KeyboardInterrupt: + print - except: - print_exc() + except: + #print_exc() + raise def read_from_fd(self, fd): - '''Reads incoming event messages from fd.''' + '''Reads event messages from a single fd.''' raw = fd.readline() if not raw: @@ -524,6 +561,66 @@ class UzblInstance(object): self.handle_event(event, args) + def listen_from_uzbl_socket(self, uzbl_socket): + '''Polls for event messages from a single uzbl socket.''' + + self._init_uzbl_socket(uzbl_socket, 10) + + if not self._socket: + error("failed to init socket: %r" % uzbl_socket) + return + + self._flush() + try: + self._running = True + while self._running: + if select.select([self._socket], [], [], 1): + self.read_from_uzbl_socket() + continue + + self._flush() + + except KeyboardInterrupt: + print + + except: + #print_exc() + raise + + + def read_from_uzbl_socket(self): + '''Reads event messages from a uzbl socket.''' + + raw = self._socket.recv(1024) + if not raw: + # Read null byte + self._running = False + return + + self._buffer += raw + msgs = self._buffer.split("\n") + self._buffer = msgs.pop() + + for msg in msgs: + msg = msg.rstrip() + if not msg: + continue + + cmd = msg.strip().split(' ', 3) + if not cmd or cmd[0] != "EVENT": + # Not an event message + print msg.rstrip() + continue + + event, args = cmd[1], cmd[3] + try: + self.handle_event(event, args) + + except: + #print_exc() + raise + + def handle_event(self, event, args): '''Handle uzbl events internally before dispatch.''' @@ -544,8 +641,9 @@ class UzblInstance(object): self._flush() elif event == 'SOCKET_SET': - self.uzbl_socket = args - self._flush() + if not self.uzbl_socket or not self._socket: + self._init_uzbl_socket(args) + self._flush() elif event == 'SHUTDOWN': for (name, plugin) in self.plugins.items(): @@ -566,7 +664,8 @@ class UzblInstance(object): handler.exec_handler(args) except: - print_exc() + #print_exc() + raise def event(self, event, *args, **kargs): @@ -580,8 +679,88 @@ class UzblInstance(object): handler.exec_handler(*args, **kargs) except: - print_ext() + #print_ext() + raise if __name__ == "__main__": - uzbl = UzblInstance().listen_from_fd(sys.stdin) + #uzbl = UzblInstance().listen_from_fd(sys.stdin) + + parser = OptionParser() + parser.add_option('-s', '--uzbl-socket', dest='socket', + action="store", metavar="SOCKET", + help="read event messages from uzbl socket.") + + parser.add_option('-v', '--verbose', dest='verbose', action="store_true", + help="print verbose output.") + + parser.add_option('-d', '--plugin-dir', dest='plugin_dir', action="store", + metavar="FILE", help="change plugin directory.") + + parser.add_option('-p', '--load-plugins', dest="load", action="store", + metavar="PLUGINS", help="comma separated list of plugins to load") + + parser.add_option('-i', '--ignore-plugins', dest="ignore", action="store", + metavar="PLUGINS", help="comma separated list of plugins to ignore") + + parser.add_option('-l', '--list-plugins', dest='list', action='store_true', + help="list all the plugins in the plugin dir.") + + (options, args) = parser.parse_args() + + if len(args): + for arg in args: + error("unknown argument: %r" % arg) + + raise ArgumentError + + if options.verbose: + config['verbose'] = True + + if options.plugin_dir: + plugin_dir = os.path.expandvars(options.plugin_dir) + if not os.path.isdir(plugin_dir): + error("%r is not a directory" % plugin_dir) + sys.exit(1) + + config['plugin_dir'] = plugin_dir + echo("changed plugin dir: %r" % plugin_dir) + + if options.load and options.ignore: + error("you can't load and ignore at the same time.") + sys.exit(1) + + elif options.load: + plugins_load = config['plugins_load'] + for plugin in options.load.split(','): + if plugin.strip(): + plugins_load.append(plugin.strip()) + + echo('only loading plugin(s): %s' % ', '.join(plugins_load)) + + elif options.ignore: + plugins_ignore = config['plugins_ignore'] + for plugin in options.ignore.split(','): + if plugin.strip(): + plugins_ignore.append(plugin.strip()) + + echo('ignoring plugin(s): %s' % ', '.join(plugins_ignore)) + + + if options.list: + plugin_dir = os.path.expandvars(config['plugin_dir']) + if not os.path.isdir(plugin_dir): + error("not a directory: %r" % plugin_dir) + sys.exit(1) + + dirlist = filter(lambda p: p.endswith('.py'), os.listdir(plugin_dir)) + print ', '.join([p[:-3] for p in dirlist]) + + else: + uzbl = UzblInstance() + if options.socket: + echo("listen from uzbl socket: %r" % options.socket) + uzbl.listen_from_uzbl_socket(options.socket) + + else: + uzbl.listen_from_fd(sys.stdin) |