mgraphctl 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mgraphctl might be problematic. Click here for more details.
- mgraphctl/__init__.py +3 -0
- mgraphctl/__main__.py +3 -0
- mgraphctl/auth.py +395 -0
- mgraphctl/cli.py +259 -0
- mgraphctl/commands/__init__.py +71 -0
- mgraphctl/commands/api.py +164 -0
- mgraphctl/commands/calendar.py +491 -0
- mgraphctl/commands/chats.py +329 -0
- mgraphctl/commands/config_cmd.py +140 -0
- mgraphctl/commands/groups.py +65 -0
- mgraphctl/commands/mail.py +705 -0
- mgraphctl/commands/mailbox.py +176 -0
- mgraphctl/commands/meetings.py +294 -0
- mgraphctl/commands/onedrive.py +351 -0
- mgraphctl/commands/onenote.py +196 -0
- mgraphctl/commands/org.py +102 -0
- mgraphctl/commands/people.py +201 -0
- mgraphctl/commands/planner.py +268 -0
- mgraphctl/commands/presence.py +102 -0
- mgraphctl/commands/search.py +75 -0
- mgraphctl/commands/sharepoint.py +304 -0
- mgraphctl/commands/teams.py +235 -0
- mgraphctl/commands/todo.py +253 -0
- mgraphctl/commands/top.py +284 -0
- mgraphctl/config.py +385 -0
- mgraphctl/errors.py +276 -0
- mgraphctl/fixtures.py +149 -0
- mgraphctl/graph/__init__.py +1 -0
- mgraphctl/graph/calendar.py +313 -0
- mgraphctl/graph/chats.py +447 -0
- mgraphctl/graph/files.py +269 -0
- mgraphctl/graph/groups.py +55 -0
- mgraphctl/graph/mail.py +663 -0
- mgraphctl/graph/mailbox.py +89 -0
- mgraphctl/graph/meetings.py +269 -0
- mgraphctl/graph/onedrive.py +35 -0
- mgraphctl/graph/onenote.py +138 -0
- mgraphctl/graph/org.py +86 -0
- mgraphctl/graph/people.py +83 -0
- mgraphctl/graph/planner.py +415 -0
- mgraphctl/graph/presence.py +89 -0
- mgraphctl/graph/search.py +178 -0
- mgraphctl/graph/sharepoint.py +294 -0
- mgraphctl/graph/teams.py +240 -0
- mgraphctl/graph/todo.py +199 -0
- mgraphctl/graph/users.py +85 -0
- mgraphctl/html.py +127 -0
- mgraphctl/http.py +843 -0
- mgraphctl/odata.py +72 -0
- mgraphctl/render.py +627 -0
- mgraphctl/resolve.py +111 -0
- mgraphctl/token_store.py +196 -0
- mgraphctl-0.1.0.dist-info/METADATA +226 -0
- mgraphctl-0.1.0.dist-info/RECORD +57 -0
- mgraphctl-0.1.0.dist-info/WHEEL +4 -0
- mgraphctl-0.1.0.dist-info/entry_points.txt +3 -0
- mgraphctl-0.1.0.dist-info/licenses/LICENSE +21 -0
mgraphctl/odata.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""URL and query-string encoding helpers for Microsoft Graph paths (spec §5.5)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import base64
|
|
6
|
+
from collections.abc import Mapping
|
|
7
|
+
from typing import Any
|
|
8
|
+
from urllib.parse import quote, urlsplit
|
|
9
|
+
|
|
10
|
+
_SITE_REF_TYPES = ("sites", "teams", "personal")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def p(*segments: str) -> str:
|
|
14
|
+
"""Build an absolute path from raw segments, each fully percent-encoded."""
|
|
15
|
+
return "/" + "/".join(quote(str(segment), safe="") for segment in segments)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def drive_path(path: str) -> str:
|
|
19
|
+
"""Quote each `/`-separated segment of a drive-relative path; no leading slash."""
|
|
20
|
+
return "/".join(quote(segment, safe="") for segment in path.split("/"))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def query(params: Mapping[str, Any]) -> str:
|
|
24
|
+
"""Render `params` as a query string: keys verbatim, values percent-encoded (%20 not +)."""
|
|
25
|
+
parts: list[str] = []
|
|
26
|
+
for key, value in params.items():
|
|
27
|
+
if value is None:
|
|
28
|
+
continue
|
|
29
|
+
if isinstance(value, bool):
|
|
30
|
+
value = "true" if value else "false"
|
|
31
|
+
parts.append(f"{key}={quote(str(value), safe='')}")
|
|
32
|
+
return "&".join(parts)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def with_query(path: str, params: Mapping[str, Any] | None) -> str:
|
|
36
|
+
"""Append `?query()` to `path`, omitting the `?` entirely when there are no params."""
|
|
37
|
+
q = query(params or {})
|
|
38
|
+
return f"{path}?{q}" if q else path
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def kql(*terms: str) -> str:
|
|
42
|
+
"""Join KQL terms with ` AND ` and wrap the result in double quotes for `$search`."""
|
|
43
|
+
return '"' + " AND ".join(terms) + '"'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def odata_str(s: str) -> str:
|
|
47
|
+
"""Escape a string literal for use inside an OData `$filter`/`search()` expression."""
|
|
48
|
+
return s.replace("'", "''")
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def share_id(url: str) -> str:
|
|
52
|
+
"""Encode a sharing URL as a Graph `shares/{share_id}` id."""
|
|
53
|
+
encoded = base64.urlsafe_b64encode(url.encode("utf-8")).decode("ascii").rstrip("=")
|
|
54
|
+
return f"u!{encoded}"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def site_ref(value: str) -> str:
|
|
58
|
+
"""Resolve a site reference (URL, `host:/a/b`, composite id, or plain id) to a Graph path."""
|
|
59
|
+
if value.startswith("http://") or value.startswith("https://"):
|
|
60
|
+
parsed = urlsplit(value)
|
|
61
|
+
host = quote(parsed.netloc, safe="")
|
|
62
|
+
segments = [s for s in parsed.path.split("/") if s]
|
|
63
|
+
if len(segments) >= 2 and segments[0] in _SITE_REF_TYPES:
|
|
64
|
+
return f"/sites/{host}:/{segments[0]}/{quote(segments[1], safe='')}"
|
|
65
|
+
return f"/sites/{host}"
|
|
66
|
+
if ":/" in value:
|
|
67
|
+
host, _, rest = value.partition(":/")
|
|
68
|
+
quoted_segments = "/".join(quote(segment, safe="") for segment in rest.split("/"))
|
|
69
|
+
return f"/sites/{quote(host, safe='')}:/{quoted_segments}"
|
|
70
|
+
if "," in value:
|
|
71
|
+
return f"/sites/{quote(value, safe=',')}"
|
|
72
|
+
return p("sites", value)
|