Release!

Stumpy is ready for use, for anyone who wants to use it. If you’re working on an application that sends email and you’d like to test that feature, you may find this useful.

In other news, searching for “pop3 client library” leads me to believe that every developer for macOS thinks that Apple Mail is the absolute bees knees and there’s just no reason anyone would want to receive email in any other way. Unless maybe they wanted to use python. Which is just mystifying to me, because come on!

Stumpy Progress

With a bit of persistence and lots of print statements, I’ve debugged my port of the core dumbster features over to Swift. Stumpy now works as a native replacement for dumbster. It turned out there was a capitalization mismatch (my code was looking for ‘Message-ID’ while Mail was writing ‘Message-Id’) and a counting error (headers and body are supposed to be separated by a blank line, and that means two successive \r\n tuples: the first to terminate the last line of the headers and the second to terminate the blank line).

So now that that’s complete, it’s time to turn my attention to the UI. Rather than independently starting and stopping the servers, I think I’d like to start and stop both servers for a given mail store together. Also, I want the UI to report how many messages are currently in the mail store. All of this information should go together into a mail store view, which gets displayed by the top level view.

Stumpy: History and Problem Statement

When we were first writing the software for LinkedIn, Jean-Luc put together a python script that would act like a dummy MTA and mail store. The point was that the application was going to be sending out emails of various kinds, notably invitations to connect, and we needed to be able to write tests that would verify that feature (the emails are well-formed, they actually get sent, etc.) without sending real messages to real email accounts. This was incredibly valuable.

Years later I was contracting at NASA, working on a system that, again, generated emails. I wanted to institute some kind of automated testing, and tried to come up with a similar tool for use there. I found out that I’m allergic to python but I found a Java program that did half of what I wanted – it would pretend to be sendmail and accept any emails and just stuff them into an in-memory store. I forked it and modified it to add a POP3 server so that the application could generate and send the emails and then a tester could open the email with Outlook or Apple Mail or whatever and then click included links or open attached files, etc.

Even later, I modified that program by putting a JavaFX graphical UI on top, and letting you spin up multiple corresponding SMTP/POP3 server pairs. The point, that time, was that I was working on a play-by-email server and I wanted to have the server and clients all talking to each other via email but still on my development machine. As a responsible software developer, I do not make a practice of turning untested robots loose on the world.

The problem that I have with the program as it stands is, well, there are a few problems. First, it’s in Java; Apple has stopped treating Java like a first-class citizen of the desktop, and it’s getting harder and harder to convince a JavaFX app to build, let alone to act like a Mac app. Second, it takes way too much in the way of computer resources. When it’s running, my laptop gets hot and the battery drops. It’s awesome to have the tool, but it gets like 1 kiloflop per hogshead of diesel. I feel like it should be possible to do better, and I feel like the problem lies in JavaFX. Third, I’m trying to learn Swift and SwiftUI so that I can write native applications. This feels like an opportunity.

In about 1991, someone I knew made a pun around “Ren & Stimpy” being like rn and SMTP and that has stuck with me. So, I’m porting dumbster from Java to Swift, and that involves changing the name. Thus, I dub the new project, “Stumpy.”

Concurrency, Closures, and SwiftUI on Mac OS X

Synopsis

I want to get some clarity about how to use GCD and closures to handle dispatching work between multiple contexts. This is something I’m very familiar with in Java, but not at all in Swift (let alone, using SwiftUI). Inspired by a cartoon that appeared in The New Yorker many years ago, Barkin’ Dogs represents the conversation that happens when two dogs get excited.

Continue reading “Concurrency, Closures, and SwiftUI on Mac OS X”

Stupid Computer Tricks

In the late 1990s I had a static IP address, DSL, and my own domain. I got my email delivered to a PC running FreeBSD that I had built out of components I bought at Fry’s Electronics and which lived in my living room, right next to the other PC I’d built out of components and which I used for playing video games. The DSL modem was a little flaky (or maybe it was the line) and so from time to time, I’d have to turn it off and turn it on again in order to have actual connectivity to the world.

What’s the solution to a problem with shitty technology? More shitty technology! I got a switchable power supply with a serial port that I could plug into the server. I plugged the modem’s power cord into the power supply. I wrote a script (can’t remember now if it was a shell script or if there was a CPAN module to communicate with the power supply that meant it was easier to use Perl) that would attempt to ping Google and, if that failed, it would turn off the modem’s outlet and then turn it back on. I added a cron job that ran the script every five minutes. Problem solved, eh?

Today I saw a tweet where the poster confessed that they had a problem necessitating rebooting the wifi router. So they created an Alexa skill for “turn off the router” and another for “turn on the router” and how, whoops, Alexa can’t recognize and then do a thing if there’s no Internet.

Once again, I’m thinking that for all the horrors of the Bush/Clinton/Bush years, things were better last century.

It’s A Mess

Last night, apparently, there was an entertainment broadcast to the world – the first Trump – Biden debate of 2020. Surprising precisely no-one, the president said awful things and behaved badly. But that’s not what I’m thinking about, right now.

On my Twitter feed this morning, I saw lots of gasping and horror tweets from last night. And the other things I saw were people who didn’t spend the evening in front of the television talking about how they were doing okay, having spent time with their dogs, or made some dinner, or done other things that made them feel good about themselves.

And here’s the thing: all the moaning people were ones who were not actively engaged in self-care. Instead, they were watching TV. And what were they watching? Not a story that got them imagining a different world, nor a morality play that told them who they were. No, they were watching a parody of a conversation, in which no surprises occurred. If, on Saturday, you’d asked anyone (not a pundit, because they’re paid not to think) what would happen during the event, you’d have gotten a perfect run-down. And the moaning tweeters were saying that they were watching this event because it was somehow important to the functioning of the apparatus of government, or maybe the culture of the nation.

I think that’s wrong. I think that what really happened is, TV just got people to volunteer to suffer for hours rather than do something life-affirming like make delicious curry or play with their dogs. Sure, sure, the politicians are horrible, and some are way more horrible than others, and voting the bastard out is really important. But you know what else is important? You. You are important. Your sanity, your happiness, and your life are important. And you are more precious than TV. A moment of reflection will show you that TV doesn’t care about you at all; there is no good reason for you to care about it. It will not save you.

Turn off the idiot box. Starve the attention seekers. Take care of yourself.

Rebuilding – Signaling

I spent the day in Santa Cruz, yesterday. I had several errands to run, most of which were uninteresting, but one which turned out to be fascinating. Since I had to be in the area for a medical appointment, I thought that I’d drop by the arena, where a bunch of county departments and some disaster relief organizations have set up tables to be available to help folks affected by the fires. I hadn’t been by before, since we evacuated to our moms’ place and we weren’t in desperate need of anything. We have resources, and we wanted to let other folks with smaller margins get the help they needed. That visit to the arena has given me a lot to think about.

For starters, how about this: we have a builder already lined up, and he’s raring to go. He wants to get debris removed, a site survey done, and permits applied for so that when the rains stop and it’s time to start construction, he can get right to work. This is awesome! But we can’t start debris removal until the site has been cleared of hazardous materials. This makes sense — we don’t want to be dumping hazmat into the regular landfill. So who’s doing the hazmat clearing? The federal (not state) EPA. When will they do this? Well, they’re showing up this week, and they reckon they should have the whole county done in six to eight weeks. (Just in time for the rainy season to start.) Okay, but do I apply for my debris removal permit now? No, one must wait until the site has been cleared by the hazmat team before one may apply for a permit. Okay, how will I know that my site has been cleared? After all, it could be the first site cleared, or the last — do you want me to just keep asking you guys every day? Um.

And this is where signaling comes in. We know that the USEPA is going to be doing the hazardous debris removal, so they are the ones who will send some sort of signal that a property has been done, but we don’t know what that signal is, nor how we should be checking for it. Other than that they’ll post some kind of notice at the property to say that they’re done with it. One hopes that there will be a less onerous status check than driving 3 hours round trip every day to go look for a piece of paper.

Puzzlin’ Code

Okay, here’s some SwiftUI code:

Section(header: Text("Tip amount")) {
                // right now we are in a trailing closure
                    Picker("Tip percentage",  selection: $tipPercentage) {
                    // and now we are inside a second closure
                        ForEach(0 ..< tipPercentages.count) { // here, tipPercentages doesn't need to be prefixed by 'self.'
                        // and now we are inside a third closure
                            Text("\(self.tipPercentages[$0])%") // here, tipPercentages *does* need to be prefixed
                        }
                    }.pickerStyle(SegmentedPickerStyle())
                }

Why, why, do I need to prefix tipPercentages with ‘self.‘ once we’re in the third closure but not inside the second or even the first? What’s magical about this situation? I know there’s something, but nobody is saying what.

Specify Your Dream

I keep wanting to be able to write native apps for my devices, and it keeps being true that I can’t wrap my brain around The Way You’re Supposed To Do It. I’ve taken Coursera and Udemy courses on iOS and macOS programming, and I’ve even shipped a couple of toy apps to the App Store, but when it comes to anything real, I find myself getting stuck because the way that the UI gets tied to the model is just so…tight.

This is absolutely not the way to write code for a web application. The whole gosh-darned point of writing a web application is that it’s skinnable, so that your business logic neither knows nor cares how it’s being displayed. I knew this in 1997, and it has only been reinforced by my experience since then.

So anyway, now I have to learn how to write non-skinnable software. It’s like it’s 1985 all over again, in my brain. And lemme tell you, this old guy has never wanted to go back and do high school over.

Okay, so this time I’m hoping it will stick. I’m doing the 100 Days of SwiftUI series from Paul Hudson. I’ve bought several of his books and found them really helpful in figuring out Swift, and I like his style. So, I am feeling pretty positive. But I’m going to go ahead and bring some of my own expertise to the table and on this, the first challenge day, spec out not only the challenge app (a unit converter) but the app that I should write for unit conversion.

Okay, so, first up: challenge. “Build a unit converter app”. The point of this application is to exercise the skills taught in the first demo. Picker, @State, Text, TextField, etc. Okay. Yawn, I’ll do it. But: I’ve already written (in Swift, but not SwiftUI) a unit converter that I would actually use: ThermoSlide. The point, here, is that if you have to select which unit to convert, then type in what value to convert, then select which unit to convert to, by the time you’ve done all that plus launched the app, the moment has passed. When, what’s really more likely is that your wife has set the display to Celsius but you can’t be bothered to learn another gosh darned system at this point in your life and you just want to know how (not) hot to make the car.

Right. So for challenge day of 100 Days of SwiftUI, I’m going to rewrite ThermoSlide as a SwiftUI application. Extra brownie points because I’m going to have to figure out how to make it a watch app at the same time, and while I’m at it I want to reorient the slider so it’s vertical, not horizontal.