AdvancedTagScript 3.3.0__tar.gz → 3.3.2__tar.gz
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.
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/PKG-INFO +1 -1
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/PKG-INFO +1 -1
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/__init__.py +1 -1
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/discordadapters.py +15 -17
- advancedtagscript-3.3.2/TagScriptEngine/adapter/redbotadapters.py +232 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/assign.py +11 -5
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/utils.py +0 -2
- advancedtagscript-3.3.0/TagScriptEngine/adapter/redbotadapters.py +0 -161
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/SOURCES.txt +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/dependency_links.txt +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/requires.txt +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/top_level.txt +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/LICENSE +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/MANIFEST.in +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/README.md +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/_warnings.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/__init__.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/functionadapter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/intadapter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/objectadapter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/stringadapter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/__init__.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/allowedmentions.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/breakblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/case.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/command.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/control.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/cooldown.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/count.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/cycleblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/embedblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/fiftyfifty.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/helpers.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/joinblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/listblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/loosevariablegetter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/mathblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/ordblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/randomblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/range.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/redirect.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/replaceblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/require_blacklist.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/shortcutredirect.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/stopblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/strf.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/strictvariablegetter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/substr.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/urlencodeblock.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/exceptions.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/interface/__init__.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/interface/adapter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/interface/block.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/interpreter.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/py.typed +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/verb.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/pyproject.toml +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/setup.cfg +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/setup.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/tests/test_adapters.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/tests/test_basic.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/tests/test_edgecase.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/tests/test_escapes.py +0 -0
- {advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/tests/test_verbs.py +0 -0
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/discordadapters.py
RENAMED
|
@@ -103,7 +103,6 @@ class DiscordAttributeAdapter(
|
|
|
103
103
|
]
|
|
104
104
|
):
|
|
105
105
|
"""
|
|
106
|
-
.. versionadded:: 3.2.0
|
|
107
106
|
"""
|
|
108
107
|
|
|
109
108
|
def __init__(
|
|
@@ -191,7 +190,6 @@ class UserAdapter(DiscordAttributeAdapter):
|
|
|
191
190
|
avatar_decoration
|
|
192
191
|
A link to the user's avatar decoration.
|
|
193
192
|
|
|
194
|
-
.. versionadded:: 3.2.0
|
|
195
193
|
"""
|
|
196
194
|
|
|
197
195
|
def update_attributes(self) -> None:
|
|
@@ -260,16 +258,26 @@ class MemberAdapter(DiscordAttributeAdapter):
|
|
|
260
258
|
If the user has boosted, this will be the UTC timestamp of when they did,
|
|
261
259
|
if not this will be empty.
|
|
262
260
|
timed_out
|
|
263
|
-
If the user is timed out,
|
|
264
|
-
|
|
261
|
+
If the user is currently timed out, the datetime of when the timeout ends;
|
|
262
|
+
otherwise ``False``.
|
|
265
263
|
banner
|
|
266
|
-
The
|
|
264
|
+
The user's banner url, if available. A banner is not delivered over the
|
|
265
|
+
gateway, so the bare engine only sees it when the member was retrieved
|
|
266
|
+
via an explicit REST fetch - otherwise this is empty for cached members.
|
|
267
|
+
The Tags cog resolves it lazily (fetching only when a tag uses ``banner``,
|
|
268
|
+
with caching and a per-user cooldown), so there it is populated on demand.
|
|
267
269
|
"""
|
|
268
270
|
|
|
269
271
|
def update_attributes(self) -> None:
|
|
270
272
|
object: discord.Member = cast(discord.Member, self.object)
|
|
271
273
|
avatar_url: str = object.display_avatar.url
|
|
272
274
|
joined_at: datetime.datetime = getattr(object, "joined_at", self.object.created_at)
|
|
275
|
+
# So ``timed_out_until`` must be compared against the current time.
|
|
276
|
+
# And Returns ``False`` when the member isn't currently timed out.
|
|
277
|
+
timed_out_until: Any = getattr(object, "timed_out_until", None)
|
|
278
|
+
is_timed_out: bool = bool(timed_out_until) and timed_out_until > discord.utils.utcnow()
|
|
279
|
+
# ``Member.banner``/``display_banner`` is now explicitly fetched.
|
|
280
|
+
banner: Any = getattr(object, "display_banner", None) or getattr(object, "banner", None)
|
|
273
281
|
additional_attributes: Dict[str, Any] = {
|
|
274
282
|
"color": object.color,
|
|
275
283
|
"colour": object.color,
|
|
@@ -282,8 +290,8 @@ class MemberAdapter(DiscordAttributeAdapter):
|
|
|
282
290
|
"bot": object.bot,
|
|
283
291
|
"top_role": getattr(object, "top_role", ""),
|
|
284
292
|
"boost": getattr(object, "premium_since", ""),
|
|
285
|
-
"timed_out":
|
|
286
|
-
"banner":
|
|
293
|
+
"timed_out": timed_out_until if is_timed_out else False,
|
|
294
|
+
"banner": banner.url if banner else "",
|
|
287
295
|
}
|
|
288
296
|
if roleids := getattr(self.object, "_roles", None):
|
|
289
297
|
additional_attributes["roleids"] = " ".join(str(r) for r in roleids)
|
|
@@ -315,7 +323,6 @@ class DMChannelAdapter(DiscordAttributeAdapter):
|
|
|
315
323
|
jump_url
|
|
316
324
|
A link to the channel.
|
|
317
325
|
|
|
318
|
-
.. versionadded:: 3.2.0
|
|
319
326
|
"""
|
|
320
327
|
|
|
321
328
|
def update_attributes(self) -> None:
|
|
@@ -359,9 +366,6 @@ class ChannelAdapter(DiscordAttributeAdapter):
|
|
|
359
366
|
If no category channel, this will return empty.
|
|
360
367
|
jump_url
|
|
361
368
|
A link to the channel.
|
|
362
|
-
|
|
363
|
-
.. versionchanged:: 3.2.0
|
|
364
|
-
Added ``jump_url`` as a parameter.
|
|
365
369
|
"""
|
|
366
370
|
|
|
367
371
|
def update_attributes(self) -> None:
|
|
@@ -429,10 +433,6 @@ class GuildAdapter(DiscordAttributeAdapter):
|
|
|
429
433
|
A link to the server's invite splash.
|
|
430
434
|
banner
|
|
431
435
|
A link to the server's banner.
|
|
432
|
-
|
|
433
|
-
.. versionchanged:: 3.2.0
|
|
434
|
-
Added ``mfa``, ``boosters``, ``boost_level``,
|
|
435
|
-
``discovery_splash``, ``invite_splash`` & ``banner``.
|
|
436
436
|
"""
|
|
437
437
|
|
|
438
438
|
def update_attributes(self) -> None:
|
|
@@ -509,7 +509,6 @@ class RoleAdapter(DiscordAttributeAdapter):
|
|
|
509
509
|
position
|
|
510
510
|
The role's position.
|
|
511
511
|
|
|
512
|
-
.. versionadded:: 3.2.0
|
|
513
512
|
"""
|
|
514
513
|
|
|
515
514
|
def update_attributes(self) -> None:
|
|
@@ -546,7 +545,6 @@ class DiscordObjectAdapter(Adapter):
|
|
|
546
545
|
timestamp
|
|
547
546
|
The object's creation date as a UTC timestamp.
|
|
548
547
|
|
|
549
|
-
.. versionadded:: 3.2.0
|
|
550
548
|
"""
|
|
551
549
|
|
|
552
550
|
__slots__: Tuple[str, ...] = ("object", "_attributes", "_methods")
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
from typing import Any, Optional, Tuple, cast
|
|
5
|
+
|
|
6
|
+
import discord
|
|
7
|
+
|
|
8
|
+
from ..verb import Verb
|
|
9
|
+
from ..interface import SimpleAdapter
|
|
10
|
+
from ..utils import escape_content
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import redbot # noqa: F401
|
|
14
|
+
except ModuleNotFoundError:
|
|
15
|
+
_has_redbot = False
|
|
16
|
+
else:
|
|
17
|
+
_has_redbot = True
|
|
18
|
+
|
|
19
|
+
from redbot.core.bot import Red
|
|
20
|
+
from redbot.core.commands import Command
|
|
21
|
+
from redbot.core.utils.chat_formatting import humanize_number, humanize_list
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
__all__: Tuple[str, ...] = ("RedCommandAdapter", "RedBotAdapter")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RedCommandAdapter(SimpleAdapter["Command"]):
|
|
28
|
+
"""
|
|
29
|
+
The ``{commandinfo}`` block reads a command's metadata and returns it as
|
|
30
|
+
text. Unlike the :ref:`Command Block`, it does **not** run the command.
|
|
31
|
+
See the attribute list below.
|
|
32
|
+
|
|
33
|
+
**Usage:** ``{commandinfo([attribute]):<command>}``
|
|
34
|
+
|
|
35
|
+
**Payload:** command (supplied by the block)
|
|
36
|
+
|
|
37
|
+
**Parameter:** attribute, None
|
|
38
|
+
|
|
39
|
+
Attributes
|
|
40
|
+
----------
|
|
41
|
+
name
|
|
42
|
+
The command's name.
|
|
43
|
+
qualified_name
|
|
44
|
+
The command's full name, including any parent groups.
|
|
45
|
+
cog_name
|
|
46
|
+
The name of the cog the command belongs to.
|
|
47
|
+
description
|
|
48
|
+
The command's description. Most commands leave this unset, so it falls
|
|
49
|
+
back to the help text's first line (``short_doc``) when empty.
|
|
50
|
+
short_doc
|
|
51
|
+
The first line of the command's help text.
|
|
52
|
+
help
|
|
53
|
+
The command's full help text (its docstring).
|
|
54
|
+
aliases
|
|
55
|
+
The command's aliases, or ``None`` if it has none.
|
|
56
|
+
signature
|
|
57
|
+
The command's argument signature. Empty for commands that take no
|
|
58
|
+
arguments.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, base: Command, *, signature: Optional[str] = None) -> None:
|
|
62
|
+
if not _has_redbot:
|
|
63
|
+
raise ImportError(
|
|
64
|
+
"A Red-DiscordBot instance is required to use this.", name="redbot"
|
|
65
|
+
)
|
|
66
|
+
self.signature: Optional[str] = signature
|
|
67
|
+
super().__init__(base=base)
|
|
68
|
+
|
|
69
|
+
def update_attributes(self) -> None:
|
|
70
|
+
command: Command = self.object
|
|
71
|
+
# As no command sets ``description`` so the docstring goes to ``help`` (and ``short_doc`` is its first line).
|
|
72
|
+
short_doc: str = getattr(command, "short_doc", "") or ""
|
|
73
|
+
description: str = getattr(command, "description", "") or short_doc
|
|
74
|
+
self._attributes.update(
|
|
75
|
+
{
|
|
76
|
+
"name": command.name,
|
|
77
|
+
"cog_name": getattr(command, "cog_name", None),
|
|
78
|
+
"description": description,
|
|
79
|
+
"short_doc": short_doc,
|
|
80
|
+
"help": getattr(command, "help", None),
|
|
81
|
+
"aliases": humanize_list(list(getattr(command, "aliases", []))) or "None",
|
|
82
|
+
"qualified_name": command.qualified_name,
|
|
83
|
+
"signature": self.signature,
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def get_value(self, ctx: Verb) -> str:
|
|
88
|
+
should_escape: bool = False
|
|
89
|
+
if ctx.parameter is None:
|
|
90
|
+
return_value: str = self.object.qualified_name
|
|
91
|
+
else:
|
|
92
|
+
try:
|
|
93
|
+
value: Any = self._attributes[ctx.parameter]
|
|
94
|
+
except KeyError:
|
|
95
|
+
return # type: ignore
|
|
96
|
+
if isinstance(value, tuple):
|
|
97
|
+
value, should_escape = value
|
|
98
|
+
return_value: str = str(value) if value is not None else None # type: ignore
|
|
99
|
+
return escape_content(return_value) if should_escape else return_value
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class RedBotAdapter(SimpleAdapter["Red"]):
|
|
103
|
+
"""
|
|
104
|
+
The ``{bot}`` block with no parameters returns the bot's name & discriminator,
|
|
105
|
+
but passing the attributes listed below to the block payload will return that attribute instead.
|
|
106
|
+
|
|
107
|
+
**Usage:** ``{bot([attribute])}``
|
|
108
|
+
|
|
109
|
+
**Payload:** None
|
|
110
|
+
|
|
111
|
+
**Parameter:** attribute, None
|
|
112
|
+
|
|
113
|
+
Attributes
|
|
114
|
+
----------
|
|
115
|
+
id
|
|
116
|
+
The bot's Discord ID.
|
|
117
|
+
name
|
|
118
|
+
The bot's username.
|
|
119
|
+
discriminator
|
|
120
|
+
The bot's discriminator.
|
|
121
|
+
nick
|
|
122
|
+
The bot's global display name. This is not a per-server nickname: the
|
|
123
|
+
bot user has no guild context here, so a server-specific nick is not
|
|
124
|
+
available through this block.
|
|
125
|
+
created_at
|
|
126
|
+
The bot's creation date.
|
|
127
|
+
timestamp
|
|
128
|
+
The bot's creation date as a UTC timestamp.
|
|
129
|
+
mention
|
|
130
|
+
A formatted text that pings the bot.
|
|
131
|
+
avatar
|
|
132
|
+
A link to the bot's avatar, which can be used in embeds.
|
|
133
|
+
verified
|
|
134
|
+
If the bot is verified or not.
|
|
135
|
+
shard_count (*)
|
|
136
|
+
The bot's total shard count.
|
|
137
|
+
servers (*)
|
|
138
|
+
Total server/guild count of the bot.
|
|
139
|
+
channels (*)
|
|
140
|
+
Total number of channels visible to the bot.
|
|
141
|
+
visible_users (*)
|
|
142
|
+
Total number of users visible to the bot.
|
|
143
|
+
total_users (*)
|
|
144
|
+
The bot's total user count.
|
|
145
|
+
unique_users (*)
|
|
146
|
+
The bot's unique user count.
|
|
147
|
+
percentage_chunked (*)
|
|
148
|
+
Percentage of the bot's members that are cached/chunked (rounded to two
|
|
149
|
+
decimals); ``0`` when no member counts are available.
|
|
150
|
+
|
|
151
|
+
Attributes marked ``(*)`` are owner-only and return nothing for other users.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
# Bot-Owner Only attributes since these require iterating the whole guild/member cache.
|
|
155
|
+
OWNER_ATTRIBUTES: Tuple[str, ...] = (
|
|
156
|
+
"shard_count",
|
|
157
|
+
"servers",
|
|
158
|
+
"channels",
|
|
159
|
+
"visible_users",
|
|
160
|
+
"total_users",
|
|
161
|
+
"unique_users",
|
|
162
|
+
"percentage_chunked",
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
def __init__(self, base: Red, *, owner: bool = True) -> None:
|
|
166
|
+
if not _has_redbot:
|
|
167
|
+
raise ImportError("A Red-DiscordBot instance is required to use this.")
|
|
168
|
+
self.is_owner: bool = owner
|
|
169
|
+
super().__init__(base=base)
|
|
170
|
+
|
|
171
|
+
def update_attributes(self) -> None:
|
|
172
|
+
self.user: discord.ClientUser = cast(discord.ClientUser, self.object.user)
|
|
173
|
+
created_at: datetime.datetime = getattr(
|
|
174
|
+
self.user, "created_at", None
|
|
175
|
+
) or discord.utils.snowflake_time(self.user.id)
|
|
176
|
+
self._attributes.update(
|
|
177
|
+
{
|
|
178
|
+
"id": self.user.id,
|
|
179
|
+
"name": self.user.name,
|
|
180
|
+
"discriminator": self.user.discriminator,
|
|
181
|
+
"nick": self.user.display_name,
|
|
182
|
+
"mention": self.user.mention,
|
|
183
|
+
"avatar": (self.user.display_avatar.url, False),
|
|
184
|
+
"created_at": created_at,
|
|
185
|
+
"timestamp": int(created_at.timestamp()),
|
|
186
|
+
"verified": self.user.verified,
|
|
187
|
+
}
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
def _compute_owner_attribute(self, name: str) -> Any:
|
|
191
|
+
bot: Red = self.object
|
|
192
|
+
if name == "shard_count":
|
|
193
|
+
# ``shard_count`` is None on an unsharded bot.
|
|
194
|
+
return humanize_number(bot.shard_count or 1)
|
|
195
|
+
if name == "servers":
|
|
196
|
+
return humanize_number(len(bot.guilds))
|
|
197
|
+
if name == "channels":
|
|
198
|
+
return humanize_number(sum(len(g.channels) for g in bot.guilds))
|
|
199
|
+
if name == "unique_users":
|
|
200
|
+
return humanize_number(len(bot.users))
|
|
201
|
+
visible_users: int = sum(len(g.members) for g in bot.guilds)
|
|
202
|
+
if name == "visible_users":
|
|
203
|
+
return humanize_number(visible_users)
|
|
204
|
+
total_users: int = sum(g.member_count or 0 for g in bot.guilds)
|
|
205
|
+
if name == "total_users":
|
|
206
|
+
return humanize_number(total_users)
|
|
207
|
+
if name == "percentage_chunked":
|
|
208
|
+
# Guard against a bot in no guilds / with no counted members.
|
|
209
|
+
return round(visible_users / total_users * 100, 2) if total_users else 0
|
|
210
|
+
return None
|
|
211
|
+
|
|
212
|
+
def get_value(self, ctx: Verb) -> str:
|
|
213
|
+
should_escape: bool = False
|
|
214
|
+
if ctx.parameter is None:
|
|
215
|
+
return_value: str = "{0.name}#{0.discriminator}".format(self.user)
|
|
216
|
+
else:
|
|
217
|
+
parameter: str = ctx.parameter
|
|
218
|
+
if parameter in self.OWNER_ATTRIBUTES:
|
|
219
|
+
# Owner-only: hidden from non-owners, computed on demand (and
|
|
220
|
+
# cached in ``_attributes``) the first time an owner asks for it.
|
|
221
|
+
if not self.is_owner:
|
|
222
|
+
return # type: ignore
|
|
223
|
+
if parameter not in self._attributes:
|
|
224
|
+
self._attributes[parameter] = self._compute_owner_attribute(parameter)
|
|
225
|
+
try:
|
|
226
|
+
value: Any = self._attributes[parameter]
|
|
227
|
+
except KeyError:
|
|
228
|
+
return # type: ignore
|
|
229
|
+
if isinstance(value, tuple):
|
|
230
|
+
value, should_escape = value
|
|
231
|
+
return_value: str = str(value) if value is not None else None # type: ignore
|
|
232
|
+
return escape_content(return_value) if should_escape else return_value
|
|
@@ -55,8 +55,10 @@ class AssignmentBlock(verb_required_block(False, parameter=True)): # type: igno
|
|
|
55
55
|
- You can name variables with **anything** ``except`` existing block names or aliases.
|
|
56
56
|
- They will ``not`` reference the value in payload, if the name is same as an existing block name or alias.
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
.. raw:: html
|
|
59
|
+
|
|
60
|
+
<hr>
|
|
61
|
+
|
|
60
62
|
.. important:: How Argument Parsing Works - In Detail
|
|
61
63
|
|
|
62
64
|
- A variable is essentially a string that can be treated as a sequence of elements (words, numbers, etc.) when accessed.
|
|
@@ -66,8 +68,10 @@ class AssignmentBlock(verb_required_block(False, parameter=True)): # type: igno
|
|
|
66
68
|
to extract ``specific`` parts. Let's take a look at **how** it works.
|
|
67
69
|
- Parsing out of bounds index will return the whole string.
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
.. raw:: html
|
|
72
|
+
|
|
73
|
+
<hr>
|
|
74
|
+
|
|
71
75
|
.. rubric:: **Basic Argument Parsing**
|
|
72
76
|
|
|
73
77
|
Example
|
|
@@ -148,7 +152,9 @@ class AssignmentBlock(verb_required_block(False, parameter=True)): # type: igno
|
|
|
148
152
|
- ``-n`` → nth element from end
|
|
149
153
|
- ``-n+`` → nth element from end → then forward to end (index resolved first)
|
|
150
154
|
|
|
151
|
-
|
|
155
|
+
.. raw:: html
|
|
156
|
+
|
|
157
|
+
<hr>
|
|
152
158
|
|
|
153
159
|
.. rubric:: **Advanced Argument Parsing**
|
|
154
160
|
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import datetime
|
|
2
|
-
from typing import Any, Dict, Optional, Tuple, cast
|
|
3
|
-
|
|
4
|
-
import discord
|
|
5
|
-
|
|
6
|
-
from ..verb import Verb
|
|
7
|
-
from ..interface import SimpleAdapter
|
|
8
|
-
from ..utils import escape_content
|
|
9
|
-
|
|
10
|
-
try:
|
|
11
|
-
import redbot # noqa: F401
|
|
12
|
-
except ModuleNotFoundError:
|
|
13
|
-
_has_redbot = False
|
|
14
|
-
else:
|
|
15
|
-
_has_redbot = True
|
|
16
|
-
|
|
17
|
-
from redbot.core.bot import Red
|
|
18
|
-
from redbot.core.commands import Command
|
|
19
|
-
from redbot.core.utils.chat_formatting import humanize_number, humanize_list
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
__all__: Tuple[str, ...] = ("RedCommandAdapter", "RedBotAdapter")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class RedCommandAdapter(SimpleAdapter["Command"]):
|
|
26
|
-
if not _has_redbot:
|
|
27
|
-
raise ImportError("A Red-DiscordBot instance is required to use this.", name="redbot")
|
|
28
|
-
|
|
29
|
-
def __init__(self, base: Command, *, signature: Optional[str] = None) -> None:
|
|
30
|
-
super().__init__(base=base)
|
|
31
|
-
self.signature: Optional[str] = signature
|
|
32
|
-
|
|
33
|
-
def update_attributes(self) -> None:
|
|
34
|
-
command: Command = self.object
|
|
35
|
-
self._attributes.update(
|
|
36
|
-
{
|
|
37
|
-
"name": command.name,
|
|
38
|
-
"cog_name": getattr(command, "cog_name", None),
|
|
39
|
-
"description": getattr(command, "description", None),
|
|
40
|
-
"aliases": humanize_list(list(getattr(command, "aliases", []))) or "None",
|
|
41
|
-
"qualified_name": command.qualified_name,
|
|
42
|
-
"signature": self.signature,
|
|
43
|
-
}
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
def get_value(self, ctx: Verb) -> str:
|
|
47
|
-
should_escape: bool = False
|
|
48
|
-
if ctx.parameter is None:
|
|
49
|
-
return_value: str = self.object.qualified_name
|
|
50
|
-
else:
|
|
51
|
-
try:
|
|
52
|
-
value: Any = self._attributes[ctx.parameter]
|
|
53
|
-
except KeyError:
|
|
54
|
-
return # type: ignore
|
|
55
|
-
if isinstance(value, tuple):
|
|
56
|
-
value, should_escape = value
|
|
57
|
-
return_value: str = str(value) if value is not None else None # type: ignore
|
|
58
|
-
return escape_content(return_value) if should_escape else return_value
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
class RedBotAdapter(SimpleAdapter["Red"]):
|
|
62
|
-
"""
|
|
63
|
-
The ``{bot}`` block with no parameters returns the bot's name & discriminator,
|
|
64
|
-
but passing the attributes listed below to the block payload will return that attribute instead.
|
|
65
|
-
|
|
66
|
-
**Usage:** ``{bot([attribute])}``
|
|
67
|
-
|
|
68
|
-
**Payload:** None
|
|
69
|
-
|
|
70
|
-
**Parameter:** attribute, None
|
|
71
|
-
|
|
72
|
-
Attributes
|
|
73
|
-
----------
|
|
74
|
-
id
|
|
75
|
-
The bot's Discord ID.
|
|
76
|
-
name
|
|
77
|
-
The bot's username.
|
|
78
|
-
discriminator
|
|
79
|
-
The bot's discriminator.
|
|
80
|
-
nick
|
|
81
|
-
The bot's nickname, if they have one, else their username.
|
|
82
|
-
created_at
|
|
83
|
-
The bot's creation date.
|
|
84
|
-
timestamp
|
|
85
|
-
The bot's creation date as a UTC timestamp.
|
|
86
|
-
mention
|
|
87
|
-
A formatted text that pings the bot.
|
|
88
|
-
verified
|
|
89
|
-
If the bot is verified or not.
|
|
90
|
-
shard_count (*)
|
|
91
|
-
The bot's total shard count.
|
|
92
|
-
servers (*)
|
|
93
|
-
Total server/guild count of the bot.
|
|
94
|
-
channels (*)
|
|
95
|
-
Total number of channels visible to the bot.
|
|
96
|
-
visible_users (*)
|
|
97
|
-
Total number of users visible to the bot.
|
|
98
|
-
total_users (*)
|
|
99
|
-
The bot's total user count.
|
|
100
|
-
unique_users (*)
|
|
101
|
-
The bot's unique user count.
|
|
102
|
-
percentage_chunked (*)
|
|
103
|
-
Percentage of chunked guilds the bot has.
|
|
104
|
-
|
|
105
|
-
.. warning::
|
|
106
|
-
Attributes denoting ``(*)`` can only be used by the bot owner.
|
|
107
|
-
"""
|
|
108
|
-
|
|
109
|
-
if not _has_redbot:
|
|
110
|
-
raise ImportError("A Red-DiscordBot instance is required to use this.")
|
|
111
|
-
|
|
112
|
-
def __init__(self, base: Red, *, owner: bool = True) -> None:
|
|
113
|
-
super().__init__(base=base)
|
|
114
|
-
self.is_owner: bool = owner
|
|
115
|
-
|
|
116
|
-
def update_attributes(self) -> None:
|
|
117
|
-
self.user: discord.ClientUser = cast(discord.ClientUser, self.object.user)
|
|
118
|
-
created_at: datetime.datetime = getattr(
|
|
119
|
-
self.user, "created_at", None
|
|
120
|
-
) or discord.utils.snowflake_time(self.user.id)
|
|
121
|
-
self._attributes.update(
|
|
122
|
-
{
|
|
123
|
-
"id": self.user.id,
|
|
124
|
-
"name": self.user.name,
|
|
125
|
-
"discriminator": self.user.discriminator,
|
|
126
|
-
"nick": self.user.display_name,
|
|
127
|
-
"mention": self.user.display_avatar.url,
|
|
128
|
-
"created_at": created_at,
|
|
129
|
-
"timestamp": int(created_at.timestamp()),
|
|
130
|
-
"verified": self.user.verified,
|
|
131
|
-
}
|
|
132
|
-
)
|
|
133
|
-
if self.is_owner:
|
|
134
|
-
visible_users: int = sum(len(g.members) for g in self.object.guilds)
|
|
135
|
-
total_users: int = sum(
|
|
136
|
-
g.member_count if g.member_count else 0 for g in self.object.guilds
|
|
137
|
-
)
|
|
138
|
-
owner_attributes: Dict[str, Any] = {
|
|
139
|
-
"shard_count": humanize_number(self.object.bot.shard_count),
|
|
140
|
-
"servers": humanize_number(len(self.object.guilds)),
|
|
141
|
-
"channels": humanize_number(sum(len(g.channels) for g in self.object.guilds)),
|
|
142
|
-
"visible_users": humanize_number(visible_users),
|
|
143
|
-
"total_users": humanize_number(total_users),
|
|
144
|
-
"unique_users": humanize_number(len(self.object.users)),
|
|
145
|
-
"percentage_chunked": visible_users / total_users * 100,
|
|
146
|
-
}
|
|
147
|
-
self._attributes.update(owner_attributes)
|
|
148
|
-
|
|
149
|
-
def get_value(self, ctx: Verb) -> str:
|
|
150
|
-
should_escape: bool = False
|
|
151
|
-
if ctx.parameter is None:
|
|
152
|
-
return_value: str = "{0.name}#{0.discriminator}".format(self.user)
|
|
153
|
-
else:
|
|
154
|
-
try:
|
|
155
|
-
value: Any = self._attributes[ctx.parameter]
|
|
156
|
-
except KeyError:
|
|
157
|
-
return # type: ignore
|
|
158
|
-
if isinstance(value, tuple):
|
|
159
|
-
value, should_escape = value
|
|
160
|
-
return_value: str = str(value) if value is not None else None # type: ignore
|
|
161
|
-
return escape_content(return_value) if should_escape else return_value
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/AdvancedTagScript.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/functionadapter.py
RENAMED
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/objectadapter.py
RENAMED
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/adapter/stringadapter.py
RENAMED
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/allowedmentions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/loosevariablegetter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/require_blacklist.py
RENAMED
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/shortcutredirect.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{advancedtagscript-3.3.0 → advancedtagscript-3.3.2}/TagScriptEngine/block/strictvariablegetter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|