#!/usr/bin/env python """ socket_notify.py - Phenny Socket Notification Copyright 2013-2016, Alexander Sulfrian Licensed under the Eiffel Forum License 2. http://inamidst.com/phenny/ """ import asyncore, socket, stat, os DEFAULT_CONFIG = { 'path': '/var/run/phenny/socket', 'umask': 0o000, } def setup(phenny): config = dict() config.update(DEFAULT_CONFIG) config.update(getattr(phenny.config, 'socket_notify', dict())) dir = os.path.dirname(config['path']) if not os.path.exists(dir): os.makedirs(dir) Monitor(config, phenny) class Sender(asyncore.dispatcher): def __init__(self, sock, phenny): asyncore.dispatcher.__init__(self, sock) self.phenny = phenny def handle_read(self): data = self.recv(8192) if data: for line in data.split('\n'): for chan in self.phenny.config.channels: self.phenny.msg(chan, line) else: self.close() class Monitor(asyncore.dispatcher): def __init__(self, config, phenny): asyncore.dispatcher.__init__(self) self.phenny = phenny self.phenny._orig_close = self.phenny.close self.phenny.close = (lambda: self._phenny_close()) self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM) try: mode = os.stat(config['path']).st_mode if stat.S_ISSOCK(mode): os.unlink(config['path']) else: print("Path '%s' exists and is not a socket!" % config['path']) sys.exit(1) except OSError: pass old_mask = os.umask(config['umask']) self.bind(config['path']) os.umask(old_mask) self.listen(5) def _phenny_close(self): self.close() self.phenny._orig_close() def handle_accept(self): pair = self.accept() if pair is not None: sock, addr = pair handler = Sender(sock, self.phenny)