1
1
import asyncio
2
2
import logging
3
3
from datetime import datetime
4
+ from itertools import zip_longest , takewhile
4
5
from typing import Optional , Union
5
6
from types import SimpleNamespace as param
6
7
7
8
import discord
8
9
from discord .ext import commands
10
+ from discord .utils import escape_markdown , escape_mentions
9
11
10
12
from dateutil import parser
11
13
from natural .date import duration
15
17
from core .models import PermissionLevel
16
18
from core .paginator import PaginatorSession
17
19
from core .time import UserFriendlyTime , human_timedelta
18
- from core .utils import format_preview , User
20
+ from core .utils import format_preview , User , create_not_found_embed
19
21
20
22
logger = logging .getLogger ("Modmail" )
21
23
@@ -100,60 +102,74 @@ async def setup(self, ctx):
100
102
101
103
@commands .group (aliases = ["snippets" ], invoke_without_command = True )
102
104
@checks .has_permissions (PermissionLevel .SUPPORTER )
103
- async def snippet (self , ctx ):
105
+ async def snippet (self , ctx , * , name : str . lower = None ):
104
106
"""
105
107
Create pre-defined messages for use in threads.
106
108
107
109
When `{prefix}snippet` is used by itself, this will retrieve
108
- a list of snippets that are currently set.
110
+ a list of snippets that are currently set. `{prefix}snippet-name` will show what the
111
+ snippet point to.
109
112
110
- To use snippets:
111
-
112
- First create a snippet using:
113
+ To create a snippet:
113
114
- `{prefix}snippet add snippet-name A pre-defined text.`
114
115
115
- Afterwards, you can use your snippet in a thread channel
116
+ You can use your snippet in a thread channel
116
117
with `{prefix}snippet-name`, the message "A pre-defined text."
117
118
will be sent to the recipient.
118
119
120
+ Currently, there is not a default anonymous snippet command; however, a workaround
121
+ is available using `{prefix}alias`. Here is how:
122
+ - `{prefix}alias add snippet-name anonreply A pre-defined anonymous text.`
123
+
119
124
See also `{prefix}alias`.
120
125
"""
121
126
122
- embeds = []
127
+ if name is not None :
128
+ val = self .bot .snippets .get (name )
129
+ if val is None :
130
+ embed = create_not_found_embed (name , self .bot .snippets .keys (), 'Snippet' )
131
+ return await ctx .send (embed = embed )
132
+ return await ctx .send (escape_mentions (val ))
123
133
124
- if self .bot .snippets :
125
- embed = discord .Embed (
126
- color = self .bot .main_color ,
127
- description = "Here is a list of snippets "
128
- "that are currently configured." ,
129
- )
130
- else :
134
+ if not self .bot .snippets :
131
135
embed = discord .Embed (
132
136
color = discord .Color .red (),
133
137
description = "You dont have any snippets at the moment." ,
134
138
)
135
139
embed .set_footer (
136
140
text = f"Do { self .bot .prefix } help snippet for more commands."
137
141
)
142
+ embed .set_author (name = "Snippets" , icon_url = ctx .guild .icon_url )
143
+ return await ctx .send (embed = embed )
138
144
139
- embed .set_author (name = "Snippets" , icon_url = ctx .guild .icon_url )
140
- embeds .append (embed )
145
+ embeds = []
141
146
142
- for name , value in self .bot .snippets .items ():
143
- if len (embed .fields ) == 5 :
144
- embed = discord .Embed (
145
- color = self .bot .main_color , description = embed .description
147
+ for names in zip_longest (* (iter (sorted (self .bot .snippets )),) * 15 ):
148
+ description = "\n " .join (
149
+ ": " .join ((str (a ), b ))
150
+ for a , b in enumerate (
151
+ takewhile (lambda x : x is not None , names ), start = 1
146
152
)
147
- embed .set_author (name = "Snippets" , icon_url = ctx .guild .icon_url )
148
- embeds .append (embed )
149
- embed .add_field (name = name , value = value , inline = False )
153
+ )
154
+ embed = discord .Embed (color = self .bot .main_color , description = description )
155
+ embed .set_author (name = "Snippets" , icon_url = ctx .guild .icon_url )
156
+ embeds .append (embed )
150
157
151
158
session = PaginatorSession (ctx , * embeds )
152
159
await session .run ()
153
160
161
+ @snippet .command (name = "raw" )
162
+ @checks .has_permissions (PermissionLevel .SUPPORTER )
163
+ async def snippet_raw (self , ctx , * , name : str .lower ):
164
+ val = self .bot .snippets .get (name )
165
+ if val is None :
166
+ embed = create_not_found_embed (name , self .bot .snippets .keys (), 'Snippet' )
167
+ return await ctx .send (embed = embed )
168
+ return await ctx .send (escape_markdown (escape_mentions (val )).replace ('<' , '\\ <' ))
169
+
154
170
@snippet .command (name = "add" )
155
171
@checks .has_permissions (PermissionLevel .SUPPORTER )
156
- async def snippet_add (self , ctx , name : str .lower , * , value ):
172
+ async def snippet_add (self , ctx , name : str .lower , * , value : commands . clean_content ):
157
173
"""
158
174
Add a snippet.
159
175
@@ -167,19 +183,35 @@ async def snippet_add(self, ctx, name: str.lower, *, value):
167
183
color = discord .Color .red (),
168
184
description = f"Snippet `{ name } ` already exists." ,
169
185
)
170
- else :
171
- self .bot .snippets [name ] = value
172
- await self .bot .config .update ()
186
+ return await ctx .send (embed = embed )
173
187
188
+ if name in self .bot .aliases :
174
189
embed = discord .Embed (
175
- title = "Added snippet" ,
176
- color = self .bot .main_color ,
177
- description = f'`{ name } ` will now send "{ value } ".' ,
190
+ title = "Error" ,
191
+ color = discord .Color .red (),
192
+ description = f"An alias with the same name already exists: `{ name } `." ,
193
+ )
194
+ return await ctx .send (embed = embed )
195
+
196
+ if len (name ) > 120 :
197
+ embed = discord .Embed (
198
+ title = "Error" ,
199
+ color = discord .Color .red (),
200
+ description = f"Snippet names cannot be longer than 120 characters." ,
178
201
)
202
+ return await ctx .send (embed = embed )
179
203
180
- await ctx .send (embed = embed )
204
+ self .bot .snippets [name ] = value
205
+ await self .bot .config .update ()
206
+
207
+ embed = discord .Embed (
208
+ title = "Added snippet" ,
209
+ color = self .bot .main_color ,
210
+ description = f'Successfully created snippet.' ,
211
+ )
212
+ return await ctx .send (embed = embed )
181
213
182
- @snippet .command (name = "remove" , aliases = ["del" , "delete" , "rm" ])
214
+ @snippet .command (name = "remove" , aliases = ["del" , "delete" ])
183
215
@checks .has_permissions (PermissionLevel .SUPPORTER )
184
216
async def snippet_remove (self , ctx , * , name : str .lower ):
185
217
"""Remove a snippet."""
@@ -188,18 +220,12 @@ async def snippet_remove(self, ctx, *, name: str.lower):
188
220
embed = discord .Embed (
189
221
title = "Removed snippet" ,
190
222
color = self .bot .main_color ,
191
- description = f"`{ name } ` no longer exists ." ,
223
+ description = f"Snippet `{ name } ` is now deleted ." ,
192
224
)
193
225
self .bot .snippets .pop (name )
194
226
await self .bot .config .update ()
195
-
196
227
else :
197
- embed = discord .Embed (
198
- title = "Error" ,
199
- color = discord .Color .red (),
200
- description = f"Snippet `{ name } ` does not exist." ,
201
- )
202
-
228
+ embed = create_not_found_embed (name , self .bot .snippets .keys (), 'Snippet' )
203
229
await ctx .send (embed = embed )
204
230
205
231
@snippet .command (name = "edit" )
@@ -221,13 +247,8 @@ async def snippet_edit(self, ctx, name: str.lower, *, value):
221
247
color = self .bot .main_color ,
222
248
description = f'`{ name } ` will now send "{ value } ".' ,
223
249
)
224
-
225
250
else :
226
- embed = discord .Embed (
227
- title = "Error" ,
228
- color = discord .Color .red (),
229
- description = f"Snippet `{ name } ` does not exist." ,
230
- )
251
+ embed = create_not_found_embed (name , self .bot .snippets .keys (), 'Snippet' )
231
252
await ctx .send (embed = embed )
232
253
233
254
@commands .command ()
0 commit comments