tlgr-cli 2.0.1__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.
- tlgr/__init__.py +3 -0
- tlgr/__main__.py +6 -0
- tlgr/actions/__init__.py +45 -0
- tlgr/actions/forward.py +74 -0
- tlgr/actions/reply.py +32 -0
- tlgr/cli/__init__.py +259 -0
- tlgr/cli/confirm.py +55 -0
- tlgr/cli/errors.py +84 -0
- tlgr/cli/gen.py +690 -0
- tlgr/cli/globals.py +273 -0
- tlgr/cli/introspect.py +170 -0
- tlgr/cli/params.py +189 -0
- tlgr/cli/render.py +418 -0
- tlgr/core/__init__.py +0 -0
- tlgr/core/accounts.py +384 -0
- tlgr/core/config.py +358 -0
- tlgr/core/custom_tl.py +170 -0
- tlgr/core/errors.py +687 -0
- tlgr/core/eventtypes.py +1170 -0
- tlgr/core/identity.py +127 -0
- tlgr/core/launchd.py +122 -0
- tlgr/core/logging.py +194 -0
- tlgr/core/media.py +134 -0
- tlgr/core/output.py +251 -0
- tlgr/core/pagination.py +227 -0
- tlgr/core/paths.py +360 -0
- tlgr/core/peers.py +427 -0
- tlgr/core/process.py +138 -0
- tlgr/core/signing.py +38 -0
- tlgr/core/systemd.py +96 -0
- tlgr/core/telethon_compat.py +295 -0
- tlgr/core/text.py +211 -0
- tlgr/core/timefmt.py +199 -0
- tlgr/core/tl.py +98 -0
- tlgr/daemon/__init__.py +0 -0
- tlgr/daemon/app.py +869 -0
- tlgr/daemon/dispatch.py +446 -0
- tlgr/daemon/events.py +723 -0
- tlgr/daemon/files.py +431 -0
- tlgr/daemon/idle.py +119 -0
- tlgr/daemon/jobs.py +68 -0
- tlgr/daemon/main.py +161 -0
- tlgr/daemon/peercred.py +75 -0
- tlgr/daemon/policy.py +113 -0
- tlgr/daemon/preauth.py +366 -0
- tlgr/daemon/ratelimit.py +391 -0
- tlgr/daemon/server.py +24 -0
- tlgr/daemon/session.py +648 -0
- tlgr/daemon/sessions.py +274 -0
- tlgr/daemon/singleton.py +114 -0
- tlgr/daemon/stream.py +193 -0
- tlgr/daemon/transfers.py +219 -0
- tlgr/daemon/webhook.py +390 -0
- tlgr/data/catalog_index.json +1 -0
- tlgr/data/parity_waivers.toml +90 -0
- tlgr/filters/__init__.py +42 -0
- tlgr/filters/compose.py +121 -0
- tlgr/filters/content.py +85 -0
- tlgr/filters/context.py +114 -0
- tlgr/filters/message.py +161 -0
- tlgr/filters/temporal.py +87 -0
- tlgr/filters/user.py +36 -0
- tlgr/gateway/__init__.py +1 -0
- tlgr/gateway/config.py +161 -0
- tlgr/gateway/engine.py +215 -0
- tlgr/gateway/event.py +22 -0
- tlgr/jobs/__init__.py +0 -0
- tlgr/jobs/base.py +81 -0
- tlgr/jobs/client.py +37 -0
- tlgr/models/__init__.py +1220 -0
- tlgr/models/admin.py +744 -0
- tlgr/models/auth.py +510 -0
- tlgr/models/base.py +81 -0
- tlgr/models/bot.py +576 -0
- tlgr/models/business.py +265 -0
- tlgr/models/call.py +586 -0
- tlgr/models/config.py +101 -0
- tlgr/models/contact.py +481 -0
- tlgr/models/daemon.py +336 -0
- tlgr/models/dialog.py +626 -0
- tlgr/models/envelope.py +68 -0
- tlgr/models/error.py +30 -0
- tlgr/models/event.py +79 -0
- tlgr/models/export.py +66 -0
- tlgr/models/gift.py +275 -0
- tlgr/models/inline.py +84 -0
- tlgr/models/location.py +115 -0
- tlgr/models/media.py +507 -0
- tlgr/models/message.py +584 -0
- tlgr/models/net.py +232 -0
- tlgr/models/notify.py +105 -0
- tlgr/models/page.py +32 -0
- tlgr/models/payment.py +172 -0
- tlgr/models/peer.py +400 -0
- tlgr/models/poll.py +119 -0
- tlgr/models/premium.py +161 -0
- tlgr/models/privacy.py +93 -0
- tlgr/models/profile.py +217 -0
- tlgr/models/reaction.py +160 -0
- tlgr/models/resolve.py +175 -0
- tlgr/models/settings.py +103 -0
- tlgr/models/stars.py +101 -0
- tlgr/models/sticker.py +243 -0
- tlgr/models/story.py +467 -0
- tlgr/models/sync.py +105 -0
- tlgr/models/todo.py +36 -0
- tlgr/models/webapp.py +89 -0
- tlgr/ops/__init__.py +63 -0
- tlgr/ops/_admin.py +313 -0
- tlgr/ops/_auth.py +599 -0
- tlgr/ops/_bots.py +586 -0
- tlgr/ops/_calls.py +535 -0
- tlgr/ops/_common.py +160 -0
- tlgr/ops/_layer.py +46 -0
- tlgr/ops/_media.py +592 -0
- tlgr/ops/_params.py +212 -0
- tlgr/ops/_rights.py +402 -0
- tlgr/ops/_send.py +593 -0
- tlgr/ops/_serialize.py +667 -0
- tlgr/ops/_settings.py +306 -0
- tlgr/ops/_spec.py +167 -0
- tlgr/ops/_story.py +743 -0
- tlgr/ops/account.py +2604 -0
- tlgr/ops/agent.py +937 -0
- tlgr/ops/auth.py +1282 -0
- tlgr/ops/bot.py +4880 -0
- tlgr/ops/business.py +1520 -0
- tlgr/ops/call.py +1610 -0
- tlgr/ops/chat.py +4025 -0
- tlgr/ops/chat_admin.py +929 -0
- tlgr/ops/chat_extra.py +1061 -0
- tlgr/ops/chat_invite.py +716 -0
- tlgr/ops/chat_manage.py +1691 -0
- tlgr/ops/chat_member.py +1357 -0
- tlgr/ops/chat_stats.py +902 -0
- tlgr/ops/chat_topic.py +905 -0
- tlgr/ops/conference.py +791 -0
- tlgr/ops/config.py +1698 -0
- tlgr/ops/contact.py +2330 -0
- tlgr/ops/daemon.py +1397 -0
- tlgr/ops/draft.py +299 -0
- tlgr/ops/emoji.py +343 -0
- tlgr/ops/events.py +1327 -0
- tlgr/ops/export.py +596 -0
- tlgr/ops/folder.py +1322 -0
- tlgr/ops/gif.py +522 -0
- tlgr/ops/gift.py +1546 -0
- tlgr/ops/giveaway.py +541 -0
- tlgr/ops/inline.py +773 -0
- tlgr/ops/job.py +799 -0
- tlgr/ops/location.py +917 -0
- tlgr/ops/media.py +4495 -0
- tlgr/ops/message.py +3769 -0
- tlgr/ops/net.py +536 -0
- tlgr/ops/notify.py +840 -0
- tlgr/ops/passport.py +464 -0
- tlgr/ops/payment.py +907 -0
- tlgr/ops/poll.py +1078 -0
- tlgr/ops/premium.py +488 -0
- tlgr/ops/privacy.py +794 -0
- tlgr/ops/profile.py +1481 -0
- tlgr/ops/proxy.py +750 -0
- tlgr/ops/reaction.py +1475 -0
- tlgr/ops/resolve.py +1140 -0
- tlgr/ops/search.py +521 -0
- tlgr/ops/settings.py +1066 -0
- tlgr/ops/stars.py +594 -0
- tlgr/ops/sticker.py +1602 -0
- tlgr/ops/story.py +3216 -0
- tlgr/ops/sync.py +788 -0
- tlgr/ops/todo.py +514 -0
- tlgr/ops/user.py +1406 -0
- tlgr/ops/vc.py +2351 -0
- tlgr/ops/webapp.py +717 -0
- tlgr/ops/webhook.py +418 -0
- tlgr/parity.py +386 -0
- tlgr/processors/__init__.py +125 -0
- tlgr/processors/regex.py +26 -0
- tlgr/processors/text.py +56 -0
- tlgr/registry.py +519 -0
- tlgr/schema.py +173 -0
- tlgr/transport/__init__.py +30 -0
- tlgr/transport/autostart.py +293 -0
- tlgr/transport/client.py +805 -0
- tlgr/transport/ndjson.py +44 -0
- tlgr/version.py +31 -0
- tlgr_cli-2.0.1.dist-info/METADATA +957 -0
- tlgr_cli-2.0.1.dist-info/RECORD +192 -0
- tlgr_cli-2.0.1.dist-info/WHEEL +5 -0
- tlgr_cli-2.0.1.dist-info/entry_points.txt +2 -0
- tlgr_cli-2.0.1.dist-info/licenses/LICENSE +21 -0
- tlgr_cli-2.0.1.dist-info/top_level.txt +1 -0
tlgr/models/net.py
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"""Network, data-centre, proxy and server-configuration shapes.
|
|
2
|
+
|
|
3
|
+
The distinction these encode is the one v1 never made: **the server's
|
|
4
|
+
configuration** (`help.getConfig`, `help.getAppConfig`) is not the same thing
|
|
5
|
+
as **the connection** (which DC, which transport, how far the clock is off),
|
|
6
|
+
and neither is **the proxy** (a client-side list with credentials in a 0600
|
|
7
|
+
file). Three nouns, three shapes.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
from tlgr.models.base import Model
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"AppConfigDoc",
|
|
18
|
+
"Country",
|
|
19
|
+
"CountryCode",
|
|
20
|
+
"DcOption",
|
|
21
|
+
"InfoTopic",
|
|
22
|
+
"NearestDc",
|
|
23
|
+
"NetStatus",
|
|
24
|
+
"NetUsage",
|
|
25
|
+
"PingResult",
|
|
26
|
+
"PromoData",
|
|
27
|
+
"Proxy",
|
|
28
|
+
"ProxyLink",
|
|
29
|
+
"ProxyProbe",
|
|
30
|
+
"ProxySelection",
|
|
31
|
+
"ServerConfig",
|
|
32
|
+
"SyncCursors",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class DcOption(Model):
|
|
37
|
+
id: int
|
|
38
|
+
ip_address: str = ""
|
|
39
|
+
port: int = 0
|
|
40
|
+
ipv6: bool = False
|
|
41
|
+
media_only: bool = False
|
|
42
|
+
tcpo_only: bool = False
|
|
43
|
+
cdn: bool = False
|
|
44
|
+
static: bool = False
|
|
45
|
+
this_port_only: bool = False
|
|
46
|
+
secret: str | None = None
|
|
47
|
+
current: bool = False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class NearestDc(Model):
|
|
51
|
+
country: str = ""
|
|
52
|
+
this_dc: int = 0
|
|
53
|
+
nearest_dc: int = 0
|
|
54
|
+
current_dc: int | None = None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class PingResult(Model):
|
|
58
|
+
account: str = ""
|
|
59
|
+
dc_id: int | None = None
|
|
60
|
+
proxy: str | None = None
|
|
61
|
+
probes: int = 0
|
|
62
|
+
min_ms: float | None = None
|
|
63
|
+
avg_ms: float | None = None
|
|
64
|
+
max_ms: float | None = None
|
|
65
|
+
loss: float = 0.0
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class SyncCursors(Model):
|
|
69
|
+
"""pts/qts/seq/date, the four numbers the update transport turns on."""
|
|
70
|
+
|
|
71
|
+
pts: int | None = None
|
|
72
|
+
qts: int | None = None
|
|
73
|
+
seq: int | None = None
|
|
74
|
+
date: str | None = None
|
|
75
|
+
date_unix: int | None = None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class NetStatus(Model):
|
|
79
|
+
account: str = ""
|
|
80
|
+
authorized: bool = False
|
|
81
|
+
connected: bool = False
|
|
82
|
+
phase: str = "disconnected"
|
|
83
|
+
dc_id: int | None = None
|
|
84
|
+
dc_address: str | None = None
|
|
85
|
+
ipv6: bool = False
|
|
86
|
+
transport: str = ""
|
|
87
|
+
proxy: str | None = None
|
|
88
|
+
ping_ms: float | None = None
|
|
89
|
+
layer: int = 0
|
|
90
|
+
#: |offset| > 30 s is reported as a warning: it pushes msg_ids outside the
|
|
91
|
+
#: server's window, and requests are then dropped with no error at all.
|
|
92
|
+
time_offset_seconds: int = 0
|
|
93
|
+
exported_senders: int = 0
|
|
94
|
+
reconnects: int = 0
|
|
95
|
+
last_error: str | None = None
|
|
96
|
+
state: SyncCursors | None = None
|
|
97
|
+
behind_seconds: int | None = None
|
|
98
|
+
frozen: bool = False
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class NetUsage(Model):
|
|
102
|
+
account: str = ""
|
|
103
|
+
since: str = ""
|
|
104
|
+
rpc_bytes_sent: int = 0
|
|
105
|
+
rpc_bytes_received: int = 0
|
|
106
|
+
download_bytes: int = 0
|
|
107
|
+
upload_bytes: int = 0
|
|
108
|
+
requests: int = 0
|
|
109
|
+
updates_received: int = 0
|
|
110
|
+
reconnects: int = 0
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class Proxy(Model):
|
|
114
|
+
"""A saved proxy. Credentials live in a 0600 file and are never printed."""
|
|
115
|
+
|
|
116
|
+
id: str
|
|
117
|
+
name: str = ""
|
|
118
|
+
type: str = "socks5"
|
|
119
|
+
host: str = ""
|
|
120
|
+
port: int = 0
|
|
121
|
+
user: str | None = None
|
|
122
|
+
rdns: bool = True
|
|
123
|
+
active: bool = False
|
|
124
|
+
order: int = 0
|
|
125
|
+
last_ping_ms: float | None = None
|
|
126
|
+
last_ok_at: str | None = None
|
|
127
|
+
failures: int = 0
|
|
128
|
+
has_password: bool = False
|
|
129
|
+
has_secret: bool = False
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ProxyProbe(Model):
|
|
133
|
+
id: str = ""
|
|
134
|
+
name: str = ""
|
|
135
|
+
ok: bool = False
|
|
136
|
+
ping_ms: float | None = None
|
|
137
|
+
dc_id: int | None = None
|
|
138
|
+
error: str | None = None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class ProxyLink(Model):
|
|
142
|
+
id: str
|
|
143
|
+
link: str
|
|
144
|
+
type: str = ""
|
|
145
|
+
host: str = ""
|
|
146
|
+
port: int = 0
|
|
147
|
+
qr: str | None = None
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class ProxySelection(Model):
|
|
151
|
+
active: str | None = None
|
|
152
|
+
type: str = ""
|
|
153
|
+
host: str = ""
|
|
154
|
+
port: int = 0
|
|
155
|
+
reconnected: bool = False
|
|
156
|
+
accounts: list[str] = []
|
|
157
|
+
removed: bool = False
|
|
158
|
+
was_active: bool = False
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ServerConfig(Model):
|
|
162
|
+
"""`help.getConfig`, the fields a client actually acts on."""
|
|
163
|
+
|
|
164
|
+
expires: str | None = None
|
|
165
|
+
test_mode: bool = False
|
|
166
|
+
this_dc: int = 0
|
|
167
|
+
date: str | None = None
|
|
168
|
+
date_unix: int | None = None
|
|
169
|
+
chat_size_max: int = 0
|
|
170
|
+
megagroup_size_max: int = 0
|
|
171
|
+
message_length_max: int = 0
|
|
172
|
+
caption_length_max: int = 0
|
|
173
|
+
online_update_period_ms: int = 0
|
|
174
|
+
offline_blur_timeout_ms: int = 0
|
|
175
|
+
offline_idle_timeout_ms: int = 0
|
|
176
|
+
edit_time_limit: int = 0
|
|
177
|
+
revoke_time_limit: int = 0
|
|
178
|
+
rating_e_decay: int = 0
|
|
179
|
+
forwarded_count_max: int = 0
|
|
180
|
+
push_chat_period_ms: int = 0
|
|
181
|
+
dc_options: list[DcOption] = []
|
|
182
|
+
values: dict[str, Any] = {}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
class AppConfigDoc(Model):
|
|
186
|
+
"""`help.getAppConfig`, hash-cached, with the freeze fields lifted out."""
|
|
187
|
+
|
|
188
|
+
hash: int = 0
|
|
189
|
+
not_modified: bool = False
|
|
190
|
+
freeze_since_date: str | None = None
|
|
191
|
+
freeze_until_date: str | None = None
|
|
192
|
+
freeze_appeal_url: str | None = None
|
|
193
|
+
values: dict[str, Any] = {}
|
|
194
|
+
config: ServerConfig | None = None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class CountryCode(Model):
|
|
198
|
+
country_code: str = ""
|
|
199
|
+
prefixes: list[str] = []
|
|
200
|
+
patterns: list[str] = []
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class Country(Model):
|
|
204
|
+
iso2: str
|
|
205
|
+
name: str = ""
|
|
206
|
+
default_name: str = ""
|
|
207
|
+
hidden: bool = False
|
|
208
|
+
flag_emoji: str = ""
|
|
209
|
+
preferred_language: str = ""
|
|
210
|
+
codes: list[CountryCode] = []
|
|
211
|
+
#: Filled only by `--phone`: what the number was classified as.
|
|
212
|
+
matched_prefix: str | None = None
|
|
213
|
+
valid: bool | None = None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class InfoTopic(Model):
|
|
217
|
+
"""One of the flat `help.*` / `langpack.*` read-only endpoints."""
|
|
218
|
+
|
|
219
|
+
topic: str
|
|
220
|
+
items: list[dict[str, Any]] = []
|
|
221
|
+
raw: dict[str, Any] = {}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class PromoData(Model):
|
|
225
|
+
kind: str = "none"
|
|
226
|
+
chat_id: int | None = None
|
|
227
|
+
psa_type: str | None = None
|
|
228
|
+
psa_message: str | None = None
|
|
229
|
+
proxy: bool = False
|
|
230
|
+
expires: str | None = None
|
|
231
|
+
hidden: bool = False
|
|
232
|
+
pending_suggestions: list[str] = []
|
tlgr/models/notify.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""The Notifications screen: scopes, per-chat exceptions, reactions, sounds.
|
|
2
|
+
|
|
3
|
+
Telegram spreads one screen over three unrelated APIs — `getNotifySettings`
|
|
4
|
+
for the scopes and the chats, `getReactionsNotifySettings` for the reaction
|
|
5
|
+
alerts, `getContactSignUpNotification` for "X joined Telegram" — so the
|
|
6
|
+
model, like the command, is one shape with a `target` naming which of them
|
|
7
|
+
answered.
|
|
8
|
+
|
|
9
|
+
`mute_until` is an **absolute UNIX timestamp**, and the second field exists
|
|
10
|
+
to say so. v1 computed it from the asyncio event loop's clock, which is an
|
|
11
|
+
arbitrary monotonic origin: "mute for an hour" produced a timestamp somewhere
|
|
12
|
+
in 1970 and the chat was never muted at all.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
from tlgr.models.base import Model
|
|
18
|
+
from tlgr.models.dialog import NotifySettings
|
|
19
|
+
from tlgr.models.peer import Peer
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ExceptionsCleared",
|
|
23
|
+
"NotifyException",
|
|
24
|
+
"NotifyReset",
|
|
25
|
+
"NotifyTarget",
|
|
26
|
+
"Ringtone",
|
|
27
|
+
"RingtoneSaved",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class NotifyTarget(Model):
|
|
32
|
+
"""Notification settings for one target, whatever kind of target it is.
|
|
33
|
+
|
|
34
|
+
`target` is the word the caller typed (`private`, `groups`, `channels`,
|
|
35
|
+
`stories`, `reactions`, `contact-joined`, or a chat reference), so the
|
|
36
|
+
answer can be piped straight back into `notify set`.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
target: str
|
|
40
|
+
kind: str = "scope"
|
|
41
|
+
chat_id: int | None = None
|
|
42
|
+
chat: Peer | None = None
|
|
43
|
+
topic: int | None = None
|
|
44
|
+
settings: NotifySettings | None = None
|
|
45
|
+
muted: bool | None = None
|
|
46
|
+
mute_until: str | None = None
|
|
47
|
+
mute_until_unix: int | None = None
|
|
48
|
+
show_previews: bool | None = None
|
|
49
|
+
sound: str | None = None
|
|
50
|
+
stories_muted: bool | None = None
|
|
51
|
+
stories_hide_sender: bool | None = None
|
|
52
|
+
stories_sound: str | None = None
|
|
53
|
+
#: `reactions` target: contacts | all | off, one per alert kind.
|
|
54
|
+
messages_from: str | None = None
|
|
55
|
+
stories_from: str | None = None
|
|
56
|
+
poll_votes_from: str | None = None
|
|
57
|
+
#: `contact-joined` target. Stored inverted on the wire (`silent=true`).
|
|
58
|
+
contact_joined: bool | None = None
|
|
59
|
+
changed: list[str] = []
|
|
60
|
+
already: bool = False
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class NotifyException(Model):
|
|
64
|
+
"""A chat whose settings differ from its scope default."""
|
|
65
|
+
|
|
66
|
+
chat_id: int
|
|
67
|
+
chat: Peer | None = None
|
|
68
|
+
title: str = ""
|
|
69
|
+
muted: bool = False
|
|
70
|
+
mute_until: str | None = None
|
|
71
|
+
mute_until_unix: int | None = None
|
|
72
|
+
show_previews: bool | None = None
|
|
73
|
+
sound: str | None = None
|
|
74
|
+
stories_muted: bool | None = None
|
|
75
|
+
scope: str = ""
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ExceptionsCleared(Model):
|
|
79
|
+
cleared: int = 0
|
|
80
|
+
chat_ids: list[int] = []
|
|
81
|
+
scope: str | None = None
|
|
82
|
+
already: bool = False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class NotifyReset(Model):
|
|
86
|
+
ok: bool
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class Ringtone(Model):
|
|
90
|
+
id: int
|
|
91
|
+
access_hash: int | None = None
|
|
92
|
+
file_name: str = ""
|
|
93
|
+
mime_type: str = ""
|
|
94
|
+
size: int = 0
|
|
95
|
+
duration: int | None = None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class RingtoneSaved(Model):
|
|
99
|
+
id: int | None = None
|
|
100
|
+
file_name: str | None = None
|
|
101
|
+
#: The server may hand back a *new* document id when an existing voice
|
|
102
|
+
#: message is saved as a ringtone; using the old one afterwards fails.
|
|
103
|
+
converted: bool = False
|
|
104
|
+
removed: bool = False
|
|
105
|
+
already: bool = False
|
tlgr/models/page.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""The one paginated shape: `Page[T]`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Generic, TypeVar
|
|
6
|
+
|
|
7
|
+
from tlgr.models.base import Model
|
|
8
|
+
|
|
9
|
+
__all__ = ["Page", "PageInfo"]
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Page(Model, Generic[T]):
|
|
15
|
+
"""A slice of a longer list.
|
|
16
|
+
|
|
17
|
+
`total` is the server's own count where it gives one and `null` otherwise;
|
|
18
|
+
it is never estimated, because a wrong total is worse than no total.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
items: list[T] = []
|
|
22
|
+
has_more: bool = False
|
|
23
|
+
next_cursor: str | None = None
|
|
24
|
+
total: int | None = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class PageInfo(Model):
|
|
28
|
+
"""The pagination half of a response envelope, without the items."""
|
|
29
|
+
|
|
30
|
+
has_more: bool = False
|
|
31
|
+
next_cursor: str | None = None
|
|
32
|
+
total: int | None = None
|
tlgr/models/payment.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""Payments, read-only by design.
|
|
2
|
+
|
|
3
|
+
tlgr models the whole checkout surface — the invoice, the form, the receipt,
|
|
4
|
+
the subscription — and implements every verb that does *not* move money.
|
|
5
|
+
`PaymentForm.payable_here` is therefore always false and carries the reason:
|
|
6
|
+
the shape a caller needs in order to decide is here, the button that would
|
|
7
|
+
charge is deliberately not, and saying so in the payload is better than
|
|
8
|
+
leaving a caller to discover it from an exit code.
|
|
9
|
+
|
|
10
|
+
Amounts are integers in the smallest unit of `currency`, exactly as Telegram
|
|
11
|
+
sends them (`XTR` means Telegram Stars, whose smallest unit is one Star).
|
|
12
|
+
Rounding them into a float here would lose money in the last decimal on every
|
|
13
|
+
currency that has three of them.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
from tlgr.models.base import Model
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"BankCard",
|
|
24
|
+
"Invoice",
|
|
25
|
+
"InvoiceLink",
|
|
26
|
+
"InvoiceSent",
|
|
27
|
+
"PaymentForm",
|
|
28
|
+
"PaymentInfo",
|
|
29
|
+
"PaymentInfoCleared",
|
|
30
|
+
"PriceLine",
|
|
31
|
+
"Receipt",
|
|
32
|
+
"StarSubscription",
|
|
33
|
+
"SubscriptionChange",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class PriceLine(Model):
|
|
38
|
+
label: str = ""
|
|
39
|
+
amount: int = 0
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class Invoice(Model):
|
|
43
|
+
"""The invoice itself: what is being charged for, and what it needs."""
|
|
44
|
+
|
|
45
|
+
currency: str = ""
|
|
46
|
+
total_amount: int = 0
|
|
47
|
+
prices: list[PriceLine] = []
|
|
48
|
+
test: bool = False
|
|
49
|
+
name_requested: bool = False
|
|
50
|
+
phone_requested: bool = False
|
|
51
|
+
email_requested: bool = False
|
|
52
|
+
shipping_address_requested: bool = False
|
|
53
|
+
flexible: bool = False
|
|
54
|
+
recurring: bool = False
|
|
55
|
+
terms_url: str | None = None
|
|
56
|
+
subscription_period: int | None = None
|
|
57
|
+
max_tip_amount: int | None = None
|
|
58
|
+
suggested_tip_amounts: list[int] = []
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class PaymentForm(Model):
|
|
62
|
+
"""A checkout form, read without paying for it."""
|
|
63
|
+
|
|
64
|
+
form_kind: str = "form"
|
|
65
|
+
form_id: int = 0
|
|
66
|
+
bot_id: int | None = None
|
|
67
|
+
provider_id: int | None = None
|
|
68
|
+
title: str | None = None
|
|
69
|
+
description: str | None = None
|
|
70
|
+
photo: str | None = None
|
|
71
|
+
invoice: Invoice | None = None
|
|
72
|
+
currency: str = ""
|
|
73
|
+
total_amount: int = 0
|
|
74
|
+
prices: list[PriceLine] = []
|
|
75
|
+
tip_amounts: list[int] = []
|
|
76
|
+
recurring: bool = False
|
|
77
|
+
terms_url: str | None = None
|
|
78
|
+
subscription_period: int | None = None
|
|
79
|
+
url: str | None = None
|
|
80
|
+
native_provider: str | None = None
|
|
81
|
+
native_params: Any = None
|
|
82
|
+
additional_methods: list[dict[str, Any]] = []
|
|
83
|
+
saved_info: dict[str, Any] | None = None
|
|
84
|
+
saved_credentials: list[dict[str, Any]] = []
|
|
85
|
+
can_save_credentials: bool = False
|
|
86
|
+
password_missing: bool = False
|
|
87
|
+
expires_at: str | None = None
|
|
88
|
+
#: Always false, and always *emitted*: an omitted flag would leave a
|
|
89
|
+
#: caller to infer the policy, and `reason` says which one it is.
|
|
90
|
+
payable_here: bool | None = None
|
|
91
|
+
reason: str = ""
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class Receipt(Model):
|
|
95
|
+
date: str | None = None
|
|
96
|
+
date_unix: int | None = None
|
|
97
|
+
bot_id: int | None = None
|
|
98
|
+
provider_id: int | None = None
|
|
99
|
+
title: str | None = None
|
|
100
|
+
description: str | None = None
|
|
101
|
+
invoice: Invoice | None = None
|
|
102
|
+
currency: str = ""
|
|
103
|
+
total_amount: int = 0
|
|
104
|
+
tip_amount: int | None = None
|
|
105
|
+
credentials_title: str | None = None
|
|
106
|
+
shipping: dict[str, Any] | None = None
|
|
107
|
+
info: dict[str, Any] | None = None
|
|
108
|
+
transaction_id: str | None = None
|
|
109
|
+
recurring: bool = False
|
|
110
|
+
refunded: bool = False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class PaymentInfo(Model):
|
|
114
|
+
"""My saved order information and saved cards. Never a card number."""
|
|
115
|
+
|
|
116
|
+
has_saved_credentials: bool | None = None
|
|
117
|
+
credentials: list[dict[str, Any]] = []
|
|
118
|
+
saved_info: dict[str, Any] | None = None
|
|
119
|
+
name: str | None = None
|
|
120
|
+
phone: str | None = None
|
|
121
|
+
email: str | None = None
|
|
122
|
+
shipping: dict[str, Any] | None = None
|
|
123
|
+
has_saved_info: bool | None = None
|
|
124
|
+
cleared: bool = False
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class PaymentInfoCleared(Model):
|
|
128
|
+
credentials_cleared: bool | None = None
|
|
129
|
+
info_cleared: bool | None = None
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class InvoiceLink(Model):
|
|
133
|
+
url: str = ""
|
|
134
|
+
slug: str = ""
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class InvoiceSent(Model):
|
|
138
|
+
chat_id: int = 0
|
|
139
|
+
msg_id: int = 0
|
|
140
|
+
slug: str | None = None
|
|
141
|
+
currency: str = ""
|
|
142
|
+
total_amount: int = 0
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class BankCard(Model):
|
|
146
|
+
title: str = ""
|
|
147
|
+
open_urls: list[dict[str, str]] = []
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class StarSubscription(Model):
|
|
151
|
+
id: str = ""
|
|
152
|
+
peer: int | None = None
|
|
153
|
+
until_date: str | None = None
|
|
154
|
+
until_date_unix: int | None = None
|
|
155
|
+
pricing: dict[str, int] | None = None
|
|
156
|
+
cancelled: bool | None = None
|
|
157
|
+
#: Re-joining a lapsed subscription debits Stars, so tlgr reports that the
|
|
158
|
+
#: server would allow it and still refuses to do it.
|
|
159
|
+
can_refulfill: bool | None = None
|
|
160
|
+
missing_balance: bool | None = None
|
|
161
|
+
invoice_slug: str | None = None
|
|
162
|
+
chat_invite_hash: str | None = None
|
|
163
|
+
title: str | None = None
|
|
164
|
+
photo: str | None = None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class SubscriptionChange(Model):
|
|
168
|
+
subscription_id: str | None = None
|
|
169
|
+
user_id: int | None = None
|
|
170
|
+
charge_id: str | None = None
|
|
171
|
+
cancelled: bool | None = None
|
|
172
|
+
until_date: str | None = None
|