gajim-plural/plugins/sock/sock.py

172 lines
4.3 KiB
Python

## plugins/sock.py
##
## Gajim Team:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Vincent Hanquez <tab@snarc.org>
##
## 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
import sys
from common import i18n
_ = i18n._
def XMLescape(txt):
"Escape XML entities"
txt = txt.replace("&", "&amp;")
txt = txt.replace("<", "&lt;")
txt = txt.replace(">", "&gt;")
return txt
def XMLunescape(txt):
"Unescape XML entities"
txt = txt.replace("&gt;", ">")
txt = txt.replace("&lt;", "<")
txt = txt.replace("&amp;", "&")
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'])
try:
self.socket.bind((HOST, self.config['port']))
except:
print _('plugin sock cannot be launched : ') + \
str(sys.exc_info()[1][0:])
return
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")