Pithee printer
Jacksfilms has created a site called Pithee.com. It is a kind of “social” network, where users can submit posts (“pithees”) up to 80 characters in length. The main way to interact with the website is through voting. You are given 4 piths and you vote for the funniest one. When you click it, a ⭐ appears and the other 3 piths refresh. Then you vote again, but you can choose the last one and give it a second star. After a pith has 3 stars, it disappears too. When you vote enough, you may encounter 4 piths with 3 stars and you choose which will receive a fourth.
At the top of the page, you see the winning post. This refreshes every 10 minutes and is often pretty damn funny. And this had me thinking…
I have TWO (2) thermal receipt printers, and one of them is on my desk. What if I made it print the winning post every 10 minutes? So that’s exactly what I did.

First, we need to figure out how the API works. I opened the Network tab in Chrome and hit refresh. I found the endpoint current_winner?select=* and this was the response:
{
"post_id": "7def49fd-160d-4f00-a68f-982f09f57214",
"post_text": "Guys do rib cages grow back?",
"post_created_at": "2024-03-28T13:57:36.05584+00:00",
"won_at": "2024-04-09T19:10:00.017029+00:00",
"player_id": "d71aa493-56e7-41a2-bba3-f09301ee5fa2",
"player_name": "lazyavatar123"
}
It seems that this endpoint has been since replaced with get_current_winner which contains less information. The code may need to be edited in the future.
For the code, I’ve used C# and created a console app. Literally anything else would work too, as this was an extremely easy app. The code below is not some crazy sophisticated stuff. I project done is better than a project stuck in overoptimization hell.
The following code is called every 10 minutes:
static void Print()
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += PrintPage;
pd.Print();
pd.Dispose();
}
This code draws the Pith onto the page:
static void PrintPage(object o, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
e.HasMorePages = false;
int y = 0;
WinningPost winningPost = FetchWinningPost();
y += DrawText(e, g, winningPost.post_text, 0, y, 12);
y += 5;
string signature = $"-{winningPost.player_name} ({winningPost.won_at.ToString("dd. MM. yyyy HH:mm")})";
DrawText(e, g, signature, 0, y, 8);
Console.WriteLine(winningPost.post_text);
Console.WriteLine(signature);
Console.WriteLine();
}
I used this snippet on a few of my printer projects. It actually forces the string to fit onto the page and returns the height. This way everything can dynamically move depending on the length of the text:
static int DrawText(PrintPageEventArgs e, Graphics g, string text, int x, int y, int fontSize = 11)
{
Font font = new Font("Atkinson Hyperlegible", fontSize);
SizeF size = g.MeasureString(text, font, 285);
e.Graphics.DrawString(text, font, Brushes.Black, new RectangleF(x, y, size.Width, size.Height));
return (int)size.Height;
}
The actual web request:
static WinningPost FetchWinningPost()
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://oqutjaxxxzzbjtyrfoka.supabase.co/rest/v1/current_winner?select=*"))
{
request.Headers.TryAddWithoutValidation("apikey", APIKEY);
var response = httpClient.SendAsync(request);
string json = response.Result.Content.ReadAsStringAsync().Result;
json = json.TrimStart('[').TrimEnd(']'); //The downloaded json is encapsulated in these, so just trim them
WinningPost winningPost = JsonConvert.DeserializeObject<WinningPost>(json);
return winningPost;
}
}
}
And of course:
[Serializable]
public class WinningPost
{
public string post_id;
public string post_text;
public DateTime post_created_at;
public DateTime won_at;
public string player_id;
public string player_name;
}
The only problem I have encountered so far is emojis. A few piths contain crazy characters which the font I used doesn’t support. If I wanted to fix this, I would probably need to combine the Noto Emoji font with the one I used for it to look nice. But even then it wouldn’t support the entire UNICODE. I’ll have to look into how to render all those characters in the future.

So far I think I must have printed hundreds of piths. Every 10 minutes my printer goes brrr and a fun new post comes out. It surprisingly doesn’t get old.