2
2
import string
3
3
import urllib .parse
4
4
from collections .abc import AsyncIterator
5
+ from io import BytesIO
5
6
from typing import NamedTuple
6
7
7
8
import discord
@@ -96,7 +97,7 @@ async def get_snippets(content: str) -> AsyncIterator[Snippet]:
96
97
)
97
98
98
99
99
- def _format_snippet (snippet : Snippet ) -> str :
100
+ def _format_snippet (snippet : Snippet , * , include_body : bool = True ) -> str :
100
101
repo_url = f"https://github.com/{ snippet .repo } "
101
102
tree_url = f"{ repo_url } /tree/{ snippet .rev } "
102
103
file_url = f"{ repo_url } /blob/{ snippet .rev } /{ snippet .path } "
@@ -115,37 +116,46 @@ def _format_snippet(snippet: Snippet) -> str:
115
116
f"[`{ unquoted_path } `](<{ file_url } >), { range_info } "
116
117
f"\n -# Repo: [`{ snippet .repo } `](<{ repo_url } >),"
117
118
f" { ref_type } : [`{ snippet .rev } `](<{ tree_url } >)"
118
- f"\n ```{ snippet .lang } \n { snippet .body } \n ```"
119
- )
119
+ ) + (f"\n ```{ snippet .lang } \n { snippet .body } \n ```" * include_body )
120
120
121
121
122
- async def snippet_message (message : discord .Message ) -> tuple [str , int ]:
122
+ async def snippet_message (
123
+ message : discord .Message ,
124
+ ) -> tuple [tuple [str , list [discord .File ]], int ]:
123
125
snippets = [s async for s in get_snippets (message .content )]
124
126
if not snippets :
125
- return "" , 0
127
+ return ( "" , []) , 0
126
128
127
129
blobs = list (map (_format_snippet , snippets ))
128
130
131
+ if len (blobs ) == 1 and len (blobs [0 ]) > 2000 :
132
+ # When there is only a single blob which goes over the limit, upload it
133
+ # as a file instead.
134
+ fp = BytesIO (snippets [0 ].body .encode ())
135
+ file = discord .File (fp , filename = f"code.{ snippets [0 ].lang } " )
136
+ return (_format_snippet (snippets [0 ], include_body = False ), [file ]), 1
137
+
129
138
if len ("\n \n " .join (blobs )) > 2000 :
130
139
while len ("\n \n " .join (blobs )) > 1970 : # Accounting for omission note
131
140
blobs .pop ()
132
141
if not blobs :
133
- return "" , - 1 # Signal that all snippets were omitted
142
+ return ( "" , []) , - 1 # Signal that all snippets were omitted
134
143
blobs .append ("-# Some snippets were omitted" )
135
- return "\n " .join (blobs ), len (snippets )
144
+ return ( "\n " .join (blobs ), [] ), len (snippets )
136
145
137
146
138
147
async def reply_with_code (message : discord .Message ) -> None :
139
148
if message .author .bot :
140
149
return
141
- msg_content , snippet_count = await snippet_message (message )
150
+ ( msg_content , files ) , snippet_count = await snippet_message (message )
142
151
if snippet_count != 0 :
143
152
await message .edit (suppress = True )
144
153
if snippet_count < 1 :
145
154
return
146
155
147
156
sent_message = await message .reply (
148
157
msg_content ,
158
+ files = files ,
149
159
suppress_embeds = True ,
150
160
mention_author = False ,
151
161
allowed_mentions = discord .AllowedMentions .none (),
0 commit comments