comparison src/plugins/plugin_xep_0054.py @ 993:301b342c697a

core: use of the new core.log module: /!\ this is a massive refactoring and was largely automated, it probably did bring some bugs /!\
author Goffi <goffi@goffi.org>
date Sat, 19 Apr 2014 19:19:19 +0200
parents c6d8fc63b1db
children 7b4600ad73ad
comparison
equal deleted inserted replaced
992:f51a1895275c 993:301b342c697a
18 # You should have received a copy of the GNU Affero General Public License 18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>. 19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 20
21 from sat.core.i18n import _ 21 from sat.core.i18n import _
22 from sat.core.constants import Const as C 22 from sat.core.constants import Const as C
23 from logging import debug, info, error 23 from sat.core.log import getLogger
24 log = getLogger(__name__)
24 from twisted.internet import threads, defer 25 from twisted.internet import threads, defer
25 from twisted.words.protocols.jabber import jid 26 from twisted.words.protocols.jabber import jid
26 from twisted.words.protocols.jabber.xmlstream import IQ 27 from twisted.words.protocols.jabber.xmlstream import IQ
27 from twisted.words.xish import domish 28 from twisted.words.xish import domish
28 from twisted.python.failure import Failure 29 from twisted.python.failure import Failure
70 #TODO: - check that nickname is ok 71 #TODO: - check that nickname is ok
71 # - refactor the code/better use of Wokkel 72 # - refactor the code/better use of Wokkel
72 # - get missing values 73 # - get missing values
73 74
74 def __init__(self, host): 75 def __init__(self, host):
75 info(_("Plugin XEP_0054 initialization")) 76 log.info(_("Plugin XEP_0054 initialization"))
76 self.host = host 77 self.host = host
77 self.avatar_path = os.path.join(self.host.memory.getConfig('', 'local_dir'), AVATAR_PATH) 78 self.avatar_path = os.path.join(self.host.memory.getConfig('', 'local_dir'), AVATAR_PATH)
78 if not os.path.exists(self.avatar_path): 79 if not os.path.exists(self.avatar_path):
79 os.makedirs(self.avatar_path) 80 os.makedirs(self.avatar_path)
80 self.avatars_cache = PersistentDict(NS_VCARD) 81 self.avatars_cache = PersistentDict(NS_VCARD)
139 140
140 def save_photo(self, photo_xml): 141 def save_photo(self, photo_xml):
141 """Parse a <PHOTO> elem and save the picture""" 142 """Parse a <PHOTO> elem and save the picture"""
142 for elem in photo_xml.elements(): 143 for elem in photo_xml.elements():
143 if elem.name == 'TYPE': 144 if elem.name == 'TYPE':
144 info(_('Photo of type [%s] found') % str(elem)) 145 log.info(_('Photo of type [%s] found') % str(elem))
145 if elem.name == 'BINVAL': 146 if elem.name == 'BINVAL':
146 debug(_('Decoding binary')) 147 log.debug(_('Decoding binary'))
147 decoded = b64decode(str(elem)) 148 decoded = b64decode(str(elem))
148 image_hash = sha1(decoded).hexdigest() 149 image_hash = sha1(decoded).hexdigest()
149 filename = self.avatar_path + '/' + image_hash 150 filename = self.avatar_path + '/' + image_hash
150 if not os.path.exists(filename): 151 if not os.path.exists(filename):
151 with open(filename, 'wb') as file: 152 with open(filename, 'wb') as file:
152 file.write(decoded) 153 file.write(decoded)
153 debug(_("file saved to %s") % image_hash) 154 log.debug(_("file saved to %s") % image_hash)
154 else: 155 else:
155 debug(_("file [%s] already in cache") % image_hash) 156 log.debug(_("file [%s] already in cache") % image_hash)
156 return image_hash 157 return image_hash
157 158
158 @defer.inlineCallbacks 159 @defer.inlineCallbacks
159 def vCard2Dict(self, vcard, target, profile): 160 def vCard2Dict(self, vcard, target, profile):
160 """Convert a VCard to a dict, and save binaries""" 161 """Convert a VCard to a dict, and save binaries"""
161 debug(_("parsing vcard")) 162 log.debug(_("parsing vcard"))
162 dictionary = {} 163 dictionary = {}
163 164
164 for elem in vcard.elements(): 165 for elem in vcard.elements():
165 if elem.name == 'FN': 166 if elem.name == 'FN':
166 dictionary['fullname'] = unicode(elem) 167 dictionary['fullname'] = unicode(elem)
178 if not dictionary["avatar"]: # can happen in case of e.g. empty photo elem 179 if not dictionary["avatar"]: # can happen in case of e.g. empty photo elem
179 del dictionary['avatar'] 180 del dictionary['avatar']
180 else: 181 else:
181 self.update_cache(target, 'avatar', dictionary['avatar'], profile) 182 self.update_cache(target, 'avatar', dictionary['avatar'], profile)
182 else: 183 else:
183 info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name) 184 log.info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
184 185
185 defer.returnValue(dictionary) 186 defer.returnValue(dictionary)
186 187
187 def vcard_ok(self, answer, profile): 188 def vcard_ok(self, answer, profile):
188 """Called after the first get IQ""" 189 """Called after the first get IQ"""
189 debug(_("VCard found")) 190 log.debug(_("VCard found"))
190 191
191 if answer.firstChildElement().name == "vCard": 192 if answer.firstChildElement().name == "vCard":
192 _jid, steam = self.host.getJidNStream(profile) 193 _jid, steam = self.host.getJidNStream(profile)
193 try: 194 try:
194 from_jid = jid.JID(answer["from"]) 195 from_jid = jid.JID(answer["from"])
195 except KeyError: 196 except KeyError:
196 from_jid = _jid.userhostJID() 197 from_jid = _jid.userhostJID()
197 d = self.vCard2Dict(answer.firstChildElement(), from_jid, profile) 198 d = self.vCard2Dict(answer.firstChildElement(), from_jid, profile)
198 d.addCallback(lambda data: self.host.bridge.actionResult("RESULT", answer['id'], data, profile)) 199 d.addCallback(lambda data: self.host.bridge.actionResult("RESULT", answer['id'], data, profile))
199 else: 200 else:
200 error(_("FIXME: vCard not found as first child element")) 201 log.error(_("FIXME: vCard not found as first child element"))
201 self.host.bridge.actionResult("SUPPRESS", answer['id'], {}, profile) # FIXME: maybe an error message would be better 202 self.host.bridge.actionResult("SUPPRESS", answer['id'], {}, profile) # FIXME: maybe an error message would be better
202 203
203 def vcard_err(self, failure, profile): 204 def vcard_err(self, failure, profile):
204 """Called when something is wrong with registration""" 205 """Called when something is wrong with registration"""
205 if failure.value.stanza.hasAttribute("from"): 206 if failure.value.stanza.hasAttribute("from"):
206 error(_("Can't find VCard of %s") % failure.value.stanza['from']) 207 log.error(_("Can't find VCard of %s") % failure.value.stanza['from'])
207 self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}, profile) # FIXME: maybe an error message would be better 208 self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}, profile) # FIXME: maybe an error message would be better
208 209
209 def getCard(self, target_s, profile_key=C.PROF_KEY_NONE): 210 def getCard(self, target_s, profile_key=C.PROF_KEY_NONE):
210 """Ask server for VCard 211 """Ask server for VCard
211 @param target_s: jid from which we want the VCard 212 @param target_s: jid from which we want the VCard
212 @result: id to retrieve the profile""" 213 @result: id to retrieve the profile"""
213 current_jid, xmlstream = self.host.getJidNStream(profile_key) 214 current_jid, xmlstream = self.host.getJidNStream(profile_key)
214 if not xmlstream: 215 if not xmlstream:
215 error(_('Asking vcard for a non-existant or not connected profile')) 216 log.error(_('Asking vcard for a non-existant or not connected profile'))
216 return "" 217 return ""
217 profile = self.host.memory.getProfileName(profile_key) 218 profile = self.host.memory.getProfileName(profile_key)
218 to_jid = jid.JID(target_s) 219 to_jid = jid.JID(target_s)
219 debug(_("Asking for %s's VCard") % to_jid.userhost()) 220 log.debug(_("Asking for %s's VCard") % to_jid.userhost())
220 reg_request = IQ(xmlstream, 'get') 221 reg_request = IQ(xmlstream, 'get')
221 reg_request["from"] = current_jid.full() 222 reg_request["from"] = current_jid.full()
222 reg_request["to"] = to_jid.userhost() 223 reg_request["to"] = to_jid.userhost()
223 reg_request.addElement('vCard', NS_VCARD) 224 reg_request.addElement('vCard', NS_VCARD)
224 reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err, callbackArgs=[profile], errbackArgs=[profile]) 225 reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err, callbackArgs=[profile], errbackArgs=[profile])
229 @param hash: SHA1 hash 230 @param hash: SHA1 hash
230 @return full_path 231 @return full_path
231 """ 232 """
232 filename = self.avatar_path + '/' + avatar_hash 233 filename = self.avatar_path + '/' + avatar_hash
233 if not os.path.exists(filename): 234 if not os.path.exists(filename):
234 error(_("Asking for an uncached avatar [%s]") % avatar_hash) 235 log.error(_("Asking for an uncached avatar [%s]") % avatar_hash)
235 return "" 236 return ""
236 return filename 237 return filename
237 238
238 def _buildSetAvatar(self, vcard_set, filepath): 239 def _buildSetAvatar(self, vcard_set, filepath):
239 try: 240 try:
301 for elem in x_elem.elements(): 302 for elem in x_elem.elements():
302 if elem.name == 'photo': 303 if elem.name == 'photo':
303 _hash = str(elem) 304 _hash = str(elem)
304 old_avatar = self.plugin_parent.get_cache(from_jid, 'avatar', self.parent.profile) 305 old_avatar = self.plugin_parent.get_cache(from_jid, 'avatar', self.parent.profile)
305 if not old_avatar or old_avatar != _hash: 306 if not old_avatar or old_avatar != _hash:
306 debug(_('New avatar found, requesting vcard')) 307 log.debug(_('New avatar found, requesting vcard'))
307 self.plugin_parent.getCard(from_jid.userhost(), self.parent.profile) 308 self.plugin_parent.getCard(from_jid.userhost(), self.parent.profile)