diff --git a/src/core/default_config.py b/src/core/default_config.py
index 1694bd3f..3f76e37b 100644
--- a/src/core/default_config.py
+++ b/src/core/default_config.py
@@ -20,9 +20,9 @@ along with this program. If not, see .
"""
CONST = {
- 'client_name' : u'SàT (Salut à toi)',
- 'client_version' : u'0.3.0', #Please add 'D' at the end for dev versions
- 'local_dir' : '~/.sat'
+ 'client_name': u'SàT (Salut à toi)',
+ 'client_version': u'0.3.0', # Please add 'D' at the end for dev versions
+ 'local_dir': '~/.sat'
}
### Defaut configuration values ###
diff --git a/src/core/exceptions.py b/src/core/exceptions.py
index a811e62d..fb8b9605 100644
--- a/src/core/exceptions.py
+++ b/src/core/exceptions.py
@@ -19,23 +19,30 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
"""
+
class ProfileUnknownError(Exception):
pass
+
class ProfileNotInCacheError(Exception):
pass
+
class NotConnectedProfileError(Exception):
pass
+
class UnknownEntityError(Exception):
pass
+
class UnknownGroupError(Exception):
pass
+
class NotFound(Exception):
pass
+
class DataError(Exception):
pass
diff --git a/src/core/sat_main.py b/src/core/sat_main.py
index 7a9f1f7a..1852e735 100644
--- a/src/core/sat_main.py
+++ b/src/core/sat_main.py
@@ -50,19 +50,19 @@ try:
except ImportError:
from wokkel.subprotocols import XMPPHandler
-
### logging configuration FIXME: put this elsewhere ###
logging.basicConfig(level=logging.DEBUG,
format='%(message)s')
###
-
sat_id = 0
+
def sat_next_id():
global sat_id
- sat_id+=1
- return "sat_id_"+str(sat_id)
+ sat_id += 1
+ return "sat_id_" + str(sat_id)
+
class SAT(service.Service):
@@ -74,18 +74,18 @@ class SAT(service.Service):
try:
_const = os.environ['SAT_CONST_%s' % name]
if _const:
- debug(_("Constant %(name)s overrided with [%(value)s]") % {'name':name, 'value': _const})
+ debug(_("Constant %(name)s overrided with [%(value)s]") % {'name': name, 'value': _const})
return _const
except KeyError:
pass
- if not CONST.has_key(name):
+ if name not in CONST:
error(_('Trying to access an undefined constant'))
raise Exception
return CONST[name]
def set_const(self, name, value):
"""Save a constant"""
- if CONST.has_key(name):
+ if name in CONST:
error(_('Trying to redefine a constant'))
raise Exception
CONST[name] = value
@@ -93,21 +93,21 @@ class SAT(service.Service):
def __init__(self):
#TODO: standardize callback system
- self.__general_cb_map = {} #callback called for general reasons (key = name)
- self.__private_data = {} #used for internal callbacks (key = id)
+ self.__general_cb_map = {} # callback called for general reasons (key = name)
+ self.__private_data = {} # used for internal callbacks (key = id)
self.profiles = {}
self.plugins = {}
- self.menus = {} #used to know which new menus are wanted by plugins
+ self.menus = {} # used to know which new menus are wanted by plugins
- self.memory=Memory(self)
+ self.memory = Memory(self)
local_dir = self.memory.getConfig('', 'local_dir')
if not os.path.exists(local_dir):
os.makedirs(local_dir)
- self.trigger = TriggerManager() #trigger are used to change SàT behaviour
+ self.trigger = TriggerManager() # trigger are used to change SàT behaviour
- self.bridge=DBusBridge()
+ self.bridge = DBusBridge()
self.bridge.register("getVersion", lambda: self.get_const('client_version'))
self.bridge.register("getProfileName", self.memory.getProfileName)
self.bridge.register("getProfilesList", self.memory.getProfilesList)
@@ -155,15 +155,14 @@ class SAT(service.Service):
info(_("Memory initialised"))
self._import_plugins()
-
def _import_plugins(self):
"""Import all plugins found in plugins directory"""
import sat.plugins
plugins_path = os.path.dirname(sat.plugins.__file__)
- plug_lst = [os.path.splitext(plugin)[0] for plugin in map(os.path.basename,glob(os.path.join(plugins_path,"plugin*.py")))]
- __plugins_to_import = {} #plugins we still have to import
+ plug_lst = [os.path.splitext(plugin)[0] for plugin in map(os.path.basename, glob(os.path.join(plugins_path, "plugin*.py")))]
+ __plugins_to_import = {} # plugins we still have to import
for plug in plug_lst:
- plugin_path = 'sat.plugins.'+plug
+ plugin_path = 'sat.plugins.' + plug
__import__(plugin_path)
mod = sys.modules[plugin_path]
plugin_info = mod.PLUGIN_INFO
@@ -176,58 +175,58 @@ class SAT(service.Service):
def _import_plugins_from_dict(self, plugins_to_import, import_name=None):
"""Recursively import and their dependencies in the right order
@param plugins_to_import: dict where key=import_name and values= (plugin_path, module, plugin_info)"""
- if self.plugins.has_key(import_name):
+ if import_name in self.plugins:
debug('Plugin [%s] already imported, passing' % import_name)
return
if not import_name:
- import_name,(plugin_path, mod, plugin_info) = plugins_to_import.popitem()
+ import_name, (plugin_path, mod, plugin_info) = plugins_to_import.popitem()
else:
if not import_name in plugins_to_import:
raise ImportError(_('Dependency plugin not found: [%s]') % import_name)
plugin_path, mod, plugin_info = plugins_to_import.pop(import_name)
- dependencies = plugin_info.setdefault("dependencies",[])
+ dependencies = plugin_info.setdefault("dependencies", [])
for dependency in dependencies:
- if not self.plugins.has_key(dependency):
+ if dependency not in self.plugins:
debug('Recursively import dependency of [%s]: [%s]' % (import_name, dependency))
self._import_plugins_from_dict(plugins_to_import, dependency)
- info (_("importing plugin: %s"), plugin_info['name'])
+ info(_("importing plugin: %s"), plugin_info['name'])
self.plugins[import_name] = getattr(mod, plugin_info['main'])(self)
- if plugin_info.has_key('handler') and plugin_info['handler'] == 'yes':
+ if 'handler' in plugin_info and plugin_info['handler'] == 'yes':
self.plugins[import_name].is_handler = True
else:
self.plugins[import_name].is_handler = False
#TODO: test xmppclient presence and register handler parent
-
- def connect(self, profile_key = '@DEFAULT@'):
+ def connect(self, profile_key='@DEFAULT@'):
"""Connect to jabber server"""
self.asyncConnect(profile_key)
- def asyncConnect(self, profile_key = '@DEFAULT@'):
+ def asyncConnect(self, profile_key='@DEFAULT@'):
"""Connect to jabber server with asynchronous reply
@param profile_key: %(doc_profile)s
"""
profile = self.memory.getProfileName(profile_key)
if not profile:
- error (_('Trying to connect a non-exsitant profile'))
+ error(_('Trying to connect a non-exsitant profile'))
raise ProfileUnknownError(profile_key)
- if (self.isConnected(profile)):
+ if self.isConnected(profile):
info(_("already connected !"))
return defer.succeed("None")
def afterMemoryInit(ignore):
"""This part must be called when we have loaded individual parameters from memory"""
try:
- port = int(self.memory.getParamA("Port", "Connection", profile_key = profile))
+ port = int(self.memory.getParamA("Port", "Connection", profile_key=profile))
except ValueError:
error(_("Can't parse port value, using default value"))
port = 5222
- current = self.profiles[profile] = xmpp.SatXMPPClient(self, profile,
- jid.JID(self.memory.getParamA("JabberID", "Connection", profile_key = profile), profile),
- self.memory.getParamA("Password", "Connection", profile_key = profile),
- self.memory.getParamA("Server", "Connection", profile_key = profile),
+ current = self.profiles[profile] = xmpp.SatXMPPClient(
+ self, profile,
+ jid.JID(self.memory.getParamA("JabberID", "Connection", profile_key=profile), profile),
+ self.memory.getParamA("Password", "Connection", profile_key=profile),
+ self.memory.getParamA("Server", "Connection", profile_key=profile),
port)
current.messageProt = xmpp.SatMessageProtocol(self)
@@ -243,10 +242,10 @@ class SAT(service.Service):
current.fallBack.setHandlerParent(current)
current.versionHandler = xmpp.SatVersionHandler(self.get_const('client_name'),
- self.get_const('client_version'))
+ self.get_const('client_version'))
current.versionHandler.setHandlerParent(current)
- debug (_("setting plugins parents"))
+ debug(_("setting plugins parents"))
for plugin in self.plugins.iteritems():
if plugin[1].is_handler:
@@ -258,7 +257,7 @@ class SAT(service.Service):
current.startService()
d = current.getConnectionDeferred()
- d.addCallback(lambda x: current.roster.got_roster) #we want to be sure that we got the roster
+ d.addCallback(lambda x: current.roster.got_roster) # we want to be sure that we got the roster
return d
self.memory.startProfileSession(profile)
@@ -266,7 +265,7 @@ class SAT(service.Service):
def disconnect(self, profile_key):
"""disconnect from jabber server"""
- if (not self.isConnected(profile_key)):
+ if not self.isConnected(profile_key):
info(_("not connected !"))
return
profile = self.memory.getProfileName(profile_key)
@@ -282,8 +281,8 @@ class SAT(service.Service):
if not client:
raise ProfileUnknownError(_('Asking contacts for a non-existant profile'))
ret = []
- for item in client.roster.getItems(): #we get all items for client's roster
- #and convert them to expected format
+ for item in client.roster.getItems(): # we get all items for client's roster
+ # and convert them to expected format
attr = client.roster.getAttributes(item)
ret.append([item.jid.userhost(), attr, item.groups])
return ret
@@ -338,12 +337,12 @@ class SAT(service.Service):
return None
return self.profiles[profile]
- def registerNewAccount(self, login, password, email, server, port = 5222, id = None, profile_key = '@DEFAULT@'):
+ def registerNewAccount(self, login, password, email, server, port=5222, id=None, profile_key='@DEFAULT@'):
"""Connect to a server and create a new account using in-band registration"""
profile = self.memory.getProfileName(profile_key)
assert(profile)
- next_id = id or sat_next_id() #the id is used to send server's answer
+ next_id = id or sat_next_id() # the id is used to send server's answer
serverRegistrer = xmlstream.XmlStreamFactory(xmpp.RegisteringAuthenticator(self, server, login, password, email, next_id, profile))
connector = reactor.connectTCP(server, port, serverRegistrer)
serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect()
@@ -356,24 +355,25 @@ class SAT(service.Service):
server = self.memory.getParamA("Server", "Connection", profile_key=profile)
if not user or not password or not server:
- info (_('No user or server given'))
+ info(_('No user or server given'))
#TODO: a proper error message must be sent to frontend
- self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")}, profile)
+ self.actionResult(id, "ERROR", {'message': _("No user, password or server given, can't register new account.")}, profile)
return
confirm_id = sat_next_id()
- self.__private_data[confirm_id]=(id,profile)
+ self.__private_data[confirm_id] = (id, profile)
- self.askConfirmation(confirm_id, "YES/NO",
- {"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server, 'profile':profile}},
+ self.askConfirmation(
+ confirm_id, "YES/NO",
+ {"message": _("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user': user, 'server': server, 'profile': profile}},
self.regisConfirmCB, profile)
- print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
- print "id=",id
- print "data=",data
+ print "===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============"
+ print "id=", id
+ print "data=", data
def regisConfirmCB(self, id, accepted, data, profile):
print _("register Confirmation CB ! (%s)") % str(accepted)
- action_id,profile = self.__private_data[id]
+ action_id, profile = self.__private_data[id]
del self.__private_data[id]
if accepted:
user = jid.parse(self.memory.getParamA("JabberID", "Connection", profile_key=profile))[0]
@@ -398,13 +398,13 @@ class SAT(service.Service):
iq["to"] = target
iq["from"] = self.profiles[profile].jid.full()
query = iq.addElement(('jabber:iq:register', 'query'))
- if action=='SUBMIT':
+ if action == 'SUBMIT':
form = tupleList2dataForm(fields)
query.addChild(form.toElement())
- elif action=='CANCEL':
+ elif action == 'CANCEL':
query.addElement('remove')
else:
- error (_("FIXME FIXME FIXME: Unmanaged action (%s) in submitForm") % action)
+ error(_("FIXME FIXME FIXME: Unmanaged action (%s) in submitForm") % action)
raise NotImplementedError
deferred = iq.send(target)
@@ -414,7 +414,7 @@ class SAT(service.Service):
def setParam(self, name, value, category, profile_key):
"""set wanted paramater and notice observers"""
- info (_("setting param: %(name)s=%(value)s in category %(category)s") % {'name':name, 'value':value, 'category':category})
+ info(_("setting param: %(name)s=%(value)s in category %(category)s") % {'name': name, 'value': value, 'category': category})
self.memory.setParam(name, value, category, profile_key)
def isConnected(self, profile_key):
@@ -424,9 +424,9 @@ class SAT(service.Service):
"""
profile = self.memory.getProfileName(profile_key)
if not profile:
- error (_('asking connection status for a non-existant profile'))
+ error(_('asking connection status for a non-existant profile'))
return
- if not self.profiles.has_key(profile):
+ if profile not in self.profiles:
return False
return self.profiles[profile].isConnected()
@@ -439,22 +439,21 @@ class SAT(service.Service):
"""
profile = self.memory.getProfileName(profile_key)
if not profile:
- error (_('trying to launch action with a non-existant profile'))
- raise Exception #TODO: raise a proper exception
- if type=="button":
+ error(_('trying to launch action with a non-existant profile'))
+ raise Exception # TODO: raise a proper exception
+ if type == "button":
try:
cb_name = data['callback_id']
except KeyError:
- error (_("Incomplete data"))
+ error(_("Incomplete data"))
return ""
id = sat_next_id()
- self.callGeneralCB(cb_name, id, data, profile = profile)
+ self.callGeneralCB(cb_name, id, data, profile=profile)
return id
else:
- error (_("Unknown action type"))
+ error(_("Unknown action type"))
return ""
-
## jabber methods ##
def getWaitingConf(self, profile_key=None):
@@ -474,19 +473,19 @@ class SAT(service.Service):
assert(profile)
client = self.profiles[profile]
current_jid = client.jid
- mess_data = { #we put data in a dict, so trigger methods can change them
- "to": jid.JID(to),
- "message": msg,
- "subject": subject,
- "type": mess_type
- }
+ mess_data = { # we put data in a dict, so trigger methods can change them
+ "to": jid.JID(to),
+ "message": msg,
+ "subject": subject,
+ "type": mess_type
+ }
if mess_data["type"] == "auto":
# we try to guess the type
if mess_data["subject"]:
mess_data["type"] = 'normal'
- elif not mess_data["to"].resource: #if to JID has a resource, the type is not 'groupchat'
- #we may have a groupchat message, we check if the we know this jid
+ elif not mess_data["to"].resource: # if to JID has a resource, the type is not 'groupchat'
+ # we may have a groupchat message, we check if the we know this jid
try:
entity_type = self.memory.getEntityData(mess_data["to"], ['type'], profile)["type"]
#FIXME: should entity_type manage ressources ?
@@ -505,7 +504,7 @@ class SAT(service.Service):
return
debug(_("Sending jabber message of type [%(type)s] to %(to)s...") % {"type": mess_data["type"], "to": to})
- message = domish.Element((None,'message'))
+ message = domish.Element((None, 'message'))
message["to"] = mess_data["to"].full()
message["from"] = current_jid.full()
message["type"] = mess_data["type"]
@@ -513,25 +512,23 @@ class SAT(service.Service):
message.addElement("subject", None, subject)
message.addElement("body", None, mess_data["message"])
client.xmlstream.send(message)
- if mess_data["type"]!="groupchat":
- self.memory.addToHistory(current_jid, jid.JID(to), unicode(mess_data["message"]), unicode(mess_data["type"]), profile=profile) #we don't add groupchat message to history, as we get them back
- #and they will be added then
- self.bridge.newMessage(message['from'], unicode(mess_data["message"]), mess_type=mess_data["type"], to_jid=message['to'], extra={}, profile=profile) #We send back the message, so all clients are aware of it
+ if mess_data["type"] != "groupchat":
+ self.memory.addToHistory(current_jid, jid.JID(to), unicode(mess_data["message"]), unicode(mess_data["type"]), profile=profile) # we don't add groupchat message to history, as we get them back
+ # and they will be added then
+ self.bridge.newMessage(message['from'], unicode(mess_data["message"]), mess_type=mess_data["type"], to_jid=message['to'], extra={}, profile=profile) # We send back the message, so all clients are aware of it
-
- def setPresence(self, to="", show="", priority = 0, statuses={}, profile_key='@DEFAULT@'):
+ def setPresence(self, to="", show="", priority=0, statuses={}, profile_key='@DEFAULT@'):
"""Send our presence information"""
profile = self.memory.getProfileName(profile_key)
assert(profile)
to_jid = jid.JID(to) if to else None
self.profiles[profile].presence.available(to_jid, show, statuses, priority)
#XXX: FIXME: temporary fix to work around openfire 3.7.0 bug (presence is not broadcasted to generating resource)
- if statuses.has_key(''):
+ if '' in statuses:
statuses['default'] = statuses['']
del statuses['']
- self.bridge.presenceUpdate(self.profiles[profile].jid.full(), show,
- int(priority), statuses, profile)
-
+ self.bridge.presenceUpdate(self.profiles[profile].jid.full(), show,
+ int(priority), statuses, profile)
def subscription(self, subs_type, raw_jid, profile_key):
"""Called to manage subscription
@@ -541,22 +538,22 @@ class SAT(service.Service):
profile = self.memory.getProfileName(profile_key)
assert(profile)
to_jid = jid.JID(raw_jid)
- debug (_('subsciption request [%(subs_type)s] for %(jid)s') % {'subs_type':subs_type, 'jid':to_jid.full()})
- if subs_type=="subscribe":
+ debug(_('subsciption request [%(subs_type)s] for %(jid)s') % {'subs_type': subs_type, 'jid': to_jid.full()})
+ if subs_type == "subscribe":
self.profiles[profile].presence.subscribe(to_jid)
- elif subs_type=="subscribed":
+ elif subs_type == "subscribed":
self.profiles[profile].presence.subscribed(to_jid)
- elif subs_type=="unsubscribe":
+ elif subs_type == "unsubscribe":
self.profiles[profile].presence.unsubscribe(to_jid)
- elif subs_type=="unsubscribed":
+ elif subs_type == "unsubscribed":
self.profiles[profile].presence.unsubscribed(to_jid)
def addContact(self, to, profile_key):
"""Add a contact in roster list"""
profile = self.memory.getProfileName(profile_key)
assert(profile)
- to_jid=jid.JID(to)
- #self.profiles[profile].roster.addItem(to_jid) XXX: disabled (cf http://wokkel.ik.nu/ticket/56))
+ to_jid = jid.JID(to)
+ #self.profiles[profile].roster.addItem(to_jid) #XXX: disabled (cf http://wokkel.ik.nu/ticket/56))
self.profiles[profile].presence.subscribe(to_jid)
def updateContact(self, to, name, groups, profile_key):
@@ -574,20 +571,19 @@ class SAT(service.Service):
"""Remove contact from roster list"""
profile = self.memory.getProfileName(profile_key)
assert(profile)
- to_jid=jid.JID(to)
+ to_jid = jid.JID(to)
self.profiles[profile].roster.removeItem(to_jid)
self.profiles[profile].presence.unsubscribe(to_jid)
-
## callbacks ##
def serverDisco(self, disco, profile):
"""xep-0030 Discovery Protocol."""
for feature in disco.features:
- debug (_("Feature found: %s"),feature)
+ debug(_("Feature found: %s"), feature)
self.memory.addServerFeature(feature, profile)
for cat, type in disco.identities:
- debug (_("Identity found: [%(category)s/%(type)s] %(identity)s") % {'category':cat, 'type':type, 'identity':disco.identities[(cat,type)]})
+ debug(_("Identity found: [%(category)s/%(type)s] %(identity)s") % {'category': cat, 'type': type, 'identity': disco.identities[(cat, type)]})
def serverDiscoItems(self, disco_result, disco_client, profile, initialized):
"""xep-0030 Discovery Protocol.
@@ -598,23 +594,21 @@ class SAT(service.Service):
def _check_entity_cb(result, entity, profile):
for category, type in result.identities:
- debug (_('Identity added: (%(category)s,%(type)s) ==> %(entity)s [%(profile)s]') % {
- 'category':category, 'type':type, 'entity':entity, 'profile':profile})
+ debug(_('Identity added: (%(category)s,%(type)s) ==> %(entity)s [%(profile)s]') % {
+ 'category': category, 'type': type, 'entity': entity, 'profile': profile})
self.memory.addServerIdentity(category, type, entity, profile)
def _errback(result, entity, profile):
- warning(_("Can't get information on identity [%(entity)s] for profile [%(profile)s]") % {'entity':entity, 'profile': profile})
+ warning(_("Can't get information on identity [%(entity)s] for profile [%(profile)s]") % {'entity': entity, 'profile': profile})
defer_list = []
for item in disco_result._items:
- if item.entity.full().count('.') == 1: #XXX: workaround for a bug on jabberfr, tmp
+ if item.entity.full().count('.') == 1: # XXX: workaround for a bug on jabberfr, tmp
warning(_('Using jabberfr workaround, be sure your domain has at least two levels (e.g. "example.tld", not "example" alone)'))
continue
args = [item.entity, profile]
defer_list.append(disco_client.requestInfo(item.entity).addCallbacks(_check_entity_cb, _errback, args, None, args))
defer.DeferredList(defer_list).chainDeferred(initialized)
-
-
## Generic HMI ##
def actionResult(self, action_id, action_type, data, profile):
@@ -636,8 +630,6 @@ class SAT(service.Service):
action_type = "DICT_DICT"
self.bridge.actionResultExt(action_type, action_id, data, profile)
-
-
def askConfirmation(self, conf_id, conf_type, data, cb, profile):
"""Add a confirmation callback
@param conf_id: conf_id used to get answer
@@ -648,21 +640,20 @@ class SAT(service.Service):
client = self.getClient(profile)
if not client:
raise ProfileUnknownError(_("Asking confirmation a non-existant profile"))
- if client._waiting_conf.has_key(conf_id):
- error (_("Attempt to register two callbacks for the same confirmation"))
+ if conf_id in client._waiting_conf:
+ error(_("Attempt to register two callbacks for the same confirmation"))
else:
client._waiting_conf[conf_id] = (conf_type, data, cb)
self.bridge.askConfirmation(conf_id, conf_type, data, profile)
-
def confirmationAnswer(self, conf_id, accepted, data, profile):
"""Called by frontends to answer confirmation requests"""
client = self.getClient(profile)
if not client:
raise ProfileUnknownError(_("Confirmation answer from a non-existant profile"))
- debug (_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success':_("accepted") if accepted else _("refused")})
- if not client._waiting_conf.has_key(conf_id):
- error (_("Received an unknown confirmation (%(id)s for %(profile)s)") % {'id': conf_id, 'profile': profile})
+ debug(_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success': _("accepted") if accepted else _("refused")})
+ if conf_id not in client._waiting_conf:
+ error(_("Received an unknown confirmation (%(id)s for %(profile)s)") % {'id': conf_id, 'profile': profile})
else:
cb = client._waiting_conf[conf_id][-1]
del client._waiting_conf[conf_id]
@@ -680,8 +671,8 @@ class SAT(service.Service):
client = self.getClient(profile)
if not client:
raise ProfileUnknownError
- if not client._progress_cb_map.has_key(progress_id):
- error (_("Trying to remove an unknow progress callback"))
+ if progress_id not in client._progress_cb_map:
+ error(_("Trying to remove an unknow progress callback"))
else:
del client._progress_cb_map[progress_id]
@@ -707,8 +698,8 @@ class SAT(service.Service):
def removeGeneralCB(self, name):
"""Remove a general callback"""
- if not self.__general_cb_map.has_key(name):
- error (_("Trying to remove an unknow general callback"))
+ if name not in self.__general_cb_map:
+ error(_("Trying to remove an unknow general callback"))
else:
del self.__general_cb_map[name]
@@ -722,15 +713,15 @@ class SAT(service.Service):
#Menus management
- def importMenu(self, category, name, callback, help_string = "", type = "NORMAL"):
+ def importMenu(self, category, name, callback, help_string="", type="NORMAL"):
"""register a new menu for frontends
@param category: category of the menu
@param name: menu item entry
@param callback: method to be called when menuitem is selected"""
- if self.menus.has_key((category,name)):
- error ("Want to register a menu which already existe")
+ if (category, name) in self.menus:
+ error("Want to register a menu which already existe")
return
- self.menus[(category,name,type)] = {'callback':callback, 'help_string':help_string, 'type':type}
+ self.menus[(category, name, type)] = {'callback': callback, 'help_string': help_string, 'type': type}
def getMenus(self):
"""Return all menus registered"""
@@ -739,21 +730,21 @@ class SAT(service.Service):
def getMenuHelp(self, category, name, type="NORMAL"):
"""return the help string of the menu"""
try:
- return self.menus[(category,name,type)]['help_string']
+ return self.menus[(category, name, type)]['help_string']
except KeyError:
- error (_("Trying to access an unknown menu"))
+ error(_("Trying to access an unknown menu"))
return ""
def callMenu(self, category, name, type="NORMAL", profile_key='@DEFAULT@'):
"""return the id of the action"""
profile = self.memory.getProfileName(profile_key)
if not profile_key:
- error (_('Non-exsitant profile'))
+ error(_('Non-exsitant profile'))
return ""
- if self.menus.has_key((category,name,type)):
+ if (category, name, type) in self.menus:
id = self.get_next_id()
- self.menus[(category,name,type)]['callback'](id, profile)
+ self.menus[(category, name, type)]['callback'](id, profile)
return id
else:
- error (_("Trying to access an unknown menu (%(category)s/%(name)s/%(type)s)")%{'category':category, 'name':name,'type':type})
+ error(_("Trying to access an unknown menu (%(category)s/%(name)s/%(type)s)") % {'category': category, 'name': name, 'type': type})
return ""
diff --git a/src/core/xmpp.py b/src/core/xmpp.py
index e71778b2..ee5e6fa3 100644
--- a/src/core/xmpp.py
+++ b/src/core/xmpp.py
@@ -22,7 +22,7 @@ along with this program. If not, see .
from twisted.internet import task, defer
from twisted.words.protocols.jabber import jid, xmlstream
from wokkel import client, disco, xmppim, generic, compat, delay
-from logging import debug, info, error
+from logging import debug, info, warning, error
from sat.core import exceptions
from calendar import timegm
@@ -32,14 +32,13 @@ class SatXMPPClient(client.XMPPClient):
def __init__(self, host_app, profile, user_jid, password, host=None, port=5222):
client.XMPPClient.__init__(self, user_jid, password, host, port)
self.factory.clientConnectionLost = self.connectionLost
- self.__connected=False
+ self.__connected = False
self.profile = profile
self.host_app = host_app
self.client_initialized = defer.Deferred()
self.conn_deferred = defer.Deferred()
- self._waiting_conf = {} #callback called when a confirmation is received
- self._progress_cb_map = {} #callback called when a progress is requested (key = progress id)
-
+ self._waiting_conf = {} # callback called when a confirmation is received
+ self._progress_cb_map = {} # callback called when a progress is requested (key = progress id)
def getConnectionDeferred(self):
"""Return a deferred which fire when the client is connected"""
@@ -49,16 +48,15 @@ class SatXMPPClient(client.XMPPClient):
if not self.host_app.trigger.point("XML Initialized", xmlstream, self.profile):
return
client.XMPPClient._authd(self, xmlstream)
- self.__connected=True
- info (_("********** [%s] CONNECTED **********") % self.profile)
+ self.__connected = True
+ info(_("********** [%s] CONNECTED **********") % self.profile)
self.streamInitialized()
- self.host_app.bridge.connected(self.profile) #we send the signal to the clients
-
+ self.host_app.bridge.connected(self.profile) # we send the signal to the clients
def streamInitialized(self):
"""Called after _authd"""
- debug (_("XML stream is initialized"))
- self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire)
+ debug(_("XML stream is initialized"))
+ self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") # Needed to avoid disconnection (specially with openfire)
self.keep_alife.start(180)
self.disco = SatDiscoProtocol(self)
@@ -73,18 +71,18 @@ class SatXMPPClient(client.XMPPClient):
self.presence.available()
- self.disco.requestInfo(jid.JID(self.jid.host)).addCallback(self.host_app.serverDisco, self.profile) #FIXME: use these informations
+ self.disco.requestInfo(jid.JID(self.jid.host)).addCallback(self.host_app.serverDisco, self.profile) # FIXME: use these informations
self.disco.requestItems(jid.JID(self.jid.host)).addCallback(self.host_app.serverDiscoItems, self.disco, self.profile, self.client_initialized)
self.conn_deferred.callback(None)
def initializationFailed(self, reason):
- print ("initializationFailed: %s" % reason)
+ print "initializationFailed: %s" % reason
self.host_app.bridge.connectionError("AUTH_ERROR", self.profile)
try:
client.XMPPClient.initializationFailed(self, reason)
except:
- #we already send an error signal, no need to raise an exception
+ # we already send an error signal, no need to raise an exception
pass
self.conn_deferred.errback()
@@ -92,14 +90,14 @@ class SatXMPPClient(client.XMPPClient):
return self.__connected
def connectionLost(self, connector, unused_reason):
- self.__connected=False
- info (_("********** [%s] DISCONNECTED **********") % self.profile)
+ self.__connected = False
+ info(_("********** [%s] DISCONNECTED **********") % self.profile)
try:
self.keep_alife.stop()
except AttributeError:
- debug (_("No keep_alife"))
- self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients
- self.host_app.purgeClient(self.profile) #and we remove references to this client
+ debug(_("No keep_alife"))
+ self.host_app.bridge.disconnected(self.profile) # we send the signal to the clients
+ self.host_app.purgeClient(self.profile) # and we remove references to this client
class SatMessageProtocol(xmppim.MessageProtocol):
@@ -109,7 +107,7 @@ class SatMessageProtocol(xmppim.MessageProtocol):
self.host = host
def onMessage(self, message):
- debug (_(u"got message from: %s"), message["from"])
+ debug(_(u"got message from: %s"), message["from"])
if not self.host.trigger.point("MessageReceived", message, profile=self.parent.profile):
return
for e in message.elements():
@@ -120,7 +118,7 @@ class SatMessageProtocol(xmppim.MessageProtocol):
_delay = delay.Delay.fromElement(filter(lambda elm: elm.name == 'delay', message.elements())[0])
timestamp = timegm(_delay.stamp.utctimetuple())
extra = {"archive": str(timestamp)}
- if mess_type != 'groupchat': #XXX: we don't save delayed messages in history for groupchats
+ if mess_type != 'groupchat': # XXX: we don't save delayed messages in history for groupchats
#TODO: add delayed messages to history if they aren't already in it
self.host.memory.addToHistory(jid.JID(message["from"]), jid.JID(message["to"]), mess_body, mess_type, timestamp, profile=self.parent.profile)
except IndexError:
@@ -129,6 +127,7 @@ class SatMessageProtocol(xmppim.MessageProtocol):
self.host.bridge.newMessage(message["from"], mess_body, mess_type, message['to'], extra, profile=self.parent.profile)
break
+
class SatRosterProtocol(xmppim.RosterClientProtocol):
def __init__(self, host):
@@ -136,8 +135,8 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
self.host = host
self.got_roster = defer.Deferred()
#XXX: the two following dicts keep a local copy of the roster
- self._groups = {} #map from groups to bare jids: key=group value=set of bare jids
- self._jids = {} #map from bare jids to RosterItem: key=jid value=RosterItem
+ self._groups = {} # map from groups to bare jids: key=group value=set of bare jids
+ self._jids = {} # map from bare jids to RosterItem: key=jid value=RosterItem
def rosterCb(self, roster):
for raw_jid, item in roster.iteritems():
@@ -193,17 +192,17 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
#TODO: send a signal to frontends
if not item.subscriptionTo and not item.subscriptionFrom and not item.ask:
#XXX: current behaviour: we don't want contact in our roster list
- #if there is no presence subscription
- #may change in the future
+ # if there is no presence subscription
+ # may change in the future
self.removeItem(item.jid)
return
- info (_("new contact in roster list: %s"), item.jid.full())
+ info(_("new contact in roster list: %s"), item.jid.full())
#self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile)
bare_jid = item.jid.userhost()
self._jids[bare_jid] = item
for group in item.groups:
- self._groups.setdefault(group,set()).add(bare_jid)
+ self._groups.setdefault(group, set()).add(bare_jid)
self.host.bridge.newContact(item.jid.full(), self.getAttributes(item), item.groups, self.parent.profile)
def onRosterRemove(self, entity):
@@ -211,11 +210,11 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
print _("removing %s from roster list") % entity.full()
bare_jid = entity.userhost()
- #we first remove item from local cache (self._groups and self._jids)
+ # we first remove item from local cache (self._groups and self._jids)
try:
item = self._jids.pop(bare_jid)
except KeyError:
- log.warning("Received a roster remove event for an item not in cache")
+ warning("Received a roster remove event for an item not in cache")
return
for group in item.groups:
try:
@@ -224,10 +223,10 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
if not jids_set:
del self._groups[group]
except KeyError:
- log.warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" %
- {"group": group, "jid": bare_jid})
+ warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" %
+ {"group": group, "jid": bare_jid})
- #then we send the bridge signal
+ # then we send the bridge signal
self.host.bridge.contactDeleted(entity.userhost(), self.parent.profile)
def getGroups(self):
@@ -256,7 +255,7 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
try:
return self._groups[group]
except KeyError:
- return exceptions.UnknownGroupError
+ return exceptions.UnknownGroupError
class SatPresenceProtocol(xmppim.PresenceClientProtocol):
@@ -266,37 +265,38 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
self.host = host
def availableReceived(self, entity, show=None, statuses=None, priority=0):
- debug (_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity':entity, 'show':show, 'statuses':statuses, 'priority':priority})
+ debug(_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity': entity, 'show': show, 'statuses': statuses, 'priority': priority})
if not statuses:
statuses = {}
- if statuses.has_key(None): #we only want string keys
+ if None in statuses: # we only want string keys
statuses["default"] = statuses[None]
del statuses[None]
self.host.memory.setPresenceStatus(entity, show or "",
- int(priority), statuses, self.parent.profile)
+ int(priority), statuses,
+ self.parent.profile)
- #now it's time to notify frontends
- self.host.bridge.presenceUpdate(entity.full(), show or "",
- int(priority), statuses, self.parent.profile)
+ # now it's time to notify frontends
+ self.host.bridge.presenceUpdate(entity.full(), show or "",
+ int(priority), statuses,
+ self.parent.profile)
def unavailableReceived(self, entity, statuses=None):
- debug (_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity':entity, 'statuses':statuses})
+ debug(_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity': entity, 'statuses': statuses})
if not statuses:
statuses = {}
- if statuses.has_key(None): #we only want string keys
+ if None in statuses: # we only want string keys
statuses["default"] = statuses[None]
del statuses[None]
self.host.memory.setPresenceStatus(entity, "unavailable", 0, statuses, self.parent.profile)
- #now it's time to notify frontends
+ # now it's time to notify frontends
self.host.bridge.presenceUpdate(entity.full(), "unavailable", 0, statuses, self.parent.profile)
-
def available(self, entity=None, show=None, statuses=None, priority=0):
if not statuses:
statuses = {}
@@ -319,7 +319,7 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
xmppim.PresenceClientProtocol.subscribed(self, entity)
self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile)
item = self.parent.roster.getItem(entity)
- if not item or not item.subscriptionTo: #we automatically subscribe to 'to' presence
+ if not item or not item.subscriptionTo: # we automatically subscribe to 'to' presence
debug(_('sending automatic "from" subscription request'))
self.subscribe(entity)
@@ -328,18 +328,18 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile)
def subscribedReceived(self, entity):
- debug (_("subscription approved for [%s]") % entity.userhost())
+ debug(_("subscription approved for [%s]") % entity.userhost())
self.host.bridge.subscribe('subscribed', entity.userhost(), self.parent.profile)
def unsubscribedReceived(self, entity):
- debug (_("unsubscription confirmed for [%s]") % entity.userhost())
+ debug(_("unsubscription confirmed for [%s]") % entity.userhost())
self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile)
def subscribeReceived(self, entity):
- debug (_("subscription request from [%s]") % entity.userhost())
+ debug(_("subscription request from [%s]") % entity.userhost())
item = self.parent.roster.getItem(entity)
if item and item.subscriptionTo:
- #We automatically accept subscription if we are already subscribed to contact presence
+ # We automatically accept subscription if we are already subscribed to contact presence
debug(_('sending automatic subscription acceptance'))
self.subscribed(entity)
else:
@@ -347,27 +347,30 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
self.host.bridge.subscribe('subscribe', entity.userhost(), self.parent.profile)
def unsubscribeReceived(self, entity):
- debug (_("unsubscription asked for [%s]") % entity.userhost())
+ debug(_("unsubscription asked for [%s]") % entity.userhost())
item = self.parent.roster.getItem(entity)
- if item and item.subscriptionFrom: #we automatically remove contact
+ if item and item.subscriptionFrom: # we automatically remove contact
debug(_('automatic contact deletion'))
self.host.delContact(entity.userhost(), self.parent.profile)
self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile)
+
class SatDiscoProtocol(disco.DiscoClientProtocol):
def __init__(self, host):
disco.DiscoClientProtocol.__init__(self)
+
class SatFallbackHandler(generic.FallbackHandler):
def __init__(self, host):
generic.FallbackHandler.__init__(self)
def iqFallback(self, iq):
- if iq.handled == True:
+ if iq.handled is True:
return
- debug (u"iqFallback: xml = [%s]" % (iq.toXml()))
+ debug(u"iqFallback: xml = [%s]" % (iq.toXml()))
generic.FallbackHandler.iqFallback(self, iq)
+
class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
def __init__(self, host, jabber_host, user_login, user_pass, email, answer_id, profile):
@@ -379,7 +382,7 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
self.user_email = email
self.answer_id = answer_id
self.profile = profile
- print _("Registration asked for"),user_login, user_pass, jabber_host
+ print _("Registration asked for"), user_login, user_pass, jabber_host
def connectionMade(self):
print "connectionMade"
@@ -400,25 +403,26 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure)
def registrationAnswer(self, answer):
- debug (_("registration answer: %s") % answer.toXml())
+ debug(_("registration answer: %s") % answer.toXml())
answer_type = "SUCCESS"
- answer_data={"message":_("Registration successfull")}
+ answer_data = {"message": _("Registration successfull")}
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile)
self.xmlstream.sendFooter()
def registrationFailure(self, failure):
- info (_("Registration failure: %s") % str(failure.value))
+ info(_("Registration failure: %s") % str(failure.value))
answer_type = "ERROR"
answer_data = {}
if failure.value.condition == 'conflict':
answer_data['reason'] = 'conflict'
- answer_data={"message":_("Username already exists, please choose an other one")}
+ answer_data = {"message": _("Username already exists, please choose an other one")}
else:
answer_data['reason'] = 'unknown'
- answer_data={"message":_("Registration failed (%s)") % str(failure.value.condition)}
+ answer_data = {"message": _("Registration failed (%s)") % str(failure.value.condition)}
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile)
self.xmlstream.sendFooter()
+
class SatVersionHandler(generic.VersionHandler):
def getDiscoInfo(self, requestor, target, node):
@@ -428,4 +432,3 @@ class SatVersionHandler(generic.VersionHandler):
# disco features, and when the server (seen on ejabberd) generate its own hash for security check
# it reject our features (resulting in e.g. no notification on PEP)
return generic.VersionHandler.getDiscoInfo(self, requestor, target, None)
-