comparison plugins/plugin_xep_0054.py @ 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 8147b4f40809
children f271fff3a713
comparison
equal deleted inserted replaced
68:9b842086d915 69:86f1f7f6d332
57 "type": "XEP", 57 "type": "XEP",
58 "protocols": ["XEP-0054", "XEP-0153"], 58 "protocols": ["XEP-0054", "XEP-0153"],
59 "dependencies": [], 59 "dependencies": [],
60 "main": "XEP_0054", 60 "main": "XEP_0054",
61 "handler": "yes", 61 "handler": "yes",
62 "description": """Implementation of vcard-temp""" 62 "description": _("""Implementation of vcard-temp""")
63 } 63 }
64 64
65 class XEP_0054(): 65 class XEP_0054():
66 66
67 def __init__(self, host): 67 def __init__(self, host):
68 info("Plugin XEP_0054 initialization") 68 info(_("Plugin XEP_0054 initialization"))
69 self.host = host 69 self.host = host
70 self.avatar_path = os.path.expanduser(self.host.get_const('local_dir') + AVATAR_PATH) 70 self.avatar_path = os.path.expanduser(self.host.get_const('local_dir') + AVATAR_PATH)
71 self.vcard_cache = host.memory.getPrivate("vcard_cache") or {} #used to store nicknames and avatar, key = jid 71 self.vcard_cache = host.memory.getPrivate("vcard_cache") or {} #used to store nicknames and avatar, key = jid
72 if not os.path.exists(self.avatar_path): 72 if not os.path.exists(self.avatar_path):
73 os.makedirs(self.avatar_path) 73 os.makedirs(self.avatar_path)
106 106
107 def save_photo(self, photo_xml): 107 def save_photo(self, photo_xml):
108 """Parse a <PHOTO> elem and save the picture""" 108 """Parse a <PHOTO> elem and save the picture"""
109 for elem in photo_xml.elements(): 109 for elem in photo_xml.elements():
110 if elem.name == 'TYPE': 110 if elem.name == 'TYPE':
111 info('Photo of type [%s] found' % str(elem)) 111 info(_('Photo of type [%s] found') % str(elem))
112 if elem.name == 'BINVAL': 112 if elem.name == 'BINVAL':
113 debug('Decoding binary') 113 debug(_('Decoding binary'))
114 decoded = b64decode(str(elem)) 114 decoded = b64decode(str(elem))
115 hash = sha1(decoded).hexdigest() 115 hash = sha1(decoded).hexdigest()
116 filename = self.avatar_path+'/'+hash 116 filename = self.avatar_path+'/'+hash
117 if not os.path.exists(filename): 117 if not os.path.exists(filename):
118 with open(filename,'wb') as file: 118 with open(filename,'wb') as file:
119 file.write(decoded) 119 file.write(decoded)
120 debug("file saved to %s" % hash) 120 debug(_("file saved to %s") % hash)
121 else: 121 else:
122 debug("file [%s] already in cache" % hash) 122 debug(_("file [%s] already in cache") % hash)
123 return hash 123 return hash
124 124
125 @defer.deferredGenerator 125 @defer.deferredGenerator
126 def vCard2Dict(self, vcard, target): 126 def vCard2Dict(self, vcard, target):
127 """Convert a VCard to a dict, and save binaries""" 127 """Convert a VCard to a dict, and save binaries"""
128 debug ("parsing vcard") 128 debug (_("parsing vcard"))
129 dictionary = {} 129 dictionary = {}
130 d = defer.Deferred() 130 d = defer.Deferred()
131 131
132 for elem in vcard.elements(): 132 for elem in vcard.elements():
133 if elem.name == 'FN': 133 if elem.name == 'FN':
149 if not dictionary["avatar"]: #can happen in case of e.g. empty photo elem 149 if not dictionary["avatar"]: #can happen in case of e.g. empty photo elem
150 del dictionary['avatar'] 150 del dictionary['avatar']
151 else: 151 else:
152 self.update_cache(target, 'avatar', dictionary['avatar']) 152 self.update_cache(target, 'avatar', dictionary['avatar'])
153 else: 153 else:
154 info ('FIXME: [%s] VCard tag is not managed yet' % elem.name) 154 info (_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
155 155
156 yield dictionary 156 yield dictionary
157 157
158 def vcard_ok(self, answer): 158 def vcard_ok(self, answer):
159 """Called after the first get IQ""" 159 """Called after the first get IQ"""
160 debug ("VCard found") 160 debug (_("VCard found"))
161 161
162 if answer.firstChildElement().name == "vCard": 162 if answer.firstChildElement().name == "vCard":
163 d = self.vCard2Dict(answer.firstChildElement(), jid.JID(answer["from"])) 163 d = self.vCard2Dict(answer.firstChildElement(), jid.JID(answer["from"]))
164 d.addCallback(lambda data: self.host.bridge.actionResult("RESULT", answer['id'], data)) 164 d.addCallback(lambda data: self.host.bridge.actionResult("RESULT", answer['id'], data))
165 else: 165 else:
166 error ("FIXME: vCard not found as first child element") 166 error (_("FIXME: vCard not found as first child element"))
167 self.host.bridge.actionResult("SUPPRESS", answer['id'], {}) #FIXME: maybe an error message would be best 167 self.host.bridge.actionResult("SUPPRESS", answer['id'], {}) #FIXME: maybe an error message would be best
168 168
169 def vcard_err(self, failure): 169 def vcard_err(self, failure):
170 """Called when something is wrong with registration""" 170 """Called when something is wrong with registration"""
171 error ("Can't find VCard of %s" % failure.value.stanza['from']) 171 error (_("Can't find VCard of %s") % failure.value.stanza['from'])
172 self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}) #FIXME: maybe an error message would be best 172 self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}) #FIXME: maybe an error message would be best
173 173
174 def getCard(self, target, profile_key='@DEFAULT@'): 174 def getCard(self, target, profile_key='@DEFAULT@'):
175 """Ask server for VCard 175 """Ask server for VCard
176 @param target: jid from which we want the VCard 176 @param target: jid from which we want the VCard
177 @result: id to retrieve the profile""" 177 @result: id to retrieve the profile"""
178 current_jid, xmlstream = self.host.getJidNStream(profile_key) 178 current_jid, xmlstream = self.host.getJidNStream(profile_key)
179 if not xmlstream: 179 if not xmlstream:
180 error ('Asking profile for an non-existant or not connected profile') 180 error (_('Asking vcard for an non-existant or not connected profile'))
181 return "" 181 return ""
182 to_jid = jid.JID(target) 182 to_jid = jid.JID(target)
183 debug("Asking for %s's VCard" % to_jid.userhost()) 183 debug(_("Asking for %s's VCard") % to_jid.userhost())
184 reg_request=IQ(xmlstream,'get') 184 reg_request=IQ(xmlstream,'get')
185 reg_request["from"]=current_jid.full() 185 reg_request["from"]=current_jid.full()
186 reg_request["to"] = to_jid.userhost() 186 reg_request["to"] = to_jid.userhost()
187 query=reg_request.addElement('vCard', NS_VCARD) 187 query=reg_request.addElement('vCard', NS_VCARD)
188 reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err) 188 reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err)
193 @param hash: SHA1 hash 193 @param hash: SHA1 hash
194 @return full_path 194 @return full_path
195 """ 195 """
196 filename = self.avatar_path+'/'+hash 196 filename = self.avatar_path+'/'+hash
197 if not os.path.exists(filename): 197 if not os.path.exists(filename):
198 error ("Asking for an uncached avatar [%s]" % hash) 198 error (_("Asking for an uncached avatar [%s]") % hash)
199 return "" 199 return ""
200 return filename 200 return filename
201 201
202 def getCardCache(self, target): 202 def getCardCache(self, target):
203 """Request for cached values of profile 203 """Request for cached values of profile
240 for elem in x_elem.elements(): 240 for elem in x_elem.elements():
241 if elem.name == 'photo': 241 if elem.name == 'photo':
242 hash = str(elem) 242 hash = str(elem)
243 old_avatar = self.plugin_parent.get_cache(to_jid, 'avatar') 243 old_avatar = self.plugin_parent.get_cache(to_jid, 'avatar')
244 if not old_avatar or old_avatar != hash: 244 if not old_avatar or old_avatar != hash:
245 debug('New avatar found, requesting vcard') 245 debug(_('New avatar found, requesting vcard'))
246 self.plugin_parent.getCard(to_jid.userhost(), self.parent.profile) 246 self.plugin_parent.getCard(to_jid.userhost(), self.parent.profile)