In the quest of getting the PerfectSoftware(tm) that suits all my necessities, for both aesthetics and usability, I test everything that I can find on the Internet. Today was the turn of my podcast player, which was CPod (that also goes by the complicated name Cumulonimbus). Don't get me wrong, I like the player but I've found some problems along the way: only loads an X amount of episodes per day, UI/UX needs more work, descriptions are shortened in preview mode, etc. After some time looking for alternatives that are FOSS and simple, I found Doughnut.
Doughnut is a simple podcast player which was originally written in JS/Electron, like CPod, and rewritten in Swift to be macOS native and more lightweight:
~ » du -sh /Applications/Doughnut.app /Applications/Cumulonimbus.app 21M /Applications/Doughnut.app 138M /Applications/Cumulonimbus.app
The interface reminds me of NetNewsWire and the code is well written which makes it simple to read and see what's happening under the hood. So far so good until you want to import podcasts to the app then you will crash into a wall: no import methods found. This was a bummer since I had my OPML feed file exported from AntennaPod (used in my mobile device), ready to be loaded.
At this point I had three possibilities: (1) modify the code with Xcode to add the import functionality and build, (2) create a tool that loads the OPML file, parses it and insert the podcasts to the SQLite3 DB used by Doughnut or (3) automate the import using AppleScript. Options (1) and (2) would take too much energy and time (although (1) is really tempting as I'm currently learning SwiftUI). Option (3) was the chosen one which only required the AppleScript docs and give Accessibility powers to Automator.
The script in action can be seen in the video at the beginning of this post and the source code can be found here. It needs more tweaking but it does what it needs to do so far.
To complement this AppleScript and to produce an OPML feed file from a Doughnut database I've written this small C application that will generate one. Check out the README on how to use it.