_import_ok = True try: import weechat except ImportError: print 'This script needs to be run with WeeChat as a plugin.' _import_ok = False import socket SCRIPT_NAME = 'WeeLM' SCRIPT_AUTHOR = 'PontusCarlsson@live.se' SCRIPT_VERSION = '0.01' SCRIPT_LICENSE = 'GPL3' SCRIPT_DESC = 'Microsoft Notification Protocol provider for WeeChat' """ Cleanup process code. Cleanup callbacks are registered in _cleanup_cbs list, new callbacks are added with register_cleanup_cb(cb). They _must_ act like any cleanup callback registered with weechat.register(), i.e. they must return: weechat.WEECHAT_RC_OK on success weechat.WEECHAT_RC_ERROR on failure. Additionally they must set a descriptive error message to _cleanup_error which is printed (or logged) by the responsible cleanup callback. All callbacks are executed in reverse order in the responsible cleanup callback cleanup_cb() """ _cleanup_cbs = [] _cleanup_error = None weelm = None msn = None def register_cleanup_cb(callback): _cleanup_cbs.append(callback) def cleanup_cb(): _cleanup_cbs.reverse() ''' The cleanup callback list is reversed before iteration. This because cleanups are registered from most responsible to least responsible. During iteration this would be the wrong way since lists are first in last out containers. ''' for callback in _cleanup_cbs: weechat_rc = callback() if weechat_rc == weechat.WEECHAT_RC_ERROR: break return weechat_rc """ Plugin component objects. WeeLM consists of several objects to provide for it's purpose. Parent objects are the ones defined first here. Extending objects are defined afterwards with a slightly less abstract name. """ class MSNP: trid = 0 host = None port = None socket = None def __init__(self, host_port): try: self.host = socket.gethostbyname(host_port[0]) self.port = host_port[1] self.socket = socket.socket() self.socket.connect((self.host, self.port)) print '[DEBUG] Connected to %s:%d' % (self.host, self.port) except (socket.error,socket.gaierror) as err: print err def send_cmd(self, cmd, *args, **kwargs): self.trid += 1 payload = kwargs.get('payload', '') params = [str(x) for x in list(args) + [len(payload)] if x] cmd = '%s %d %s\r\n%s' % (cmd, self.trid, ' '.join(params), payload) print '[DEBUG] >> %s' % cmd.replace('\r\n', '') return self.socket.send(cmd) def readline(self): buff = '' while True: buff += self.socket.recv(1) if buff[-1:] == '\n': break print '[DEBUG] << %s' % buff.replace('\r\n', '') return buff def close(self): print '[DEBUG] Closed connection' return self.socket.close() class WeeLM: """ Main class for WeeLM. This class distributes to our main buffer, also executes the connection process. """ _buffer = None def __init__(self): """ Note that we are trying to maintain a sort of namespaced buffer hierarchy. """ self._buffer = weechat.buffer_new('WeeLM.Main', '', '', '', '') register_cleanup_cb(self.cleanup) def write(self, data, *args): weechat.prnt(self._buffer, data % args) def cleanup(self): weechat.buffer_close(self._buffer) return weechat.WEECHAT_RC_OK def read_socket_cb(data, fd): global weelm, msn weelm.write('Got buffert %s', msn.readline()) return weechat.WEECHAT_RC_OK if __name__ == '__main__' and _import_ok: ''' Make sure that we are executing ourselves, not as a module. Also make sure that we succeeded in importing weechat. ''' weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, 'cleanup_cb', '') weelm = WeeLM() weechat.prnt('', 'before') msn = MSNP(('messenger.microsoft.com', 1863)) weechat.prnt('', 'after') weechat.hook_fd(msn.socket.fileno(), 1, 0, 0, 'read_socket_cb', '')