Pylint checking
darcs-hash:20061001204010-86b55-2b2b3997794d11e2257effc502563ef32eac4560.gz
This commit is contained in:
3
TODO
3
TODO
@@ -0,0 +1,3 @@
|
|||||||
|
* pylint sources
|
||||||
|
* make tests for every methods
|
||||||
|
* merge all necessary features from jmc to jcl
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
__revision__ = "$Id: __init__.py dax $"
|
||||||
|
|||||||
@@ -21,13 +21,26 @@
|
|||||||
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##
|
##
|
||||||
|
|
||||||
|
"""JCL base component
|
||||||
|
"""
|
||||||
|
|
||||||
|
__revision__ = ""
|
||||||
|
|
||||||
|
import thread
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
import logging
|
import logging
|
||||||
import signal
|
import signal
|
||||||
|
import re
|
||||||
|
|
||||||
from pyxmpp.jid import JID
|
from pyxmpp.jid import JID
|
||||||
from pyxmpp.jabberd.component import Component
|
from pyxmpp.jabberd.component import Component
|
||||||
|
from pyxmpp.jabber.disco import DiscoInfo, DiscoItems
|
||||||
|
from pyxmpp.message import Message
|
||||||
from pyxmpp.presence import Presence
|
from pyxmpp.presence import Presence
|
||||||
|
from pyxmpp.streambase import StreamError, FatalStreamError
|
||||||
|
|
||||||
|
from jcl.jabber.x import X
|
||||||
from jcl.model.account import Account
|
from jcl.model.account import Account
|
||||||
|
|
||||||
VERSION = "0.1"
|
VERSION = "0.1"
|
||||||
@@ -36,57 +49,127 @@ VERSION = "0.1"
|
|||||||
# JCL implementation
|
# JCL implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
class JCLComponent(Component):
|
class JCLComponent(Component):
|
||||||
|
"""Implement default JCL component behavior:
|
||||||
|
- regular interval behavior
|
||||||
|
- Jabber register process (add, delete, update accounts)
|
||||||
|
- Jabber presence handling
|
||||||
|
- passwork request at login
|
||||||
|
"""
|
||||||
|
|
||||||
|
timeout = 1
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
jid,
|
jid,
|
||||||
secret,
|
secret,
|
||||||
server,
|
server,
|
||||||
port,
|
port,
|
||||||
name = "Jabber Component Library generic component",
|
|
||||||
disco_category = "gateway",
|
disco_category = "gateway",
|
||||||
disco_type = "headline",
|
disco_type = "headline"):
|
||||||
spool_dir = ".",
|
|
||||||
check_interval = 1,
|
|
||||||
account_class = Account):
|
|
||||||
Component.__init__(self, \
|
Component.__init__(self, \
|
||||||
JID(jid), \
|
JID(jid), \
|
||||||
secret, \
|
secret, \
|
||||||
|
server, \
|
||||||
port, \
|
port, \
|
||||||
disco_category, \
|
disco_category, \
|
||||||
disco_type)
|
disco_type)
|
||||||
|
# default values
|
||||||
|
self.name = "Jabber Component Library generic component"
|
||||||
|
self.spool_dir = "."
|
||||||
|
self.__account_class = None
|
||||||
|
self.account_class = Account
|
||||||
|
self.version = VERSION
|
||||||
|
self.accounts = []
|
||||||
|
|
||||||
|
self.disco_info.add_feature("jabber:iq:version")
|
||||||
|
self.disco_info.add_feature("jabber:iq:register")
|
||||||
self.__logger = logging.getLogger("jcl.jabber.JCLComponent")
|
self.__logger = logging.getLogger("jcl.jabber.JCLComponent")
|
||||||
# TODO : self.__lang = Lang(default_lang)
|
# TODO : self.__lang = Lang(default_lang)
|
||||||
self.__name = name
|
self.__lang = None
|
||||||
self.__disco_category = disco_category
|
|
||||||
self.__disco_type = disco_type
|
|
||||||
self.__interval = check_interval
|
|
||||||
self.running = False
|
self.running = False
|
||||||
|
|
||||||
self.__shutdown = 0
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, self.signal_handler)
|
signal.signal(signal.SIGINT, self.signal_handler)
|
||||||
signal.signal(signal.SIGTERM, self.signal_handler)
|
signal.signal(signal.SIGTERM, self.signal_handler)
|
||||||
spool_dir += "/" + jid
|
|
||||||
|
def set_account_class(self, account_class):
|
||||||
self.__account_class = account_class
|
self.__account_class = account_class
|
||||||
self.__account_class.createTable(ifNotExists = True)
|
self.__account_class.createTable(ifNotExists = True)
|
||||||
self.version = VERSION
|
|
||||||
|
def get_account_class(self):
|
||||||
|
return self.__account_class
|
||||||
|
|
||||||
|
account_class = property(get_account_class, set_account_class)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Main loop
|
||||||
|
Connect to Jabber server
|
||||||
|
Start timer thread
|
||||||
|
Call Component main loop
|
||||||
|
Clean up when shutting down JCLcomponent
|
||||||
|
"""
|
||||||
|
self.spool_dir += "/" + str(self.jid)
|
||||||
|
self.running = True
|
||||||
|
self.connect()
|
||||||
|
thread.start_new_thread(self.time_handler, ())
|
||||||
|
try:
|
||||||
|
while (self.running and self.stream
|
||||||
|
and not self.stream.eof and self.stream.socket is not None):
|
||||||
|
try:
|
||||||
|
self.stream.loop_iter(JCLComponent.timeout)
|
||||||
|
except (KeyboardInterrupt, SystemExit, FatalStreamError, \
|
||||||
|
StreamError):
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
self.__logger.exception("Exception cought:")
|
||||||
|
finally:
|
||||||
|
if self.stream:
|
||||||
|
# TODO : send unavailble from transport and all account to users
|
||||||
|
pass
|
||||||
|
# for jid in self.__storage.keys(()):
|
||||||
|
# p = Presence(from_jid = unicode(self.jid), to_jid = jid, \
|
||||||
|
# stanza_type = "unavailable")
|
||||||
|
# self.stream.send(p)
|
||||||
|
# for jid, name in self.__storage.keys():
|
||||||
|
# if self.__storage[(jid, name)].status != "offline":
|
||||||
|
# p = Presence(from_jid = name + "@" + unicode(self.jid),\
|
||||||
|
# to_jid = jid, \
|
||||||
|
# stanza_type = "unavailable")
|
||||||
|
# self.stream.send(p)
|
||||||
|
threads = threading.enumerate()
|
||||||
|
for _thread in threads:
|
||||||
|
try:
|
||||||
|
_thread.join(10 * JCLComponent.timeout)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
for _thread in threads:
|
||||||
|
try:
|
||||||
|
_thread.join(JCLComponent.timeout)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.disconnect()
|
||||||
|
# TODO : terminate SQLObject
|
||||||
|
self.__logger.debug("Exitting normally")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
# Handlers
|
||||||
|
###########################################################################
|
||||||
|
def time_handler(self):
|
||||||
|
"""Timer thread handler
|
||||||
|
"""
|
||||||
|
self.__logger.info("Timer thread started...")
|
||||||
|
while self.running:
|
||||||
|
self.handle_tick()
|
||||||
|
self.__logger.debug("Resetting alarm signal")
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
def authenticated(self):
|
def authenticated(self):
|
||||||
Component.authenticated(self)
|
"""Override authenticated Component event handler
|
||||||
|
Register event handlers
|
||||||
|
Probe for every accounts registered
|
||||||
|
"""
|
||||||
self.__logger.debug("AUTHENTICATED")
|
self.__logger.debug("AUTHENTICATED")
|
||||||
# Send probe for transport
|
Component.authenticated(self)
|
||||||
current_jid = None
|
|
||||||
for account in self.__account_class.select(orderBy = "user_jid"):
|
|
||||||
if account.user_jid != current_jid:
|
|
||||||
p = Presence(from_jid = unicode(self.jid), \
|
|
||||||
to_jid = account.user_jid, \
|
|
||||||
stanza_type = "probe")
|
|
||||||
self.stream.send(p)
|
|
||||||
current_jid = account.user_jid
|
|
||||||
p = Presence(from_jid = self.get_jid(account), \
|
|
||||||
to_jid = account.user_jid, \
|
|
||||||
stanza_type = "probe")
|
|
||||||
self.stream.send(p)
|
|
||||||
|
|
||||||
self.stream.set_iq_get_handler("query", "jabber:iq:version", \
|
self.stream.set_iq_get_handler("query", "jabber:iq:version", \
|
||||||
self.handle_get_version)
|
self.handle_get_version)
|
||||||
self.stream.set_iq_get_handler("query", "jabber:iq:register", \
|
self.stream.set_iq_get_handler("query", "jabber:iq:register", \
|
||||||
@@ -114,180 +197,128 @@ class JCLComponent(Component):
|
|||||||
|
|
||||||
self.stream.set_message_handler("normal", \
|
self.stream.set_message_handler("normal", \
|
||||||
self.handle_message)
|
self.handle_message)
|
||||||
|
current_jid = None
|
||||||
|
for account in self.account_class.select(orderBy = "user_jid"):
|
||||||
|
if account.user_jid != current_jid:
|
||||||
|
presence = Presence(from_jid = unicode(self.jid), \
|
||||||
|
to_jid = account.user_jid, \
|
||||||
|
stanza_type = "probe")
|
||||||
|
self.stream.send(presence)
|
||||||
|
current_jid = account.user_jid
|
||||||
|
presence = Presence(from_jid = self.get_jid(account), \
|
||||||
|
to_jid = account.user_jid, \
|
||||||
|
stanza_type = "probe")
|
||||||
|
self.stream.send(presence)
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.connect()
|
|
||||||
self.running = True
|
|
||||||
thread.start_new_thread(self.time_handler, ())
|
|
||||||
try:
|
|
||||||
while (not self.__shutdown and self.stream
|
|
||||||
and not self.stream.eof and self.stream.socket is not None):
|
|
||||||
try:
|
|
||||||
self.stream.loop_iter(timeout)
|
|
||||||
except (KeyboardInterrupt, SystemExit, FatalStreamError, \
|
|
||||||
StreamError):
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
self.__logger.exception("Exception cought:")
|
|
||||||
finally:
|
|
||||||
self.running = False
|
|
||||||
if self.stream:
|
|
||||||
# TODO : send unavailble from transport and all account to users
|
|
||||||
pass
|
|
||||||
# for jid in self.__storage.keys(()):
|
|
||||||
# p = Presence(from_jid = unicode(self.jid), to_jid = jid, \
|
|
||||||
# stanza_type = "unavailable")
|
|
||||||
# self.stream.send(p)
|
|
||||||
# for jid, name in self.__storage.keys():
|
|
||||||
# if self.__storage[(jid, name)].status != "offline":
|
|
||||||
# p = Presence(from_jid = name + "@" + unicode(self.jid), \
|
|
||||||
# to_jid = jid, \
|
|
||||||
# stanza_type = "unavailable")
|
|
||||||
# self.stream.send(p)
|
|
||||||
threads = threading.enumerate()
|
|
||||||
for th in threads:
|
|
||||||
try:
|
|
||||||
th.join(10 * timeout)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
for th in threads:
|
|
||||||
try:
|
|
||||||
th.join(timeout)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.disconnect()
|
|
||||||
# TODO : terminate SQLObject
|
|
||||||
self.__logger.debug("Exitting normally")
|
|
||||||
|
|
||||||
def get_reg_form(self, lang_class, account_class):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_reg_form_init(self, lang_class, account):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _ask_password(self, lang_class, account):
|
|
||||||
if not account.waiting_password_reply \
|
|
||||||
and account.status != "offline":
|
|
||||||
account.waiting_password_reply = True
|
|
||||||
msg = Message(from_jid = account.jid, \
|
|
||||||
to_jid = from_jid, \
|
|
||||||
stanza_type = "normal", \
|
|
||||||
subject = u"[PASSWORD] " + lang_class.ask_password_subject, \
|
|
||||||
body = lang_class.ask_password_body % \
|
|
||||||
(account.host, account.login))
|
|
||||||
self.stream.send(msg)
|
|
||||||
|
|
||||||
def get_jid(self, account):
|
|
||||||
return account.name + u"@" + unicode(self.jid)
|
|
||||||
|
|
||||||
## Handlers
|
|
||||||
|
|
||||||
""" Stop method handler """
|
|
||||||
def signal_handler(self, signum, frame):
|
def signal_handler(self, signum, frame):
|
||||||
|
"""Stop method handler
|
||||||
|
"""
|
||||||
self.__logger.debug("Signal %i received, shutting down..." % (signum,))
|
self.__logger.debug("Signal %i received, shutting down..." % (signum,))
|
||||||
self.__shutdown = 1
|
self.running = False
|
||||||
|
|
||||||
|
def disco_get_info(self, node, input_query):
|
||||||
def stream_state_changed(self,state,arg):
|
"""Discovery get info handler
|
||||||
self.__logger.debug("*** State changed: %s %r ***" % (state,arg))
|
"""
|
||||||
|
|
||||||
""" Discovery get info handler """
|
|
||||||
def disco_get_info(self, node, iq):
|
|
||||||
self.__logger.debug("DISCO_GET_INFO")
|
self.__logger.debug("DISCO_GET_INFO")
|
||||||
di = DiscoInfo()
|
if node is not None:
|
||||||
if node is None:
|
disco_info = DiscoInfo()
|
||||||
di.add_feature("jabber:iq:version")
|
disco_info.add_feature("jabber:iq:register")
|
||||||
di.add_feature("jabber:iq:register")
|
return disco_info
|
||||||
DiscoIdentity(di, self.__name, \
|
|
||||||
self.__disco_category, \
|
|
||||||
self.__disco_type)
|
|
||||||
else:
|
else:
|
||||||
di.add_feature("jabber:iq:register")
|
return self.disco_info
|
||||||
return di
|
|
||||||
|
|
||||||
""" Discovery get nested nodes handler """
|
def disco_get_items(self, node, input_query):
|
||||||
def disco_get_items(self, node, iq):
|
"""Discovery get nested nodes handler
|
||||||
|
"""
|
||||||
self.__logger.debug("DISCO_GET_ITEMS")
|
self.__logger.debug("DISCO_GET_ITEMS")
|
||||||
# lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
|
## TODO Lang
|
||||||
base_from_jid = unicode(iq.get_from().bare())
|
## lang_class = self.__lang.get_lang_class_from_node(input_query.get_node())
|
||||||
di = DiscoItems()
|
## base_from_jid = unicode(input_query.get_from().bare())
|
||||||
|
disco_items = DiscoItems()
|
||||||
if not node:
|
if not node:
|
||||||
# TODO : list accounts
|
## TODO : list accounts
|
||||||
for account in self.__accounts:
|
for account in self.accounts:
|
||||||
pass
|
self.__logger.debug(str(account))
|
||||||
# DiscoItem(di, JID(name + "@" + unicode(self.jid)), \
|
## DiscoItem(di, JID(name + "@" + unicode(self.jid)), \
|
||||||
# name, str_name)
|
## name, str_name)
|
||||||
return di
|
return disco_items
|
||||||
|
|
||||||
""" Get Version handler """
|
def handle_get_version(self, input_query):
|
||||||
def handle_get_version(self, iq):
|
"""Get Version handler
|
||||||
|
"""
|
||||||
self.__logger.debug("GET_VERSION")
|
self.__logger.debug("GET_VERSION")
|
||||||
iq = iq.make_result_response()
|
input_query = input_query.make_result_response()
|
||||||
q = iq.new_query("jabber:iq:version")
|
query = input_query.new_query("jabber:iq:version")
|
||||||
q.newTextChild(q.ns(), "name", self.__name)
|
query.newTextChild(query.ns(), "name", self.name)
|
||||||
q.newTextChild(q.ns(), "version", self.version)
|
query.newTextChild(query.ns(), "version", self.version)
|
||||||
self.stream.send(iq)
|
self.stream.send(input_query)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" Send back register form to user """
|
def handle_get_register(self, input_query):
|
||||||
def handle_get_register(self, iq):
|
"""Send back register form to user
|
||||||
|
"""
|
||||||
self.__logger.debug("GET_REGISTER")
|
self.__logger.debug("GET_REGISTER")
|
||||||
# lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
|
## TODO Lang
|
||||||
base_from_jid = unicode(iq.get_from().bare())
|
## lang_class = self.__lang.get_lang_class_from_node(input_query.get_node())
|
||||||
to = iq.get_to()
|
lang_class = None
|
||||||
iq = iq.make_result_response()
|
## base_from_jid = unicode(input_query.get_from().bare())
|
||||||
q = iq.new_query("jabber:iq:register")
|
to_jid = input_query.get_to()
|
||||||
if to and to != self.jid:
|
input_query = input_query.make_result_response()
|
||||||
|
query = input_query.new_query("jabber:iq:register")
|
||||||
|
if to_jid and to_jid != self.jid:
|
||||||
self.get_reg_form_init(lang_class, \
|
self.get_reg_form_init(lang_class, \
|
||||||
self.__accounts.select() # TODO
|
self.accounts.select() # TODO
|
||||||
).attach_xml(q)
|
).attach_xml(query)
|
||||||
else:
|
else:
|
||||||
self.get_reg_form(lang_class).attach_xml(q)
|
self.get_reg_form(lang_class).attach_xml(query)
|
||||||
self.stream.send(iq)
|
self.stream.send(input_query)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" Handle user registration response """
|
def handle_set_register(self, input_query):
|
||||||
def handle_set_register(self, iq):
|
"""Handle user registration response
|
||||||
|
"""
|
||||||
self.__logger.debug("SET_REGISTER")
|
self.__logger.debug("SET_REGISTER")
|
||||||
lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
|
## lang_class = \
|
||||||
to = iq.get_to()
|
## self.__lang.get_lang_class_from_node(input_query.get_node())
|
||||||
from_jid = iq.get_from()
|
from_jid = input_query.get_from()
|
||||||
base_from_jid = unicode(from_jid.bare())
|
## base_from_jid = unicode(from_jid.bare())
|
||||||
remove = iq.xpath_eval("r:query/r:remove", \
|
remove = input_query.xpath_eval("r:query/r:remove", \
|
||||||
{"r" : "jabber:iq:register"})
|
{"r" : "jabber:iq:register"})
|
||||||
if remove:
|
if remove:
|
||||||
for name in self.__storage.keys((base_from_jid,)):
|
# for name in self.__storage.keys((base_from_jid,)):
|
||||||
self.__logger.debug("Deleting " + name + " for " + base_from_jid)
|
# self.__logger.debug("Deleting " + name \
|
||||||
p = Presence(from_jid = name + "@" + unicode(self.jid), \
|
# + " for " + base_from_jid)
|
||||||
to_jid = from_jid, \
|
# presence = Presence(from_jid = name + "@" + unicode(self.jid), \
|
||||||
stanza_type = "unsubscribe")
|
# to_jid = from_jid, \
|
||||||
self.stream.send(p)
|
# stanza_type = "unsubscribe")
|
||||||
p = Presence(from_jid = name + "@" + unicode(self.jid), \
|
# self.stream.send(presence)
|
||||||
to_jid = from_jid, \
|
# presence = Presence(from_jid = name + "@" + unicode(self.jid), \
|
||||||
stanza_type = "unsubscribed")
|
# to_jid = from_jid, \
|
||||||
self.stream.send(p)
|
# stanza_type = "unsubscribed")
|
||||||
del self.__storage[(base_from_jid, name)]
|
# self.stream.send(presence)
|
||||||
p = Presence(from_jid = self.jid, to_jid = from_jid, \
|
# del self.__storage[(base_from_jid, name)]
|
||||||
stanza_type = "unsubscribe")
|
presence = Presence(from_jid = self.jid, to_jid = from_jid, \
|
||||||
self.stream.send(p)
|
stanza_type = "unsubscribe")
|
||||||
p = Presence(from_jid = self.jid, to_jid = from_jid, \
|
self.stream.send(presence)
|
||||||
stanza_type = "unsubscribed")
|
presence = Presence(from_jid = self.jid, to_jid = from_jid, \
|
||||||
self.stream.send(p)
|
stanza_type = "unsubscribed")
|
||||||
|
self.stream.send(presence)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
query = iq.get_query()
|
query = input_query.get_query()
|
||||||
x = X()
|
x_data = X()
|
||||||
x.from_xml(query.children)
|
x_data.from_xml(query.children)
|
||||||
# TODO : get info from Xdata
|
# TODO : get info from Xdata
|
||||||
|
|
||||||
|
|
||||||
""" Handle presence availability """
|
|
||||||
def handle_presence_available(self, stanza):
|
def handle_presence_available(self, stanza):
|
||||||
|
"""Handle presence availability
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_AVAILABLE")
|
self.__logger.debug("PRESENCE_AVAILABLE")
|
||||||
from_jid = stanza.get_from()
|
from_jid = stanza.get_from()
|
||||||
base_from_jid = unicode(from_jid.bare())
|
base_from_jid = unicode(from_jid.bare())
|
||||||
name = stanza.get_to().node
|
name = stanza.get_to().node
|
||||||
lang_class = self.__lang.get_lang_class_from_node(stanza.get_node())
|
## lang_class = self.__lang.get_lang_class_from_node(stanza.get_node())
|
||||||
show = stanza.get_show()
|
show = stanza.get_show()
|
||||||
self.__logger.debug("SHOW : " + str(show))
|
self.__logger.debug("SHOW : " + str(show))
|
||||||
if name:
|
if name:
|
||||||
@@ -296,63 +327,71 @@ class JCLComponent(Component):
|
|||||||
# else send available presence
|
# else send available presence
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" handle presence unavailability """
|
|
||||||
def handle_presence_unavailable(self, stanza):
|
def handle_presence_unavailable(self, stanza):
|
||||||
|
"""Handle presence unavailability
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_UNAVAILABLE")
|
self.__logger.debug("PRESENCE_UNAVAILABLE")
|
||||||
from_jid = stanza.get_from()
|
## from_jid = stanza.get_from()
|
||||||
base_from_jid = unicode(from_jid.bare())
|
## base_from_jid = unicode(from_jid.bare())
|
||||||
# TODO : send unavailable to all user's account if target is transport
|
# TODO : send unavailable to all user's account if target is transport
|
||||||
# else send unavailable back
|
# else send unavailable back
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" handle subscribe presence from user """
|
|
||||||
def handle_presence_subscribe(self, stanza):
|
def handle_presence_subscribe(self, stanza):
|
||||||
|
"""Handle subscribe presence from user
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_SUBSCRIBE")
|
self.__logger.debug("PRESENCE_SUBSCRIBE")
|
||||||
p = stanza.make_accept_response()
|
presence = stanza.make_accept_response()
|
||||||
self.stream.send(p)
|
self.stream.send(presence)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" handle subscribed presence from user """
|
|
||||||
def handle_presence_subscribed(self, stanza):
|
def handle_presence_subscribed(self, stanza):
|
||||||
|
"""Handle subscribed presence from user
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_SUBSCRIBED")
|
self.__logger.debug("PRESENCE_SUBSCRIBED")
|
||||||
name = stanza.get_to().node
|
name = stanza.get_to().node
|
||||||
from_jid = stanza.get_from()
|
## from_jid = stanza.get_from()
|
||||||
base_from_jid = unicode(from_jid.bare())
|
## base_from_jid = unicode(from_jid.bare())
|
||||||
# TODO : send presence available to subscribed user
|
# TODO : send presence available to subscribed user
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" handle unsubscribe presence from user """
|
|
||||||
def handle_presence_unsubscribe(self, stanza):
|
def handle_presence_unsubscribe(self, stanza):
|
||||||
|
"""Handle unsubscribe presence from user
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_UNSUBSCRIBE")
|
self.__logger.debug("PRESENCE_UNSUBSCRIBE")
|
||||||
name = stanza.get_to().node
|
name = stanza.get_to().node
|
||||||
from_jid = stanza.get_from()
|
from_jid = stanza.get_from()
|
||||||
base_from_jid = unicode(from_jid.bare())
|
## base_from_jid = unicode(from_jid.bare())
|
||||||
# TODO : delete from account base
|
# TODO : delete from account base
|
||||||
p = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \
|
presence = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \
|
||||||
stanza_type = "unsubscribe")
|
stanza_type = "unsubscribe")
|
||||||
self.stream.send(p)
|
self.stream.send(presence)
|
||||||
p = stanza.make_accept_response()
|
presence = stanza.make_accept_response()
|
||||||
self.stream.send(p)
|
self.stream.send(presence)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" handle unsubscribed presence from user """
|
|
||||||
def handle_presence_unsubscribed(self, stanza):
|
def handle_presence_unsubscribed(self, stanza):
|
||||||
|
"""Handle unsubscribed presence from user
|
||||||
|
"""
|
||||||
self.__logger.debug("PRESENCE_UNSUBSCRIBED")
|
self.__logger.debug("PRESENCE_UNSUBSCRIBED")
|
||||||
p = Presence(from_jid = stanza.get_to(), \
|
presence = Presence(from_jid = stanza.get_to(), \
|
||||||
to_jid = stanza.get_from(), \
|
to_jid = stanza.get_from(), \
|
||||||
stanza_type = "unavailable")
|
stanza_type = "unavailable")
|
||||||
self.stream.send(p)
|
self.stream.send(presence)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
""" Handle new message """
|
|
||||||
def handle_message(self, message):
|
def handle_message(self, message):
|
||||||
|
"""Handle new message
|
||||||
|
"""
|
||||||
self.__logger.debug("MESSAGE: " + message.get_body())
|
self.__logger.debug("MESSAGE: " + message.get_body())
|
||||||
lang_class = self.__lang.get_lang_class_from_node(message.get_node())
|
lang_class = self.__lang.get_lang_class_from_node(message.get_node())
|
||||||
name = message.get_to().node
|
## name = message.get_to().node
|
||||||
base_from_jid = unicode(message.get_from().bare())
|
## base_from_jid = unicode(message.get_from().bare())
|
||||||
if re.compile("\[PASSWORD\]").search(message.get_subject()) is not None:
|
if re.compile("\[PASSWORD\]").search(message.get_subject()) \
|
||||||
# TODO and self.__storage.has_key((base_from_jid, name)):
|
is not None:
|
||||||
# account = self.__storage[(base_from_jid, name)]
|
## TODO and self.__storage.has_key((base_from_jid, name)):
|
||||||
|
## account = self.__storage[(base_from_jid, name)]
|
||||||
|
account = Account()
|
||||||
account.password = message.get_body()
|
account.password = message.get_body()
|
||||||
account.waiting_password_reply = False
|
account.waiting_password_reply = False
|
||||||
msg = Message(from_jid = account.jid, \
|
msg = Message(from_jid = account.jid, \
|
||||||
@@ -363,5 +402,47 @@ class JCLComponent(Component):
|
|||||||
self.stream.send(msg)
|
self.stream.send(msg)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
# Utils
|
||||||
|
###########################################################################
|
||||||
|
def _ask_password(self, from_jid, lang_class, account):
|
||||||
|
"""Send a Jabber message to ask for account password
|
||||||
|
"""
|
||||||
|
#TODO be JMC independant
|
||||||
|
if not account.waiting_password_reply \
|
||||||
|
and account.status != "offline":
|
||||||
|
account.waiting_password_reply = True
|
||||||
|
msg = Message(from_jid = account.jid, \
|
||||||
|
to_jid = from_jid, \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = u"[PASSWORD] " + \
|
||||||
|
lang_class.ask_password_subject, \
|
||||||
|
body = lang_class.ask_password_body % \
|
||||||
|
(account.host, account.login))
|
||||||
|
self.stream.send(msg)
|
||||||
|
|
||||||
|
def get_jid(self, account):
|
||||||
|
"""Return account jid based on account instance and component jid
|
||||||
|
"""
|
||||||
|
return account.name + u"@" + unicode(self.jid)
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
# Virtual methods
|
||||||
|
###########################################################################
|
||||||
def handle_tick(self):
|
def handle_tick(self):
|
||||||
|
"""Virtual method
|
||||||
|
Called regularly
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_reg_form(self, lang_class, account_class):
|
||||||
|
"""Virtual method
|
||||||
|
Return register form based on language and account class
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_reg_form_init(self, lang_class, account):
|
||||||
|
"""Virtual method
|
||||||
|
Return register form for an existing account (update)
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -21,50 +21,70 @@
|
|||||||
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##
|
##
|
||||||
|
|
||||||
|
"""FeederComponent with default Feeder and Sender
|
||||||
|
implementation
|
||||||
|
"""
|
||||||
|
|
||||||
|
__revision__ = "$Id: feeder.py dax $"
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
from jcl.jabber.component import JCLComponent
|
from jcl.jabber.component import JCLComponent
|
||||||
from jcl.model.account import *
|
from jcl.model.account import Account
|
||||||
|
|
||||||
class FeederComponent(JCLComponent):
|
class FeederComponent(JCLComponent):
|
||||||
|
"""Implement a feeder sender behavior based on the
|
||||||
|
regular interval behavior of JCLComponent
|
||||||
|
feed data from given Feeder and send it to user
|
||||||
|
through the given Sender.
|
||||||
|
"""
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
jid,
|
jid,
|
||||||
secret,
|
secret,
|
||||||
server,
|
server,
|
||||||
port,
|
port):
|
||||||
name = "Generic Feeder Component",
|
|
||||||
disco_category = "gateway",
|
|
||||||
disco_type = "headline",
|
|
||||||
spool_dir = ".",
|
|
||||||
check_interval = 1):
|
|
||||||
JCLComponent.__init__(self, \
|
JCLComponent.__init__(self, \
|
||||||
jid, \
|
jid, \
|
||||||
secret, \
|
secret, \
|
||||||
server, \
|
server, \
|
||||||
port, \
|
port)
|
||||||
name, \
|
self.name = "Generic Feeder Component"
|
||||||
disco_category, \
|
# Define default feeder and sender, can be override
|
||||||
disco_type, \
|
self.feeder = Feeder()
|
||||||
spool_dir, \
|
self.sender = Sender()
|
||||||
check_interval)
|
self.check_interval = 1
|
||||||
|
|
||||||
|
self.__logger = logging.getLogger("jcl.jabber.JCLComponent")
|
||||||
|
|
||||||
def handle_tick(self):
|
def handle_tick(self):
|
||||||
|
"""Implement main feed/send behavior
|
||||||
|
"""
|
||||||
for account in Account.select("*"):
|
for account in Account.select("*"):
|
||||||
for message in self.__jabber_component.feeder.feed(account):
|
for data in self.feeder.feed(account):
|
||||||
self.__jabber_component.sender.send(account, message)
|
self.sender.send(account, data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Feeder(object):
|
class Feeder(object):
|
||||||
|
"""Abstract feeder class
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def feed(self, account):
|
def feed(self, account):
|
||||||
|
"""Feed data for given account
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Sender(object):
|
class Sender(object):
|
||||||
|
"""Abstract sender class
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def send(self, to_account, message):
|
def send(self, to_account, data):
|
||||||
|
"""Send data to given account
|
||||||
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -20,110 +20,134 @@
|
|||||||
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##
|
##
|
||||||
|
|
||||||
import sys
|
"""X -- X data handling
|
||||||
|
"""
|
||||||
|
|
||||||
|
__revision__ = ""
|
||||||
|
|
||||||
from pyxmpp.stanza import common_doc
|
from pyxmpp.stanza import common_doc
|
||||||
|
|
||||||
class Option(object):
|
class Option(object):
|
||||||
|
"""Option value for list field
|
||||||
|
"""
|
||||||
def __init__(self, label, value):
|
def __init__(self, label, value):
|
||||||
self.__label = label
|
self.__label = label
|
||||||
self.__value = value
|
self.__value = value
|
||||||
|
|
||||||
def get_xml(self, parent):
|
def get_xml(self, parent):
|
||||||
if parent is None:
|
"""Return XML Option representation from
|
||||||
option = common_doc.newChild(None, "option", None)
|
self.__label and self.__value and attach it to parent
|
||||||
else:
|
"""
|
||||||
option = parent.newChild(None, "option", None)
|
if parent is None:
|
||||||
option.setProp("label", self.__label)
|
option = common_doc.newChild(None, "option", None)
|
||||||
option.newChild(None, "value", self.__value)
|
else:
|
||||||
return option
|
option = parent.newChild(None, "option", None)
|
||||||
|
option.setProp("label", self.__label)
|
||||||
|
option.newChild(None, "value", self.__value)
|
||||||
|
return option
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
def __init__(self, type, label, var, value):
|
"""Jabber Xdata form Field
|
||||||
self.__type = type
|
"""
|
||||||
self.__label = label
|
def __init__(self, field_type, label, var, value):
|
||||||
self.__var = var
|
self.__type = field_type
|
||||||
self.value = value
|
self.__label = label
|
||||||
self.__options = []
|
self.__var = var
|
||||||
|
self.value = value
|
||||||
|
self.__options = []
|
||||||
|
|
||||||
def add_option(self, label, value):
|
def add_option(self, label, value):
|
||||||
option = Option(label, value)
|
"""Add an Option to this field
|
||||||
self.__options.append(option)
|
"""
|
||||||
return option
|
option = Option(label, value)
|
||||||
|
self.__options.append(option)
|
||||||
|
return option
|
||||||
|
|
||||||
def get_xml(self, parent):
|
def get_xml(self, parent):
|
||||||
if parent is None:
|
"""Return XML Field representation
|
||||||
raise Exception, "parent field should not be None"
|
and attach it to parent
|
||||||
else:
|
"""
|
||||||
field = parent.newChild(None, "field", None)
|
if parent is None:
|
||||||
field.setProp("type", self.__type)
|
raise Exception, "parent field should not be None"
|
||||||
if not self.__label is None:
|
else:
|
||||||
field.setProp("label", self.__label)
|
field = parent.newChild(None, "field", None)
|
||||||
if not self.__var is None:
|
field.setProp("type", self.__type)
|
||||||
field.setProp("var", self.__var)
|
if not self.__label is None:
|
||||||
if self.value:
|
field.setProp("label", self.__label)
|
||||||
field.newChild(None, "value", self.value)
|
if not self.__var is None:
|
||||||
for option in self.__options:
|
field.setProp("var", self.__var)
|
||||||
option.get_xml(field)
|
if self.value:
|
||||||
return field
|
field.newChild(None, "value", self.value)
|
||||||
|
for option in self.__options:
|
||||||
|
option.get_xml(field)
|
||||||
|
return field
|
||||||
|
|
||||||
class X(object):
|
class X(object):
|
||||||
|
"""Jabber Xdata form
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.fields = {}
|
self.fields = {}
|
||||||
self.fields_tab = []
|
self.fields_tab = []
|
||||||
self.title = None
|
self.title = None
|
||||||
self.instructions = None
|
self.instructions = None
|
||||||
self.type = None
|
self.x_type = None
|
||||||
self.xmlns = None
|
self.xmlns = None
|
||||||
|
|
||||||
def add_field(self, type = "fixed", label = None, var = None, value = ""):
|
def add_field(self, field_type = "fixed", label = None, var = None, value = ""):
|
||||||
field = Field(type, label, var, value)
|
"""Add a Field to this Xdata form
|
||||||
self.fields[var] = field
|
"""
|
||||||
# fields_tab exist to keep added fields order
|
field = Field(field_type, label, var, value)
|
||||||
self.fields_tab.append(field)
|
self.fields[var] = field
|
||||||
return field
|
# fields_tab exist to keep added fields order
|
||||||
|
self.fields_tab.append(field)
|
||||||
|
return field
|
||||||
|
|
||||||
def attach_xml(self, iq):
|
def attach_xml(self, iq):
|
||||||
node = iq.newChild(None, "x", None)
|
"""Attach this Xdata form to iq node
|
||||||
_ns = node.newNs(self.xmlns, None)
|
"""
|
||||||
node.setNs(_ns)
|
node = iq.newChild(None, "x", None)
|
||||||
if not self.title is None:
|
_ns = node.newNs(self.xmlns, None)
|
||||||
node.newTextChild(None, "title", self.title)
|
node.setNs(_ns)
|
||||||
if not self.instructions is None:
|
if not self.title is None:
|
||||||
node.newTextChild(None, "instructions", self.instructions)
|
node.newTextChild(None, "title", self.title)
|
||||||
for field in self.fields_tab:
|
if not self.instructions is None:
|
||||||
field.get_xml(node)
|
node.newTextChild(None, "instructions", self.instructions)
|
||||||
return node
|
for field in self.fields_tab:
|
||||||
|
field.get_xml(node)
|
||||||
|
return node
|
||||||
|
|
||||||
def from_xml(self, node):
|
def from_xml(self, node):
|
||||||
## TODO : test node type and ns and clean that loop !!!!
|
"""Populate this X object from an XML representation
|
||||||
while node and node.type != "element":
|
"""
|
||||||
node = node.next
|
## TODO : test node type and ns and clean that loop !!!!
|
||||||
child = node.children
|
while node and node.type != "element":
|
||||||
while child:
|
node = node.next
|
||||||
## TODO : test child type (element) and ns (jabber:x:data)
|
child = node.children
|
||||||
if child.type == "element" and child.name == "field":
|
while child:
|
||||||
if child.hasProp("type"):
|
## TODO : test child type (element) and ns (jabber:x:data)
|
||||||
type = child.prop("type")
|
if child.type == "element" and child.name == "field":
|
||||||
else:
|
if child.hasProp("type"):
|
||||||
type = ""
|
field_type = child.prop("type")
|
||||||
|
else:
|
||||||
|
field_type = ""
|
||||||
|
|
||||||
if child.hasProp("label"):
|
if child.hasProp("label"):
|
||||||
label = child.prop("label")
|
label = child.prop("label")
|
||||||
else:
|
else:
|
||||||
label = ""
|
label = ""
|
||||||
|
|
||||||
if child.hasProp("var"):
|
if child.hasProp("var"):
|
||||||
var = child.prop("var")
|
var = child.prop("var")
|
||||||
else:
|
else:
|
||||||
var = ""
|
var = ""
|
||||||
|
|
||||||
xval = child.children
|
xval = child.children
|
||||||
while xval and xval.name != "value":
|
while xval and xval.name != "value":
|
||||||
xval = xval.next
|
xval = xval.next
|
||||||
if xval:
|
if xval:
|
||||||
value = xval.getContent()
|
value = xval.getContent()
|
||||||
else:
|
else:
|
||||||
value = ""
|
value = ""
|
||||||
field = Field(type, label, var, value)
|
field = Field(field_type, label, var, value)
|
||||||
self.fields[var] = field
|
self.fields[var] = field
|
||||||
child = child.next
|
child = child.next
|
||||||
|
|||||||
140
src/jcl/lang.py
140
src/jcl/lang.py
@@ -21,12 +21,27 @@
|
|||||||
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##
|
##
|
||||||
|
|
||||||
# TODO delete not JCL translation
|
"""lang -- contains translations
|
||||||
|
"""
|
||||||
|
|
||||||
|
# TODO get help to generate revision
|
||||||
|
__revision__ = "$Id: lang.py dax $"
|
||||||
|
|
||||||
|
# TODO delete JMC translation
|
||||||
class Lang:
|
class Lang:
|
||||||
|
"""Lang.
|
||||||
|
"""
|
||||||
|
# TODO get help on docstring
|
||||||
|
# pylint: disable-msg=W0232, R0903, C0103, C0111
|
||||||
def __init__(self, default_lang = "en"):
|
def __init__(self, default_lang = "en"):
|
||||||
self.default_lang = default_lang
|
self.default_lang = default_lang
|
||||||
|
|
||||||
def get_lang_from_node(self, node):
|
def get_lang_from_node(self, node):
|
||||||
|
"""Extract lang contain in a XML node.
|
||||||
|
|
||||||
|
:Parameters:
|
||||||
|
- `node`: XML node.
|
||||||
|
"""
|
||||||
lang = node.getLang()
|
lang = node.getLang()
|
||||||
if lang is None:
|
if lang is None:
|
||||||
print "Using default lang " + self.default_lang
|
print "Using default lang " + self.default_lang
|
||||||
@@ -34,9 +49,19 @@ class Lang:
|
|||||||
return lang
|
return lang
|
||||||
|
|
||||||
def get_lang_class(self, lang):
|
def get_lang_class(self, lang):
|
||||||
return getattr(Lang, lang)
|
"""Return lang class from lang code.
|
||||||
|
|
||||||
|
:Parameters:
|
||||||
|
- `lang`: lang code.
|
||||||
|
"""
|
||||||
|
return getattr(self, lang)
|
||||||
|
|
||||||
def get_lang_class_from_node(self, node):
|
def get_lang_class_from_node(self, node):
|
||||||
|
"""Return lang class from XML node.
|
||||||
|
|
||||||
|
:Parameters:
|
||||||
|
- `node`: XML node.
|
||||||
|
"""
|
||||||
return self.get_lang_class(self.get_lang_from_node(node))
|
return self.get_lang_class(self.get_lang_from_node(node))
|
||||||
|
|
||||||
class en:
|
class en:
|
||||||
@@ -57,7 +82,8 @@ class Lang:
|
|||||||
account_dnd_action = u"Action when state is 'Do not Disturb'"
|
account_dnd_action = u"Action when state is 'Do not Disturb'"
|
||||||
account_offline_action = u"Action when state is 'Offline'"
|
account_offline_action = u"Action when state is 'Offline'"
|
||||||
account_check_interval = u"Mail check interval (in minutes)"
|
account_check_interval = u"Mail check interval (in minutes)"
|
||||||
account_live_email_only = u"Reports only emails received while connected to Jabber"
|
account_live_email_only = u"Reports only emails received while " \
|
||||||
|
u"connected to Jabber"
|
||||||
action_nothing = u"Do nothing"
|
action_nothing = u"Do nothing"
|
||||||
action_retrieve = u"Retrieve mail"
|
action_retrieve = u"Retrieve mail"
|
||||||
action_digest = u"Send mail digest"
|
action_digest = u"Send mail digest"
|
||||||
@@ -66,7 +92,7 @@ class Lang:
|
|||||||
connection_label = u"%s connection '%s'"
|
connection_label = u"%s connection '%s'"
|
||||||
update_account_message_subject = u"Updated %s connection '%s'"
|
update_account_message_subject = u"Updated %s connection '%s'"
|
||||||
update_account_message_body = u"Registered with username '%s' and " \
|
update_account_message_body = u"Registered with username '%s' and " \
|
||||||
"password '%s' on '%s'"
|
u"password '%s' on '%s'"
|
||||||
new_account_message_subject = u"New %s connection '%s' created"
|
new_account_message_subject = u"New %s connection '%s' created"
|
||||||
new_account_message_body = u"Registered with " \
|
new_account_message_body = u"Registered with " \
|
||||||
"username '%s' and password '%s' on '%s'"
|
"username '%s' and password '%s' on '%s'"
|
||||||
@@ -75,19 +101,22 @@ class Lang:
|
|||||||
"for the following account: \n" \
|
"for the following account: \n" \
|
||||||
"\thost = %s\n" \
|
"\thost = %s\n" \
|
||||||
"\tlogin = %s\n"
|
"\tlogin = %s\n"
|
||||||
password_saved_for_session = u"Password will be kept during your Jabber session"
|
password_saved_for_session = u"Password will be kept during your " \
|
||||||
|
u"Jabber session"
|
||||||
check_error_subject = u"Error while checking emails."
|
check_error_subject = u"Error while checking emails."
|
||||||
check_error_body = u"An error appears while checking emails:\n\t%s"
|
check_error_body = u"An error appears while checking emails:\n\t%s"
|
||||||
new_mail_subject = u"New email from %s"
|
new_mail_subject = u"New email from %s"
|
||||||
new_digest_subject = u"%i new email(s)"
|
new_digest_subject = u"%i new email(s)"
|
||||||
|
|
||||||
class fr:
|
class fr:
|
||||||
register_title = u"Enregistrement d'une nouvelle connexion à un serveur email."
|
register_title = u"Enregistrement d'une nouvelle connexion à un " \
|
||||||
|
u"serveur email."
|
||||||
register_instructions = u"Entrer les paramètres de connexion"
|
register_instructions = u"Entrer les paramètres de connexion"
|
||||||
account_name = u"Nom de la connexion"
|
account_name = u"Nom de la connexion"
|
||||||
account_login = u"Nom d'utilisateur"
|
account_login = u"Nom d'utilisateur"
|
||||||
account_password = u"Mot de passe"
|
account_password = u"Mot de passe"
|
||||||
account_password_store = u"Sauvegarder le mot de passe sur le serveur Jabber ?"
|
account_password_store = u"Sauvegarder le mot de passe sur le " \
|
||||||
|
u"serveur Jabber ?"
|
||||||
account_host = u"Adresse du serveur email"
|
account_host = u"Adresse du serveur email"
|
||||||
account_port = u"Port du serveur email"
|
account_port = u"Port du serveur email"
|
||||||
account_type = u"Type du serveur email"
|
account_type = u"Type du serveur email"
|
||||||
@@ -98,7 +127,8 @@ class Lang:
|
|||||||
account_xa_action = u"Action lorsque l'état est 'Not Available'"
|
account_xa_action = u"Action lorsque l'état est 'Not Available'"
|
||||||
account_dnd_action = u"Action lorsque l'état est 'Do not Disturb'"
|
account_dnd_action = u"Action lorsque l'état est 'Do not Disturb'"
|
||||||
account_offline_action = u"Action lorsque l'état est 'Offline'"
|
account_offline_action = u"Action lorsque l'état est 'Offline'"
|
||||||
account_check_interval = u"Interval de vérification de nouveaux emails (en minutes)"
|
account_check_interval = u"Interval de vérification de nouveaux " \
|
||||||
|
u"emails (en minutes)"
|
||||||
account_live_email_only = u"Vérifier les nouveaux emails seulement " \
|
account_live_email_only = u"Vérifier les nouveaux emails seulement " \
|
||||||
"lorsqu'une session Jabber est ouverte"
|
"lorsqu'une session Jabber est ouverte"
|
||||||
action_nothing = u"Ne rien faire"
|
action_nothing = u"Ne rien faire"
|
||||||
@@ -107,20 +137,23 @@ class Lang:
|
|||||||
update_title = u"Mise à jour du compte JMC"
|
update_title = u"Mise à jour du compte JMC"
|
||||||
update_instructions = u"Modification de la connexion '%s'"
|
update_instructions = u"Modification de la connexion '%s'"
|
||||||
connection_label = u"Connexion %s '%s'"
|
connection_label = u"Connexion %s '%s'"
|
||||||
update_account_message_subject = u"La connexion %s '%s' a été mise à jour"
|
update_account_message_subject = u"La connexion %s '%s' a été mise " \
|
||||||
update_account_message_body = u"Nom d'utilisateur : '%s'\nMot de passe : '%s'\nsur : '%s'"
|
u"à jour"
|
||||||
|
update_account_message_body = u"Nom d'utilisateur : '%s'\nMot de " \
|
||||||
|
u"passe : '%s'\nsur : '%s'"
|
||||||
new_account_message_subject = u"La connexion %s '%s' a été créée"
|
new_account_message_subject = u"La connexion %s '%s' a été créée"
|
||||||
new_account_message_body = u"Nom d'utilisateur : '%s'\nMot de passe : '%s'\nsur : '%s'"
|
new_account_message_body = u"Nom d'utilisateur : '%s'\nMot de passe " \
|
||||||
|
u": '%s'\nsur : '%s'"
|
||||||
ask_password_subject = u"Demande de mot de passe"
|
ask_password_subject = u"Demande de mot de passe"
|
||||||
ask_password_body = u"Répondre à ce message avec le mot de passe du " \
|
ask_password_body = u"Répondre à ce message avec le mot de passe " \
|
||||||
"compte suivant : \n" \
|
u"du compte suivant : \n" \
|
||||||
"\thost = %s\n" \
|
u"\thost = %s\n" \
|
||||||
"\tlogin = %s\n"
|
u"\tlogin = %s\n"
|
||||||
password_saved_for_session = u"Le mot de passe sera garder tout au " \
|
password_saved_for_session = u"Le mot de passe sera garder tout au " \
|
||||||
"long de la session Jabber."
|
u"long de la session Jabber."
|
||||||
check_error_subject = u"Erreur lors de la vérification des emails."
|
check_error_subject = u"Erreur lors de la vérification des emails."
|
||||||
check_error_body = u"Une erreur est survenue lors de la vérification " \
|
check_error_body = u"Une erreur est survenue lors de la " \
|
||||||
"des emails :\n\t%s"
|
u"vérification des emails :\n\t%s"
|
||||||
new_mail_subject = u"Nouvel email de %s"
|
new_mail_subject = u"Nouvel email de %s"
|
||||||
new_digest_subject = u"%i nouveau(x) email(s)"
|
new_digest_subject = u"%i nouveau(x) email(s)"
|
||||||
|
|
||||||
@@ -152,16 +185,18 @@ class Lang:
|
|||||||
connection_label = u"%s verbinding '%s'"
|
connection_label = u"%s verbinding '%s'"
|
||||||
update_account_message_subject = u"Verbinding %s '%s' werd bijgewerkt"
|
update_account_message_subject = u"Verbinding %s '%s' werd bijgewerkt"
|
||||||
update_account_message_body = u"Geregistreerd met gebruikersnaam '%s'"\
|
update_account_message_body = u"Geregistreerd met gebruikersnaam '%s'"\
|
||||||
"en wachtwoord '%s' op '%s'"
|
u"en wachtwoord '%s' op '%s'"
|
||||||
new_account_message_subject = u"Nieuwe %s verbinding '%s' aangemaakt"
|
new_account_message_subject = u"Nieuwe %s verbinding '%s' aangemaakt"
|
||||||
new_account_message_body = u"Geregistreerd met " \
|
new_account_message_body = u"Geregistreerd met " \
|
||||||
"gebruikersnaam '%s' en wachtwoord '%s' op '%s'"
|
u"gebruikersnaam '%s' en wachtwoord " \
|
||||||
|
u"'%s' op '%s'"
|
||||||
ask_password_subject = u"Wachtwoordaanvraag"
|
ask_password_subject = u"Wachtwoordaanvraag"
|
||||||
ask_password_body = u"Antwoord dit bericht met het volgende wachtwoord" \
|
ask_password_body = u"Antwoord dit bericht met het volgende " \
|
||||||
"voor de volgende account: \n" \
|
u"wachtwoord voor de volgende account: \n" \
|
||||||
"\thost = %s\n" \
|
u"\thost = %s\n" \
|
||||||
"\tlogin = %s\n"
|
u"\tlogin = %s\n"
|
||||||
password_saved_for_session = u"Het wachtwoord zal worden bewaard tijdens uw Jabber-sessie"
|
password_saved_for_session = u"Het wachtwoord zal worden bewaard " \
|
||||||
|
u"tijdens uw Jabber-sessie"
|
||||||
check_error_subject = u"Fout tijdens controle op e-mails."
|
check_error_subject = u"Fout tijdens controle op e-mails."
|
||||||
check_error_body = u"Fout tijdens controle op e-mails:\n\t%s"
|
check_error_body = u"Fout tijdens controle op e-mails:\n\t%s"
|
||||||
new_mail_subject = u"Nieuwe e-mail van %s"
|
new_mail_subject = u"Nieuwe e-mail van %s"
|
||||||
@@ -173,19 +208,24 @@ class Lang:
|
|||||||
account_name = u"Nombre para la cuenta"
|
account_name = u"Nombre para la cuenta"
|
||||||
account_login = u"Usuario (login)"
|
account_login = u"Usuario (login)"
|
||||||
account_password = u"Contraseña"
|
account_password = u"Contraseña"
|
||||||
account_password_store = u"¿Guardar la contraseña en el servidor Jabber?"
|
account_password_store = u"¿Guardar la contraseña en el servidor " \
|
||||||
|
u"Jabber?"
|
||||||
account_host = u"Host"
|
account_host = u"Host"
|
||||||
account_port = u"Puerto"
|
account_port = u"Puerto"
|
||||||
account_type = u"Tipo de servidor Mail"
|
account_type = u"Tipo de servidor Mail"
|
||||||
account_mailbox = u"Ruta del mailbox (solo para IMAP)"
|
account_mailbox = u"Ruta del mailbox (solo para IMAP)"
|
||||||
account_ffc_action = u"Acción para cuando tu estado sea 'Listopara hablar'"
|
account_ffc_action = u"Acción para cuando tu estado sea " \
|
||||||
|
u"'Listopara hablar'"
|
||||||
account_online_action = u"Acción para cuando tu estado sea 'Conectado'"
|
account_online_action = u"Acción para cuando tu estado sea 'Conectado'"
|
||||||
account_away_action = u"Acción para cuando tu estado sea 'Ausente'"
|
account_away_action = u"Acción para cuando tu estado sea 'Ausente'"
|
||||||
account_xa_action = u"Acción para cuando tu estado sea 'No disponible'"
|
account_xa_action = u"Acción para cuando tu estado sea 'No disponible'"
|
||||||
account_dnd_action = u"Acción para cuando tu estado sea 'No molestar'"
|
account_dnd_action = u"Acción para cuando tu estado sea 'No molestar'"
|
||||||
account_offline_action = u"Acción para cuando tu estado sea 'Desconectado'"
|
account_offline_action = u"Acción para cuando tu estado sea " \
|
||||||
account_check_interval = u"Intervalo para comprobar emails nuevos (en minutos)"
|
u"'Desconectado'"
|
||||||
account_live_email_only = u"Avisarme de emails nuevos solo cuando esté conectado"
|
account_check_interval = u"Intervalo para comprobar emails nuevos " \
|
||||||
|
u"(en minutos)"
|
||||||
|
account_live_email_only = u"Avisarme de emails nuevos solo cuando " \
|
||||||
|
u"esté conectado"
|
||||||
action_nothing = u"No hacer nada"
|
action_nothing = u"No hacer nada"
|
||||||
action_retrieve = u"Mostrarme el email"
|
action_retrieve = u"Mostrarme el email"
|
||||||
action_digest = u"Enviar resúmen"
|
action_digest = u"Enviar resúmen"
|
||||||
@@ -193,15 +233,19 @@ class Lang:
|
|||||||
update_instructions = u"Modifica los datos de la cuenta '%s'"
|
update_instructions = u"Modifica los datos de la cuenta '%s'"
|
||||||
connection_label = u"%s conexión '%s'"
|
connection_label = u"%s conexión '%s'"
|
||||||
update_account_message_subject = u"Actualizada %s conexión '%s'"
|
update_account_message_subject = u"Actualizada %s conexión '%s'"
|
||||||
update_account_message_body = u"Registrado con el usuario '%s' y contraseña '%s' en '%s'"
|
update_account_message_body = u"Registrado con el usuario '%s' y " \
|
||||||
|
u"contraseña '%s' en '%s'"
|
||||||
new_account_message_subject = u"Nueva %s conexión '%s' creada"
|
new_account_message_subject = u"Nueva %s conexión '%s' creada"
|
||||||
new_account_message_body = u"Registrado con usuario '%s' y contraseña '%s' en '%s'"
|
new_account_message_body = u"Registrado con usuario '%s' y " \
|
||||||
|
u"contraseña '%s' en '%s'"
|
||||||
ask_password_subject = u"Petición de contraseña"
|
ask_password_subject = u"Petición de contraseña"
|
||||||
ask_password_body = u"Para avisarte de emails nuevos, contesta a este mensaje con la contraseña " \
|
ask_password_body = u"Para avisarte de emails nuevos, contesta a " \
|
||||||
"de la cuenta: \n" \
|
u"este mensaje con la contraseña " \
|
||||||
"\tHost = %s\n" \
|
u"de la cuenta: \n" \
|
||||||
"\tUsuario = %s\n"
|
u"\tHost = %s\n" \
|
||||||
password_saved_for_session = u"La contraseña será guardada para esta sesión únicamente."
|
u"\tUsuario = %s\n"
|
||||||
|
password_saved_for_session = u"La contraseña será guardada para " \
|
||||||
|
u"esta sesión únicamente."
|
||||||
check_error_subject = u"Error al revisar los emails."
|
check_error_subject = u"Error al revisar los emails."
|
||||||
check_error_body = u"Un error apareció al revisar los emails:\n\t%s"
|
check_error_body = u"Un error apareció al revisar los emails:\n\t%s"
|
||||||
new_mail_subject = u"Nuevo email en %s"
|
new_mail_subject = u"Nuevo email en %s"
|
||||||
@@ -225,7 +269,8 @@ class Lang:
|
|||||||
account_dnd_action = u"Akcja gdy status to 'Nie przeszkadzać'"
|
account_dnd_action = u"Akcja gdy status to 'Nie przeszkadzać'"
|
||||||
account_offline_action = u"Akcja gdy status to 'Rozłączony'"
|
account_offline_action = u"Akcja gdy status to 'Rozłączony'"
|
||||||
account_check_interval = u"Sprawdzaj email co (w minutach)"
|
account_check_interval = u"Sprawdzaj email co (w minutach)"
|
||||||
account_live_email_only = u"Raportuj otrzymane emaile tylko\n gdy podłączony do Jabbera"
|
account_live_email_only = u"Raportuj otrzymane emaile tylko\n gdy " \
|
||||||
|
u"podłączony do Jabbera"
|
||||||
action_nothing = u"Nic nie rób"
|
action_nothing = u"Nic nie rób"
|
||||||
action_retrieve = u"Pobierz emaila"
|
action_retrieve = u"Pobierz emaila"
|
||||||
action_digest = u"Wyślij zarys emaila"
|
action_digest = u"Wyślij zarys emaila"
|
||||||
@@ -233,15 +278,20 @@ class Lang:
|
|||||||
update_instructions = u"Modyfikacja połączenia '%s'"
|
update_instructions = u"Modyfikacja połączenia '%s'"
|
||||||
connection_label = u"%s połączenie '%s'"
|
connection_label = u"%s połączenie '%s'"
|
||||||
update_account_message_subject = u"Zmodyfikowane %s połączenie '%s'"
|
update_account_message_subject = u"Zmodyfikowane %s połączenie '%s'"
|
||||||
update_account_message_body = u"Zarejestrowany z nazwą użytkownika '%s' i hasłem '%s' na '%s'"
|
update_account_message_body = u"Zarejestrowany z nazwą użytkownika " \
|
||||||
|
u"'%s' i hasłem '%s' na '%s'"
|
||||||
new_account_message_subject = u"Nowe %s połączenie '%s' utworzone"
|
new_account_message_subject = u"Nowe %s połączenie '%s' utworzone"
|
||||||
new_account_message_body = u"Zarejestrowany z nazwą użytkownika '%s' i hasłem '%s' na '%s'"
|
new_account_message_body = u"Zarejestrowany z nazwą użytkownika " \
|
||||||
|
u"'%s' i hasłem '%s' na '%s'"
|
||||||
ask_password_subject = u"Żądanie hasła"
|
ask_password_subject = u"Żądanie hasła"
|
||||||
ask_password_body = u"Odpowiedz na ta wiadomosc z hasłem dla podanego konta: \n" \
|
ask_password_body = u"Odpowiedz na ta wiadomosc z hasłem dla " \
|
||||||
"\tnazwa hosta = %s\n" \
|
u"podanego konta: \n" \
|
||||||
"\tnazwa uzytkownika = %s\n"
|
u"\tnazwa hosta = %s\n" \
|
||||||
password_saved_for_session = u"Hasło będzie przechowywane podczas Twojej sesji Jabbera"
|
u"\tnazwa uzytkownika = %s\n"
|
||||||
|
password_saved_for_session = u"Hasło będzie przechowywane podczas " \
|
||||||
|
u"Twojej sesji Jabbera"
|
||||||
check_error_subject = u"Błąd podczas sprawdzania emaili."
|
check_error_subject = u"Błąd podczas sprawdzania emaili."
|
||||||
check_error_body = u"Pojawił się błąd podczas sprawdzania emaili:\n\t%s"
|
check_error_body = u"Pojawił się błąd podczas sprawdzania " \
|
||||||
|
u"emaili:\n\t%s"
|
||||||
new_mail_subject = u"Nowy email od %s"
|
new_mail_subject = u"Nowy email od %s"
|
||||||
new_digest_subject = u"%i nowy(ch) email(i)"
|
new_digest_subject = u"%i nowy(ch) email(i)"
|
||||||
|
|||||||
@@ -26,5 +26,7 @@ from sqlobject import *
|
|||||||
class Account(SQLObject):
|
class Account(SQLObject):
|
||||||
user_jid = StringCol()
|
user_jid = StringCol()
|
||||||
name = StringCol()
|
name = StringCol()
|
||||||
|
jid = StringCol()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,11 @@
|
|||||||
##
|
##
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import thread
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
from sqlobject import *
|
from sqlobject import *
|
||||||
|
|
||||||
from jcl.jabber.component import JCLComponent
|
from jcl.jabber.component import JCLComponent
|
||||||
@@ -31,6 +36,8 @@ from jcl.lang import Lang
|
|||||||
class MockStream(object):
|
class MockStream(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.sended = []
|
self.sended = []
|
||||||
|
self.connection_started = False
|
||||||
|
self.connection_stoped = False
|
||||||
|
|
||||||
def send(self, iq):
|
def send(self, iq):
|
||||||
self.sended.append(iq)
|
self.sended.append(iq)
|
||||||
@@ -66,6 +73,15 @@ class MockStream(object):
|
|||||||
if handler is None:
|
if handler is None:
|
||||||
raise Exception("Handler must not be None")
|
raise Exception("Handler must not be None")
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.connection_started = True
|
||||||
|
|
||||||
|
def disconnect(self):
|
||||||
|
self.connection_stoped = True
|
||||||
|
|
||||||
|
def loop_iter(self, timeout):
|
||||||
|
time.sleep(timeout)
|
||||||
|
|
||||||
class JCLComponent_TestCase(unittest.TestCase):
|
class JCLComponent_TestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
connection = sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
|
connection = sqlhub.processConnection = connectionForURI('sqlite:/:memory:')
|
||||||
@@ -80,6 +96,25 @@ class JCLComponent_TestCase(unittest.TestCase):
|
|||||||
def test_constructor(self):
|
def test_constructor(self):
|
||||||
self.assertTrue(Account._connection.tableExists("account"))
|
self.assertTrue(Account._connection.tableExists("account"))
|
||||||
|
|
||||||
|
def test_run(self):
|
||||||
|
self.comp.stream = MockStream()
|
||||||
|
run_thread = thread.start_new_thread(self.comp.run, ())
|
||||||
|
self.assertTrue(self.comp.stream.connection_started)
|
||||||
|
self.comp.running = False
|
||||||
|
time.sleep(JCLComponent.timeout + 1)
|
||||||
|
threads = threading.enumerate()
|
||||||
|
self.assertNone(threads)
|
||||||
|
for _thread in threads:
|
||||||
|
try:
|
||||||
|
_thread.join(1)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.assertTrue(self.comp.connection_stoped)
|
||||||
|
|
||||||
|
def test_run_go_offline(self):
|
||||||
|
## TODO : verify offline stanza are sent
|
||||||
|
pass
|
||||||
|
|
||||||
def test_authenticated_handler(self):
|
def test_authenticated_handler(self):
|
||||||
self.comp.stream = MockStream()
|
self.comp.stream = MockStream()
|
||||||
self.comp.authenticated()
|
self.comp.authenticated()
|
||||||
|
|||||||
Reference in New Issue
Block a user