Mercurial > libervia-backend
comparison sat.tac @ 69:86f1f7f6d332
i18n first draft
- gettext support added in SàT
- first draft of french translation
- added README with a HOWTO for translators
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 03 Mar 2010 17:12:23 +1100 |
parents | 9b842086d915 |
children | f271fff3a713 |
comparison
equal
deleted
inserted
replaced
68:9b842086d915 | 69:86f1f7f6d332 |
---|---|
23 'client_name' : u'SàT (Salut à toi)', | 23 'client_name' : u'SàT (Salut à toi)', |
24 'client_version' : u'0.0.2D', #Please add 'D' at the end for dev versions | 24 'client_version' : u'0.0.2D', #Please add 'D' at the end for dev versions |
25 'local_dir' : '~/.sat' | 25 'local_dir' : '~/.sat' |
26 } | 26 } |
27 | 27 |
28 | |
28 from twisted.application import internet, service | 29 from twisted.application import internet, service |
29 from twisted.internet import glib2reactor, protocol, task | 30 from twisted.internet import glib2reactor, protocol, task |
30 glib2reactor.install() | 31 glib2reactor.install() |
31 | 32 |
32 from twisted.words.protocols.jabber import jid, xmlstream | 33 from twisted.words.protocols.jabber import jid, xmlstream |
46 import os.path | 47 import os.path |
47 | 48 |
48 from tools.memory import Memory | 49 from tools.memory import Memory |
49 from tools.xml_tools import XMLTools | 50 from tools.xml_tools import XMLTools |
50 from glob import glob | 51 from glob import glob |
52 | |
53 import gettext | |
54 gettext.install('sat', "i18n", unicode=True) | |
51 | 55 |
52 try: | 56 try: |
53 from twisted.words.protocols.xmlstream import XMPPHandler | 57 from twisted.words.protocols.xmlstream import XMPPHandler |
54 except ImportError: | 58 except ImportError: |
55 from wokkel.subprotocols import XMPPHandler | 59 from wokkel.subprotocols import XMPPHandler |
79 | 83 |
80 def _authd(self, xmlstream): | 84 def _authd(self, xmlstream): |
81 print "SatXMPPClient" | 85 print "SatXMPPClient" |
82 client.XMPPClient._authd(self, xmlstream) | 86 client.XMPPClient._authd(self, xmlstream) |
83 self.__connected=True | 87 self.__connected=True |
84 print "********** [%s] CONNECTED **********" % self.profile | 88 info (_("********** [%s] CONNECTED **********") % self.profile) |
85 self.streamInitialized() | 89 self.streamInitialized() |
86 self.host_app.bridge.connected(self.profile) #we send the signal to the clients | 90 self.host_app.bridge.connected(self.profile) #we send the signal to the clients |
87 | 91 |
88 def streamInitialized(self): | 92 def streamInitialized(self): |
89 """Called after _authd""" | 93 """Called after _authd""" |
90 debug ("XML stream is initialized") | 94 debug (_("XML stream is initialized")) |
91 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) | 95 self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") #Needed to avoid disconnection (specially with openfire) |
92 self.keep_alife.start(180) | 96 self.keep_alife.start(180) |
93 | 97 |
94 self.disco = SatDiscoProtocol(self) | 98 self.disco = SatDiscoProtocol(self) |
95 self.disco.setHandlerParent(self) | 99 self.disco.setHandlerParent(self) |
105 def isConnected(self): | 109 def isConnected(self): |
106 return self.__connected | 110 return self.__connected |
107 | 111 |
108 def connectionLost(self, connector, unused_reason): | 112 def connectionLost(self, connector, unused_reason): |
109 self.__connected=False | 113 self.__connected=False |
110 print "********** [%s] DISCONNECTED **********" % self.profile | 114 info (_("********** [%s] DISCONNECTED **********") % self.profile) |
111 try: | 115 try: |
112 self.keep_alife.stop() | 116 self.keep_alife.stop() |
113 except AttributeError: | 117 except AttributeError: |
114 debug("No keep_alife") | 118 debug (_("No keep_alife")) |
115 self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients | 119 self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients |
116 | 120 |
117 | 121 |
118 class SatMessageProtocol(xmppim.MessageProtocol): | 122 class SatMessageProtocol(xmppim.MessageProtocol): |
119 | 123 |
120 def __init__(self, host): | 124 def __init__(self, host): |
121 xmppim.MessageProtocol.__init__(self) | 125 xmppim.MessageProtocol.__init__(self) |
122 self.host = host | 126 self.host = host |
123 | 127 |
124 def onMessage(self, message): | 128 def onMessage(self, message): |
125 debug (u"got_message from: %s", message["from"]) | 129 debug (_(u"got message from: %s"), message["from"]) |
126 for e in message.elements(): | 130 for e in message.elements(): |
127 if e.name == "body": | 131 if e.name == "body": |
128 type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs | 132 type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs |
129 self.host.bridge.newMessage(message["from"], e.children[0], type, profile=self.parent.profile) | 133 self.host.bridge.newMessage(message["from"], e.children[0], type, profile=self.parent.profile) |
130 self.host.memory.addToHistory(self.parent.jid, jid.JID(message["from"]), self.parent.jid, "chat", e.children[0]) | 134 self.host.memory.addToHistory(self.parent.jid, jid.JID(message["from"]), self.parent.jid, "chat", e.children[0]) |
162 'from': str(item.subscriptionFrom), | 166 'from': str(item.subscriptionFrom), |
163 'ask': str(item.ask) | 167 'ask': str(item.ask) |
164 } | 168 } |
165 if item.name: | 169 if item.name: |
166 item_attr['name'] = item.name | 170 item_attr['name'] = item.name |
167 info ("new contact in roster list: %s", item.jid.full()) | 171 info (_("new contact in roster list: %s"), item.jid.full()) |
168 self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile) | 172 self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile) |
169 self.host.bridge.newContact(item.jid.full(), item_attr, item.groups, self.parent.profile) | 173 self.host.bridge.newContact(item.jid.full(), item_attr, item.groups, self.parent.profile) |
170 | 174 |
171 def onRosterRemove(self, entity): | 175 def onRosterRemove(self, entity): |
172 """Called when a roster removal event is received""" | 176 """Called when a roster removal event is received""" |
173 #TODO: send a signal to frontends | 177 #TODO: send a signal to frontends |
174 print "removing %s from roster list" % entity.full() | 178 print _("removing %s from roster list") % entity.full() |
175 self.host.memory.delContact(entity, self.parent.profile) | 179 self.host.memory.delContact(entity, self.parent.profile) |
176 | 180 |
177 class SatPresenceProtocol(xmppim.PresenceClientProtocol): | 181 class SatPresenceProtocol(xmppim.PresenceClientProtocol): |
178 | 182 |
179 def __init__(self, host): | 183 def __init__(self, host): |
180 xmppim.PresenceClientProtocol.__init__(self) | 184 xmppim.PresenceClientProtocol.__init__(self) |
181 self.host = host | 185 self.host = host |
182 | 186 |
183 def availableReceived(self, entity, show=None, statuses=None, priority=0): | 187 def availableReceived(self, entity, show=None, statuses=None, priority=0): |
184 info ("presence update for [%s]", entity) | 188 info (_("presence update for [%s]"), entity) |
185 | 189 |
186 if statuses.has_key(None): #we only want string keys | 190 if statuses.has_key(None): #we only want string keys |
187 statuses["default"] = statuses[None] | 191 statuses["default"] = statuses[None] |
188 del statuses[None] | 192 del statuses[None] |
189 | 193 |
209 statuses[None] = statuses['default'] | 213 statuses[None] = statuses['default'] |
210 del statuses['default'] | 214 del statuses['default'] |
211 xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority) | 215 xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority) |
212 | 216 |
213 def subscribedReceived(self, entity): | 217 def subscribedReceived(self, entity): |
214 debug ("subscription approved for [%s]" % entity.userhost()) | 218 debug (_("subscription approved for [%s]") % entity.userhost()) |
215 self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) | 219 self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) |
216 self.host.bridge.subscribe('subscribed', entity.userhost(), self.parent.profile) | 220 self.host.bridge.subscribe('subscribed', entity.userhost(), self.parent.profile) |
217 | 221 |
218 def unsubscribedReceived(self, entity): | 222 def unsubscribedReceived(self, entity): |
219 debug ("unsubscription confirmed for [%s]" % entity.userhost()) | 223 debug (_("unsubscription confirmed for [%s]") % entity.userhost()) |
220 self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) | 224 self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile) |
221 self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile) | 225 self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile) |
222 | 226 |
223 def subscribeReceived(self, entity): | 227 def subscribeReceived(self, entity): |
224 debug ("subscription request for [%s]" % entity.userhost()) | 228 debug (_("subscription request for [%s]") % entity.userhost()) |
225 self.host.memory.addWaitingSub('subscribe', entity.userhost(), self.parent.profile) | 229 self.host.memory.addWaitingSub('subscribe', entity.userhost(), self.parent.profile) |
226 self.host.bridge.subscribe('subscribe', entity.userhost(), self.parent.profile) | 230 self.host.bridge.subscribe('subscribe', entity.userhost(), self.parent.profile) |
227 | 231 |
228 def unsubscribeReceived(self, entity): | 232 def unsubscribeReceived(self, entity): |
229 debug ("unsubscription asked for [%s]" % entity.userhost()) | 233 debug (_("unsubscription asked for [%s]") % entity.userhost()) |
230 self.host.memory.addWaitingSub('unsubscribe', entity.userhost(), self.parent.profile) | 234 self.host.memory.addWaitingSub('unsubscribe', entity.userhost(), self.parent.profile) |
231 self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile) | 235 self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile) |
232 | 236 |
233 class SatDiscoProtocol(disco.DiscoClientProtocol): | 237 class SatDiscoProtocol(disco.DiscoClientProtocol): |
234 def __init__(self, host): | 238 def __init__(self, host): |
250 self.host = host | 254 self.host = host |
251 self.jabber_host = jabber_host | 255 self.jabber_host = jabber_host |
252 self.user_login = user_login | 256 self.user_login = user_login |
253 self.user_pass = user_pass | 257 self.user_pass = user_pass |
254 self.answer_id = answer_id | 258 self.answer_id = answer_id |
255 print "Registration asked for",user_login, user_pass, jabber_host | 259 print _("Registration asked for"),user_login, user_pass, jabber_host |
256 | 260 |
257 def connectionMade(self): | 261 def connectionMade(self): |
258 print "connectionMade" | 262 print "connectionMade" |
259 | 263 |
260 self.xmlstream.namespace = "jabber:client" | 264 self.xmlstream.namespace = "jabber:client" |
268 _pass = query.addElement('password') | 272 _pass = query.addElement('password') |
269 _pass.addContent(self.user_pass) | 273 _pass.addContent(self.user_pass) |
270 reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure) | 274 reg = iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure) |
271 | 275 |
272 def registrationAnswer(self, answer): | 276 def registrationAnswer(self, answer): |
273 debug ("registration answer: %s" % answer.toXml()) | 277 debug (_("registration answer: %s") % answer.toXml()) |
274 answer_type = "SUCCESS" | 278 answer_type = "SUCCESS" |
275 answer_data={"message":"Registration successfull"} | 279 answer_data={"message":_("Registration successfull")} |
276 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data) | 280 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data) |
277 self.xmlstream.sendFooter() | 281 self.xmlstream.sendFooter() |
278 | 282 |
279 def registrationFailure(self, failure): | 283 def registrationFailure(self, failure): |
280 info ("Registration failure: %s" % str(failure.value)) | 284 info (_("Registration failure: %s") % str(failure.value)) |
281 answer_type = "ERROR" | 285 answer_type = "ERROR" |
282 answer_data = {} | 286 answer_data = {} |
283 if failure.value.condition == 'conflict': | 287 if failure.value.condition == 'conflict': |
284 answer_data['reason'] = 'conflict' | 288 answer_data['reason'] = 'conflict' |
285 answer_data={"message":"Username already exists, please choose an other one"} | 289 answer_data={"message":_("Username already exists, please choose an other one")} |
286 else: | 290 else: |
287 answer_data['reason'] = 'unknown' | 291 answer_data['reason'] = 'unknown' |
288 answer_data={"message":"Registration failed (%s)" % str(failure.value.condition)} | 292 answer_data={"message":_("Registration failed (%s)") % str(failure.value.condition)} |
289 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data) | 293 self.host.bridge.actionResult(answer_type, self.answer_id, answer_data) |
290 self.xmlstream.sendFooter() | 294 self.xmlstream.sendFooter() |
291 | 295 |
292 | 296 |
293 class SAT(service.Service): | 297 class SAT(service.Service): |
296 return sat_next_id() | 300 return sat_next_id() |
297 | 301 |
298 def get_const(self, name): | 302 def get_const(self, name): |
299 """Return a constant""" | 303 """Return a constant""" |
300 if not CONST.has_key(name): | 304 if not CONST.has_key(name): |
301 error('Trying to access an undefined constant') | 305 error(_('Trying to access an undefined constant')) |
302 raise Exception | 306 raise Exception |
303 return CONST[name] | 307 return CONST[name] |
304 | 308 |
305 def set_const(self, name, value): | 309 def set_const(self, name, value): |
306 """Save a constant""" | 310 """Save a constant""" |
307 if CONST.has_key(name): | 311 if CONST.has_key(name): |
308 error('Trying to redefine a constant') | 312 error(_('Trying to redefine a constant')) |
309 raise Exception | 313 raise Exception |
310 CONST[name] = value | 314 CONST[name] = value |
311 | 315 |
312 def __init__(self): | 316 def __init__(self): |
313 #TODO: standardize callback system | 317 #TODO: standardize callback system |
364 for plug in plug_lst: | 368 for plug in plug_lst: |
365 plug_path = 'plugins.'+plug | 369 plug_path = 'plugins.'+plug |
366 __import__(plug_path) | 370 __import__(plug_path) |
367 mod = sys.modules[plug_path] | 371 mod = sys.modules[plug_path] |
368 plug_info = mod.PLUGIN_INFO | 372 plug_info = mod.PLUGIN_INFO |
369 info ("importing plugin: %s", plug_info['name']) | 373 info (_("importing plugin: %s"), plug_info['name']) |
370 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) | 374 self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self) |
371 if plug_info.has_key('handler') and plug_info['handler'] == 'yes': | 375 if plug_info.has_key('handler') and plug_info['handler'] == 'yes': |
372 self.plugins[plug_info['import_name']].is_handler = True | 376 self.plugins[plug_info['import_name']].is_handler = True |
373 else: | 377 else: |
374 self.plugins[plug_info['import_name']].is_handler = False | 378 self.plugins[plug_info['import_name']].is_handler = False |
378 """Connect to jabber server""" | 382 """Connect to jabber server""" |
379 | 383 |
380 | 384 |
381 profile = self.memory.getProfileName(profile_key) | 385 profile = self.memory.getProfileName(profile_key) |
382 if not profile_key: | 386 if not profile_key: |
383 error ('Trying to connect a non-exsitant profile') | 387 error (_('Trying to connect a non-exsitant profile')) |
384 return | 388 return |
385 | 389 |
386 if (self.isConnected()): | 390 if (self.isConnected()): |
387 info("already connected !") | 391 info(_("already connected !")) |
388 return | 392 return |
389 print "connecting..." | 393 print "connecting..." |
390 current = self.profiles[profile] = SatXMPPClient(self, profile, | 394 current = self.profiles[profile] = SatXMPPClient(self, profile, |
391 jid.JID(self.memory.getParamA("JabberID", "Connection", profile_key = profile_key), profile), | 395 jid.JID(self.memory.getParamA("JabberID", "Connection", profile_key = profile_key), profile), |
392 self.memory.getParamA("Password", "Connection", profile_key = profile_key), | 396 self.memory.getParamA("Password", "Connection", profile_key = profile_key), |
406 | 410 |
407 current.versionHandler = generic.VersionHandler(self.get_const('client_name'), | 411 current.versionHandler = generic.VersionHandler(self.get_const('client_name'), |
408 self.get_const('client_version')) | 412 self.get_const('client_version')) |
409 current.versionHandler.setHandlerParent(current) | 413 current.versionHandler.setHandlerParent(current) |
410 | 414 |
411 debug ("setting plugins parents") | 415 debug (_("setting plugins parents")) |
412 | 416 |
413 for plugin in self.plugins.iteritems(): | 417 for plugin in self.plugins.iteritems(): |
414 if plugin[1].is_handler: | 418 if plugin[1].is_handler: |
415 plugin[1].getHandler().setHandlerParent(current) | 419 plugin[1].getHandler().setHandlerParent(current) |
416 | 420 |
417 current.startService() | 421 current.startService() |
418 | 422 |
419 def disconnect(self, profile_key='@DEFAULT@'): | 423 def disconnect(self, profile_key='@DEFAULT@'): |
420 """disconnect from jabber server""" | 424 """disconnect from jabber server""" |
421 if (not self.isConnected(profile_key)): | 425 if (not self.isConnected(profile_key)): |
422 info("not connected !") | 426 info(_("not connected !")) |
423 return | 427 return |
424 profile = self.memory.getProfileName(profile_key) | 428 profile = self.memory.getProfileName(profile_key) |
425 info("Disconnecting...") | 429 info(_("Disconnecting...")) |
426 self.profiles[profile].stopService() | 430 self.profiles[profile].stopService() |
427 | 431 |
428 def startService(self): | 432 def startService(self): |
429 info("Salut à toi ô mon frère !") | 433 info("Salut à toi ô mon frère !") |
430 self.connect() | 434 self.connect() |
432 def stopService(self): | 436 def stopService(self): |
433 self.memory.save() | 437 self.memory.save() |
434 info("Salut aussi à Rantanplan") | 438 info("Salut aussi à Rantanplan") |
435 | 439 |
436 def run(self): | 440 def run(self): |
437 debug("running app") | 441 debug(_("running app")) |
438 reactor.run() | 442 reactor.run() |
439 | 443 |
440 def stop(self): | 444 def stop(self): |
441 debug("stopping app") | 445 debug(_("stopping app")) |
442 reactor.stop() | 446 reactor.stop() |
443 | 447 |
444 ## Misc methods ## | 448 ## Misc methods ## |
445 | 449 |
446 def getJidNStream(self, profile_key): | 450 def getJidNStream(self, profile_key): |
474 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0] | 478 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0] |
475 password = self.memory.getParamA("Password", "Connection") | 479 password = self.memory.getParamA("Password", "Connection") |
476 server = self.memory.getParamA("Server", "Connection") | 480 server = self.memory.getParamA("Server", "Connection") |
477 | 481 |
478 if not user or not password or not server: | 482 if not user or not password or not server: |
479 info ('No user or server given') | 483 info (_('No user or server given')) |
480 #TODO: a proper error message must be sent to frontend | 484 #TODO: a proper error message must be sent to frontend |
481 self.actionResult(id, "ERROR", {'message':"No user, password or server given, can't register new account."}) | 485 self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")}) |
482 return | 486 return |
483 | 487 |
484 confirm_id = sat_next_id() | 488 confirm_id = sat_next_id() |
485 self.__private_data[confirm_id]=id | 489 self.__private_data[confirm_id]=id |
486 | 490 |
487 self.askConfirmation(confirm_id, "YES/NO", | 491 self.askConfirmation(confirm_id, "YES/NO", |
488 {"message":"Are you sure to register new account [%s] to server %s ?" % (user, server)}, | 492 {"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server}}, |
489 self.regisConfirmCB) | 493 self.regisConfirmCB) |
490 print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============") | 494 print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============") |
491 print "id=",id | 495 print "id=",id |
492 print "data=",data | 496 print "data=",data |
493 | 497 |
494 def regisConfirmCB(self, id, accepted, data): | 498 def regisConfirmCB(self, id, accepted, data): |
495 #FIXME: gof: profile not managed here ! | 499 #FIXME: gof: profile not managed here ! |
496 print "register Confirmation CB ! (%s)" % str(accepted) | 500 print _("register Confirmation CB ! (%s)") % str(accepted) |
497 action_id = self.__private_data[id] | 501 action_id = self.__private_data[id] |
498 del self.__private_data[id] | 502 del self.__private_data[id] |
499 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0] | 503 user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0] |
500 password = self.memory.getParamA("Password", "Connection") | 504 password = self.memory.getParamA("Password", "Connection") |
501 server = self.memory.getParamA("Server", "Connection") | 505 server = self.memory.getParamA("Server", "Connection") |
523 form = XMLTools.tupleList2dataForm(fields) | 527 form = XMLTools.tupleList2dataForm(fields) |
524 query.addChild(form.toElement()) | 528 query.addChild(form.toElement()) |
525 elif action=='CANCEL': | 529 elif action=='CANCEL': |
526 query.addElement('remove') | 530 query.addElement('remove') |
527 else: | 531 else: |
528 error ("FIXME FIXME FIXME: Unmanaged action (%s) in submitForm" % action) | 532 error (_("FIXME FIXME FIXME: Unmanaged action (%s) in submitForm") % action) |
529 raise NotImplementedError | 533 raise NotImplementedError |
530 | 534 |
531 deferred = iq.send(target) | 535 deferred = iq.send(target) |
532 return (iq['id'], deferred) | 536 return (iq['id'], deferred) |
533 | 537 |
534 ## Client management ## | 538 ## Client management ## |
535 | 539 |
536 def setParam(self, name, value, category, profile_key='@DEFAULT@'): | 540 def setParam(self, name, value, category, profile_key='@DEFAULT@'): |
537 """set wanted paramater and notice observers""" | 541 """set wanted paramater and notice observers""" |
538 info ("setting param: %s=%s in category %s", name, value, category) | 542 info (_("setting param: %(name)s=%(value)s in category %(category)s") % {'name':name, 'value':value, 'category':category}) |
539 self.memory.setParam(name, value, category, profile_key) | 543 self.memory.setParam(name, value, category, profile_key) |
540 | 544 |
541 def isConnected(self, profile_key='@DEFAULT@'): | 545 def isConnected(self, profile_key='@DEFAULT@'): |
542 """Return connection status of profile | 546 """Return connection status of profile |
543 @param profile_key: key_word or profile name to determine profile name | 547 @param profile_key: key_word or profile name to determine profile name |
544 @return True if connected | 548 @return True if connected |
545 """ | 549 """ |
546 profile = self.memory.getProfileName(profile_key) | 550 profile = self.memory.getProfileName(profile_key) |
547 if not profile: | 551 if not profile: |
548 error ('asking connection status for a non-existant profile') | 552 error (_('asking connection status for a non-existant profile')) |
549 raise Exception #TODO: raise a proper exception | 553 raise Exception #TODO: raise a proper exception |
550 if not self.profiles.has_key(profile): | 554 if not self.profiles.has_key(profile): |
551 return False | 555 return False |
552 return self.profiles[profile].isConnected() | 556 return self.profiles[profile].isConnected() |
553 | 557 |
560 """ | 564 """ |
561 if type=="button": | 565 if type=="button": |
562 try: | 566 try: |
563 cb_name = self.memory.getParamA(data["name"], data["category"], "callback") | 567 cb_name = self.memory.getParamA(data["name"], data["category"], "callback") |
564 except KeyError: | 568 except KeyError: |
565 error ("Incomplete data") | 569 error (_("Incomplete data")) |
566 return "" | 570 return "" |
567 id = sat_next_id() | 571 id = sat_next_id() |
568 self.callGeneralCB(cb_name, id, data) | 572 self.callGeneralCB(cb_name, id, data) |
569 return id | 573 return id |
570 else: | 574 else: |
571 error ("Unknown action type") | 575 error (_("Unknown action type")) |
572 return "" | 576 return "" |
573 | 577 |
574 | 578 |
575 ## jabber methods ## | 579 ## jabber methods ## |
576 | 580 |
578 print "sendtype=", type #gof | 582 print "sendtype=", type #gof |
579 #FIXME: check validity of recipient | 583 #FIXME: check validity of recipient |
580 profile = self.memory.getProfileName(profile_key) | 584 profile = self.memory.getProfileName(profile_key) |
581 assert(profile) | 585 assert(profile) |
582 current_jid = self.profiles[profile].jid | 586 current_jid = self.profiles[profile].jid |
583 debug("Sending jabber message to %s...", to) | 587 debug(_("Sending jabber message to %s..."), to) |
584 message = domish.Element(('jabber:client','message')) | 588 message = domish.Element(('jabber:client','message')) |
585 message["to"] = jid.JID(to).full() | 589 message["to"] = jid.JID(to).full() |
586 message["from"] = current_jid.full() | 590 message["from"] = current_jid.full() |
587 message["type"] = type | 591 message["type"] = type |
588 message.addElement("body", "jabber:client", msg) | 592 message.addElement("body", "jabber:client", msg) |
601 def subscription(self, type, raw_jid, profile_key='@DEFAULT@'): | 605 def subscription(self, type, raw_jid, profile_key='@DEFAULT@'): |
602 """Called to manage subscription""" | 606 """Called to manage subscription""" |
603 profile = self.memory.getProfileName(profile_key) | 607 profile = self.memory.getProfileName(profile_key) |
604 assert(profile) | 608 assert(profile) |
605 to_jid = jid.JID(raw_jid) | 609 to_jid = jid.JID(raw_jid) |
606 debug ('subsciption request [%s] for %s', type, to_jid.full()) | 610 debug (_('subsciption request [%(type)s] for %(jid)s') % {'type':type, 'jid':to_jid.full()}) |
607 if type=="subscribe": | 611 if type=="subscribe": |
608 self.profiles[profile].presence.subscribe(to_jid) | 612 self.profiles[profile].presence.subscribe(to_jid) |
609 elif type=="subscribed": | 613 elif type=="subscribed": |
610 self.profiles[profile].subscribed(to_jid) | 614 self.profiles[profile].subscribed(to_jid) |
611 contact = self.memory.getContact(to_jid) | 615 contact = self.memory.getContact(to_jid) |
612 if not contact or not bool(contact['to']): #we automatically subscribe to 'to' presence | 616 if not contact or not bool(contact['to']): #we automatically subscribe to 'to' presence |
613 debug('sending automatic "to" subscription request') | 617 debug(_('sending automatic "to" subscription request')) |
614 self.subscription('subscribe', to_jid.userhost()) | 618 self.subscription('subscribe', to_jid.userhost()) |
615 elif type=="unsubscribe": | 619 elif type=="unsubscribe": |
616 self.profiles[profile].presence.unsubscribe(to_jid) | 620 self.profiles[profile].presence.unsubscribe(to_jid) |
617 elif type=="unsubscribed": | 621 elif type=="unsubscribed": |
618 self.profiles[profile].presence.unsubscribed(to_jid) | 622 self.profiles[profile].presence.unsubscribed(to_jid) |
639 ## callbacks ## | 643 ## callbacks ## |
640 | 644 |
641 def serverDisco(self, disco): | 645 def serverDisco(self, disco): |
642 """xep-0030 Discovery Protocol.""" | 646 """xep-0030 Discovery Protocol.""" |
643 for feature in disco.features: | 647 for feature in disco.features: |
644 debug ("Feature found: %s",feature) | 648 debug (_("Feature found: %s"),feature) |
645 self.server_features.append(feature) | 649 self.server_features.append(feature) |
646 for cat, type in disco.identities: | 650 for cat, type in disco.identities: |
647 debug ("Identity found: [%s/%s] %s" % (cat, type, disco.identities[(cat,type)])) | 651 debug (_("Identity found: [%(category)s/%(type)s] %(identity)s") % {'category':cat, 'type':type, 'identity':disco.identities[(cat,type)]}) |
648 | 652 |
649 | 653 |
650 ## Generic HMI ## | 654 ## Generic HMI ## |
651 | 655 |
652 def actionResult(self, id, type, data): | 656 def actionResult(self, id, type, data): |
662 @param id: same id used with action | 666 @param id: same id used with action |
663 @param type: result type /!\ only "DICT_DICT" for this method | 667 @param type: result type /!\ only "DICT_DICT" for this method |
664 @param data: dictionary of dictionaries | 668 @param data: dictionary of dictionaries |
665 """ | 669 """ |
666 if type != "DICT_DICT": | 670 if type != "DICT_DICT": |
667 error("type for actionResultExt must be DICT_DICT, fixing it") | 671 error(_("type for actionResultExt must be DICT_DICT, fixing it")) |
668 type = "DICT_DICT" | 672 type = "DICT_DICT" |
669 self.bridge.actionResultExt(type, id, data) | 673 self.bridge.actionResultExt(type, id, data) |
670 | 674 |
671 | 675 |
672 | 676 |
676 @param type: confirmation type ("YES/NO", "FILE_TRANSFERT") | 680 @param type: confirmation type ("YES/NO", "FILE_TRANSFERT") |
677 @param data: data (depend of confirmation type) | 681 @param data: data (depend of confirmation type) |
678 @param cb: callback called with the answer | 682 @param cb: callback called with the answer |
679 """ | 683 """ |
680 if self.__waiting_conf.has_key(id): | 684 if self.__waiting_conf.has_key(id): |
681 error ("Attempt to register two callbacks for the same confirmation") | 685 error (_("Attempt to register two callbacks for the same confirmation")) |
682 else: | 686 else: |
683 self.__waiting_conf[id] = cb | 687 self.__waiting_conf[id] = cb |
684 self.bridge.askConfirmation(type, id, data) | 688 self.bridge.askConfirmation(type, id, data) |
685 | 689 |
686 | 690 |
687 def confirmationAnswer(self, id, accepted, data): | 691 def confirmationAnswer(self, id, accepted, data): |
688 """Called by frontends to answer confirmation requests""" | 692 """Called by frontends to answer confirmation requests""" |
689 debug ("Received confirmation answer for id [%s]: %s", id, "accepted" if accepted else "refused") | 693 debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':u("accepted") if accepted else _("refused")}) |
690 if not self.__waiting_conf.has_key(id): | 694 if not self.__waiting_conf.has_key(id): |
691 error ("Received an unknown confirmation") | 695 error (_("Received an unknown confirmation")) |
692 else: | 696 else: |
693 cb = self.__waiting_conf[id] | 697 cb = self.__waiting_conf[id] |
694 del self.__waiting_conf[id] | 698 del self.__waiting_conf[id] |
695 cb(id, accepted, data) | 699 cb(id, accepted, data) |
696 | 700 |
699 self.__progress_cb_map[id] = CB | 703 self.__progress_cb_map[id] = CB |
700 | 704 |
701 def removeProgressCB(self, id): | 705 def removeProgressCB(self, id): |
702 """Remove a progress callback""" | 706 """Remove a progress callback""" |
703 if not self.__progress_cb_map.has_key(id): | 707 if not self.__progress_cb_map.has_key(id): |
704 error ("Trying to remove an unknow progress callback") | 708 error (_("Trying to remove an unknow progress callback")) |
705 else: | 709 else: |
706 del self.__progress_cb_map[id] | 710 del self.__progress_cb_map[id] |
707 | 711 |
708 def getProgress(self, id): | 712 def getProgress(self, id): |
709 """Return a dict with progress information | 713 """Return a dict with progress information |
723 self.__general_cb_map[name] = CB | 727 self.__general_cb_map[name] = CB |
724 | 728 |
725 def removeGeneralCB(self, name): | 729 def removeGeneralCB(self, name): |
726 """Remove a general callback""" | 730 """Remove a general callback""" |
727 if not self.__general_cb_map.has_key(name): | 731 if not self.__general_cb_map.has_key(name): |
728 error ("Trying to remove an unknow general callback") | 732 error (_("Trying to remove an unknow general callback")) |
729 else: | 733 else: |
730 del self.__general_cb_map[name] | 734 del self.__general_cb_map[name] |
731 | 735 |
732 def callGeneralCB(self, name, *args, **kwargs): | 736 def callGeneralCB(self, name, *args, **kwargs): |
733 """Call general function back""" | 737 """Call general function back""" |
734 try: | 738 try: |
735 return self.__general_cb_map[name](*args, **kwargs) | 739 return self.__general_cb_map[name](*args, **kwargs) |
736 except KeyError: | 740 except KeyError: |
737 error("Trying to call unknown function") | 741 error(_("Trying to call unknown function")) |
738 return None | 742 return None |
739 | 743 |
740 application = service.Application('SàT') | 744 application = service.Application('SàT') |
741 service = SAT() | 745 service = SAT() |
742 service.setServiceParent(application) | 746 service.setServiceParent(application) |