screenshotting 2 - how to use that API

In the last post I outlined and implemented a rough version of the code that I'm using on my backend for screenshot upload handling. In reality I have designed and implemented a token generation system and even a user account and login system for better organization and security, but I have omitted those from my example implementation in favor of brevity.

In this post I will outline two methods that one could implement to make use of their fancy new screenshot endpoint. The first will be my personal implementation inside my window manger (some logic lifted from a pre-existing StumpWM module), and the other implementation will make use of Flameshot, which is an absolutely awesome utility for screenshotting, with more features than I could dream up (with the exception of what I consider lackluster UI).

implementation 1: the lisp hacker way

The CL hacker way is to use my preexisting window manager's connection to X using the CLX library, which the default way to interact with X from Common Lisp. The basic function is jacked from the screenshot module of StumpWM. Here's my version of the screenshot function, I added X and Y coordinates (for selection) and I use loop instead of a do, for readability.

Here's how it operates: let png be an instance of the zpng:pixel-streamed-png type, xlib:get-raw-image the drawable, then write each pixel into the PNG with zpng:write-pixel in either big or small endian order. (For some reason, apparently X can return the raw image in either big or small endian.

Also in the linked file I have a screenshot-selection function, which queries for a selection by holding the mouse and keyboard hostage using xlib:grab-keyboard and xlib:grab-pointer until you click two points, then it screenshot-drawable's the selected area, and saves the screenshot to tempfile.png. This is because dexador uses autodetection of multipart content, and I haven't dived in enough to remove this tempfile.

After I have dumped a screenshot to tempfile.png, I use the aforementioned dexador to post the file using this:
(defun post (data type) (dex:post "" :content `(("file" . ,data) ("token" . ,*solb-token*) ("type" . ,type))))

And that's about it! The CL implementation is working.

implementation 2: the busy person way (a flameshot and a curl)

This is a simple one bash one-liner:
flameshot gui -r | curl -XPOST "" -F "file=@-" -F "token=TOKEN"

What does it it?
flameshot gui -r: use flameshot to take a screenshot with the GUI, -r option means output the photo into stdout.

curl -XPOST "" -F "file=@-" -F "token=TOKEN": the important note here is -F "file=@-". The @- option signifies taking input from stdin.

Not only is this way much simpler, it has more options and doesn't use a temporary file. The moral might be someting along the lines of don't bother homebrewing your own software, because it'll probably be worse than some preexisting solution. Or you could just have fun making your own software and have a good time, even if the result isn't quite as featured as the mature, existing implementation. Keep hacking!