From 52613952d2cf4663c38f2a6d8f317c82a11cd337 Mon Sep 17 00:00:00 2001 From: Paul Colomiets Date: Tue, 3 May 2011 18:21:48 +0300 Subject: Implemented asynchronous message send to avoid deadlocks --- bin/uzbl-event-manager | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index cb462c7..667f1fd 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -315,6 +315,7 @@ class Uzbl(object): self.opts = opts self.parent = parent self.child_socket = child_socket + self.child_buffer = [] self.time = time.time() self.pid = None self.name = None @@ -371,7 +372,24 @@ class Uzbl(object): if opts.print_events: print ascii(u'%s<-- %s' % (' ' * self._depth, msg)) - self.child_socket.send(ascii("%s\n" % msg)) + self.child_buffer.append(ascii("%s\n" % msg)) + + def do_send(self): + data = ''.join(self.child_buffer) + try: + bsend = self.child_socket.send(data) + except socket.error as e: + if e.errno in (errno.EAGAIN, errno.EINTR): + self.child_buffer = [data] + return + else: + self.close() + return + else: + if bsend < len(data): + self.child_buffer = [ data[bsend:] ] + else: + del self.child_buffer[:] def read(self): @@ -607,7 +625,8 @@ class UzblEventDaemon(object): while (self.uzbls or not connections) or (not opts.auto_close): socks = [self.server_socket] + self.uzbls.keys() - reads, _, errors = select(socks, [], socks, 1) + wsocks = [k for k, v in self.uzbls.items() if v.child_buffer] + reads, writes, errors = select(socks, wsocks, socks, 1) if self.server_socket in reads: reads.remove(self.server_socket) @@ -617,6 +636,9 @@ class UzblEventDaemon(object): self.uzbls[child_socket] = Uzbl(self, child_socket) connections += 1 + for uzbl in [self.uzbls[s] for s in writes]: + uzbl.do_send() + for uzbl in [self.uzbls[s] for s in reads]: uzbl.read() -- cgit v1.2.3 From bffc57a31e64da24356a69f588eb8d8eeede8232 Mon Sep 17 00:00:00 2001 From: Paul Colomiets Date: Tue, 3 May 2011 20:08:16 +0300 Subject: Added `setblocking(False)` to make async writes really useful --- bin/uzbl-event-manager | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 667f1fd..000162a 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -633,6 +633,7 @@ class UzblEventDaemon(object): # Accept connection and create uzbl instance. child_socket = self.server_socket.accept()[0] + child_socket.setblocking(False) self.uzbls[child_socket] = Uzbl(self, child_socket) connections += 1 -- cgit v1.2.3 From c27ccf9dc2c9a2e2554596a891fe51e76ec409c3 Mon Sep 17 00:00:00 2001 From: Paul Colomiets Date: Tue, 3 May 2011 21:59:45 +0300 Subject: Added better logging and connection close detection --- bin/uzbl-event-manager | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 000162a..be7db8e 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -377,17 +377,20 @@ class Uzbl(object): def do_send(self): data = ''.join(self.child_buffer) try: - bsend = self.child_socket.send(data) + bsent = self.child_socket.send(data) except socket.error as e: if e.errno in (errno.EAGAIN, errno.EINTR): self.child_buffer = [data] return else: - self.close() - return + self.logger.error(get_exc()) + return self.close() else: - if bsend < len(data): - self.child_buffer = [ data[bsend:] ] + if bsent == 0: + self.logger.debug('write end of connection closed') + self.close() + elif bsent < len(data): + self.child_buffer = [ data[bsent:] ] else: del self.child_buffer[:] -- cgit v1.2.3 From 2da45f9abe35c35c02c692d921bae60f8d0236af Mon Sep 17 00:00:00 2001 From: Donald Johnson Date: Thu, 26 May 2011 03:57:57 -0500 Subject: Made main() method for uzbl-event-manager Calls main() upon running the event manager. Work done was moving a gigantic block of repetetive adding for the parser into its own function `make_parser()`, moved `get_logger(...)` out of the if-main branch, and declaring a lot of variables as globals (this can be fixed later; recommended to make all globals in all caps later). This allows someone to attach a debugger or profiler to the event manager more easily, just by editing the script. --- bin/uzbl-event-manager | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index cb462c7..2ba1938 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -815,8 +815,7 @@ def list_action(): for plugin in sorted(names.values()): print plugin - -if __name__ == "__main__": +def make_parser(): parser = OptionParser('usage: %prog [options] {start|stop|restart|list}') add = parser.add_option @@ -862,6 +861,29 @@ if __name__ == "__main__": dest='print_events', action="store_false", default=True, help="silence the printing of events to stdout") + return parser + +def get_logger(name): + handlers = [ch, fh] + level = [max(log_level, 10),] + logger = logging.getLogger(name) + logger.setLevel(level[0]) + for handler in handlers: + logger.addHandler(handler) + + return logger + + +def main(): + global opts + global args + global logger + global ch + global fh + global log_level + + parser = make_parser() + (opts, args) = parser.parse_args() opts.server_socket = expandpath(opts.server_socket) @@ -897,16 +919,6 @@ if __name__ == "__main__": # logging.getLogger wrapper which sets the levels and adds the # file and console handlers automagically - def get_logger(name): - handlers = [ch, fh] - level = [max(log_level, 10),] - logger = logging.getLogger(name) - logger.setLevel(level[0]) - for handler in handlers: - logger.addHandler(handler) - - return logger - # Get main logger logger = get_logger(SCRIPTNAME) logger.info('logging to %r' % opts.log_file) @@ -988,4 +1000,9 @@ if __name__ == "__main__": logger.debug('process CPU time: %f' % time.clock()) + +if __name__ == "__main__": + main() + + # vi: set et ts=4: -- cgit v1.2.3 From 0dd3b8e35a50a3946be03fa1969e34dd3ecab636 Mon Sep 17 00:00:00 2001 From: Donald Johnson Date: Fri, 27 May 2011 15:04:11 -0500 Subject: Deleted unneeded `global args` declaration. --- bin/uzbl-event-manager | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 2ba1938..3c64239 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -874,9 +874,9 @@ def get_logger(name): return logger + def main(): global opts - global args global logger global ch global fh -- cgit v1.2.3 From e48f3ca7de9ff20559506e2bae08fd860a3984b9 Mon Sep 17 00:00:00 2001 From: Donald Johnson Date: Fri, 3 Jun 2011 17:41:25 -0500 Subject: Made logging easier Made init_logger() which sets up the root logger and log level, and then used `logger` as a global to refer to the script's logger right off the bat. Removed usage of `get_logger(name)` entirely. --- bin/uzbl-event-manager | 52 +++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 5299a5e..4b3e976 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -65,6 +65,8 @@ CACHE_DIR = os.path.join(xdghome('CACHE', '.cache/'), 'uzbl/') # Define some globals. SCRIPTNAME = os.path.basename(sys.argv[0]) +logger = logging.getLogger(SCRIPTNAME) + def get_exc(): '''Format `format_exc` for logging.''' return "\n%s" % format_exc().rstrip() @@ -841,6 +843,7 @@ def list_action(): for plugin in sorted(names.values()): print plugin + def make_parser(): parser = OptionParser('usage: %prog [options] {start|stop|restart|list}') add = parser.add_option @@ -858,6 +861,7 @@ def make_parser(): help='load plugin, loads before plugins in search dirs') socket_location = os.path.join(CACHE_DIR, 'event_daemon') + add('-s', '--server-socket', dest='server_socket', metavar="SOCKET", default=socket_location, help='server AF_UNIX socket location') @@ -889,24 +893,29 @@ def make_parser(): return parser -def get_logger(name): - handlers = [ch, fh] - level = [max(log_level, 10),] - logger = logging.getLogger(name) - logger.setLevel(level[0]) - for handler in handlers: - logger.addHandler(handler) - return logger +def init_logger(): + log_level = logging.CRITICAL - opts.verbose*10 + logger = logging.getLogger() + logger.setLevel(max(log_level, 10)) + # Console + handler = logging.StreamHandler() + handler.setLevel(max(log_level+10, 10)) + handler.setFormatter(logging.Formatter( + '%(name)s: %(levelname)s: %(message)s')) + logger.addHandler(handler) + + # Logfile + handler = logging.FileHandler(opts.log_file, 'w', 'utf-8', 1) + handler.setLevel(max(log_level, 10)) + handler.setFormatter(logging.Formatter( + '[%(created)f] %(name)s: %(levelname)s: %(message)s')) + logger.addHandler(handler) def main(): global opts - global logger - global ch - global fh - global log_level parser = make_parser() @@ -929,24 +938,7 @@ def main(): opts.log_file = expandpath(opts.log_file) # Logging setup - log_level = logging.CRITICAL - opts.verbose*10 - - # Console logging handler - ch = logging.StreamHandler() - ch.setLevel(max(log_level+10, 10)) - ch.setFormatter(logging.Formatter( - '%(name)s: %(levelname)s: %(message)s')) - - # File logging handler - fh = logging.FileHandler(opts.log_file, 'w', 'utf-8', 1) - fh.setLevel(max(log_level, 10)) - fh.setFormatter(logging.Formatter( - '[%(created)f] %(name)s: %(levelname)s: %(message)s')) - - # logging.getLogger wrapper which sets the levels and adds the - # file and console handlers automagically - # Get main logger - logger = get_logger(SCRIPTNAME) + init_logger() logger.info('logging to %r' % opts.log_file) plugins = {} -- cgit v1.2.3 From ad544637823e5ec58d9680e0af8980903f0afdfd Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 4 Jun 2011 12:14:02 +0200 Subject: remove all uses of get_logger --- bin/uzbl-event-manager | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 4b3e976..a2f1c7e 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -189,7 +189,7 @@ class Plugin(object): self.name = name self.path = path self.plugin = plugin - self.logger = get_logger('plugin.%s' % name) + self.logger = logging.getLogger('plugin.%s' % name) # Weakrefs to all handlers created by this plugin self.handlers = set([]) @@ -326,7 +326,7 @@ class Uzbl(object): self.instance_start = False # Use name "unknown" until name is discovered. - self.logger = get_logger('uzbl-instance[]') + self.logger = logging.getLogger('uzbl-instance[]') # Track plugin event handlers and exported functions. self.exports = {} @@ -442,7 +442,7 @@ class Uzbl(object): assert name and event, 'event string missing elements' if not self.name: self.name = name - self.logger = get_logger('uzbl-instance%s' % name) + self.logger = logging.getLogger('uzbl-instance%s' % name) self.logger.info('found instance name %r' % name) assert self.name == name, 'instance name mismatch' -- cgit v1.2.3 From 927fa85c26566acaebe7e3d1d74aff05fa3877a5 Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 4 Jun 2011 12:22:59 +0200 Subject: fix some import misses in event manager --- bin/uzbl-event-manager | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index a2f1c7e..43348b2 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -30,18 +30,18 @@ import atexit import imp import logging import os -import socket import sys import time import weakref import re +import errno from collections import defaultdict from functools import partial from glob import glob from itertools import count from optparse import OptionParser from select import select -from signal import signal, SIGTERM, SIGINT +from signal import signal, SIGTERM, SIGINT, SIGKILL from socket import socket, AF_UNIX, SOCK_STREAM from traceback import format_exc -- cgit v1.2.3 From 832e00d4675bfcc1b49e28b3cc2457a23bb62f12 Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 4 Jun 2011 12:34:09 +0200 Subject: make event-manager pass pep8 check --- bin/uzbl-event-manager | 73 ++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index 43348b2..d351f67 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -45,6 +45,7 @@ from signal import signal, SIGTERM, SIGINT, SIGKILL from socket import socket, AF_UNIX, SOCK_STREAM from traceback import format_exc + def xdghome(key, default): '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise use $HOME and the default path.''' @@ -67,14 +68,17 @@ SCRIPTNAME = os.path.basename(sys.argv[0]) logger = logging.getLogger(SCRIPTNAME) + def get_exc(): '''Format `format_exc` for logging.''' return "\n%s" % format_exc().rstrip() + def expandpath(path): '''Expand and realpath paths.''' return os.path.realpath(os.path.expandvars(path)) + def ascii(u): '''Convert unicode strings into ascii for transmission over ascii-only streams/sockets/devices.''' @@ -149,7 +153,6 @@ class EventHandler(object): self.args = args self.kwargs = kwargs - def __repr__(self): elems = ['id=%d' % self.id, 'event=%s' % self.event, 'callback=%r' % self.callback] @@ -163,7 +166,6 @@ class EventHandler(object): elems.append('plugin=%s' % self.plugin.name) return u'' % ', '.join(elems) - def call(self, uzbl, *args, **kwargs): '''Execute the handler function and merge argument lists.''' @@ -172,9 +174,6 @@ class EventHandler(object): self.callback(uzbl, *args, **kwargs) - - - class Plugin(object): '''Plugin module wrapper object.''' @@ -183,7 +182,6 @@ class Plugin(object): special_functions = ['require', 'export', 'export_dict', 'connect', 'connect_dict', 'logger', 'unquote', 'splitquoted'] - def __init__(self, parent, name, path, plugin): self.parent = parent self.name = name @@ -212,11 +210,9 @@ class Plugin(object): for attr in self.special_functions: plugin.__dict__[attr] = getattr(self, attr) - def __repr__(self): return u'' % self.plugin - def export(self, uzbl, attr, object, prepend=True): '''Attach `object` to `uzbl` instance. This is the preferred method of sharing functionality, functions, data and objects between @@ -236,12 +232,10 @@ class Plugin(object): uzbl.logger.info('exported %r to %r by plugin %r, prepended %r' % (object, 'uzbl.%s' % attr, self.name, prepend)) - def export_dict(self, uzbl, exports): for (attr, object) in exports.items(): self.export(uzbl, attr, object) - def find_handler(self, event, callback, args, kwargs): '''Check if a handler with the identical callback and arguments exists and return it.''' @@ -255,7 +249,6 @@ class Plugin(object): and handler.args == args and handler.kwargs == kwargs: return handler - def connect(self, uzbl, event, callback, *args, **kwargs): '''Create an event handler object which handles `event` events. @@ -284,12 +277,10 @@ class Plugin(object): uzbl.logger.info('connected %r' % handler) return handler - def connect_dict(self, uzbl, connects): for (event, callback) in connects.items(): self.connect(uzbl, event, callback) - def require(self, plugin): '''Check that plugin with name `plugin` has been loaded. Use this to ensure that your plugins dependencies have been met.''' @@ -306,10 +297,12 @@ class Plugin(object): return s.encode('utf-8').decode('string_escape').decode('utf-8') _splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')") + @classmethod def splitquoted(cls, text): '''Splits string on whitespace while respecting quotations''' - return [cls.unquote(p) for p in cls._splitquoted.split(text) if p.strip()] + parts = cls._splitquoted.split(text) + return [cls.unquote(p) for p in parts if p.strip()] class Uzbl(object): @@ -336,16 +329,14 @@ class Uzbl(object): self._depth = 0 self._buffer = '' - def __repr__(self): return '' % ', '.join([ 'pid=%s' % (self.pid if self.pid else "Unknown"), 'name=%s' % ('%r' % self.name if self.name else "Unknown"), - 'uptime=%f' % (time.time()-self.time), + 'uptime=%f' % (time.time() - self.time), '%d exports' % len(self.exports.keys()), '%d handlers' % sum([len(l) for l in self.handlers.values()])]) - def init_plugins(self): '''Call the init and after hooks in all loaded plugins for this instance.''' @@ -360,10 +351,9 @@ class Uzbl(object): # optional `after` function in the plugins namespace. for plugin in self.parent.plugins.values(): if plugin.after: - self.logger.debug('calling %r plugin after hook'%plugin.name) + self.logger.debug('calling %r plugin after hook' % plugin.name) plugin.after(self) - def send(self, msg): '''Send a command to the uzbl instance via the child socket instance.''' @@ -392,11 +382,10 @@ class Uzbl(object): self.logger.debug('write end of connection closed') self.close() elif bsent < len(data): - self.child_buffer = [ data[bsent:] ] + self.child_buffer = [data[bsent:]] else: del self.child_buffer[:] - def read(self): '''Read data from the child socket and pass lines to the parse_msg function.''' @@ -422,13 +411,12 @@ class Uzbl(object): self.logger.error(get_exc()) self.logger.error('erroneous event: %r' % line) - def parse_msg(self, line): '''Parse an incoming message from a uzbl instance. Event strings will be parsed into `self.event(event, args)`.''' # Split by spaces (and fill missing with nulls) - elems = (line.split(' ', 3) + ['',]*3)[:4] + elems = (line.split(' ', 3) + [''] * 3)[:4] # Ignore non-event messages. if elems[0] != 'EVENT': @@ -450,16 +438,17 @@ class Uzbl(object): # Handle the event with the event handlers through the event method self.event(event, args) - def event(self, event, *args, **kargs): '''Raise an event.''' event = event.upper() if not opts.daemon_mode and opts.print_events: - elems = [event,] - if args: elems.append(unicode(args)) - if kargs: elems.append(unicode(kargs)) + elems = [event] + if args: + elems.append(unicode(args)) + if kargs: + elems.append(unicode(kargs)) print ascii(u'%s--> %s' % (' ' * self._depth, ' '.join(elems))) if event == "INSTANCE_START" and args: @@ -487,12 +476,10 @@ class Uzbl(object): self._depth -= 1 - def close_connection(self, child_socket): '''Close child socket and delete the uzbl instance created for that child socket connection.''' - def close(self): '''Close the client socket and call the plugin cleanup hooks.''' @@ -552,7 +539,6 @@ class UzblEventDaemon(object): # Load plugins into self.plugins self.load_plugins(opts.plugins) - def load_plugins(self, plugins): '''Load event manager plugins.''' @@ -561,7 +547,7 @@ class UzblEventDaemon(object): (dir, file) = os.path.split(path) name = file[:-3] if file.lower().endswith('.py') else file - info = imp.find_module(name, [dir,]) + info = imp.find_module(name, [dir]) module = imp.load_module(name, *info) # Check if the plugin has a callable hook. @@ -574,7 +560,6 @@ class UzblEventDaemon(object): self.plugins[name] = plugin logger.info('new %r' % plugin) - def create_server_socket(self): '''Create the event manager daemon socket for uzbl instance duplex communication.''' @@ -589,7 +574,6 @@ class UzblEventDaemon(object): self.server_socket = sock logger.debug('bound server socket to %r' % opts.server_socket) - def run(self): '''Main event daemon loop.''' @@ -618,7 +602,6 @@ class UzblEventDaemon(object): logger.debug('exiting main loop') - def listen(self): '''Accept incoming connections and constantly poll instance sockets for incoming data.''' @@ -654,7 +637,6 @@ class UzblEventDaemon(object): logger.info('auto closing') - def close_server_socket(self): '''Close and delete the server socket.''' @@ -671,7 +653,6 @@ class UzblEventDaemon(object): except: logger.error(get_exc()) - def quit(self, sigint=None, *args): '''Close all instance socket objects, server socket and delete the pid file.''' @@ -770,7 +751,7 @@ def term_process(pid): logger.debug('process with pid %d exit' % pid) return True - if (time.time()-start) > 5: + if (time.time() - start) > 5: logger.warning('process with pid %d failed to exit' % pid) logger.info('sending SIGKILL to process with pid %d' % pid) try: @@ -779,7 +760,7 @@ def term_process(pid): logger.critical(get_exc()) raise - if (time.time()-start) > 10: + if (time.time() - start) > 10: logger.critical('unable to kill process with pid %d' % pid) raise OSError @@ -895,13 +876,13 @@ def make_parser(): def init_logger(): - log_level = logging.CRITICAL - opts.verbose*10 + log_level = logging.CRITICAL - opts.verbose * 10 logger = logging.getLogger() logger.setLevel(max(log_level, 10)) # Console handler = logging.StreamHandler() - handler.setLevel(max(log_level+10, 10)) + handler.setLevel(max(log_level + 10, 10)) handler.setFormatter(logging.Formatter( '%(name)s: %(levelname)s: %(message)s')) logger.addHandler(handler) @@ -988,11 +969,15 @@ def main(): if not os.path.isfile(plugin): parser.error('plugin not a file: %r' % plugin) - if opts.auto_close: logger.debug('will auto close') - else: logger.debug('will not auto close') + if opts.auto_close: + logger.debug('will auto close') + else: + logger.debug('will not auto close') - if opts.daemon_mode: logger.debug('will daemonize') - else: logger.debug('will not daemonize') + if opts.daemon_mode: + logger.debug('will daemonize') + else: + logger.debug('will not daemonize') opts.plugins = plugins -- cgit v1.2.3 From 8bb15157d56f31970003aba6da814e9a4e9236bd Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 4 Jun 2011 12:49:42 +0200 Subject: proper use of logger --- bin/uzbl-event-manager | 132 ++++++++++++++++++++++++------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/bin/uzbl-event-manager b/bin/uzbl-event-manager index d351f67..64a1354 100755 --- a/bin/uzbl-event-manager +++ b/bin/uzbl-event-manager @@ -95,7 +95,7 @@ def daemonize(): os._exit(0) except OSError: - logger.critical(get_exc()) + logger.critical('failed to daemonize', exc_info=True) sys.exit(1) os.chdir('/') @@ -107,7 +107,7 @@ def daemonize(): os._exit(0) except OSError: - logger.critical(get_exc()) + logger.critical('failed to daemonize', exc_info=True) sys.exit(1) if sys.stdout.isatty(): @@ -132,11 +132,11 @@ def make_dirs(path): try: dirname = os.path.dirname(path) if not os.path.isdir(dirname): - logger.debug('creating directories %r' % dirname) + logger.debug('creating directories %r', dirname) os.makedirs(dirname) except OSError: - logger.error(get_exc()) + logger.error('failed to create directories', exc_info=True) class EventHandler(object): @@ -213,8 +213,8 @@ class Plugin(object): def __repr__(self): return u'' % self.plugin - def export(self, uzbl, attr, object, prepend=True): - '''Attach `object` to `uzbl` instance. This is the preferred method + def export(self, uzbl, attr, obj, prepend=True): + '''Attach `obj` to `uzbl` instance. This is the preferred method of sharing functionality, functions, data and objects between plugins. @@ -226,11 +226,11 @@ class Plugin(object): assert attr not in uzbl.exports, "attr %r already exported by %r" %\ (attr, uzbl.exports[attr][0]) - prepend = True if prepend and callable(object) else False - uzbl.__dict__[attr] = partial(object, uzbl) if prepend else object - uzbl.exports[attr] = (self, object, prepend) - uzbl.logger.info('exported %r to %r by plugin %r, prepended %r' - % (object, 'uzbl.%s' % attr, self.name, prepend)) + prepend = True if prepend and callable(obj) else False + uzbl.__dict__[attr] = partial(obj, uzbl) if prepend else obj + uzbl.exports[attr] = (self, obj, prepend) + uzbl.logger.info('exported %r to %r by plugin %r, prepended %r', + obj, 'uzbl.%s' % attr, self.name, prepend) def export_dict(self, uzbl, exports): for (attr, object) in exports.items(): @@ -271,10 +271,10 @@ class Plugin(object): # Create a new handler handler = EventHandler(self, event, callback, args, kwargs) self.handlers.add(weakref.ref(handler)) - self.logger.info('new %r' % handler) + self.logger.info('new %r', handler) uzbl.handlers[event].append(handler) - uzbl.logger.info('connected %r' % handler) + uzbl.logger.info('connected %r', handler) return handler def connect_dict(self, uzbl, connects): @@ -286,7 +286,7 @@ class Plugin(object): ensure that your plugins dependencies have been met.''' assert plugin in self.parent.plugins, self.logger.critical( - 'plugin %r required by plugin %r' (plugin, self.name)) + 'plugin %r required by plugin %r', plugin, self.name) @classmethod def unquote(cls, s): @@ -344,14 +344,14 @@ class Uzbl(object): # Initialise each plugin with the current uzbl instance. for plugin in self.parent.plugins.values(): if plugin.init: - self.logger.debug('calling %r plugin init hook' % plugin.name) + self.logger.debug('calling %r plugin init hook', plugin.name) plugin.init(self) # Allow plugins to use exported features of other plugins by calling an # optional `after` function in the plugins namespace. for plugin in self.parent.plugins.values(): if plugin.after: - self.logger.debug('calling %r plugin after hook' % plugin.name) + self.logger.debug('calling %r plugin after hook', plugin.name) plugin.after(self) def send(self, msg): @@ -375,7 +375,7 @@ class Uzbl(object): self.child_buffer = [data] return else: - self.logger.error(get_exc()) + self.logger.error('failed to send', exc_info=True) return self.close() else: if bsent == 0: @@ -397,7 +397,7 @@ class Uzbl(object): return self.close() except: - self.logger.error(get_exc()) + self.logger.error('failed to read', exc_info=True) return self.close() lines = (self._buffer + raw).split('\n') @@ -420,7 +420,7 @@ class Uzbl(object): # Ignore non-event messages. if elems[0] != 'EVENT': - logger.info('non-event message: %r' % line) + logger.info('non-event message: %r', line) if opts.print_events: print '--- %s' % ascii(line) return @@ -431,7 +431,7 @@ class Uzbl(object): if not self.name: self.name = name self.logger = logging.getLogger('uzbl-instance%s' % name) - self.logger.info('found instance name %r' % name) + self.logger.info('found instance name %r', name) assert self.name == name, 'instance name mismatch' @@ -455,7 +455,7 @@ class Uzbl(object): assert not self.instance_start, 'instance already started' self.pid = int(args[0]) - self.logger.info('found instance pid %r' % self.pid) + self.logger.info('found instance pid %r', self.pid) self.init_plugins() @@ -472,7 +472,7 @@ class Uzbl(object): handler.call(self, *args, **kargs) except: - self.logger.error(get_exc()) + self.logger.error('error in handler', exc_info=True) self._depth -= 1 @@ -496,7 +496,7 @@ class Uzbl(object): self.child_socket.close() except: - self.logger.error(get_exc()) + self.logger.error('failed to close socket', exc_info=True) finally: self.child_socket = None @@ -504,11 +504,11 @@ class Uzbl(object): # Call plugins cleanup hooks. for plugin in self.parent.plugins.values(): if plugin.cleanup: - self.logger.debug('calling %r plugin cleanup hook' - % plugin.name) + self.logger.debug('calling %r plugin cleanup hook', + plugin.name) plugin.cleanup(self) - logger.info('removed %r' % self) + logger.info('removed %r', self) class UzblEventDaemon(object): @@ -543,7 +543,7 @@ class UzblEventDaemon(object): '''Load event manager plugins.''' for path in plugins: - logger.debug('loading plugin %r' % path) + logger.debug('loading plugin %r', path) (dir, file) = os.path.split(path) name = file[:-3] if file.lower().endswith('.py') else file @@ -555,10 +555,10 @@ class UzblEventDaemon(object): for attr in ['init', 'after', 'cleanup']]) assert hooks, "no hooks in plugin %r" % module - logger.debug('creating plugin instance for %r plugin' % name) + logger.debug('creating plugin instance for %r plugin', name) plugin = Plugin(self, name, path, module) self.plugins[name] = plugin - logger.info('new %r' % plugin) + logger.info('new %r', plugin) def create_server_socket(self): '''Create the event manager daemon socket for uzbl instance duplex @@ -572,7 +572,7 @@ class UzblEventDaemon(object): sock.listen(5) self.server_socket = sock - logger.debug('bound server socket to %r' % opts.server_socket) + logger.debug('bound server socket to %r', opts.server_socket) def run(self): '''Main event daemon loop.''' @@ -595,7 +595,7 @@ class UzblEventDaemon(object): except: if not self._quit: - logger.critical(get_exc()) + logger.critical('failed to listen', exc_info=True) # Clean up and exit self.quit() @@ -606,7 +606,7 @@ class UzblEventDaemon(object): '''Accept incoming connections and constantly poll instance sockets for incoming data.''' - logger.info('listening on %r' % opts.server_socket) + logger.info('listening on %r', opts.server_socket) # Count accepted connections connections = 0 @@ -647,11 +647,11 @@ class UzblEventDaemon(object): self.server_socket = None if os.path.exists(opts.server_socket): - logger.info('unlinking %r' % opts.server_socket) + logger.info('unlinking %r', opts.server_socket) os.unlink(opts.server_socket) except: - logger.error(get_exc()) + logger.error('failed to close server socket', exc_info=True) def quit(self, sigint=None, *args): '''Close all instance socket objects, server socket and delete the @@ -682,16 +682,16 @@ def make_pid_file(pid_file): '''Creates a pid file at `pid_file`, fails silently.''' try: - logger.debug('creating pid file %r' % pid_file) + logger.debug('creating pid file %r', pid_file) make_dirs(pid_file) pid = os.getpid() fileobj = open(pid_file, 'w') fileobj.write('%d' % pid) fileobj.close() - logger.info('created pid file %r with pid %d' % (pid_file, pid)) + logger.info('created pid file %r with pid %d', pid_file, pid) except: - logger.error(get_exc()) + logger.error('failed to create pid file', exc_info=True) def del_pid_file(pid_file): @@ -699,27 +699,27 @@ def del_pid_file(pid_file): if os.path.isfile(pid_file): try: - logger.debug('deleting pid file %r' % pid_file) + logger.debug('deleting pid file %r', pid_file) os.remove(pid_file) - logger.info('deleted pid file %r' % pid_file) + logger.info('deleted pid file %r', pid_file) except: - logger.error(get_exc()) + logger.error('failed to delete pid file', exc_info=True) def get_pid(pid_file): '''Reads a pid from pid file `pid_file`, fails None.''' try: - logger.debug('reading pid file %r' % pid_file) + logger.debug('reading pid file %r', pid_file) fileobj = open(pid_file, 'r') pid = int(fileobj.read()) fileobj.close() - logger.info('read pid %d from pid file %r' % (pid, pid_file)) + logger.info('read pid %d from pid file %r', pid, pid_file) return pid except (IOError, ValueError): - logger.error(get_exc()) + logger.error('failed to read pid', exc_info=True) return None @@ -738,30 +738,30 @@ def term_process(pid): '''Asks nicely then forces process with pid `pid` to exit.''' try: - logger.info('sending SIGTERM to process with pid %r' % pid) + logger.info('sending SIGTERM to process with pid %r', pid) os.kill(pid, SIGTERM) except OSError: logger.error(get_exc()) - logger.debug('waiting for process with pid %r to exit' % pid) + logger.debug('waiting for process with pid %r to exit', pid) start = time.time() while True: if not pid_running(pid): - logger.debug('process with pid %d exit' % pid) + logger.debug('process with pid %d exit', pid) return True if (time.time() - start) > 5: - logger.warning('process with pid %d failed to exit' % pid) - logger.info('sending SIGKILL to process with pid %d' % pid) + logger.warning('process with pid %d failed to exit', pid) + logger.info('sending SIGKILL to process with pid %d', pid) try: os.kill(pid, SIGKILL) except: - logger.critical(get_exc()) + logger.critical('failed to kill %d', pid, exc_info=True) raise if (time.time() - start) > 10: - logger.critical('unable to kill process with pid %d' % pid) + logger.critical('unable to kill process with pid %d', pid) raise OSError time.sleep(0.25) @@ -772,20 +772,20 @@ def stop_action(): pid_file = opts.pid_file if not os.path.isfile(pid_file): - logger.error('could not find running event manager with pid file %r' - % opts.pid_file) + logger.error('could not find running event manager with pid file %r', + pid_file) return pid = get_pid(pid_file) if not pid_running(pid): - logger.debug('no process with pid %r' % pid) + logger.debug('no process with pid %r', pid) del_pid_file(pid_file) return - logger.debug('terminating process with pid %r' % pid) + logger.debug('terminating process with pid %r', pid) term_process(pid) del_pid_file(pid_file) - logger.info('stopped event manager process with pid %d' % pid) + logger.info('stopped event manager process with pid %d', pid) def start_action(): @@ -795,10 +795,10 @@ def start_action(): if os.path.isfile(pid_file): pid = get_pid(pid_file) if pid_running(pid): - logger.error('event manager already started with pid %d' % pid) + logger.error('event manager already started with pid %d', pid) return - logger.info('no process with pid %d' % pid) + logger.info('no process with pid %d', pid) del_pid_file(pid_file) UzblEventDaemon().run() @@ -920,7 +920,7 @@ def main(): # Logging setup init_logger() - logger.info('logging to %r' % opts.log_file) + logger.info('logging to %r', opts.log_file) plugins = {} @@ -934,11 +934,11 @@ def main(): for plugin in matches: (head, tail) = os.path.split(plugin) if tail not in plugins: - logger.debug('found plugin: %r' % plugin) + logger.debug('found plugin: %r', plugin) plugins[tail] = plugin else: - logger.debug('ignoring plugin: %r' % plugin) + logger.debug('ignoring plugin: %r', plugin) # Add default plugin locations if opts.default_dirs: @@ -952,15 +952,15 @@ def main(): # Load all plugins in `opts.plugin_dirs` into the plugins list for dir in opts.plugin_dirs: dir = expandpath(dir) - logger.debug('searching plugin dir: %r' % dir) + logger.debug('searching plugin dir: %r', dir) for plugin in glob(os.path.join(dir, '*.py')): (head, tail) = os.path.split(plugin) if tail not in plugins: - logger.debug('found plugin: %r' % plugin) + logger.debug('found plugin: %r', plugin) plugins[tail] = plugin else: - logger.debug('ignoring plugin: %r' % plugin) + logger.debug('ignoring plugin: %r', plugin) plugins = plugins.values() @@ -991,17 +991,17 @@ def main(): parser.error('invalid action: %r' % action) elif not args: - logger.warning('no daemon action given, assuming %r' % 'start') action = 'start' + logger.warning('no daemon action given, assuming %r', action) else: parser.error('invalid action argument: %r' % args) - logger.info('daemon action %r' % action) + logger.info('daemon action %r', action) # Do action daemon_actions[action]() - logger.debug('process CPU time: %f' % time.clock()) + logger.debug('process CPU time: %f', time.clock()) if __name__ == "__main__": -- cgit v1.2.3