diff 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
line wrap: on
line diff
--- a/sat.tac	Thu Feb 25 17:09:18 2010 +1100
+++ b/sat.tac	Wed Mar 03 17:12:23 2010 +1100
@@ -25,6 +25,7 @@
     'local_dir' : '~/.sat'
 }
 
+
 from twisted.application import internet, service
 from twisted.internet import glib2reactor, protocol, task
 glib2reactor.install()
@@ -49,6 +50,9 @@
 from tools.xml_tools import XMLTools 
 from glob import glob
 
+import gettext
+gettext.install('sat', "i18n", unicode=True)
+
 try:
     from twisted.words.protocols.xmlstream import XMPPHandler
 except ImportError:
@@ -81,13 +85,13 @@
         print "SatXMPPClient"
         client.XMPPClient._authd(self, xmlstream)
         self.__connected=True
-        print "********** [%s] CONNECTED **********" % self.profile
+        info (_("********** [%s] CONNECTED **********") % self.profile)
         self.streamInitialized()
         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")
+        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)
         
@@ -107,11 +111,11 @@
     
     def connectionLost(self, connector, unused_reason):
         self.__connected=False
-        print "********** [%s] DISCONNECTED **********" % self.profile
+        info (_("********** [%s] DISCONNECTED **********") % self.profile)
         try:
             self.keep_alife.stop()
         except AttributeError:
-            debug("No keep_alife")
+            debug (_("No keep_alife"))
         self.host_app.bridge.disconnected(self.profile) #we send the signal to the clients
 
 
@@ -122,7 +126,7 @@
         self.host = host
 
     def onMessage(self, message):
-      debug (u"got_message from: %s", message["from"])
+      debug (_(u"got message from: %s"), message["from"])
       for e in message.elements():
         if e.name == "body":
           type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs
@@ -164,14 +168,14 @@
                      }
         if item.name:
             item_attr['name'] = item.name
-        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)
         self.host.bridge.newContact(item.jid.full(), item_attr, item.groups, self.parent.profile)
     
     def onRosterRemove(self, entity):
         """Called when a roster removal event is received"""
         #TODO: send a signal to frontends
-        print "removing %s from roster list" % entity.full()
+        print _("removing %s from roster list") % entity.full()
         self.host.memory.delContact(entity, self.parent.profile)
 
 class SatPresenceProtocol(xmppim.PresenceClientProtocol):
@@ -181,7 +185,7 @@
         self.host = host
     
     def availableReceived(self, entity, show=None, statuses=None, priority=0):
-        info ("presence update for [%s]", entity)
+        info (_("presence update for [%s]"), entity)
         
         if statuses.has_key(None):   #we only want string keys
             statuses["default"] = statuses[None]
@@ -211,22 +215,22 @@
         xmppim.PresenceClientProtocol.available(self, entity, show, statuses, priority)
     
     def subscribedReceived(self, entity):
-        debug ("subscription approved for [%s]" % entity.userhost())
+        debug (_("subscription approved for [%s]") % entity.userhost())
         self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile)
         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.memory.delWaitingSub(entity.userhost(), self.parent.profile)
         self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile)
 
     def subscribeReceived(self, entity):
-        debug ("subscription request for [%s]" % entity.userhost())
+        debug (_("subscription request for [%s]") % entity.userhost())
         self.host.memory.addWaitingSub('subscribe', entity.userhost(), self.parent.profile)
         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())
         self.host.memory.addWaitingSub('unsubscribe', entity.userhost(), self.parent.profile)
         self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile)
 
@@ -252,7 +256,7 @@
         self.user_login = user_login
         self.user_pass = user_pass
         self.answer_id = answer_id
-        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"
@@ -270,22 +274,22 @@
         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.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.xmlstream.sendFooter()
         
@@ -298,14 +302,14 @@
     def get_const(self, name):
         """Return a constant"""
         if not CONST.has_key(name):
-            error('Trying to access an undefined constant')
+            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):
-            error('Trying to redefine a constant')
+            error(_('Trying to redefine a constant'))
             raise Exception  
         CONST[name] = value
     
@@ -366,7 +370,7 @@
             __import__(plug_path)
             mod = sys.modules[plug_path]
             plug_info = mod.PLUGIN_INFO
-            info ("importing plugin: %s", plug_info['name'])
+            info (_("importing plugin: %s"), plug_info['name'])
             self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self)
             if plug_info.has_key('handler') and plug_info['handler'] == 'yes':
                 self.plugins[plug_info['import_name']].is_handler = True
@@ -380,11 +384,11 @@
 
         profile = self.memory.getProfileName(profile_key)
         if not profile_key:
-            error ('Trying to connect a non-exsitant profile')
+            error (_('Trying to connect a non-exsitant profile'))
             return
         
         if (self.isConnected()):
-            info("already connected !")
+            info(_("already connected !"))
             return
         print "connecting..."
         current = self.profiles[profile] = SatXMPPClient(self, profile,
@@ -408,7 +412,7 @@
                                                      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:
@@ -419,10 +423,10 @@
     def disconnect(self, profile_key='@DEFAULT@'):
         """disconnect from jabber server"""
         if (not self.isConnected(profile_key)):
-            info("not connected !")
+            info(_("not connected !"))
             return
         profile = self.memory.getProfileName(profile_key)
-        info("Disconnecting...")
+        info(_("Disconnecting..."))
         self.profiles[profile].stopService()
 
     def startService(self):
@@ -434,11 +438,11 @@
         info("Salut aussi à Rantanplan")
 
     def run(self):
-        debug("running app")
+        debug(_("running app"))
         reactor.run()
     
     def stop(self):
-        debug("stopping app")
+        debug(_("stopping app"))
         reactor.stop()
         
     ## Misc methods ##
@@ -476,16 +480,16 @@
         server = self.memory.getParamA("Server", "Connection")
 
         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."})
+            self.actionResult(id, "ERROR", {'message':_("No user, password or server given, can't register new account.")})
             return
 
         confirm_id = sat_next_id()
         self.__private_data[confirm_id]=id
     
         self.askConfirmation(confirm_id, "YES/NO",
-            {"message":"Are you sure to register new account [%s] to server %s ?" % (user, server)},
+            {"message":_("Are you sure to register new account [%(user)s] to server %(server)s ?") % {'user':user, 'server':server}},
             self.regisConfirmCB)
         print ("===============+++++++++++ REGISTER NEW ACCOUNT++++++++++++++============")
         print "id=",id
@@ -493,7 +497,7 @@
 
     def regisConfirmCB(self, id, accepted, data):
         #FIXME: gof: profile not managed here !
-        print "register Confirmation CB ! (%s)" % str(accepted)
+        print _("register Confirmation CB ! (%s)") % str(accepted)
         action_id = self.__private_data[id]
         del self.__private_data[id]
         user = jid.parse(self.memory.getParamA("JabberID", "Connection"))[0]
@@ -525,7 +529,7 @@
         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)
@@ -535,7 +539,7 @@
 
     def setParam(self, name, value, category, profile_key='@DEFAULT@'):
         """set wanted paramater and notice observers"""
-        info ("setting param: %s=%s in category %s", name, value, 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='@DEFAULT@'):
@@ -545,7 +549,7 @@
         """
         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'))
             raise Exception  #TODO: raise a proper exception
         if not self.profiles.has_key(profile):
             return False
@@ -562,13 +566,13 @@
             try:
                 cb_name = self.memory.getParamA(data["name"], data["category"], "callback")
             except KeyError:
-                error ("Incomplete data")
+                error (_("Incomplete data"))
                 return ""
             id = sat_next_id()
             self.callGeneralCB(cb_name, id, data)
             return id
         else:
-            error ("Unknown action type")
+            error (_("Unknown action type"))
             return ""
 
 
@@ -580,7 +584,7 @@
         profile = self.memory.getProfileName(profile_key)
         assert(profile)
         current_jid = self.profiles[profile].jid
-        debug("Sending jabber message to %s...", to)
+        debug(_("Sending jabber message to %s..."), to)
         message = domish.Element(('jabber:client','message'))
         message["to"] = jid.JID(to).full()
         message["from"] = current_jid.full()
@@ -603,14 +607,14 @@
         profile = self.memory.getProfileName(profile_key)
         assert(profile)
         to_jid = jid.JID(raw_jid)
-        debug ('subsciption request [%s] for %s', type, to_jid.full())
+        debug (_('subsciption request [%(type)s] for %(jid)s') % {'type':type, 'jid':to_jid.full()})
         if type=="subscribe":
             self.profiles[profile].presence.subscribe(to_jid)
         elif type=="subscribed":
             self.profiles[profile].subscribed(to_jid)
             contact = self.memory.getContact(to_jid) 
             if not contact or not bool(contact['to']): #we automatically subscribe to 'to' presence
-                debug('sending automatic "to" subscription request')
+                debug(_('sending automatic "to" subscription request'))
                 self.subscription('subscribe', to_jid.userhost())
         elif type=="unsubscribe":
             self.profiles[profile].presence.unsubscribe(to_jid)
@@ -641,10 +645,10 @@
     def serverDisco(self, disco):
         """xep-0030 Discovery Protocol."""
         for feature in disco.features:
-            debug ("Feature found: %s",feature)
+            debug (_("Feature found: %s"),feature)
             self.server_features.append(feature)
         for cat, type in disco.identities:
-            debug ("Identity found: [%s/%s] %s" % (cat, type, disco.identities[(cat,type)]))
+            debug (_("Identity found: [%(category)s/%(type)s] %(identity)s") % {'category':cat, 'type':type, 'identity':disco.identities[(cat,type)]})
 
     
     ## Generic HMI ## 
@@ -664,7 +668,7 @@
         @param data: dictionary of dictionaries
         """
         if type != "DICT_DICT":
-            error("type for actionResultExt must be DICT_DICT, fixing it")
+            error(_("type for actionResultExt must be DICT_DICT, fixing it"))
             type = "DICT_DICT"
         self.bridge.actionResultExt(type, id, data)
 
@@ -678,7 +682,7 @@
         @param cb: callback called with the answer
         """
         if self.__waiting_conf.has_key(id):
-            error ("Attempt to register two callbacks for the same confirmation")
+            error (_("Attempt to register two callbacks for the same confirmation"))
         else:
             self.__waiting_conf[id] = cb
             self.bridge.askConfirmation(type, id, data)
@@ -686,9 +690,9 @@
 
     def confirmationAnswer(self, id, accepted, data):
         """Called by frontends to answer confirmation requests"""
-        debug ("Received confirmation answer for id [%s]: %s", id, "accepted" if accepted else "refused")
+        debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':u("accepted") if accepted else _("refused")})
         if not self.__waiting_conf.has_key(id):
-            error ("Received an unknown confirmation")
+            error (_("Received an unknown confirmation"))
         else:
             cb = self.__waiting_conf[id]
             del self.__waiting_conf[id]
@@ -701,7 +705,7 @@
     def removeProgressCB(self, id):
         """Remove a progress callback"""
         if not self.__progress_cb_map.has_key(id):
-            error ("Trying to remove an unknow progress callback")
+            error (_("Trying to remove an unknow progress callback"))
         else:
             del self.__progress_cb_map[id]
 
@@ -725,7 +729,7 @@
     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")
+            error (_("Trying to remove an unknow general callback"))
         else:
             del self.__general_cb_map[name]
 
@@ -734,7 +738,7 @@
         try:
             return self.__general_cb_map[name](*args, **kwargs)
         except KeyError:
-            error("Trying to call unknown function")
+            error(_("Trying to call unknown function"))
             return None
 
 application = service.Application('SàT')