Mercurial > libervia-backend
annotate sat/tools/xmpp_datetime.py @ 3913:944f51f9c2b4
core (xmpp): make `send` a blocking method, fix `sendMessageData` calls:
original `send` method is blocking, and it is used as such by Wokkel and thus can't be
changed to an async method easily. However, an Async method is necessary to have an async
trigger at the very end of the send workflow for end-to-end encryption. To workaround
that, `send` is an async method which call `a_send`, an async method which actually does
the sending. This way legacy method can still call `send` while `a_send` can be await
otherwise.
Fix calls to `sendMessageData`: the method now being an `async` one, `ensureDeferred` had
to be used in some calls.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 24 Sep 2022 16:31:39 +0200 |
parents | 8289ac1b34f4 |
children | cecf45416403 |
rev | line source |
---|---|
3877
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
1 #!/usr/bin/env python3 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
2 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
3 # Libervia: XMPP Date and Time profiles as per XEP-0082 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
4 # Copyright (C) 2022-2022 Tim Henkes (me@syndace.dev) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
5 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
9 # (at your option) any later version. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
10 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
15 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
18 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
19 from datetime import date, datetime, time, timezone |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
20 import re |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
21 from typing import Optional, Tuple |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
22 |
3911
8289ac1b34f4
plugin XEP-0384: Fully reworked to adjust to the reworked python-omemo:
Syndace <me@syndace.dev>
parents:
3879
diff
changeset
|
23 from sat.core import exceptions |
8289ac1b34f4
plugin XEP-0384: Fully reworked to adjust to the reworked python-omemo:
Syndace <me@syndace.dev>
parents:
3879
diff
changeset
|
24 |
3877
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
25 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
26 __all__ = [ # pylint: disable=unused-variable |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
27 "format_date", |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
28 "parse_date", |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
29 "format_datetime", |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
30 "parse_datetime", |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
31 "format_time", |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
32 "parse_time" |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
33 ] |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
34 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
35 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
36 def __parse_fraction_of_a_second(value: str) -> Tuple[str, Optional[int]]: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
37 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
38 datetime's strptime only supports up to six digits of the fraction of a seconds, while |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
39 the XEP-0082 specification allows for any number of digits. This function parses and |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
40 removes the optional fraction of a second from the input string. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
41 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
42 @param value: The input string, containing a section of the format [.sss]. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
43 @return: The input string with the fraction of a second removed, and the fraction of a |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
44 second parsed with microsecond resolution. Returns the unaltered input string and |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
45 ``None`` if no fraction of a second was found in the input string. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
46 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
47 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
48 # The following regex matches the optional fraction of a seconds for manual |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
49 # processing. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
50 match = re.search(r"\.(\d*)", value) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
51 microsecond: Optional[int] = None |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
52 if match is not None: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
53 # Remove the fraction of a second from the input string |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
54 value = value[:match.start()] + value[match.end():] |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
55 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
56 # datetime supports microsecond resolution for the fraction of a second, thus |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
57 # limit/pad the parsed fraction of a second to six digits |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
58 microsecond = int(match.group(1)[:6].ljust(6, '0')) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
59 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
60 return value, microsecond |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
61 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
62 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
63 def format_date(value: Optional[date] = None) -> str: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
64 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
65 @param value: The date for format. Defaults to the current date in the UTC timezone. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
66 @return: The date formatted according to the Date profile specified in XEP-0082. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
67 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
68 @warning: Formatting of the current date in the local timezone may leak geographical |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
69 information of the sender. Thus, it is advised to only format the current date in |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
70 UTC. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
71 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
72 # CCYY-MM-DD |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
73 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
74 # The Date profile of XEP-0082 is equal to the ISO 8601 format. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
75 return (datetime.now(timezone.utc).date() if value is None else value).isoformat() |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
76 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
77 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
78 def parse_date(value: str) -> date: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
79 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
80 @param value: A string containing date information formatted according to the Date |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
81 profile specified in XEP-0082. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
82 @return: The date parsed from the input string. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
83 @raise ValueError: if the input string is not correctly formatted. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
84 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
85 # CCYY-MM-DD |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
86 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
87 # The Date profile of XEP-0082 is equal to the ISO 8601 format. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
88 return date.fromisoformat(value) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
89 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
90 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
91 def format_datetime( |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
92 value: Optional[datetime] = None, |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
93 include_microsecond: bool = False |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
94 ) -> str: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
95 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
96 @param value: The datetime to format. Defaults to the current datetime. |
3878
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
97 must be an aware datetime object (timezone must be specified) |
3877
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
98 @param include_microsecond: Include the microsecond of the datetime in the output. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
99 @return: The datetime formatted according to the DateTime profile specified in |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
100 XEP-0082. The datetime is always converted to UTC before formatting to avoid |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
101 leaking geographical information of the sender. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
102 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
103 # CCYY-MM-DDThh:mm:ss[.sss]TZD |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
104 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
105 # We format the time in UTC, since the %z formatter of strftime doesn't include colons |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
106 # to separate hours and minutes which is required by XEP-0082. UTC allows us to put a |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
107 # simple letter 'Z' as the time zone definition. |
3878
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
108 if value is not None: |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
109 if value.tzinfo is None: |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
110 raise exceptions.InternalError( |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
111 "an aware datetime object must be used, but a naive one has been provided" |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
112 ) |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
113 value = value.astimezone(timezone.utc) # pylint: disable=no-member |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
114 else: |
32087d7c25d4
tools (datetime, utils): fix incorrect use of naive object:
Goffi <goffi@goffi.org>
parents:
3877
diff
changeset
|
115 value = datetime.now(timezone.utc) |
3877
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
116 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
117 if include_microsecond: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
118 return value.strftime("%Y-%m-%dT%H:%M:%S.%fZ") |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
119 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
120 return value.strftime("%Y-%m-%dT%H:%M:%SZ") |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
121 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
122 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
123 def parse_datetime(value: str) -> datetime: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
124 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
125 @param value: A string containing datetime information formatted according to the |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
126 DateTime profile specified in XEP-0082. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
127 @return: The datetime parsed from the input string. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
128 @raise ValueError: if the input string is not correctly formatted. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
129 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
130 # CCYY-MM-DDThh:mm:ss[.sss]TZD |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
131 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
132 value, microsecond = __parse_fraction_of_a_second(value) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
133 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
134 result = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S%z") |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
135 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
136 if microsecond is not None: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
137 result = result.replace(microsecond=microsecond) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
138 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
139 return result |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
140 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
141 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
142 def format_time(value: Optional[time] = None, include_microsecond: bool = False) -> str: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
143 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
144 @param value: The time to format. Defaults to the current time in the UTC timezone. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
145 @param include_microsecond: Include the microsecond of the time in the output. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
146 @return: The time formatted according to the Time profile specified in XEP-0082. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
147 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
148 @warning: Since accurate timezone conversion requires the date to be known, this |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
149 function cannot convert input times to UTC before formatting. This means that |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
150 geographical information of the sender may be leaked if a time in local timezone |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
151 is formatted. Thus, when passing a time to format, it is advised to pass the time |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
152 in UTC if possible. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
153 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
154 # hh:mm:ss[.sss][TZD] |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
155 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
156 if value is None: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
157 # There is no time.now() method as one might expect, but the current time can be |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
158 # extracted from a datetime object including time zone information. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
159 value = datetime.now(timezone.utc).timetz() |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
160 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
161 # The format created by time.isoformat complies with the XEP-0082 Time profile. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
162 return value.isoformat("auto" if include_microsecond else "seconds") |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
163 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
164 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
165 def parse_time(value: str) -> time: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
166 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
167 @param value: A string containing time information formatted according to the Time |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
168 profile specified in XEP-0082. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
169 @return: The time parsed from the input string. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
170 @raise ValueError: if the input string is not correctly formatted. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
171 """ |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
172 # hh:mm:ss[.sss][TZD] |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
173 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
174 value, microsecond = __parse_fraction_of_a_second(value) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
175 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
176 # The format parsed by time.fromisoformat mostly complies with the XEP-0082 Time |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
177 # profile, except that it doesn't handle the letter Z as time zone information for |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
178 # UTC. This can be fixed with a simple string replacement of 'Z' with "+00:00", which |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
179 # is another way to represent UTC. |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
180 result = time.fromisoformat(value.replace('Z', "+00:00")) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
181 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
182 if microsecond is not None: |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
183 result = result.replace(microsecond=microsecond) |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
184 |
00212260f659
plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff
changeset
|
185 return result |