aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples
diff options
context:
space:
mode:
authorGravatar Mason Larobina <mason.larobina@gmail.com>2009-09-10 22:15:23 +0800
committerGravatar Mason Larobina <mason.larobina@gmail.com>2009-09-10 22:15:23 +0800
commit09cb17496ce37b96898eb6a4246aa9e6603222a8 (patch)
tree8a469e4781752308c97a35a9a6e67a848af906aa /examples
parent6e9d1499e263b488336a877fd7b1acbed2551d92 (diff)
Added listen_from_uzbl_socket added various command line options.
Diffstat (limited to 'examples')
-rwxr-xr-xexamples/data/uzbl/scripts/event_manager.py267
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)