Mercurial > libervia-backend
comparison src/plugins/plugin_comp_file_sharing.py @ 2528:65e278997715
component file sharing: comments metadata:
new <comments> element is added to file metadata, it contains the URL to the comments virtual node and the count of comments (this way client knows if it make sense to request comments or not).
Fixed triggers in plugin XEP-0264 (return value was missing).
New trigger in plugin XEP-0329 to allow component to add metadata (used here for comments url).
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 16 Mar 2018 18:43:11 +0100 |
parents | a201194fc461 |
children | cbbf2ff2ef3f |
comparison
equal
deleted
inserted
replaced
2527:a201194fc461 | 2528:65e278997715 |
---|---|
21 from sat.core.constants import Const as C | 21 from sat.core.constants import Const as C |
22 from sat.core import exceptions | 22 from sat.core import exceptions |
23 from sat.core.log import getLogger | 23 from sat.core.log import getLogger |
24 log = getLogger(__name__) | 24 log = getLogger(__name__) |
25 from sat.tools.common import regex | 25 from sat.tools.common import regex |
26 from sat.tools.common import uri | |
26 from sat.tools import stream | 27 from sat.tools import stream |
27 from twisted.internet import defer | 28 from twisted.internet import defer |
28 from twisted.words.protocols.jabber import error | 29 from twisted.words.protocols.jabber import error |
29 from wokkel import pubsub | 30 from wokkel import pubsub |
30 from wokkel import generic | 31 from wokkel import generic |
46 C.PI_HANDLER: C.BOOL_TRUE, | 47 C.PI_HANDLER: C.BOOL_TRUE, |
47 C.PI_DESCRIPTION: _(u"""Component hosting and sharing files""") | 48 C.PI_DESCRIPTION: _(u"""Component hosting and sharing files""") |
48 } | 49 } |
49 | 50 |
50 HASH_ALGO = u'sha-256' | 51 HASH_ALGO = u'sha-256' |
52 NS_COMMENTS = 'org.salut-a-toi.comments' | |
51 COMMENT_NODE_PREFIX = 'org.salut-a-toi.file_comments/' | 53 COMMENT_NODE_PREFIX = 'org.salut-a-toi.file_comments/' |
52 | 54 |
53 | 55 |
54 class FileSharing(object): | 56 class FileSharing(object): |
55 | 57 |
60 self._jf = host.plugins['XEP-0234'] | 62 self._jf = host.plugins['XEP-0234'] |
61 self._h = host.plugins['XEP-0300'] | 63 self._h = host.plugins['XEP-0300'] |
62 self._t = host.plugins['XEP-0264'] | 64 self._t = host.plugins['XEP-0264'] |
63 host.trigger.add("FILE_getDestDir", self._getDestDirTrigger) | 65 host.trigger.add("FILE_getDestDir", self._getDestDirTrigger) |
64 host.trigger.add("XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000) | 66 host.trigger.add("XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000) |
67 host.trigger.add("XEP-0234_buildFileElement", self._addFileComments) | |
68 host.trigger.add("XEP-0234_parseFileElement", self._getFileComments) | |
69 host.trigger.add("XEP-0329_compGetFilesFromNode", self._addCommentsData) | |
65 self.files_path = host.getLocalPath(None, C.FILES_DIR, profile=False) | 70 self.files_path = host.getLocalPath(None, C.FILES_DIR, profile=False) |
66 | 71 |
67 def getHandler(self, client): | 72 def getHandler(self, client): |
68 return Comments_handler(self) | 73 return Comments_handler(self) |
69 | 74 |
75 if not os.path.exists(path): | 80 if not os.path.exists(path): |
76 os.makedirs(path) | 81 os.makedirs(path) |
77 | 82 |
78 @defer.inlineCallbacks | 83 @defer.inlineCallbacks |
79 def _fileTransferedCb(self, dummy, client, peer_jid, file_data, file_path): | 84 def _fileTransferedCb(self, dummy, client, peer_jid, file_data, file_path): |
85 """post file reception tasks | |
86 | |
87 on file is received, this method create hash/thumbnails if necessary | |
88 move the file to the right location, and create metadata entry in database | |
89 """ | |
80 name = file_data[u'name'] | 90 name = file_data[u'name'] |
81 extra = {} | 91 extra = {} |
82 | 92 |
83 if file_data[u'hash_algo'] == HASH_ALGO: | 93 if file_data[u'hash_algo'] == HASH_ALGO: |
84 log.debug(_(u"Reusing already generated hash")) | 94 log.debug(_(u"Reusing already generated hash")) |
124 mime_type=mime_type, | 134 mime_type=mime_type, |
125 owner=peer_jid, | 135 owner=peer_jid, |
126 extra=extra) | 136 extra=extra) |
127 | 137 |
128 def _getDestDirTrigger(self, client, peer_jid, transfer_data, file_data, stream_object): | 138 def _getDestDirTrigger(self, client, peer_jid, transfer_data, file_data, stream_object): |
139 """This trigger accept file sending request, and store file locally""" | |
129 if not client.is_component: | 140 if not client.is_component: |
130 return True, None | 141 return True, None |
131 assert stream_object | 142 assert stream_object |
132 assert 'stream_object' not in transfer_data | 143 assert 'stream_object' not in transfer_data |
133 assert C.KEY_PROGRESS_ID in file_data | 144 assert C.KEY_PROGRESS_ID in file_data |
141 self._f.openFileWrite(client, file_tmp_path, transfer_data, file_data, stream_object) | 152 self._f.openFileWrite(client, file_tmp_path, transfer_data, file_data, stream_object) |
142 return False, defer.succeed(True) | 153 return False, defer.succeed(True) |
143 | 154 |
144 @defer.inlineCallbacks | 155 @defer.inlineCallbacks |
145 def _retrieveFiles(self, client, session, content_data, content_name, file_data, file_elt): | 156 def _retrieveFiles(self, client, session, content_data, content_name, file_data, file_elt): |
157 """This method retrieve a file on request, and send if after checking permissions""" | |
146 peer_jid = session[u'peer_jid'] | 158 peer_jid = session[u'peer_jid'] |
147 try: | 159 try: |
148 found_files = yield self.host.memory.getFiles(client, | 160 found_files = yield self.host.memory.getFiles(client, |
149 peer_jid=peer_jid, | 161 peer_jid=peer_jid, |
150 name=file_data.get(u'name'), | 162 name=file_data.get(u'name'), |
190 if not client.is_component: | 202 if not client.is_component: |
191 return True, None | 203 return True, None |
192 else: | 204 else: |
193 return False, self._retrieveFiles(client, session, content_data, content_name, file_data, file_elt) | 205 return False, self._retrieveFiles(client, session, content_data, content_name, file_data, file_elt) |
194 | 206 |
207 ## comments triggers ## | |
208 | |
209 def _addFileComments(self, file_elt, extra_args): | |
210 try: | |
211 comments_url = extra_args.pop('comments_url') | |
212 except KeyError: | |
213 return | |
214 | |
215 comment_elt = file_elt.addElement((NS_COMMENTS, 'comments'), content=comments_url) | |
216 | |
217 try: | |
218 count = len(extra_args[u'extra'][u'comments']) | |
219 except KeyError: | |
220 count = 0 | |
221 | |
222 comment_elt['count'] = unicode(count) | |
223 return True | |
224 | |
225 def _getFileComments(self, file_elt, file_data): | |
226 try: | |
227 comments_elt = next(file_elt.elements(NS_COMMENTS, 'comments')) | |
228 except StopIteration: | |
229 return | |
230 file_data['comments_url'] = unicode(comments_elt) | |
231 file_data['comments_count'] = comments_elt['count'] | |
232 return True | |
233 | |
234 def _addCommentsData(self, client, iq_elt, owner, node_path, files_data): | |
235 for file_data in files_data: | |
236 file_data['comments_url'] = uri.buildXMPPUri('pubsub', | |
237 path=client.jid.full(), | |
238 node=COMMENT_NODE_PREFIX + file_data['id']) | |
239 return True | |
240 | |
195 | 241 |
196 class Comments_handler(pubsub.PubSubService): | 242 class Comments_handler(pubsub.PubSubService): |
243 """This class is a minimal Pubsub service handling virtual nodes for comments""" | |
197 | 244 |
198 def __init__(self, plugin_parent): | 245 def __init__(self, plugin_parent): |
199 super(Comments_handler, self).__init__() # PubsubVirtualResource()) | 246 super(Comments_handler, self).__init__() # PubsubVirtualResource()) |
200 self.host = plugin_parent.host | 247 self.host = plugin_parent.host |
201 self.plugin_parent = plugin_parent | 248 self.plugin_parent = plugin_parent |