comparison src/plugins/plugin_xep_0234.py @ 1585:846a39900fa6

plugins XEP-0096, XEP-0260, file: sendFile method is managed by file plugin, which choose the best available method + progress_id fix
author Goffi <goffi@goffi.org>
date Sat, 14 Nov 2015 19:18:05 +0100
parents 833bdb227b16
children b144babc2658
comparison
equal deleted inserted replaced
1584:b57b4683dc33 1585:846a39900fa6
47 } 47 }
48 48
49 49
50 class XEP_0234(object): 50 class XEP_0234(object):
51 # TODO: assure everything is closed when file is sent or session terminate is received 51 # TODO: assure everything is closed when file is sent or session terminate is received
52 # TODO: call self._f.unregister when unloading order will be managing (i.e. when depenencies will be unloaded at the end)
52 53
53 def __init__(self, host): 54 def __init__(self, host):
54 log.info(_("plugin Jingle File Transfer initialization")) 55 log.info(_("plugin Jingle File Transfer initialization"))
55 self.host = host 56 self.host = host
56 self._j = host.plugins["XEP-0166"] # shortcut to access jingle 57 self._j = host.plugins["XEP-0166"] # shortcut to access jingle
57 self._j.registerApplication(NS_JINGLE_FT, self) 58 self._j.registerApplication(NS_JINGLE_FT, self)
58 self._f = host.plugins["FILE"] 59 self._f = host.plugins["FILE"]
60 self._f.register(NS_JINGLE_FT, self.fileJingleSend, priority = 10000, method_name=u"Jingle")
59 host.bridge.addMethod("fileJingleSend", ".plugin", in_sign='sssss', out_sign='', method=self._fileJingleSend) 61 host.bridge.addMethod("fileJingleSend", ".plugin", in_sign='sssss', out_sign='', method=self._fileJingleSend)
60 62
61 def getHandler(self, profile): 63 def getHandler(self, profile):
62 return XEP_0234_handler() 64 return XEP_0234_handler()
63 65
66 def _getProgressId(self, session, content_name):
67 """Return a unique progress ID
68
69 @param session(dict): jingle session
70 @param content_name(unicode): name of the content
71 @return (unicode): unique progress id
72 """
73 return u'{}_{}'.format(session['id'], content_name)
74
64 def _fileJingleSend(self, peer_jid, filepath, name="", file_desc="", profile=C.PROF_KEY_NONE): 75 def _fileJingleSend(self, peer_jid, filepath, name="", file_desc="", profile=C.PROF_KEY_NONE):
65 return self.fileJingleSend(jid.JID(peer_jid), filepath, name or None, file_desc or None, profile) 76 return self.fileJingleSend(jid.JID(peer_jid), filepath, name or None, file_desc or None, profile)
66 77
67 def fileJingleSend(self, peer_jid, filepath, name=None, file_desc=None, profile=C.PROF_KEY_NONE): 78 def fileJingleSend(self, peer_jid, filepath, name, file_desc=None, profile=C.PROF_KEY_NONE):
79 """Send a file using jingle file transfer
80
81 @param peer_jid(jid.JID): destinee jid
82 @param filepath(str): absolute path of the file
83 @param name(unicode, None): name of the file
84 @param file_desc(unicode, None): description of the file
85 @param profile: %(doc_profile)s
86 @return (D(unicode)): progress id
87 """
88 progress_id_d = defer.Deferred()
68 self._j.initiate(peer_jid, 89 self._j.initiate(peer_jid,
69 [{'app_ns': NS_JINGLE_FT, 90 [{'app_ns': NS_JINGLE_FT,
70 'senders': self._j.ROLE_INITIATOR, 91 'senders': self._j.ROLE_INITIATOR,
71 'app_kwargs': {'filepath': filepath, 92 'app_kwargs': {'filepath': filepath,
72 'name': name, 93 'name': name,
73 'file_desc': file_desc}, 94 'file_desc': file_desc,
95 'progress_id_d': progress_id_d},
74 }], 96 }],
75 profile=profile) 97 profile=profile)
98 return progress_id_d
76 99
77 # jingle callbacks 100 # jingle callbacks
78 101
79 def jingleSessionInit(self, session, content_name, filepath, name=None, file_desc=None, profile=C.PROF_KEY_NONE): 102 def jingleSessionInit(self, session, content_name, filepath, name, file_desc, progress_id_d, profile=C.PROF_KEY_NONE):
103 progress_id_d.callback(self.getProgressId(session, content_name))
80 content_data = session['contents'][content_name] 104 content_data = session['contents'][content_name]
81 application_data = content_data['application_data'] 105 application_data = content_data['application_data']
82 assert 'file_path' not in application_data 106 assert 'file_path' not in application_data
83 application_data['file_path'] = filepath 107 application_data['file_path'] = filepath
84 file_data = application_data['file_data'] = {} 108 file_data = application_data['file_data'] = {}
104 # first we grab file informations 128 # first we grab file informations
105 try: 129 try:
106 file_elt = desc_elt.elements(NS_JINGLE_FT, 'file').next() 130 file_elt = desc_elt.elements(NS_JINGLE_FT, 'file').next()
107 except StopIteration: 131 except StopIteration:
108 raise failure.Failure(exceptions.DataError) 132 raise failure.Failure(exceptions.DataError)
109 file_data = {} 133 file_data = {'progress_id': self._getProgressId(session, content_name)}
110 for name in ('date', 'desc', 'media-type', 'name', 'range', 'size'): 134 for name in ('date', 'desc', 'media-type', 'name', 'range', 'size'):
111 try: 135 try:
112 file_data[name] = unicode(file_elt.elements(NS_JINGLE_FT, name).next()) 136 file_data[name] = unicode(file_elt.elements(NS_JINGLE_FT, name).next())
113 except StopIteration: 137 except StopIteration:
114 file_data[name] = '' 138 file_data[name] = ''
157 assert not 'file_obj' in content_data 181 assert not 'file_obj' in content_data
158 file_path = application_data['file_path'] 182 file_path = application_data['file_path']
159 size = application_data['file_data']['size'] 183 size = application_data['file_data']['size']
160 content_data['file_obj'] = self._f.File(self.host, 184 content_data['file_obj'] = self._f.File(self.host,
161 file_path, 185 file_path,
186 uid=self._getProgressId(session, content_name),
162 size=size, 187 size=size,
163 profile=profile 188 profile=profile
164 ) 189 )
165 finished_d = content_data['finished_d'] = defer.Deferred() 190 finished_d = content_data['finished_d'] = defer.Deferred()
166 args = [session, content_name, content_data, profile] 191 args = [session, content_name, content_data, profile]
168 else: 193 else:
169 log.warning(u"FIXME: unmanaged action {}".format(action)) 194 log.warning(u"FIXME: unmanaged action {}".format(action))
170 return desc_elt 195 return desc_elt
171 196
172 def _finishedCb(self, dummy, session, content_name, content_data, profile): 197 def _finishedCb(self, dummy, session, content_name, content_data, profile):
173 log.debug(u"File transfer completed successfuly") 198 log.info(u"File transfer completed successfuly")
174 if content_data['senders'] != session['role']: 199 if content_data['senders'] != session['role']:
175 # we terminate the session only if we are the received, 200 # we terminate the session only if we are the received,
176 # as recommanded in XEP-0234 §2 (after example 6) 201 # as recommanded in XEP-0234 §2 (after example 6)
177 self._j.contentTerminate(session, content_name, profile=profile) 202 self._j.contentTerminate(session, content_name, profile=profile)
178 content_data['file_obj'].close() 203 content_data['file_obj'].close()