Mercurial > libervia-backend
diff sat/plugins/plugin_xep_0329.py @ 3028:ab2696e34d29
Python 3 port:
/!\ this is a huge commit
/!\ starting from this commit, SàT is needs Python 3.6+
/!\ SàT maybe be instable or some feature may not work anymore, this will improve with time
This patch port backend, bridge and frontends to Python 3.
Roughly this has been done this way:
- 2to3 tools has been applied (with python 3.7)
- all references to python2 have been replaced with python3 (notably shebangs)
- fixed files not handled by 2to3 (notably the shell script)
- several manual fixes
- fixed issues reported by Python 3 that where not handled in Python 2
- replaced "async" with "async_" when needed (it's a reserved word from Python 3.7)
- replaced zope's "implements" with @implementer decorator
- temporary hack to handle data pickled in database, as str or bytes may be returned,
to be checked later
- fixed hash comparison for password
- removed some code which is not needed anymore with Python 3
- deactivated some code which needs to be checked (notably certificate validation)
- tested with jp, fixed reported issues until some basic commands worked
- ported Primitivus (after porting dependencies like urwid satext)
- more manual fixes
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Aug 2019 19:08:41 +0200 |
parents | db0890c9c7db |
children | 95e2fd14a761 |
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0329.py Wed Jul 31 11:31:22 2019 +0200 +++ b/sat/plugins/plugin_xep_0329.py Tue Aug 13 19:08:41 2019 +0200 @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # SAT plugin for File Information Sharing (XEP-0329) @@ -26,7 +26,7 @@ from sat.tools import stream from sat.tools.common import regex from wokkel import disco, iwokkel -from zope.interface import implements +from zope.interface import implementer from twisted.words.protocols.jabber import xmlstream from twisted.words.protocols.jabber import jid from twisted.words.protocols.jabber import error as jabber_error @@ -45,17 +45,17 @@ C.PI_DEPENDENCIES: ["XEP-0234", "XEP-0300", "XEP-0106"], C.PI_MAIN: "XEP_0329", C.PI_HANDLER: "yes", - C.PI_DESCRIPTION: _(u"""Implementation of File Information Sharing"""), + C.PI_DESCRIPTION: _("""Implementation of File Information Sharing"""), } NS_FIS = "urn:xmpp:fis:0" IQ_FIS_REQUEST = C.IQ_GET + '/query[@xmlns="' + NS_FIS + '"]' -SINGLE_FILES_DIR = u"files" -TYPE_VIRTUAL = u"virtual" -TYPE_PATH = u"path" +SINGLE_FILES_DIR = "files" +TYPE_VIRTUAL = "virtual" +TYPE_PATH = "path" SHARE_TYPES = (TYPE_PATH, TYPE_VIRTUAL) -KEY_TYPE = u"type" +KEY_TYPE = "type" class ShareNode(object): @@ -66,14 +66,14 @@ def __init__(self, name, parent, type_, access, path=None): assert type_ in SHARE_TYPES if name is not None: - if name == u".." or u"/" in name or u"\\" in name: + if name == ".." or "/" in name or "\\" in name: log.warning( - _(u"path change chars found in name [{name}], hack attempt?").format( + _("path change chars found in name [{name}], hack attempt?").format( name=name ) ) - if name == u"..": - name = u"--" + if name == "..": + name = "--" else: name = regex.pathEscape(name) self.name = name @@ -89,7 +89,7 @@ assert name is None if path is not None: if type_ != TYPE_PATH: - raise exceptions.InternalError(_(u"path can only be set on path nodes")) + raise exceptions.InternalError(_("path can only be set on path nodes")) self._path = path @property @@ -106,10 +106,10 @@ return self.children.__iter__() def iteritems(self): - return self.children.iteritems() + return iter(self.children.items()) def itervalues(self): - return self.children.itervalues() + return iter(self.children.values()) def getOrCreate(self, name, type_=TYPE_VIRTUAL, access=None): """Get a node or create a virtual node and return it""" @@ -123,7 +123,7 @@ def addChild(self, node): if node.parent is not None: - raise exceptions.ConflictError(_(u"a node can't have several parents")) + raise exceptions.ConflictError(_("a node can't have several parents")) node.parent = self self.children[node.name] = node @@ -132,10 +132,10 @@ del self.parent.children[self.name] except TypeError: raise exceptions.InternalError( - u"trying to remove a node from inexisting parent" + "trying to remove a node from inexisting parent" ) except KeyError: - raise exceptions.InternalError(u"node not found in parent's children") + raise exceptions.InternalError("node not found in parent's children") self.parent = None def _checkNodePermission(self, client, node, perms, peer_jid): @@ -146,7 +146,7 @@ @param peer_jid(jid.JID): entity which try to access the node @return (bool): True if entity can access """ - file_data = {u"access": self.access, u"owner": client.jid.userhostJID()} + file_data = {"access": self.access, "owner": client.jid.userhostJID()} try: self.host.memory.checkFilePermission(file_data, peer_jid, perms) except exceptions.PermissionError: @@ -189,16 +189,16 @@ @raise exceptions.DataError: path is invalid @raise NotFound: path lead to a non existing file/directory """ - path_elts = filter(None, path.split(u"/")) + path_elts = [_f for _f in path.split("/") if _f] - if u".." in path_elts: + if ".." in path_elts: log.warning(_( - u'parent dir ("..") found in path, hack attempt? path is {path} ' - u'[{profile}]').format(path=path, profile=client.profile)) - raise exceptions.PermissionError(u"illegal path elements") + 'parent dir ("..") found in path, hack attempt? path is {path} ' + '[{profile}]').format(path=path, profile=client.profile)) + raise exceptions.PermissionError("illegal path elements") if not path_elts: - raise exceptions.DataError(_(u"path is invalid: {path}").format(path=path)) + raise exceptions.DataError(_("path is invalid: {path}").format(path=path)) node = client._XEP_0329_root_node @@ -212,9 +212,9 @@ break if not node.checkPermissions(client, peer_jid, perms=perms): - raise exceptions.PermissionError(u"permission denied") + raise exceptions.PermissionError("permission denied") - return node, u"/".join(path_elts) + return node, "/".join(path_elts) def findByLocalPath(self, path): """retrieve nodes linking to local path @@ -230,13 +230,13 @@ def _getSharedPaths(self, node, paths): if node.type == TYPE_VIRTUAL: - for node in node.itervalues(): + for node in node.values(): self._getSharedPaths(node, paths) elif node.type == TYPE_PATH: paths.setdefault(node.path, []).append(node) else: raise exceptions.InternalError( - u"unknown node type: {type}".format(type=node.type) + "unknown node type: {type}".format(type=node.type) ) def getSharedPaths(self): @@ -267,7 +267,7 @@ in_sign="ssa{ss}s", out_sign="aa{ss}", method=self._listFiles, - async=True, + async_=True, ) host.bridge.addMethod( "FISLocalSharesGet", @@ -320,21 +320,21 @@ return True, None try: - name = file_data[u"name"] + name = file_data["name"] except KeyError: return True, None - assert u"/" not in name + assert "/" not in name - path = file_data.get(u"path") + path = file_data.get("path") if path is not None: # we have a path, we can follow it to find node try: - node, rem_path = ShareNode.find(client, path, session[u"peer_jid"]) + node, rem_path = ShareNode.find(client, path, session["peer_jid"]) except (exceptions.PermissionError, exceptions.NotFound): # no file, or file not allowed, we continue normal workflow return True, None except exceptions.DataError: - log.warning(_(u"invalid path: {path}").format(path=path)) + log.warning(_("invalid path: {path}").format(path=path)) return True, None if node.type == TYPE_VIRTUAL: @@ -348,7 +348,7 @@ path = os.path.join(node.path, rem_path, name) else: raise exceptions.InternalError( - u"unknown type: {type}".format(type=node.type) + "unknown type: {type}".format(type=node.type) ) if not os.path.exists(path): return True, None @@ -360,25 +360,25 @@ except KeyError: return True, None - for path, shared_file in name_data.iteritems(): + for path, shared_file in name_data.items(): if True: # FIXME: filters are here break else: return True, None - parent_node = shared_file[u"parent"] - if not parent_node.checkPermissions(client, session[u"peer_jid"]): + parent_node = shared_file["parent"] + if not parent_node.checkPermissions(client, session["peer_jid"]): log.warning( _( - u"{peer_jid} requested a file (s)he can't access [{profile}]" - ).format(peer_jid=session[u"peer_jid"], profile=client.profile) + "{peer_jid} requested a file (s)he can't access [{profile}]" + ).format(peer_jid=session["peer_jid"], profile=client.profile) ) return True, None - size = shared_file[u"size"] + size = shared_file["size"] - file_data[u"size"] = size - file_elt.addElement(u"size", content=unicode(size)) - hash_algo = file_data[u"hash_algo"] = self._h.getDefaultAlgo() - hasher = file_data[u"hash_hasher"] = self._h.getHasher(hash_algo) + file_data["size"] = size + file_elt.addElement("size", content=str(size)) + hash_algo = file_data["hash_algo"] = self._h.getDefaultAlgo() + hasher = file_data["hash_hasher"] = self._h.getHasher(hash_algo) file_elt.addChild(self._h.buildHashUsedElt(hash_algo)) content_data["stream_object"] = stream.FileStreamObject( self.host, @@ -401,7 +401,7 @@ d = defer.maybeDeferred(files_from_node_cb, client, iq_elt, node) d.addErrback( lambda failure_: log.error( - _(u"error while retrieving files: {msg}").format(msg=failure_) + _("error while retrieving files: {msg}").format(msg=failure_) ) ) @@ -452,7 +452,7 @@ name = name.decode("utf-8", "strict") except UnicodeDecodeError as e: log.warning( - _(u"ignoring invalid unicode name ({name}): {msg}").format( + _("ignoring invalid unicode name ({name}): {msg}").format( name=name.decode("utf-8", "replace"), msg=e ) ) @@ -462,7 +462,7 @@ def _virtualNodeHandler(self, client, peer_jid, iq_elt, query_elt, node): """Fill query_elt for virtual nodes""" - for name, child_node in node.iteritems(): + for name, child_node in node.items(): if not child_node.checkPermissions(client, peer_jid, check_parents=False): continue node_type = child_node.type @@ -473,14 +473,14 @@ self._addPathData(client, query_elt, child_node.path, child_node) else: raise exceptions.InternalError( - _(u"unexpected type: {type}").format(type=node_type) + _("unexpected type: {type}").format(type=node_type) ) def _getRootNodesCb(self, client, iq_elt): peer_jid = jid.JID(iq_elt["from"]) iq_result_elt = xmlstream.toResponse(iq_elt, "result") query_elt = iq_result_elt.addElement((NS_FIS, "query")) - for name, node in client._XEP_0329_root_node.iteritems(): + for name, node in client._XEP_0329_root_node.items(): if not node.checkPermissions(client, peer_jid, check_parents=False): continue directory_elt = query_elt.addElement("directory") @@ -489,7 +489,7 @@ def _getFilesFromNodeCb(self, client, iq_elt, node_path): """Main method to retrieve files/directories from a node_path""" - peer_jid = jid.JID(iq_elt[u"from"]) + peer_jid = jid.JID(iq_elt["from"]) try: node, path = ShareNode.find(client, node_path, peer_jid) except (exceptions.PermissionError, exceptions.NotFound): @@ -501,7 +501,7 @@ peer_jid = jid.JID(iq_elt["from"]) iq_result_elt = xmlstream.toResponse(iq_elt, "result") query_elt = iq_result_elt.addElement((NS_FIS, "query")) - query_elt[u"node"] = node_path + query_elt["node"] = node_path # we now fill query_elt according to node_type if node_type == TYPE_PATH: @@ -512,7 +512,7 @@ self._virtualNodeHandler(client, peer_jid, iq_elt, query_elt, node) else: raise exceptions.InternalError( - _(u"unknown node type: {type}").format(type=node_type) + _("unknown node type: {type}").format(type=node_type) ) client.send(iq_result_elt) @@ -533,7 +533,7 @@ to_jid = jid.JID(iq_elt['to']) if to_jid.user: user = self.host.plugins['XEP-0106'].unescape(to_jid.user) - if u'@' in user: + if '@' in user: # a full jid is specified owner = jid.JID(user) else: @@ -551,16 +551,16 @@ files_data = yield self.host.memory.getFiles( client, peer_jid=peer_jid, - parent=u"", + parent="", type_=C.FILE_TYPE_DIRECTORY, owner=owner, ) iq_result_elt = xmlstream.toResponse(iq_elt, "result") query_elt = iq_result_elt.addElement((NS_FIS, "query")) for file_data in files_data: - name = file_data[u"name"] - directory_elt = query_elt.addElement(u"directory") - directory_elt[u"name"] = name + name = file_data["name"] + directory_elt = query_elt.addElement("directory") + directory_elt["name"] = name client.send(iq_result_elt) @defer.inlineCallbacks @@ -584,19 +584,19 @@ self._iqError(client, iq_elt, condition='not-allowed') return except Exception as e: - log.error(u"internal server error: {e}".format(e=e)) + log.error("internal server error: {e}".format(e=e)) self._iqError(client, iq_elt, condition='internal-server-error') return iq_result_elt = xmlstream.toResponse(iq_elt, "result") query_elt = iq_result_elt.addElement((NS_FIS, "query")) - query_elt[u"node"] = node_path + query_elt["node"] = node_path if not self.host.trigger.point( - u"XEP-0329_compGetFilesFromNode", client, iq_elt, owner, node_path, files_data + "XEP-0329_compGetFilesFromNode", client, iq_elt, owner, node_path, files_data ): return for file_data in files_data: file_elt = self._jf.buildFileElementFromDict( - file_data, modified=file_data.get(u"modified", file_data[u"created"]) + file_data, modified=file_data.get("modified", file_data["created"]) ) query_elt.addChild(file_elt) client.send(iq_result_elt) @@ -617,14 +617,14 @@ file_data = self._jf.parseFileElement(elt) except exceptions.DataError: continue - file_data[u"type"] = C.FILE_TYPE_FILE + file_data["type"] = C.FILE_TYPE_FILE elif elt.name == "directory" and elt.uri == NS_FIS: # we have a directory file_data = {"name": elt["name"], "type": C.FILE_TYPE_DIRECTORY} else: log.warning( - _(u"unexpected element, ignoring: {elt}").format(elt=elt.toXml()) + _("unexpected element, ignoring: {elt}").format(elt=elt.toXml()) ) continue files.append(file_data) @@ -634,9 +634,9 @@ def _serializeData(self, files_data): for file_data in files_data: - for key, value in file_data.iteritems(): + for key, value in file_data.items(): file_data[key] = ( - json.dumps(value) if key in ("extra",) else unicode(value) + json.dumps(value) if key in ("extra",) else str(value) ) return files_data @@ -670,7 +670,7 @@ return self.localSharesGet(client) def localSharesGet(self, client): - return client._XEP_0329_root_node.getSharedPaths().keys() + return list(client._XEP_0329_root_node.getSharedPaths().keys()) def _sharePath(self, name, path, access, profile): client = self.host.getClient(profile) @@ -681,11 +681,11 @@ if client.is_component: raise exceptions.ClientTypeError if not os.path.exists(path): - raise ValueError(_(u"This path doesn't exist!")) - if not path or not path.strip(u" /"): - raise ValueError(_(u"A path need to be specified")) + raise ValueError(_("This path doesn't exist!")) + if not path or not path.strip(" /"): + raise ValueError(_("A path need to be specified")) if not isinstance(access, dict): - raise ValueError(_(u"access must be a dict")) + raise ValueError(_("access must be a dict")) node = client._XEP_0329_root_node node_type = TYPE_PATH @@ -695,20 +695,20 @@ node = node.getOrCreate(SINGLE_FILES_DIR) if not name: - name = os.path.basename(path.rstrip(u" /")) + name = os.path.basename(path.rstrip(" /")) if not name: - raise exceptions.InternalError(_(u"Can't find a proper name")) + raise exceptions.InternalError(_("Can't find a proper name")) if name in node or name == SINGLE_FILES_DIR: idx = 1 - new_name = name + "_" + unicode(idx) + new_name = name + "_" + str(idx) while new_name in node: idx += 1 - new_name = name + "_" + unicode(idx) + new_name = name + "_" + str(idx) name = new_name log.info(_( - u"A directory with this name is already shared, renamed to {new_name} " - u"[{profile}]".format( new_name=new_name, profile=client.profile))) + "A directory with this name is already shared, renamed to {new_name} " + "[{profile}]".format( new_name=new_name, profile=client.profile))) ShareNode(name=name, parent=node, type_=node_type, access=access, path=path) self.host.bridge.FISSharedPathNew(path, name, client.profile) @@ -725,8 +725,8 @@ self.host.bridge.FISSharedPathRemoved(path, client.profile) +@implementer(iwokkel.IDisco) class XEP_0329_handler(xmlstream.XMPPHandler): - implements(iwokkel.IDisco) def __init__(self, plugin_parent): self.plugin_parent = plugin_parent