syntax highlighting in html
12/07/24
Words: 693 (and a bunch of html you don’t need to read)
premise
syntax highlighting is really cool. vscode does a really great job of visually communicating what every piece of code is, but a lot of this information is lost when you copy and paste the code into markdown or html. i want to make my code look pretty in my blog posts.
idea(s)
i have a few potential ideas for how i can make this work out:
- find a tool that will do it all for me
- do it all manually by hand
i would obviously prefer to avoid the latter, so i’ll look for tools first.
attempted solutions
00 - pandoc
in attempts to find something to export my markdown file (what i am writing this in) into html that i can put on my website, i came across pandoc, a neat document converter. it even has a handy vscode plugin that can do it all from a command in the editor.
this is wonderful and all, but it crucially doesn’t generate the colors for you, and… honestly does a pretty terrible job of labelling the code. most of it is left unlabelled and some are even labelled incorrectly.
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="at">@app_commands.allowed_contexts</span>(guilds<span class="op">=</span><span class="va">True</span>, dms<span class="op">=</span><span class="va">True</span>, private_channels<span class="op">=</span><span class="va">True</span>)</span><span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="at">@tree.context_menu</span>(name<span class="op">=</span><span class="st">"fixfiles"</span>)</span><span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="cf">async</span> <span class="kw">def</span> fixfiles(interaction: discord.Interaction, message: discord.Message):</span><span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> interaction.response.defer()</span><span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a> images <span class="op">=</span> []</span><span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> hardware <span class="op">=</span> path.exists(<span class="st">"/dev/dri/renderD128"</span>)</span><span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> params <span class="op">=</span> [<span class="st">"-vaapi_device"</span>, <span class="st">"/dev/dri/renderD128"</span>, <span class="st">"-vf"</span>, <span class="st">"hwupload,scale_vaapi=w=-2:h='min(720,iw)':format=nv12"</span>, <span class="st">"-c:v"</span>, <span class="st">"h264_vaapi"</span>, <span class="st">"-b:v"</span>, <span class="st">"1M"</span>] <span class="cf">if</span> hardware <span class="cf">else</span> [<span class="st">"-c:v"</span>, <span class="st">"h264"</span>, <span class="st">"-vf"</span>, <span class="st">"scale=-2:'min(720,iw)'"</span>]</span><span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a></span><span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a> <span class="cf">for</span> attachment <span class="kw">in</span> message.attachments:</span><span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a> extension <span class="op">=</span> <span class="st">""</span></span><span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a> attachment_data <span class="op">=</span> <span class="cf">await</span> attachment.read()</span><span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a> mime <span class="op">=</span> magic.from_buffer(attachment_data, mime <span class="op">=</span> <span class="va">True</span>).split(<span class="st">"/"</span>)</span><span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a> contentType <span class="op">=</span> mime[<span class="dv">0</span>]</span><span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a> contentExtension <span class="op">=</span> mime[<span class="dv">1</span>]</span><span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a> <span class="cf">match</span> contentType:</span><span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a> <span class="cf">case</span> <span class="st">"image"</span>:</span><span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> contentExtension <span class="op">==</span> <span class="st">"gif"</span>:</span><span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a> <span class="cf">continue</span></span><span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a> command <span class="op">=</span> [<span class="st">"ffmpeg"</span>, <span class="st">"-i"</span>, <span class="st">"pipe:0"</span>, <span class="st">"-f"</span>, <span class="st">"image2"</span>, <span class="st">"pipe:1"</span>]</span><span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a> extension <span class="op">=</span> <span class="st">"jpg"</span></span><span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a> <span class="cf">case</span> <span class="st">"video"</span>:</span><span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a> command <span class="op">=</span> [<span class="st">"ffmpeg"</span>, <span class="st">"-i"</span>, <span class="st">"pipe:0"</span>, <span class="op">*</span>params, <span class="st">"-c:a"</span>, <span class="st">"aac"</span>, <span class="st">"-pix_fmt"</span>, <span class="st">"yuv420p"</span>, <span class="st">"-movflags"</span>, <span class="st">"frag_keyframe+empty_moov+faststart"</span>, <span class="st">"-f"</span>, <span class="st">"mp4"</span>, <span class="st">"pipe:1"</span>]</span><span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a> extension <span class="op">=</span> <span class="st">"mp4"</span></span><span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a> <span class="cf">case</span> <span class="st">"audio"</span>:</span><span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a> command <span class="op">=</span> [<span class="st">"ffmpeg"</span>, <span class="st">"-i"</span>, <span class="st">"pipe:0"</span>, <span class="st">"-loop"</span>, <span class="st">"1"</span>, <span class="st">"-r"</span>, <span class="st">"10"</span>, <span class="st">"-i"</span>, <span class="st">"assets/sus.webp"</span>, <span class="st">"-shortest"</span>, <span class="op">*</span>params, <span class="st">"-c:a"</span>, <span class="st">"aac"</span>, <span class="st">"-pix_fmt"</span>, <span class="st">"yuv420p"</span>, <span class="st">"-movflags"</span>, <span class="st">"frag_keyframe+empty_moov+faststart"</span>, <span class="st">"-f"</span>, <span class="st">"mp4"</span>, <span class="st">"pipe:1"</span>]</span><span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a> extension <span class="op">=</span> <span class="st">"mp4"</span></span><span id="cb12-28"><a href="#cb12-28" aria-hidden="true" tabindex="-1"></a> <span class="cf">case</span> _:</span><span id="cb12-29"><a href="#cb12-29" aria-hidden="true" tabindex="-1"></a> <span class="cf">continue</span></span><span id="cb12-30"><a href="#cb12-30" aria-hidden="true" tabindex="-1"></a></span><span id="cb12-31"><a href="#cb12-31" aria-hidden="true" tabindex="-1"></a> process <span class="op">=</span> run(command, <span class="bu">input</span> <span class="op">=</span> attachment_data, stdout <span class="op">=</span> PIPE)</span><span id="cb12-32"><a href="#cb12-32" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> process.returncode <span class="op">==</span> <span class="dv">0</span>:</span><span id="cb12-33"><a href="#cb12-33" aria-hidden="true" tabindex="-1"></a> discord_file <span class="op">=</span> discord.File(fp <span class="op">=</span> BytesIO(process.stdout), filename <span class="op">=</span> <span class="ss">f"</span><span class="sc">{</span>attachment<span class="sc">.</span>filename<span class="sc">.</span>split(<span class="st">"."</span>)[<span class="dv">0</span>]<span class="sc">}</span><span class="ss">.</span><span class="sc">{</span>extension<span class="sc">}</span><span class="ss">"</span>)</span><span id="cb12-34"><a href="#cb12-34" aria-hidden="true" tabindex="-1"></a> images.append(discord_file)</span><span id="cb12-35"><a href="#cb12-35" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="bu">len</span>(images) <span class="op">></span> <span class="dv">0</span>:</span><span id="cb12-36"><a href="#cb12-36" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> interaction.followup.send(files <span class="op">=</span> images)</span><span id="cb12-37"><a href="#cb12-37" aria-hidden="true" tabindex="-1"></a> <span class="cf">else</span>:</span><span id="cb12-38"><a href="#cb12-38" aria-hidden="true" tabindex="-1"></a> <span class="cf">await</span> interaction.followup.send(<span class="st">"No files to fix"</span>)</span></code></pre></div>
the amount of code that this left unlabelled or not labelled properly
was… frustrating to say the least. i wanted to find another solution,
one that had better coverage in the highlighting and that didn’t require
me to choose the colors myself.
01 - prism.js
while troubleshooting this, annie recommended trying prism.js. after about 15 minutes of
tinkering, i got it running in node, and tried using its output in the
same way the pandoc code would be used.
<span class="token decorator annotation punctuation">@app_commands<span class="token punctuation">.</span>allowed_installs</span><span class="token punctuation">(</span>guilds<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> users<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span>
<span class="token decorator annotation punctuation">@app_commands<span class="token punctuation">.</span>allowed_contexts</span><span class="token punctuation">(</span>guilds<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> dms<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">,</span> private_channels<span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation">)</span><span class="token decorator annotation punctuation">@tree<span class="token punctuation">.</span>context_menu</span><span class="token punctuation">(</span>name<span class="token operator">=</span><span class="token string">"fixfiles"</span><span class="token punctuation">)</span><span class="token keyword">async</span> <span class="token keyword">def</span> <span class="token function">fixfiles</span><span class="token punctuation">(</span>interaction<span class="token punctuation">:</span> discord<span class="token punctuation">.</span>Interaction<span class="token punctuation">,</span> message<span class="token punctuation">:</span> discord<span class="token punctuation">.</span>Message<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">await</span> interaction<span class="token punctuation">.</span>response<span class="token punctuation">.</span>defer<span class="token punctuation">(</span><span class="token punctuation">)</span> images <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> hardware <span class="token operator">=</span> path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span><span class="token string">"/dev/dri/renderD128"</span><span class="token punctuation">)</span> params <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"-vaapi_device"</span><span class="token punctuation">,</span> <span class="token string">"/dev/dri/renderD128"</span><span class="token punctuation">,</span> <span class="token string">"-vf"</span><span class="token punctuation">,</span> <span class="token string">"hwupload,scale_vaapi=w=-2:h='min(720,iw)':format=nv12"</span><span class="token punctuation">,</span> <span class="token string">"-c:v"</span><span class="token punctuation">,</span> <span class="token string">"h264_vaapi"</span><span class="token punctuation">,</span> <span class="token string">"-b:v"</span><span class="token punctuation">,</span> <span class="token string">"1M"</span><span class="token punctuation">]</span> <span class="token keyword">if</span> hardware <span class="token keyword">else</span> <span class="token punctuation">[</span><span class="token string">"-c:v"</span><span class="token punctuation">,</span> <span class="token string">"h264"</span><span class="token punctuation">,</span> <span class="token string">"-vf"</span><span class="token punctuation">,</span> <span class="token string">"scale=-2:'min(720,iw)'"</span><span class="token punctuation">]</span>
<span class="token keyword">for</span> attachment <span class="token keyword">in</span> message<span class="token punctuation">.</span>attachments<span class="token punctuation">:</span> extension <span class="token operator">=</span> <span class="token string">""</span> attachment_data <span class="token operator">=</span> <span class="token keyword">await</span> attachment<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span> mime <span class="token operator">=</span> magic<span class="token punctuation">.</span>from_buffer<span class="token punctuation">(</span>attachment_data<span class="token punctuation">,</span> mime <span class="token operator">=</span> <span class="token boolean">True</span><span class="token punctuation">)</span><span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">)</span> contentType <span class="token operator">=</span> mime<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> contentExtension <span class="token operator">=</span> mime<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token keyword">match</span> contentType<span class="token punctuation">:</span> <span class="token keyword">case</span> <span class="token string">"image"</span><span class="token punctuation">:</span> <span class="token keyword">if</span> contentExtension <span class="token operator">==</span> <span class="token string">"gif"</span><span class="token punctuation">:</span> <span class="token keyword">continue</span> command <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"ffmpeg"</span><span class="token punctuation">,</span> <span class="token string">"-i"</span><span class="token punctuation">,</span> <span class="token string">"pipe:0"</span><span class="token punctuation">,</span> <span class="token string">"-f"</span><span class="token punctuation">,</span> <span class="token string">"image2"</span><span class="token punctuation">,</span> <span class="token string">"pipe:1"</span><span class="token punctuation">]</span> extension <span class="token operator">=</span> <span class="token string">"jpg"</span> <span class="token keyword">case</span> <span class="token string">"video"</span><span class="token punctuation">:</span> command <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"ffmpeg"</span><span class="token punctuation">,</span> <span class="token string">"-i"</span><span class="token punctuation">,</span> <span class="token string">"pipe:0"</span><span class="token punctuation">,</span> <span class="token operator">*</span>params<span class="token punctuation">,</span> <span class="token string">"-c:a"</span><span class="token punctuation">,</span> <span class="token string">"aac"</span><span class="token punctuation">,</span> <span class="token string">"-pix_fmt"</span><span class="token punctuation">,</span> <span class="token string">"yuv420p"</span><span class="token punctuation">,</span> <span class="token string">"-movflags"</span><span class="token punctuation">,</span> <span class="token string">"frag_keyframe+empty_moov+faststart"</span><span class="token punctuation">,</span> <span class="token string">"-f"</span><span class="token punctuation">,</span> <span class="token string">"mp4"</span><span class="token punctuation">,</span> <span class="token string">"pipe:1"</span><span class="token punctuation">]</span> extension <span class="token operator">=</span> <span class="token string">"mp4"</span> <span class="token keyword">case</span> <span class="token string">"audio"</span><span class="token punctuation">:</span> command <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"ffmpeg"</span><span class="token punctuation">,</span> <span class="token string">"-i"</span><span class="token punctuation">,</span> <span class="token string">"pipe:0"</span><span class="token punctuation">,</span> <span class="token string">"-loop"</span><span class="token punctuation">,</span> <span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token string">"-r"</span><span class="token punctuation">,</span> <span class="token string">"10"</span><span class="token punctuation">,</span> <span class="token string">"-i"</span><span class="token punctuation">,</span> <span class="token string">"assets/sus.webp"</span><span class="token punctuation">,</span> <span class="token string">"-shortest"</span><span class="token punctuation">,</span> <span class="token operator">*</span>params<span class="token punctuation">,</span> <span class="token string">"-c:a"</span><span class="token punctuation">,</span> <span class="token string">"aac"</span><span class="token punctuation">,</span> <span class="token string">"-pix_fmt"</span><span class="token punctuation">,</span> <span class="token string">"yuv420p"</span><span class="token punctuation">,</span> <span class="token string">"-movflags"</span><span class="token punctuation">,</span> <span class="token string">"frag_keyframe+empty_moov+faststart"</span><span class="token punctuation">,</span> <span class="token string">"-f"</span><span class="token punctuation">,</span> <span class="token string">"mp4"</span><span class="token punctuation">,</span> <span class="token string">"pipe:1"</span><span class="token punctuation">]</span> extension <span class="token operator">=</span> <span class="token string">"mp4"</span> <span class="token keyword">case</span> <span class="token keyword">_</span><span class="token punctuation">:</span> <span class="token keyword">continue</span>
process <span class="token operator">=</span> run<span class="token punctuation">(</span>command<span class="token punctuation">,</span> <span class="token builtin">input</span> <span class="token operator">=</span> attachment_data<span class="token punctuation">,</span> stdout <span class="token operator">=</span> PIPE<span class="token punctuation">)</span> <span class="token keyword">if</span> process<span class="token punctuation">.</span>returncode <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">:</span> discord_file <span class="token operator">=</span> discord<span class="token punctuation">.</span>File<span class="token punctuation">(</span>fp <span class="token operator">=</span> BytesIO<span class="token punctuation">(</span>process<span class="token punctuation">.</span>stdout<span class="token punctuation">)</span><span class="token punctuation">,</span> filename <span class="token operator">=</span> <span class="token string-interpolation"><span class="token string">f"{attachment.filename.split("</span></span><span class="token punctuation">.</span><span class="token string">")[0]}.{extension}"</span><span class="token punctuation">)</span> images<span class="token punctuation">.</span>append<span class="token punctuation">(</span>discord_file<span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token builtin">len</span><span class="token punctuation">(</span>images<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">:</span> <span class="token keyword">await</span> interaction<span class="token punctuation">.</span>followup<span class="token punctuation">.</span>send<span class="token punctuation">(</span>files <span class="token operator">=</span> images<span class="token punctuation">)</span> <span class="token keyword">else</span><span class="token punctuation">:</span> <span class="token keyword">await</span> interaction<span class="token punctuation">.</span>followup<span class="token punctuation">.</span>send<span class="token punctuation">(</span><span class="token string">"No files to fix"</span><span class="token punctuation">)</span>
this yielded much better results, with better coverage in the code,
and much less code left behind. additionally, i could use a
theme someone else made for prism to mimic the vscode dark+ theme
(what i use). however, this still wasn’t good enough for me. it still
didn’t look as pretty as i wanted it to, but then i took a shower and
had an epiphany
02 - pandocs again (kinda)
while in the shower, i had a big realization. surely there had to be
some way to copy the text from vscode including the syntax highlighting,
because you can do as such in other places like word and google docs. if
i could manage to figure this out, i could do the following: 1. copy
with syntax highlighting 2. paste into a doc 3. export as docx 4. use
pandoc to convert docx into html 5. insert html into pre>code
tags
this was a great plan, and worked great until step 4. pandoc made
this harder than it needed to be, and instead i ended up using an online converter instead. this… just
sort of worked. it exported the text as a bunch of p
tags
with span
s instead of them. this meant i had to fix these
by pulling the span
s out of the p
tags before
inputting them into my code tags, but i did that with a simple python
script:
with open("code.html", "r+") as f:
d = f.readlines() f.seek(0) for line in d: if line.startswith("<span"): f.write(line) f.truncate()
this fully worked! i got a fully functional perfect paste of my code
just as it looked in vscode.
<span style="font-family:'Courier New'; color:#dcdcaa">@</span><span style="font-family:'Courier New'; color:#4ec9b0">app_commands</span><span style="font-family:'Courier New'; color:#dcdcaa">.allowed_installs</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">guilds</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">users</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span>
<span style="font-family:'Courier New'; color:#dcdcaa">@</span><span style="font-family:'Courier New'; color:#4ec9b0">app_commands</span><span style="font-family:'Courier New'; color:#dcdcaa">.allowed_contexts</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">guilds</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">dms</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">private_channels</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#dcdcaa">@</span><span style="font-family:'Courier New'; color:#9cdcfe">tree</span><span style="font-family:'Courier New'; color:#dcdcaa">.context_menu</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">name</span><span style="font-family:'Courier New'; color:#d4d4d4">=</span><span style="font-family:'Courier New'; color:#ce9178">"fixfiles"</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#569cd6">async</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#569cd6">def</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#dcdcaa">fixfiles</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">interaction</span><span style="font-family:'Courier New'; color:#d4d4d4">: </span><span style="font-family:'Courier New'; color:#4ec9b0">discord</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#4ec9b0">Interaction</span><span style="font-family:'Courier New'; color:#d4d4d4">,</span><span style="font-family:'Courier New'; color:#d4d4d4">  </span><span style="font-family:'Courier New'; color:#9cdcfe">message</span><span style="font-family:'Courier New'; color:#d4d4d4">: </span><span style="font-family:'Courier New'; color:#4ec9b0">discord</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#4ec9b0">Message</span><span style="font-family:'Courier New'; color:#d4d4d4">):</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#c586c0">await</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">interaction</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">response</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">defer</span><span style="font-family:'Courier New'; color:#d4d4d4">()</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#9cdcfe">images</span><span style="font-family:'Courier New'; color:#d4d4d4"> = []</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#9cdcfe">hardware</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#9cdcfe">path</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">exists</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#ce9178">"/dev/dri/renderD128"</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#9cdcfe">params</span><span style="font-family:'Courier New'; color:#d4d4d4"> = [</span><span style="font-family:'Courier New'; color:#ce9178">"-vaapi_device"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"/dev/dri/renderD128"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-vf"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"hwupload,scale_vaapi=w=-2:h='min(720,iw)':format=nv12"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-c:v"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"h264_vaapi"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-b:v"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"1M"</span><span style="font-family:'Courier New'; color:#d4d4d4">] </span><span style="font-family:'Courier New'; color:#c586c0">if</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">hardware</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#c586c0">else</span><span style="font-family:'Courier New'; color:#d4d4d4"> [</span><span style="font-family:'Courier New'; color:#ce9178">"-c:v"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"h264"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-vf"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"scale=-2:'min(720,iw)'"</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#c586c0">for</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">attachment</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#c586c0">in</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">message</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">attachments</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">extension</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#ce9178">""</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">attachment_data</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#c586c0">await</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">attachment</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">read</span><span style="font-family:'Courier New'; color:#d4d4d4">()</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">mime</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#4ec9b0">magic</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">from_buffer</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">attachment_data</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">mime</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#4fc1ff">True</span><span style="font-family:'Courier New'; color:#d4d4d4">).</span><span style="font-family:'Courier New'; color:#dcdcaa">split</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#ce9178">"/"</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">contentType</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#9cdcfe">mime</span><span style="font-family:'Courier New'; color:#d4d4d4">[</span><span style="font-family:'Courier New'; color:#b5cea8">0</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">contentExtension</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#9cdcfe">mime</span><span style="font-family:'Courier New'; color:#d4d4d4">[</span><span style="font-family:'Courier New'; color:#b5cea8">1</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#c586c0">match</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">contentType</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#c586c0">case</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#ce9178">"image"</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#c586c0">if</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">contentExtension</span><span style="font-family:'Courier New'; color:#d4d4d4"> == </span><span style="font-family:'Courier New'; color:#ce9178">"gif"</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">                   </span><span style="font-family:'Courier New'; color:#c586c0">continue</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">command</span><span style="font-family:'Courier New'; color:#d4d4d4"> = [</span><span style="font-family:'Courier New'; color:#ce9178">"ffmpeg"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-i"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:0"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-f"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"image2"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:1"</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">extension</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#ce9178">"jpg"</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#c586c0">case</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#ce9178">"video"</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">command</span><span style="font-family:'Courier New'; color:#d4d4d4"> = [</span><span style="font-family:'Courier New'; color:#ce9178">"ffmpeg"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-i"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:0"</span><span style="font-family:'Courier New'; color:#d4d4d4">, *</span><span style="font-family:'Courier New'; color:#9cdcfe">params</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-c:a"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"aac"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-pix_fmt"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"yuv420p"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-movflags"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"frag_keyframe+empty_moov+faststart"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-f"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"mp4"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:1"</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">extension</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#ce9178">"mp4"</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#c586c0">case</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#ce9178">"audio"</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">command</span><span style="font-family:'Courier New'; color:#d4d4d4"> = [</span><span style="font-family:'Courier New'; color:#ce9178">"ffmpeg"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-i"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:0"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-loop"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"1"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-r"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"10"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-i"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"assets/sus.webp"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-shortest"</span><span style="font-family:'Courier New'; color:#d4d4d4">, *</span><span style="font-family:'Courier New'; color:#9cdcfe">params</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-c:a"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"aac"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-pix_fmt"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"yuv420p"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-movflags"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"frag_keyframe+empty_moov+faststart"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"-f"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"mp4"</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#ce9178">"pipe:1"</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#9cdcfe">extension</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#ce9178">"mp4"</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#c586c0">case</span><span style="font-family:'Courier New'; color:#d4d4d4"> _:</span><span style="font-family:'Courier New'; color:#d4d4d4">               </span><span style="font-family:'Courier New'; color:#c586c0">continue</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#9cdcfe">process</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#dcdcaa">run</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">command</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">input</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#9cdcfe">attachment_data</span><span style="font-family:'Courier New'; color:#d4d4d4">, </span><span style="font-family:'Courier New'; color:#9cdcfe">stdout</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#4fc1ff">PIPE</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#c586c0">if</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">process</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">returncode</span><span style="font-family:'Courier New'; color:#d4d4d4"> == </span><span style="font-family:'Courier New'; color:#b5cea8">0</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#9cdcfe">discord_file</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#4ec9b0">discord</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#4ec9b0">File</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">fp</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#4ec9b0">BytesIO</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">process</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">stdout</span><span style="font-family:'Courier New'; color:#d4d4d4">), </span><span style="font-family:'Courier New'; color:#9cdcfe">filename</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#569cd6">f</span><span style="font-family:'Courier New'; color:#ce9178">"</span><span style="font-family:'Courier New'; color:#569cd6">{</span><span style="font-family:'Courier New'; color:#9cdcfe">attachment</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">filename</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">split</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#ce9178">"."</span><span style="font-family:'Courier New'; color:#d4d4d4">)[</span><span style="font-family:'Courier New'; color:#b5cea8">0</span><span style="font-family:'Courier New'; color:#d4d4d4">]</span><span style="font-family:'Courier New'; color:#569cd6">}</span><span style="font-family:'Courier New'; color:#ce9178">.</span><span style="font-family:'Courier New'; color:#569cd6">{</span><span style="font-family:'Courier New'; color:#9cdcfe">extension</span><span style="font-family:'Courier New'; color:#569cd6">}</span><span style="font-family:'Courier New'; color:#ce9178">"</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">           </span><span style="font-family:'Courier New'; color:#9cdcfe">images</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">append</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">discord_file</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#c586c0">if</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#dcdcaa">len</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">images</span><span style="font-family:'Courier New'; color:#d4d4d4">) > </span><span style="font-family:'Courier New'; color:#b5cea8">0</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#c586c0">await</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">interaction</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">followup</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">send</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#9cdcfe">files</span><span style="font-family:'Courier New'; color:#d4d4d4"> = </span><span style="font-family:'Courier New'; color:#9cdcfe">images</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span><span style="font-family:'Courier New'; color:#d4d4d4">   </span><span style="font-family:'Courier New'; color:#c586c0">else</span><span style="font-family:'Courier New'; color:#d4d4d4">:</span><span style="font-family:'Courier New'; color:#d4d4d4">       </span><span style="font-family:'Courier New'; color:#c586c0">await</span><span style="font-family:'Courier New'; color:#d4d4d4"> </span><span style="font-family:'Courier New'; color:#9cdcfe">interaction</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#9cdcfe">followup</span><span style="font-family:'Courier New'; color:#d4d4d4">.</span><span style="font-family:'Courier New'; color:#dcdcaa">send</span><span style="font-family:'Courier New'; color:#d4d4d4">(</span><span style="font-family:'Courier New'; color:#ce9178">"No files to fix"</span><span style="font-family:'Courier New'; color:#d4d4d4">)</span>
victory! well, almost.
03 - clipboard inspection
after i had done all of this process, mary suggested that it could be
possible to “make a thing that listens to the paste event and grabs the
text/html copy of the clipboard”. in response to this, my girlfriend sent clipboard
inspector and clipboard
viewer, two tools that did exactly that. these could entirely skip
the intermediaries of the doc and the converters, allowing me to simply
copy the html out of the clipboard. The only extra effort it required is removing the two divs that the code is inside.
this yielded a much simpler and faster process, and one that gave
seemingly much more concise html:
<span style="color: #dcdcaa;">@</span><span style="color: #4ec9b0;">app_commands</span><span style="color: #dcdcaa;">.</span><span style="color: #dcdcaa;">allowed_installs</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">guilds</span><span style="color: #d4d4d4;">=</span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">users</span><span style="color: #d4d4d4;">=</span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #dcdcaa;">@</span><span style="color: #4ec9b0;">app_commands</span><span style="color: #dcdcaa;">.</span><span style="color: #dcdcaa;">allowed_contexts</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">guilds</span><span style="color: #d4d4d4;">=</span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">dms</span><span style="color: #d4d4d4;">=</span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">private_channels</span><span style="color: #d4d4d4;">=</span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #dcdcaa;">@</span><span style="color: #9cdcfe;">tree</span><span style="color: #dcdcaa;">.</span><span style="color: #dcdcaa;">context_menu</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">name</span><span style="color: #d4d4d4;">=</span><span style="color: #ce9178;">"fixfiles"</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #569cd6;">async</span><span style="color: #d4d4d4;"> </span><span style="color: #569cd6;">def</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">fixfiles</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">interaction</span><span style="color: #d4d4d4;">: </span><span style="color: #4ec9b0;">discord</span><span style="color: #d4d4d4;">.</span><span style="color: #4ec9b0;">Interaction</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;">: </span><span style="color: #4ec9b0;">discord</span><span style="color: #d4d4d4;">.</span><span style="color: #4ec9b0;">Message</span><span style="color: #d4d4d4;">):</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">await</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">interaction</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">response</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">defer</span><span style="color: #d4d4d4;">()</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">images</span><span style="color: #d4d4d4;"> = []</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">hardware</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">path</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">exists</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"/dev/dri/renderD128"</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">params</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">"-vaapi_device"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"/dev/dri/renderD128"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-vf"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"hwupload,scale_vaapi=w=-2:h='min(720,iw)':format=nv12"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-c:v"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"h264_vaapi"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-b:v"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"1M"</span><span style="color: #d4d4d4;">] </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">hardware</span><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">else</span><span style="color: #d4d4d4;"> [</span><span style="color: #ce9178;">"-c:v"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"h264"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-vf"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"scale=-2:'min(720,iw)'"</span><span style="color: #d4d4d4;">]</span></div><br><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">for</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">attachment</span><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">in</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">message</span><span style="color: #d4d4d4;">.</span><span style="color: #9cdcfe;">attachments</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">extension</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">""</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">attachment_data</span><span style="color: #d4d4d4;"> = </span><span style="color: #c586c0;">await</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">attachment</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">read</span><span style="color: #d4d4d4;">()</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">mime</span><span style="color: #d4d4d4;"> = </span><span style="color: #4ec9b0;">magic</span><span style="color: #d4d4d4;">.</span><span style="color: #dcdcaa;">from_buffer</span><span style="color: #d4d4d4;">(</span><span style="color: #9cdcfe;">attachment_data</span><span style="color: #d4d4d4;">, </span><span style="color: #9cdcfe;">mime</span><span style="color: #d4d4d4;"> = </span><span style="color: #4fc1ff;">True</span><span style="color: #d4d4d4;">).</span><span style="color: #dcdcaa;">split</span><span style="color: #d4d4d4;">(</span><span style="color: #ce9178;">"/"</span><span style="color: #d4d4d4;">)</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">contentType</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">mime</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">0</span><span style="color: #d4d4d4;">]</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">contentExtension</span><span style="color: #d4d4d4;"> = </span><span style="color: #9cdcfe;">mime</span><span style="color: #d4d4d4;">[</span><span style="color: #b5cea8;">1</span><span style="color: #d4d4d4;">]</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">match</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">contentType</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">case</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"image"</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">if</span><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">contentExtension</span><span style="color: #d4d4d4;"> == </span><span style="color: #ce9178;">"gif"</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">continue</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">command</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">"ffmpeg"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-i"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:0"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-f"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"image2"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:1"</span><span style="color: #d4d4d4;">]</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">extension</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">"jpg"</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">case</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"video"</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">command</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">"ffmpeg"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-i"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:0"</span><span style="color: #d4d4d4;">, *</span><span style="color: #9cdcfe;">params</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-c:a"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"aac"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-pix_fmt"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"yuv420p"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-movflags"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"frag_keyframe+empty_moov+faststart"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-f"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"mp4"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:1"</span><span style="color: #d4d4d4;">]</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">extension</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">"mp4"</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">case</span><span style="color: #d4d4d4;"> </span><span style="color: #ce9178;">"audio"</span><span style="color: #d4d4d4;">:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">command</span><span style="color: #d4d4d4;"> = [</span><span style="color: #ce9178;">"ffmpeg"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-i"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:0"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-loop"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"1"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-r"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"10"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-i"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"assets/sus.webp"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-shortest"</span><span style="color: #d4d4d4;">, *</span><span style="color: #9cdcfe;">params</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-c:a"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"aac"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-pix_fmt"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"yuv420p"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-movflags"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"frag_keyframe+empty_moov+faststart"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"-f"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"mp4"</span><span style="color: #d4d4d4;">, </span><span style="color: #ce9178;">"pipe:1"</span><span style="color: #d4d4d4;">]</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #9cdcfe;">extension</span><span style="color: #d4d4d4;"> = </span><span style="color: #ce9178;">"mp4"</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">case</span><span style="color: #d4d4d4;"> _:</span></div><div><span style="color: #d4d4d4;"> </span><span style="color: #c586c0;">continue</span>```
conclusion
this was an… interesting, and while very confusing and very long
process, honestly kind of fun. plus my code looks pretty now so it’s
WORTH IT!