bTagScript 5.0.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.
- bTagScript/__init__.py +66 -0
- bTagScript/adapter/__init__.py +16 -0
- bTagScript/adapter/discord_adapters.py +275 -0
- bTagScript/adapter/function_adapter.py +33 -0
- bTagScript/adapter/int_adapter.py +30 -0
- bTagScript/adapter/object_adapter.py +41 -0
- bTagScript/adapter/string_adapter.py +69 -0
- bTagScript/block/__init__.py +67 -0
- bTagScript/block/break_block.py +41 -0
- bTagScript/block/case_block.py +62 -0
- bTagScript/block/comment_block.py +33 -0
- bTagScript/block/control_block.py +161 -0
- bTagScript/block/counting_blocks.py +88 -0
- bTagScript/block/digitshorthand_block.py +38 -0
- bTagScript/block/discord_blocks/__init__.py +20 -0
- bTagScript/block/discord_blocks/command_block.py +52 -0
- bTagScript/block/discord_blocks/cooldown_block.py +101 -0
- bTagScript/block/discord_blocks/delete_block.py +47 -0
- bTagScript/block/discord_blocks/embed_block.py +248 -0
- bTagScript/block/discord_blocks/override_block.py +61 -0
- bTagScript/block/discord_blocks/react_block.py +49 -0
- bTagScript/block/discord_blocks/redirect_block.py +42 -0
- bTagScript/block/discord_blocks/requirement_blocks.py +83 -0
- bTagScript/block/helpers.py +121 -0
- bTagScript/block/math_blocks.py +257 -0
- bTagScript/block/random_block.py +65 -0
- bTagScript/block/range_block.py +54 -0
- bTagScript/block/replace_block.py +110 -0
- bTagScript/block/stop_block.py +38 -0
- bTagScript/block/strf_block.py +70 -0
- bTagScript/block/url_blocks.py +76 -0
- bTagScript/block/util_blocks/__init__.py +3 -0
- bTagScript/block/util_blocks/debug_block.py +107 -0
- bTagScript/block/var_block.py +49 -0
- bTagScript/block/vargetter_blocks.py +91 -0
- bTagScript/exceptions.py +139 -0
- bTagScript/interface/__init__.py +4 -0
- bTagScript/interface/adapter.py +43 -0
- bTagScript/interface/block.py +136 -0
- bTagScript/interpreter.py +614 -0
- bTagScript/utils.py +65 -0
- bTagScript/verb.py +129 -0
- btagscript-5.0.0.dist-info/METADATA +109 -0
- btagscript-5.0.0.dist-info/RECORD +47 -0
- btagscript-5.0.0.dist-info/WHEEL +5 -0
- btagscript-5.0.0.dist-info/licenses/LICENSE +1 -0
- btagscript-5.0.0.dist-info/top_level.txt +1 -0
bTagScript/__init__.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This work is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of this license,
|
|
3
|
+
visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
|
|
4
|
+
|
|
5
|
+
This fork was made by _Leg3ndary and contains everything he thought should be added to tagscript. Hope you enjoy!
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from collections import namedtuple
|
|
9
|
+
|
|
10
|
+
from .adapter import *
|
|
11
|
+
from .block import *
|
|
12
|
+
from .exceptions import *
|
|
13
|
+
from .interface import *
|
|
14
|
+
from .interpreter import *
|
|
15
|
+
from .utils import *
|
|
16
|
+
from .verb import Verb
|
|
17
|
+
|
|
18
|
+
__version__ = "5.0.0"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class VersionInfo(namedtuple("VersionInfo", "major minor micro")):
|
|
22
|
+
"""
|
|
23
|
+
Version information.
|
|
24
|
+
|
|
25
|
+
Attributes
|
|
26
|
+
----------
|
|
27
|
+
major: int
|
|
28
|
+
Major version number.
|
|
29
|
+
minor: int
|
|
30
|
+
Minor version number.
|
|
31
|
+
micro: int
|
|
32
|
+
Micro version number.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
__slots__ = ()
|
|
36
|
+
|
|
37
|
+
def __str__(self):
|
|
38
|
+
"""
|
|
39
|
+
Returns a string representation of the version information.
|
|
40
|
+
|
|
41
|
+
Returns
|
|
42
|
+
-------
|
|
43
|
+
str
|
|
44
|
+
String representation of the version information.
|
|
45
|
+
"""
|
|
46
|
+
return "{major}.{minor}.{micro}".format(**self._asdict())
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_str(cls, version):
|
|
50
|
+
"""
|
|
51
|
+
Returns a VersionInfo instance from a string.
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
version: str
|
|
56
|
+
String representation of the version information.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
VersionInfo
|
|
61
|
+
Version information.
|
|
62
|
+
"""
|
|
63
|
+
return cls(*map(int, version.split(".")))
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
version_info = VersionInfo.from_str(__version__)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from .discord_adapters import *
|
|
2
|
+
from .function_adapter import FunctionAdapter
|
|
3
|
+
from .int_adapter import IntAdapter
|
|
4
|
+
from .object_adapter import SafeObjectAdapter
|
|
5
|
+
from .string_adapter import StringAdapter
|
|
6
|
+
|
|
7
|
+
__all__ = (
|
|
8
|
+
"SafeObjectAdapter",
|
|
9
|
+
"StringAdapter",
|
|
10
|
+
"IntAdapter",
|
|
11
|
+
"FunctionAdapter",
|
|
12
|
+
"AttributeAdapter",
|
|
13
|
+
"MemberAdapter",
|
|
14
|
+
"ChannelAdapter",
|
|
15
|
+
"GuildAdapter",
|
|
16
|
+
)
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
from random import choice
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from discord import Guild, Member, TextChannel, Thread
|
|
5
|
+
|
|
6
|
+
from ..interface import Adapter
|
|
7
|
+
from ..utils import escape_content
|
|
8
|
+
from ..verb import Verb
|
|
9
|
+
|
|
10
|
+
__all__ = (
|
|
11
|
+
"AttributeAdapter",
|
|
12
|
+
"MemberAdapter",
|
|
13
|
+
"ChannelAdapter",
|
|
14
|
+
"GuildAdapter",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AttributeAdapter(Adapter):
|
|
19
|
+
"""
|
|
20
|
+
Base attribute adapter for discord.py objects
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
__slots__ = ("object", "_attributes", "_methods")
|
|
24
|
+
|
|
25
|
+
def __init__(self, base: Union[TextChannel, Member, Guild]) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Init for the attribute adapter
|
|
28
|
+
"""
|
|
29
|
+
self.object = base
|
|
30
|
+
self._attributes = {
|
|
31
|
+
"id": base.id,
|
|
32
|
+
"created_at": base.created_at,
|
|
33
|
+
"timestamp": int(base.created_at.timestamp()),
|
|
34
|
+
"name": getattr(base, "name", str(base)),
|
|
35
|
+
}
|
|
36
|
+
self._methods = {}
|
|
37
|
+
self.update_attributes()
|
|
38
|
+
self.update_methods()
|
|
39
|
+
|
|
40
|
+
def __repr__(self) -> str:
|
|
41
|
+
"""
|
|
42
|
+
printable repr
|
|
43
|
+
"""
|
|
44
|
+
return f"<{type(self).__qualname__} object={self.object!r}>"
|
|
45
|
+
|
|
46
|
+
def update_attributes(self) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Update attributes for the block
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def update_methods(self) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Update methods for the block
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def get_value(self, ctx: Verb) -> str:
|
|
57
|
+
"""
|
|
58
|
+
Get the value for the adapter
|
|
59
|
+
"""
|
|
60
|
+
should_escape = False
|
|
61
|
+
|
|
62
|
+
if ctx.parameter is None:
|
|
63
|
+
return_value = str(self.object)
|
|
64
|
+
else:
|
|
65
|
+
try:
|
|
66
|
+
value = self._attributes[ctx.parameter]
|
|
67
|
+
except KeyError:
|
|
68
|
+
if method := self._methods.get(ctx.parameter):
|
|
69
|
+
value = method()
|
|
70
|
+
else:
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
if isinstance(value, tuple):
|
|
74
|
+
value, should_escape = value
|
|
75
|
+
|
|
76
|
+
return_value = str(value) if value is not None else None
|
|
77
|
+
|
|
78
|
+
return escape_content(return_value) if should_escape else return_value
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class MemberAdapter(AttributeAdapter):
|
|
82
|
+
"""
|
|
83
|
+
The ``{author}`` block with no parameters returns the tag invoker's full username
|
|
84
|
+
and discriminator, but passing the attributes listed below to the block payload
|
|
85
|
+
will return that attribute instead.
|
|
86
|
+
|
|
87
|
+
**Aliases:** ``user``
|
|
88
|
+
|
|
89
|
+
**Usage:** ``{author([attribute])``
|
|
90
|
+
|
|
91
|
+
**Payload:** None
|
|
92
|
+
|
|
93
|
+
**Parameter:** attribute, None
|
|
94
|
+
|
|
95
|
+
Attributes
|
|
96
|
+
----------
|
|
97
|
+
id
|
|
98
|
+
The author's Discord ID.
|
|
99
|
+
name
|
|
100
|
+
The author's username.
|
|
101
|
+
nick
|
|
102
|
+
The author's nickname, if they have one, else their username.
|
|
103
|
+
avatar
|
|
104
|
+
A link to the author's avatar, which can be used in embeds.
|
|
105
|
+
discriminator
|
|
106
|
+
The author's discriminator.
|
|
107
|
+
created_at
|
|
108
|
+
The author's account creation date.
|
|
109
|
+
timestamp
|
|
110
|
+
The author's account creation date as a UTC timestamp.
|
|
111
|
+
joined_at
|
|
112
|
+
The date the author joined the server.
|
|
113
|
+
mention
|
|
114
|
+
A formatted text that pings the author.
|
|
115
|
+
bot
|
|
116
|
+
Whether or not the author is a bot.
|
|
117
|
+
color
|
|
118
|
+
The author's top role's color as a hex code.
|
|
119
|
+
top_role
|
|
120
|
+
The author's top role.
|
|
121
|
+
boost
|
|
122
|
+
If the user boosted, this will be the the UTC timestamp of when they did, if not, this will be empty.
|
|
123
|
+
timed_out
|
|
124
|
+
If the user is timed out, this will be the the UTC timestamp of when they'll be "untimed-out", if not timed out, this will be empty.
|
|
125
|
+
banner
|
|
126
|
+
The users banner url
|
|
127
|
+
roleids
|
|
128
|
+
A list of the author's role IDs, split by spaces.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
def update_attributes(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Update the adapter with all it's needed attributes
|
|
134
|
+
"""
|
|
135
|
+
additional_attributes = {
|
|
136
|
+
"color": self.object.color,
|
|
137
|
+
"colour": self.object.color,
|
|
138
|
+
"nick": self.object.display_name,
|
|
139
|
+
"avatar": (self.object.display_avatar.url, False),
|
|
140
|
+
"discriminator": self.object.discriminator,
|
|
141
|
+
"joined_at": getattr(self.object, "joined_at", ""),
|
|
142
|
+
"mention": self.object.mention,
|
|
143
|
+
"bot": self.object.bot,
|
|
144
|
+
"top_role": getattr(self.object, "top_role", ""),
|
|
145
|
+
"boost": getattr(self.object, "premium_since", ""),
|
|
146
|
+
"timed_out": getattr(self.object, "timed_out_until", ""),
|
|
147
|
+
"banner": self.object.banner.url if self.object.banner else "",
|
|
148
|
+
}
|
|
149
|
+
if roleids := getattr(self.object, "_roles", None):
|
|
150
|
+
additional_attributes["roleids"] = " ".join(str(r) for r in roleids)
|
|
151
|
+
self._attributes.update(additional_attributes)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class ChannelAdapter(AttributeAdapter):
|
|
155
|
+
"""
|
|
156
|
+
The ``{channel}`` block with no parameters returns the channel's full name
|
|
157
|
+
but passing the attributes listed below to the block payload
|
|
158
|
+
will return that attribute instead.
|
|
159
|
+
|
|
160
|
+
**Usage:** ``{channel([attribute])``
|
|
161
|
+
|
|
162
|
+
**Payload:** None
|
|
163
|
+
|
|
164
|
+
**Parameter:** attribute, None
|
|
165
|
+
|
|
166
|
+
Attributes
|
|
167
|
+
----------
|
|
168
|
+
id
|
|
169
|
+
The channel's ID.
|
|
170
|
+
name
|
|
171
|
+
The channel's name.
|
|
172
|
+
created_at
|
|
173
|
+
The channel's creation date.
|
|
174
|
+
timestamp
|
|
175
|
+
The channel's creation date as a UTC timestamp.
|
|
176
|
+
nsfw
|
|
177
|
+
Whether the channel is nsfw.
|
|
178
|
+
mention
|
|
179
|
+
A formatted text that pings the channel.
|
|
180
|
+
topic
|
|
181
|
+
The channel's topic.
|
|
182
|
+
slowmode
|
|
183
|
+
The channel's slowmode in seconds, 0 if disabled
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def update_attributes(self) -> None:
|
|
187
|
+
"""
|
|
188
|
+
Update block attributes
|
|
189
|
+
"""
|
|
190
|
+
if isinstance(self.object, TextChannel):
|
|
191
|
+
additional_attributes = {
|
|
192
|
+
"channel_type": "textchannel",
|
|
193
|
+
"nsfw": self.object.nsfw,
|
|
194
|
+
"mention": self.object.mention,
|
|
195
|
+
"topic": self.object.topic or None,
|
|
196
|
+
"slowmode": self.object.slowmode_delay,
|
|
197
|
+
}
|
|
198
|
+
self._attributes.update(additional_attributes)
|
|
199
|
+
elif isinstance(self.object, Thread):
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class GuildAdapter(AttributeAdapter):
|
|
204
|
+
"""
|
|
205
|
+
The ``{server}`` block with no parameters returns the server's name
|
|
206
|
+
but passing the attributes listed below to the block payload
|
|
207
|
+
will return that attribute instead.
|
|
208
|
+
|
|
209
|
+
**Aliases:** ``guild``
|
|
210
|
+
|
|
211
|
+
**Usage:** ``{server([attribute])``
|
|
212
|
+
|
|
213
|
+
**Payload:** None
|
|
214
|
+
|
|
215
|
+
**Parameter:** attribute, None
|
|
216
|
+
|
|
217
|
+
Attributes
|
|
218
|
+
----------
|
|
219
|
+
id
|
|
220
|
+
The server's ID.
|
|
221
|
+
name
|
|
222
|
+
The server's name.
|
|
223
|
+
icon
|
|
224
|
+
A link to the server's icon, which can be used in embeds.
|
|
225
|
+
created_at
|
|
226
|
+
The server's creation date.
|
|
227
|
+
timestamp
|
|
228
|
+
The server's creation date as a UTC timestamp.
|
|
229
|
+
member_count
|
|
230
|
+
The server's member count.
|
|
231
|
+
bots
|
|
232
|
+
The number of bots in the server.
|
|
233
|
+
humans
|
|
234
|
+
The number of humans in the server.
|
|
235
|
+
description
|
|
236
|
+
The server's description if one is set, or "No description".
|
|
237
|
+
random
|
|
238
|
+
A random member from the server.
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
def update_attributes(self) -> None:
|
|
242
|
+
"""
|
|
243
|
+
Update block attributes
|
|
244
|
+
"""
|
|
245
|
+
guild = self.object
|
|
246
|
+
bots = 0
|
|
247
|
+
humans = 0
|
|
248
|
+
for m in guild.members:
|
|
249
|
+
if m.bot:
|
|
250
|
+
bots += 1
|
|
251
|
+
else:
|
|
252
|
+
humans += 1
|
|
253
|
+
member_count = guild.member_count
|
|
254
|
+
additional_attributes = {
|
|
255
|
+
"icon": guild.icon.url if guild.icon else "",
|
|
256
|
+
"member_count": member_count,
|
|
257
|
+
"members": member_count,
|
|
258
|
+
"bots": bots,
|
|
259
|
+
"humans": humans,
|
|
260
|
+
"description": guild.description or "No description",
|
|
261
|
+
}
|
|
262
|
+
self._attributes.update(additional_attributes)
|
|
263
|
+
|
|
264
|
+
def update_methods(self) -> None:
|
|
265
|
+
"""
|
|
266
|
+
Update methods for the block
|
|
267
|
+
"""
|
|
268
|
+
additional_methods = {"random": self.random_member}
|
|
269
|
+
self._methods.update(additional_methods)
|
|
270
|
+
|
|
271
|
+
def random_member(self) -> None:
|
|
272
|
+
"""
|
|
273
|
+
Return a random member
|
|
274
|
+
"""
|
|
275
|
+
return choice(self.object.members)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
from ..interface import Adapter
|
|
4
|
+
from ..verb import Verb
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FunctionAdapter(Adapter):
|
|
8
|
+
"""
|
|
9
|
+
Function adapter...
|
|
10
|
+
|
|
11
|
+
Would be cool to have functions in tagscript
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__slots__ = ("fn",)
|
|
15
|
+
|
|
16
|
+
def __init__(self, function_pointer: Callable[[], str]) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Construct the adapter
|
|
19
|
+
"""
|
|
20
|
+
self.fn = function_pointer
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
def __repr__(self) -> str:
|
|
24
|
+
"""
|
|
25
|
+
String repr
|
|
26
|
+
"""
|
|
27
|
+
return f"<{type(self).__qualname__} fn={self.fn!r}>"
|
|
28
|
+
|
|
29
|
+
def get_value(self, ctx: Verb) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Run the function and get the value
|
|
32
|
+
"""
|
|
33
|
+
return str(self.fn())
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from ..interface import Adapter
|
|
2
|
+
from ..verb import Verb
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class IntAdapter(Adapter):
|
|
6
|
+
"""
|
|
7
|
+
IntAdapter
|
|
8
|
+
|
|
9
|
+
This will be useful in the future if types are ever introduced.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__slots__ = ("integer",)
|
|
13
|
+
|
|
14
|
+
def __init__(self, integer: int) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Construct the int adapter
|
|
17
|
+
"""
|
|
18
|
+
self.integer: int = int(integer)
|
|
19
|
+
|
|
20
|
+
def __repr__(self) -> str:
|
|
21
|
+
"""
|
|
22
|
+
String repr
|
|
23
|
+
"""
|
|
24
|
+
return f"<{type(self).__qualname__} integer={repr(self.integer)}>"
|
|
25
|
+
|
|
26
|
+
def get_value(self, ctx: Verb) -> str:
|
|
27
|
+
"""
|
|
28
|
+
Get the value of the int into string, not sure why this even exists
|
|
29
|
+
"""
|
|
30
|
+
return str(self.integer)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from inspect import ismethod
|
|
2
|
+
|
|
3
|
+
from ..interface import Adapter
|
|
4
|
+
from ..verb import Verb
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SafeObjectAdapter(Adapter):
|
|
8
|
+
"""
|
|
9
|
+
Object adapter, though again this will likely not be used
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__slots__ = ("object",)
|
|
13
|
+
|
|
14
|
+
def __init__(self, base) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Construct the safe object adapter.
|
|
17
|
+
"""
|
|
18
|
+
self.object = base
|
|
19
|
+
|
|
20
|
+
def __repr__(self) -> str:
|
|
21
|
+
"""
|
|
22
|
+
String repr"""
|
|
23
|
+
return f"<{type(self).__qualname__} object={repr(self.object)}>"
|
|
24
|
+
|
|
25
|
+
def get_value(self, ctx: Verb) -> str:
|
|
26
|
+
"""
|
|
27
|
+
Get the value safely
|
|
28
|
+
"""
|
|
29
|
+
if ctx.parameter is None:
|
|
30
|
+
return str(self.object)
|
|
31
|
+
if ctx.parameter.startswith("_") or "." in ctx.parameter:
|
|
32
|
+
return None
|
|
33
|
+
try:
|
|
34
|
+
attribute = getattr(self.object, ctx.parameter)
|
|
35
|
+
except AttributeError:
|
|
36
|
+
return None
|
|
37
|
+
if ismethod(attribute):
|
|
38
|
+
return None
|
|
39
|
+
if isinstance(attribute, float):
|
|
40
|
+
attribute = int(attribute)
|
|
41
|
+
return str(attribute)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from ..interface import Adapter
|
|
2
|
+
from ..utils import escape_content
|
|
3
|
+
from ..verb import Verb
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class StringAdapter(Adapter):
|
|
7
|
+
"""
|
|
8
|
+
String adapter, allows blocks to be parsed, used basically only for variables
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
__slots__ = ("string", "escape_content")
|
|
12
|
+
|
|
13
|
+
def __init__(self, string: str, *, escape: bool = False) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Construction for string adapter
|
|
16
|
+
"""
|
|
17
|
+
self.string: str = str(string)
|
|
18
|
+
self.escape_content = escape
|
|
19
|
+
|
|
20
|
+
def __repr__(self) -> str:
|
|
21
|
+
"""
|
|
22
|
+
String repr
|
|
23
|
+
"""
|
|
24
|
+
return f"<{type(self).__qualname__} string={repr(self.string)}>"
|
|
25
|
+
|
|
26
|
+
def get_value(self, ctx: Verb) -> str:
|
|
27
|
+
"""
|
|
28
|
+
Get the value given the verb
|
|
29
|
+
"""
|
|
30
|
+
return self.return_value(self.handle_ctx(ctx))
|
|
31
|
+
|
|
32
|
+
def handle_ctx(self, ctx: Verb) -> str:
|
|
33
|
+
"""
|
|
34
|
+
Transform any parsing data the block may have
|
|
35
|
+
"""
|
|
36
|
+
if ctx.parameter is None:
|
|
37
|
+
return self.string
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
index = None
|
|
41
|
+
splitter = " " if ctx.payload is None else ctx.payload
|
|
42
|
+
if ctx.parameter.isdigit():
|
|
43
|
+
index = int(ctx.parameter) - 1
|
|
44
|
+
|
|
45
|
+
if ctx.parameter.startswith("-") and ctx.parameter.split("-", 1)[-1].isdigit():
|
|
46
|
+
index = int(ctx.parameter)
|
|
47
|
+
|
|
48
|
+
if index is not None:
|
|
49
|
+
return self.string.split(splitter)[index]
|
|
50
|
+
|
|
51
|
+
index = (
|
|
52
|
+
int(ctx.parameter.replace("+", "")) - 1
|
|
53
|
+
if int(ctx.parameter.replace("+", "")) > 0
|
|
54
|
+
else int(ctx.parameter.replace("+", ""))
|
|
55
|
+
)
|
|
56
|
+
splitter = " " if ctx.payload is None else ctx.payload
|
|
57
|
+
if ctx.parameter.startswith("+"):
|
|
58
|
+
return splitter.join(self.string.split(splitter)[: index + 1])
|
|
59
|
+
if ctx.parameter.endswith("+"):
|
|
60
|
+
return splitter.join(self.string.split(splitter)[index:])
|
|
61
|
+
return self.string.split(splitter)[index]
|
|
62
|
+
except: # pylint: disable=bare-except
|
|
63
|
+
return self.string
|
|
64
|
+
|
|
65
|
+
def return_value(self, string: str) -> str:
|
|
66
|
+
"""
|
|
67
|
+
Return the value, escaped
|
|
68
|
+
"""
|
|
69
|
+
return escape_content(string) if self.escape_content else string
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# isort: off
|
|
2
|
+
from .helpers import *
|
|
3
|
+
|
|
4
|
+
# isort: on
|
|
5
|
+
from .break_block import BreakBlock
|
|
6
|
+
from .case_block import LowerBlock, UpperBlock
|
|
7
|
+
from .comment_block import CommentBlock
|
|
8
|
+
from .control_block import AllBlock, AnyBlock, IfBlock
|
|
9
|
+
from .counting_blocks import CountBlock, LengthBlock
|
|
10
|
+
from .digitshorthand_block import DigitShorthandBlock
|
|
11
|
+
from .discord_blocks import (
|
|
12
|
+
BlacklistBlock,
|
|
13
|
+
CommandBlock,
|
|
14
|
+
CooldownBlock,
|
|
15
|
+
DeleteBlock,
|
|
16
|
+
EmbedBlock,
|
|
17
|
+
OverrideBlock,
|
|
18
|
+
ReactBlock,
|
|
19
|
+
RedirectBlock,
|
|
20
|
+
RequireBlock,
|
|
21
|
+
)
|
|
22
|
+
from .math_blocks import MathBlock, OrdinalAbbreviationBlock
|
|
23
|
+
from .random_block import RandomBlock
|
|
24
|
+
from .range_block import RangeBlock
|
|
25
|
+
from .replace_block import PythonBlock, ReplaceBlock
|
|
26
|
+
from .stop_block import StopBlock
|
|
27
|
+
from .strf_block import StrfBlock
|
|
28
|
+
from .url_blocks import URLDecodeBlock, URLEncodeBlock
|
|
29
|
+
from .util_blocks.debug_block import DebugBlock
|
|
30
|
+
from .var_block import VarBlock
|
|
31
|
+
from .vargetter_blocks import LooseVariableGetterBlock, StrictVariableGetterBlock
|
|
32
|
+
|
|
33
|
+
__all__ = (
|
|
34
|
+
"BreakBlock",
|
|
35
|
+
"CommentBlock",
|
|
36
|
+
"AllBlock",
|
|
37
|
+
"AnyBlock",
|
|
38
|
+
"IfBlock",
|
|
39
|
+
"CountBlock",
|
|
40
|
+
"LengthBlock",
|
|
41
|
+
"BlacklistBlock",
|
|
42
|
+
"CommandBlock",
|
|
43
|
+
"CooldownBlock",
|
|
44
|
+
"DeleteBlock",
|
|
45
|
+
"EmbedBlock",
|
|
46
|
+
"OverrideBlock",
|
|
47
|
+
"ReactBlock",
|
|
48
|
+
"RedirectBlock",
|
|
49
|
+
"RequireBlock",
|
|
50
|
+
"MathBlock",
|
|
51
|
+
"OrdinalAbbreviationBlock",
|
|
52
|
+
"RandomBlock",
|
|
53
|
+
"RangeBlock",
|
|
54
|
+
"PythonBlock",
|
|
55
|
+
"ReplaceBlock",
|
|
56
|
+
"StopBlock",
|
|
57
|
+
"StrfBlock",
|
|
58
|
+
"URLDecodeBlock",
|
|
59
|
+
"URLEncodeBlock",
|
|
60
|
+
"DebugBlock",
|
|
61
|
+
"VarBlock",
|
|
62
|
+
"LooseVariableGetterBlock",
|
|
63
|
+
"StrictVariableGetterBlock",
|
|
64
|
+
"DigitShorthandBlock",
|
|
65
|
+
"UpperBlock",
|
|
66
|
+
"LowerBlock",
|
|
67
|
+
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from ..interface import Block
|
|
4
|
+
from ..interpreter import Context
|
|
5
|
+
from . import helper_parse_if
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BreakBlock(Block):
|
|
9
|
+
"""
|
|
10
|
+
The break block will force the tag output to only be the payload of this block, if the passed
|
|
11
|
+
expresssion evaluates true.
|
|
12
|
+
If no message is provided to the payload, the tag output will be empty.
|
|
13
|
+
|
|
14
|
+
This differs from the StopBlock as the stop block stops all tagscript processing and returns
|
|
15
|
+
its message while the break block continues to process blocks. If command blocks exist after
|
|
16
|
+
the break block, they will still execute.
|
|
17
|
+
|
|
18
|
+
**Usage:** ``{break(<expression>):[message]}``
|
|
19
|
+
|
|
20
|
+
**Aliases:** ``short, shortcircuit``
|
|
21
|
+
|
|
22
|
+
**Payload:** ``message``
|
|
23
|
+
|
|
24
|
+
**Parameter:** ``expression``
|
|
25
|
+
|
|
26
|
+
**Examples:**
|
|
27
|
+
|
|
28
|
+
.. tagscript::
|
|
29
|
+
|
|
30
|
+
{break(=={args}):You did not provide any input.}
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
ACCEPTED_NAMES = ("break", "shortcircuit", "short")
|
|
34
|
+
|
|
35
|
+
def process(self, ctx: Context) -> Optional[str]:
|
|
36
|
+
"""
|
|
37
|
+
Process the block and break the tag.
|
|
38
|
+
"""
|
|
39
|
+
if helper_parse_if(ctx.verb.parameter):
|
|
40
|
+
ctx.response.body = ctx.verb.payload if ctx.verb.payload is not None else ""
|
|
41
|
+
return ""
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from ..interface import verb_required_block
|
|
4
|
+
from ..interpreter import Context
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class UpperBlock(verb_required_block(True, payload=True)):
|
|
8
|
+
"""
|
|
9
|
+
The Upper block will do exactly as it and will make the payload uppercase. The
|
|
10
|
+
block alone will not do anything.
|
|
11
|
+
|
|
12
|
+
**Usage:** ``{upper:<string>}``
|
|
13
|
+
|
|
14
|
+
**Aliases:** ``upper``
|
|
15
|
+
|
|
16
|
+
**Payload:** ``string``
|
|
17
|
+
|
|
18
|
+
**Parameter:** ``None``
|
|
19
|
+
|
|
20
|
+
**Examples:**
|
|
21
|
+
|
|
22
|
+
.. tagscript::
|
|
23
|
+
|
|
24
|
+
{upper:I love strawberries!} -> I LOVE STRAWBERRIES!
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
ACCEPTED_NAMES = ("upper",)
|
|
28
|
+
|
|
29
|
+
def process(self, ctx: Context) -> Optional[str]:
|
|
30
|
+
"""
|
|
31
|
+
Process the block and break the tag.
|
|
32
|
+
"""
|
|
33
|
+
return ctx.verb.payload.upper()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class LowerBlock(verb_required_block(True, payload=True)):
|
|
37
|
+
"""
|
|
38
|
+
The Lower block will make the payload lowercase. The block alone will
|
|
39
|
+
not do anything.
|
|
40
|
+
|
|
41
|
+
**Usage:** ``{lower:<string>}``
|
|
42
|
+
|
|
43
|
+
**Aliases:** ``lower``
|
|
44
|
+
|
|
45
|
+
**Payload:** ``string``
|
|
46
|
+
|
|
47
|
+
**Parameter:** ``None``
|
|
48
|
+
|
|
49
|
+
**Examples:**
|
|
50
|
+
|
|
51
|
+
.. tagscript::
|
|
52
|
+
|
|
53
|
+
{lower:I LOVE STRAWBERRIES!} -> i love strawberries!
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
ACCEPTED_NAMES = ("lower",)
|
|
57
|
+
|
|
58
|
+
def process(self, ctx: Context) -> Optional[str]:
|
|
59
|
+
"""
|
|
60
|
+
Process the block and break the tag.
|
|
61
|
+
"""
|
|
62
|
+
return ctx.verb.payload.lower()
|