## plugins/sock.py ## ## Gajim Team: ## - Yann Le Boulanger ## - Vincent Hanquez ## ## Copyright (C) 2003-2005 Gajim Team ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published ## by the Free Software Foundation; version 2 only. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## import socket, select import pickle import Queue from common import i18n _ = i18n._ def XMLescape(txt): "Escape XML entities" txt = txt.replace("&", "&") txt = txt.replace("<", "<") txt = txt.replace(">", ">") return txt def XMLunescape(txt): "Unescape XML entities" txt = txt.replace(">", ">") txt = txt.replace("<", "<") txt = txt.replace("&", "&") return txt class plugin: def wait(self, what): """Wait for a message from Core""" #TODO: timeout temp_q = Queue.Queue(50) while 1: if not self.queueIN.empty(): ev = self.queueIN.get() if ev[0] == what and ev[2][0] == 'sock': #Restore messages while not temp_q.empty(): ev2 = temp_q.get() self.queueIN.put(ev2) return ev[2][1] else: #Save messages temp_q.put(ev) def send(self, event, account, data): self.queueOUT.put((event, account, data)) def handle_queue_quit(self, account, array): # for sock in self.active_socket: # if sock != self.active_socket: # sock.close() self.quit_recieved = 1 def handle_socket_reg_message(self, sock, array): for type in array: if self.message_types.has_key(type): if not sock in self.message_types[type]: self.message_types[type].append(sock) else: self.message_types[type] = [sock] def send_to_socket(self, ev, sock): evp = pickle.dumps(ev) sock.send('<'+XMLescape(evp)+'>') def unparse_socket(self, data): list_ev = [] while data: deb = data.find('<') end = data.find('>', deb) list_ev.append(pickle.loads(data[deb+1:end])) data = data[end+1:] return list_ev def read_queue(self): while self.queueIN.empty() == 0: ev = self.queueIN.get() if ev[0] in self.message_types: for sock in self.message_types[ev[0]]: self.send_to_socket(ev, sock) if ev[0] == 'QUIT': self.handle_queue_quit(ev[1], ev[2]) # return 1 return 0 def read_socket(self): ready_to_read, ready_to_write, in_error = select.select( self.active_socket, [], [], 0.1) for sock in ready_to_read: if sock == self.socket: conn, addr = self.socket.accept() # Connected by addr print _("Connection from "), addr self.active_socket.append(conn) else: try: data = sock.recv(1024) except: self.active_socket.remove(sock) break if not data: # disconnected print _("disconnected") self.active_socket.remove(sock) break while len(data) == 1024: data += sock.recv(1024) list_ev = self.unparse_socket(data) for ev in list_ev: if ev[0] == 'REG_MESSAGE': self.handle_socket_reg_message(sock, ev[2]) ev = (ev[0], 'sock', ev[2]) self.queueOUT.put(ev) return 0 def __init__(self, quIN, quOUT): self.queueIN = quIN self.queueOUT = quOUT self.send('REG_MESSAGE', 'sock', ['QUIT', 'CONFIG']) quOUT.put(('ASK_CONFIG', None, ('sock', 'sock', {\ 'port':8255}))) self.config = self.wait('CONFIG') self.message_types = {} #create socket self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) HOST = socket.gethostbyname(socket.gethostname()) if self.config.has_key('host'): HOST = socket.gethostbyname(self.config['host']) self.socket.bind((HOST, self.config['port'])) self.socket.listen(5) self.active_socket = [self.socket] end = 0 self.quit_recieved = 0 while not end: # listen to the socket end = self.read_socket() # listen to the input Queue end = self.read_queue() if self.quit_recieved: if len(self.active_socket) == 1: end = 1 print _("plugin sock stopped") if __name__ == "__main__": plugin(None, None) print _("plugin sock loaded")