Mercurial > libervia-backend
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() |