comparison sat/plugins/plugin_xep_0329.py @ 2909:90146552cde5

core (memory), plugin XEP-0329, plugin invitation: minor style improvments
author Goffi <goffi@goffi.org>
date Sun, 14 Apr 2019 08:21:51 +0200
parents 003b8b4b56a7
children 1fd3ecb3351a
comparison
equal deleted inserted replaced
2908:695fc440c3b8 2909:90146552cde5
57 SHARE_TYPES = (TYPE_PATH, TYPE_VIRTUAL) 57 SHARE_TYPES = (TYPE_PATH, TYPE_VIRTUAL)
58 KEY_TYPE = u"type" 58 KEY_TYPE = u"type"
59 59
60 60
61 class ShareNode(object): 61 class ShareNode(object):
62 """node containing directory or files to share, virtual or real""" 62 """Node containing directory or files to share, virtual or real"""
63 63
64 host = None 64 host = None
65 65
66 def __init__(self, name, parent, type_, access, path=None): 66 def __init__(self, name, parent, type_, access, path=None):
67 assert type_ in SHARE_TYPES 67 assert type_ in SHARE_TYPES
110 110
111 def itervalues(self): 111 def itervalues(self):
112 return self.children.itervalues() 112 return self.children.itervalues()
113 113
114 def getOrCreate(self, name, type_=TYPE_VIRTUAL, access=None): 114 def getOrCreate(self, name, type_=TYPE_VIRTUAL, access=None):
115 """get a node or create a virtual node and return it""" 115 """Get a node or create a virtual node and return it"""
116 if access is None: 116 if access is None:
117 access = {C.ACCESS_PERM_READ: {KEY_TYPE: C.ACCESS_TYPE_PUBLIC}} 117 access = {C.ACCESS_PERM_READ: {KEY_TYPE: C.ACCESS_TYPE_PUBLIC}}
118 try: 118 try:
119 return self.children[name] 119 return self.children[name]
120 except KeyError: 120 except KeyError:
155 return True 155 return True
156 156
157 def checkPermissions( 157 def checkPermissions(
158 self, client, peer_jid, perms=(C.ACCESS_PERM_READ,), check_parents=True 158 self, client, peer_jid, perms=(C.ACCESS_PERM_READ,), check_parents=True
159 ): 159 ):
160 """check that peer_jid can access this node and all its parents 160 """Check that peer_jid can access this node and all its parents
161 161
162 @param peer_jid(jid.JID): entrity trying to access the node 162 @param peer_jid(jid.JID): entrity trying to access the node
163 @param perms(unicode): permissions to check, iterable of C.ACCESS_PERM_* 163 @param perms(unicode): permissions to check, iterable of C.ACCESS_PERM_*
164 @param check_parents(bool): if True, access of all parents of this node will be checked too 164 @param check_parents(bool): if True, access of all parents of this node will be
165 checked too
165 @return (bool): True if entity can access this node 166 @return (bool): True if entity can access this node
166 """ 167 """
167 peer_jid = peer_jid.userhostJID() 168 peer_jid = peer_jid.userhostJID()
168 if peer_jid == client.jid.userhostJID(): 169 if peer_jid == client.jid.userhostJID():
169 return True 170 return True
189 @raise NotFound: path lead to a non existing file/directory 190 @raise NotFound: path lead to a non existing file/directory
190 """ 191 """
191 path_elts = filter(None, path.split(u"/")) 192 path_elts = filter(None, path.split(u"/"))
192 193
193 if u".." in path_elts: 194 if u".." in path_elts:
194 log.warning( 195 log.warning(_(
195 _( 196 u'parent dir ("..") found in path, hack attempt? path is {path} '
196 u'parent dir ("..") found in path, hack attempt? path is {path} [{profile}]' 197 u'[{profile}]').format(path=path, profile=client.profile))
197 ).format(path=path, profile=client.profile)
198 )
199 raise exceptions.PermissionError(u"illegal path elements") 198 raise exceptions.PermissionError(u"illegal path elements")
200 199
201 if not path_elts: 200 if not path_elts:
202 raise exceptions.DataError(_(u"path is invalid: {path}").format(path=path)) 201 raise exceptions.DataError(_(u"path is invalid: {path}").format(path=path))
203 202
310 client._XEP_0329_names_data = {} #  name to share map 309 client._XEP_0329_names_data = {} #  name to share map
311 310
312 def _fileSendingRequestTrigger( 311 def _fileSendingRequestTrigger(
313 self, client, session, content_data, content_name, file_data, file_elt 312 self, client, session, content_data, content_name, file_data, file_elt
314 ): 313 ):
315 """this trigger check that a requested file is available, and fill suitable data if so 314 """This trigger check that a requested file is available, and fill suitable data
316 315
317 path and name are used to retrieve the file. If path is missing, we try our luck with known names 316 Path and name are used to retrieve the file. If path is missing, we try our luck
317 with known names
318 """ 318 """
319 if client.is_component: 319 if client.is_component:
320 return True, None 320 return True, None
321 321
322 try: 322 try:
421 file_elt = self._jf.buildFileElement( 421 file_elt = self._jf.buildFileElement(
422 name=name, size=size, mime_type=mime_type, modified=os.path.getmtime(path) 422 name=name, size=size, mime_type=mime_type, modified=os.path.getmtime(path)
423 ) 423 )
424 424
425 query_elt.addChild(file_elt) 425 query_elt.addChild(file_elt)
426 # we don't specify hash as it would be too resource intensive to calculate it for all files 426 # we don't specify hash as it would be too resource intensive to calculate
427 # it for all files.
427 # we add file to name_data, so users can request it later 428 # we add file to name_data, so users can request it later
428 name_data = client._XEP_0329_names_data.setdefault(name, {}) 429 name_data = client._XEP_0329_names_data.setdefault(name, {})
429 if path not in name_data: 430 if path not in name_data:
430 name_data[path] = { 431 name_data[path] = {
431 "size": size, 432 "size": size,
545 @defer.inlineCallbacks 546 @defer.inlineCallbacks
546 def _compGetFilesFromNodeCb(self, client, iq_elt, owner, node_path): 547 def _compGetFilesFromNodeCb(self, client, iq_elt, owner, node_path):
547 """retrieve files from local files repository according to permissions 548 """retrieve files from local files repository according to permissions
548 549
549 result stanza is then built and sent to requestor 550 result stanza is then built and sent to requestor
550 @trigger XEP-0329_compGetFilesFromNode(client, iq_elt, owner, node_path, files_data): can be used to add data/elements 551 @trigger XEP-0329_compGetFilesFromNode(client, iq_elt, owner, node_path,
552 files_data):
553 can be used to add data/elements
551 """ 554 """
552 peer_jid = jid.JID(iq_elt["from"]) 555 peer_jid = jid.JID(iq_elt["from"])
553 try: 556 try:
554 files_data = yield self.host.memory.getFiles( 557 files_data = yield self.host.memory.getFiles(
555 client, peer_jid=peer_jid, path=node_path, owner=owner 558 client, peer_jid=peer_jid, path=node_path, owner=owner
658 raise ValueError(_(u"access must be a dict")) 661 raise ValueError(_(u"access must be a dict"))
659 662
660 node = client._XEP_0329_root_node 663 node = client._XEP_0329_root_node
661 node_type = TYPE_PATH 664 node_type = TYPE_PATH
662 if os.path.isfile(path): 665 if os.path.isfile(path):
663 #  we have a single file, the workflow is diferrent as we store all single files in the same dir 666 # we have a single file, the workflow is diferrent as we store all single
667 # files in the same dir
664 node = node.getOrCreate(SINGLE_FILES_DIR) 668 node = node.getOrCreate(SINGLE_FILES_DIR)
665 669
666 if not name: 670 if not name:
667 name = os.path.basename(path.rstrip(u" /")) 671 name = os.path.basename(path.rstrip(u" /"))
668 if not name: 672 if not name:
673 new_name = name + "_" + unicode(idx) 677 new_name = name + "_" + unicode(idx)
674 while new_name in node: 678 while new_name in node:
675 idx += 1 679 idx += 1
676 new_name = name + "_" + unicode(idx) 680 new_name = name + "_" + unicode(idx)
677 name = new_name 681 name = new_name
678 log.info( 682 log.info(_(
679 _( 683 u"A directory with this name is already shared, renamed to {new_name} "
680 u"A directory with this name is already shared, renamed to {new_name} [{profile}]".format( 684 u"[{profile}]".format( new_name=new_name, profile=client.profile)))
681 new_name=new_name, profile=client.profile
682 )
683 )
684 )
685 685
686 ShareNode(name=name, parent=node, type_=node_type, access=access, path=path) 686 ShareNode(name=name, parent=node, type_=node_type, access=access, path=path)
687 self.host.bridge.FISSharedPathNew(path, name, client.profile) 687 self.host.bridge.FISSharedPathNew(path, name, client.profile)
688 return name 688 return name
689 689