Meanwhile, on my end...

The past month has gone by in a blur, but until I am able to fully catch up I decided to put some useful tidbits out there, since macOS is still my preferred platform and I have a lot of personal backlog to go through–so best to space it out and get started right away:

Getting EXIF information from HEIC files

One of the things I have been putting off is rebuilding my photo processing and archiving pipeline to deal with HEIC files. I’ve long been using jhead to extract EXIF metadata and rename files accordingly as a first step, but jhead (and plenty of other similar CLI tools) are showing their age, so I decided to see what I could do with native macOS.

Another thing I’ve been putting off is writing more JavaScript (which I still despise as a language but cannot ignore), so I looked at JavaScript for Automation as a way to get going quickly.

As usual, the best resources for this kind of niche are third-parties rather than terse and unfriendly Apple docs, and there’s a great cookbook that walks you through the basics–it only took me half an hour (and some cursing) to build a little CLI tool to dump metadata from anything that supports EXIF in macOS:

#!/usr/bin/env osascript -l JavaScript

ObjC.import("Cocoa");

function run(argv) {
    if(argv[0]) {
        var url = $.NSURL.fileURLWithPath(argv[0]),
            source = $.CGImageSourceCreateWithURL(url, null),
            metadataRef = $.CGImageSourceCopyPropertiesAtIndex(source, 0, null),
            err = $.NSError;
        if(metadataRef) {
            var dic = $.NSDictionary.dictionaryWithDictionary(metadataRef);
            /* Alternatively, you can have some fun with this: 
            var allKeys = ObjC.unwrap(dic.allKeys);
            var keys = allKeys.map((x => ObjC.unwrap(x)));
            var values = keys.map((x => ObjC.unwrap(dic.objectForKey(x))));
            console.log([keys, values]);
            */
            var json = $.NSJSONSerialization.dataWithJSONObjectOptionsError(
                    dic.objectForKey('{Exif}'), // yeah, magic.
                    $.NSJSONReadingMutableContainers, err),
                buffer = $.NSString.alloc.initWithDataEncoding(json, 
                    $.NSUTF8StringEncoding);
            console.log(ObjC.unwrap(buffer));
        }
    }
}

There is a little bit of magic involved here–you need to know how the Objective-C bridge name mangling works, but I’ve had plenty of experience with the Python bridge, so it all boils down to a bit of experience and educated trial and error.

But it works fine for HEIC, DNG and CRW (Canon RAW), and I’ll be rewriting my Automator workflows to incorporate it as time permits.

Personal E-Mail and Domains

It’s now been well over six months since I changed my personal e-mail workflow to MsgFiler, and it’s been working great for me: I can zip through most of my e-mail and re-file it with a few keystrokes, and I sorely miss this kind of thing when I’m on Windows. Overall, it’s probably the only third-party Mac app I have running 100% of the time.

When I have time to use it, that is. I am woefully behind on personal mail, so much so that I only caught up with Cloudflare‘s DNS registrar e-mails recently, and began the long and arduous process of clicking through Network Solutions’ hilariously bad back-office to migrate my domains to Cloudflare.

The experience is fraught with glitches, largely because Network Solutions appears to have re-locked this domain after sending me the transfer code, even though it shows up as unlocked on their back-office.

So I’m currently dead-locked between Cloudflare support and Network Solutions, which makes me dread the inevitable moment when I try to call them to get this fixed…

Assuming all of it eventually works on NetSol’s side, the only real drawback so far seems to be that Cloudflare only allows for yearly renewals, which is just plain weird, really. I really don’t want to deal with renewals annually and would gladly pay a little extra to renew domains for 3-5 years.

Ghosts, in Various Forms

Every now and then I benchmark other blog engines, and this week I had the occasion to set up Ghost on Azure App Service using this nice ARM template to help a customer put together a test web site.

It’s pretty nice as far as the authoring experience goes (it feels a lot like Medium, but without a good iOS app1) and it might be useful if I need to quickly set up an event blog, but the lack of search, proper tables, and (shockingly) an easy way to insert relative links to other posts turns it from a pretty nice to an ultimately pointless experience for me.

I’m also planning to tweak my infrastructure a bit, since I suspect uwsgi has been breaking the site now and then due to a memory corruption bug and really want to move to aiohttp and traefik to match the rest of the stuff I build.

Serendipitously, I’ve also been editing Pixels Camp posts on Medium, and expect to spend three days at the event having some fun (for a change)…


  1. Phantom doesn’t count, since it was recently removed from the App Store and seems to be dead, besides apparently lacking rich editing capabilities. ↩︎

Back on the saddle

I spent a week in Seattle attending the winter Ready conference (a Microsoft internal event held twice a year that brings together thousands of people to either Seattle or Vegas), and even though I can’t say anything about the conference itself, it was a great opportunity to meet up with people from all around the company, hear about what is coming down the pipeline, and taking an early shot at getting certified on the AI stuff I do as part of my work.

Read More...

Dining By The Lake

The view out from the restaurant as we came in from the snow

Pike Street

A view out from the entrance at the Farmer’s Market

Driving Around

A few hours of traipsing around the snowy landscape en route to various (mostly closed) locations.

Snowmageddon Aftermath

A walk around Seattle after breakfast. It was actually pretty nice.

Snowed in Seattle

A week in sub-zero temperatures, along with 5.000 other Microsoft folk...

Breath Of The Wild

This game is absolutely glorious, and I'm glad we got it for my youngest. Ahem. Right, carry on...

Building The Future

Microsoft's main (CIO-focused) IT event of the year, which I unfortunately had little time to enjoy.
I was curator of a few Azure & AI sessions, but attended only a handful due to overlapping meetings...

Inconsequentials

The past few weeks have gone by in a blur of insomnia, stress and a bunch of random entropy that has triggered my penchant for radical simplification, so I turned off nearly all notifications on work apps, set some recurring reminders to go offline earlier in the day, and decided to spend some time tying up loose ends (as well as building Docker containers to run R, but that’s another story).

Read More...

My Quest For Home Automation, Part 4

Winter is (definitely) taking hold, and I managed to be foolish enough to be walking around with a half-mended flu on the coldest day so far and, as a direct consequence of that foolishness, had to stay home another week–so I definitely appreciated having taken the trouble to automate my heaters last year, and believe it’s time for another installment in that particular quest.

Read More...

Archives