Mercurial > libervia-backend
annotate libervia/backend/tools/common/uri.py @ 4100:810921c33a47
tools (common/template): add filter to get media types:
Add 2 filters to get main type and subtype of media type. Jinja2 and Nunjucks don't handle
slices in the same way (Python way for Jinja2, JS way for Nunjucks), making it difficult
to retrieve main type of a media from media type. Thoses filters work in both cases.
author | Goffi <goffi@goffi.org> |
---|---|
date | Thu, 22 Jun 2023 15:49:06 +0200 |
parents | 4b842c1fb686 |
children |
rev | line source |
---|---|
3028 | 1 #!/usr/bin/env python3 |
3137 | 2 |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
3 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
4 # SAT: a jabber client |
3479 | 5 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # This program is free software: you can redistribute it and/or modify |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # it under the terms of the GNU Affero General Public License as published by |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # the Free Software Foundation, either version 3 of the License, or |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 # (at your option) any later version. |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # This program is distributed in the hope that it will be useful, |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 # GNU Affero General Public License for more details. |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # You should have received a copy of the GNU Affero General Public License |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
19 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 """ XMPP uri parsing tools """ |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 |
3829
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
22 from typing import Optional |
3642
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
23 import sys |
3028 | 24 import urllib.parse |
25 import urllib.request, urllib.parse, urllib.error | |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
27 # FIXME: basic implementation, need to follow RFC 5122 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
29 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3829
diff
changeset
|
30 def parse_xmpp_uri(uri): |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 """Parse an XMPP uri and return a dict with various information |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
33 @param uri(unicode): uri to parse |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
34 @return dict(unicode, unicode): data depending of the URI where key can be: |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 type: one of ("pubsub", TODO) |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
36 type is always present |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 sub_type: can be: |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 - microblog |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 only used for pubsub for now |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 path: XMPP path (jid of the service or entity) |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 node: node used |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 id: id of the element (item for pubsub) |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 @raise ValueError: the scheme is not xmpp |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 """ |
3028 | 45 uri_split = urllib.parse.urlsplit(uri) |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
46 if uri_split.scheme != "xmpp": |
3028 | 47 raise ValueError("this is not a XMPP URI") |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 |
2229
761fa220a717
tools (common/uri): minor comment update
Goffi <goffi@goffi.org>
parents:
2222
diff
changeset
|
49 # XXX: we don't use jid.JID for path as it can be used both in backend and frontend |
761fa220a717
tools (common/uri): minor comment update
Goffi <goffi@goffi.org>
parents:
2222
diff
changeset
|
50 # which may use different JID classes |
3028 | 51 data = {"path": urllib.parse.unquote(uri_split.path)} |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
53 query_end = uri_split.query.find(";") |
3829
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
54 if query_end == -1: |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
55 # we just have a JID |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
56 query_type = None |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
57 else: |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
58 query_type = uri_split.query[:query_end] |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
59 if "=" in query_type: |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
60 raise ValueError("no query type, invalid XMPP URI") |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
61 |
3642
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
62 if sys.version_info >= (3, 9): |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
63 # parse_qs behaviour has been modified in Python 3.9, ";" is not understood as a |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
64 # parameter separator anymore but the "separator" argument has been added to |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
65 # change it. |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
66 pairs = urllib.parse.parse_qs(uri_split.geturl(), separator=";") |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
67 else: |
cc3b453670a2
tools (common/uri): fix uri parsing for Python 3.9+
Goffi <goffi@goffi.org>
parents:
3479
diff
changeset
|
68 pairs = urllib.parse.parse_qs(uri_split.geturl()) |
3028 | 69 for k, v in list(pairs.items()): |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
70 if len(v) != 1: |
3028 | 71 raise NotImplementedError("multiple values not managed") |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
72 if k in ("path", "type", "sub_type"): |
3028 | 73 raise NotImplementedError("reserved key used in URI, this is not supported") |
74 data[k] = urllib.parse.unquote(v[0]) | |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
75 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
76 if query_type: |
3028 | 77 data["type"] = query_type |
78 elif "node" in data: | |
79 data["type"] = "pubsub" | |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 else: |
3028 | 81 data["type"] = "" |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
82 |
3028 | 83 if "node" in data: |
84 if data["node"].startswith("urn:xmpp:microblog:"): | |
85 data["sub_type"] = "microblog" | |
2216
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
86 |
7e06eafef409
tools(common/uri): XMPP uri parsing module, first draft
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 return data |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
88 |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
89 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3829
diff
changeset
|
90 def add_pairs(uri, pairs): |
3028 | 91 for k, v in pairs.items(): |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
92 uri.append( |
3028 | 93 ";" |
94 + urllib.parse.quote_plus(k.encode("utf-8")) | |
95 + "=" | |
96 + urllib.parse.quote_plus(v.encode("utf-8")) | |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
97 ) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
98 |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
99 |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3829
diff
changeset
|
100 def build_xmpp_uri(type_: Optional[str] = None, **kwargs: str) -> str: |
3028 | 101 uri = ["xmpp:"] |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
102 subtype = kwargs.pop("subtype", None) |
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
103 path = kwargs.pop("path") |
3028 | 104 uri.append(urllib.parse.quote_plus(path.encode("utf-8")).replace("%40", "@")) |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
105 |
3829
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
106 if type_ is None: |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
107 # we have an URI to a JID |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
108 if kwargs: |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
109 raise NotImplementedError( |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
110 "keyword arguments are not supported for URI without type" |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
111 ) |
67fc066ed2cd
tools (common/uri): accept URIs without type:
Goffi <goffi@goffi.org>
parents:
3642
diff
changeset
|
112 elif type_ == "pubsub": |
2624
56f94936df1e
code style reformatting using black
Goffi <goffi@goffi.org>
parents:
2562
diff
changeset
|
113 if subtype == "microblog" and not kwargs.get("node"): |
3028 | 114 kwargs["node"] = "urn:xmpp:microblog:0" |
2242
e5e54ff0b775
core (tools/common/uri): don't display finale "?" if no extra data is specified
Goffi <goffi@goffi.org>
parents:
2229
diff
changeset
|
115 if kwargs: |
3028 | 116 uri.append("?") |
4037
524856bd7b19
massive refactoring to switch from camelCase to snake_case:
Goffi <goffi@goffi.org>
parents:
3829
diff
changeset
|
117 add_pairs(uri, kwargs) |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
118 else: |
3028 | 119 raise NotImplementedError("{type_} URI are not handled yet".format(type_=type_)) |
2222
bdc64c487e21
tools/common (uri): added a method to build URI
Goffi <goffi@goffi.org>
parents:
2216
diff
changeset
|
120 |
3028 | 121 return "".join(uri) |