Fixing the Mastered for iTunes Droplet

Sleep Studies, the band I play with, is in the process of finishing up our next EP. One of the (many) things I’m neurotic about is making sure the masters will translate as well as possible. I’ve written about how I use afclip to examine the master audio files for headroom; another thing I do is run the masters through the Apple’s Master for iTunes Droplet. This is distributed as part of the Mastered for iTunes program.

The Master for iTunes Droplet accepts your lossless files and returns .m4a files that mirror the files the iTunes backend will generate, so you can preview what your content in the store will sound like.

Well, it used to do this until Mac OS X 10.10 Yosemite was released.

The droplet is just a wrapper around an AppleScript file, and it’s easy to examine the script by dragging the entire droplet to the Script Editor application. The problem, it turns out, is just a trivial bug. On lines 62 and 109 you’ll find this chunk of code:

set systemVersion to system version of (get system info)
if systemVersion is less than "10.6" then
    log ("ITUNESMASTERINGDROPLET: incompatible system version")
    display alert SYSTEM_CHECK_ERROR_TITLE message SYSTEM_CHECK_ERROR_MESSAGE as warning buttons {CANCEL_BUTTON_TITLE} default button 1
    log ("ITUNESMASTERINGDROPLET: shutting down")
    error number -128
end if

It’s the if systemVersion is less than "10.6" then part that is troublesome — this is just a string comparison, not a numeric comparison. Starting with Yosemite (10.10), this conditional started doing the wrong thing. “10.10” is in fact less than “10.6” when comparing as strings. The fix is pretty easy, too. The incomparable Michael Tsai laid out a solution on Stack Overflow, which I’ve implemented here:

set systemVersion to system version of (get system info)
considering numeric strings
    set systemVersionNewEnough to systemVersion ≥ 10.6
end considering
if systemVersionNewEnough is false then
    log ("ITUNESMASTERINGDROPLET: incompatible system version")
    display alert SYSTEM_CHECK_ERROR_TITLE message SYSTEM_CHECK_ERROR_MESSAGE as warning buttons {CANCEL_BUTTON_TITLE} default button 1
    log ("ITUNESMASTERINGDROPLET: shutting down")
    error number -128
end if

While I was at it, I wanted to fix the other issue with the Apple-distributed version of the droplet: it isn’t code signed. Because of this, when you download the droplet, Gatekeeper informs you that the application can’t be run.

Sal Soghoian’s MacOSXAutomation site has instructions for signing AppleScript Droplets. They’re easy to follow — the only snag I ran into was that I tried to use my iPhone developer certificate to sign the droplet, and that doesn’t help with Gatekeeper. I had to request a new “Developer ID Application”1 certificate to get things working.

With that, the version of the droplet linked below includes fixes for:

  • Droplet returning an error on Mac OS X 10.10 and later
  • Gatekeeper returning an issue with an unknown developer

I’ve filed a bug report with Apple reflecting these issues — it would be ideal if they fixed the versions they’re distributing. It’s rdar://30067799 if you’re interested in reading it.

Download the fixed Master for iTunes Droplet

  1. I did this via Xcode 8.2.1 — from the Preferences -> Accounts -> View Details screen, I used the Create button to get the certificate. 

A Custom Recent Posts Widget

One consequence of adding a Microblog feed to this site was that a lot of post IDs were showing up in the Recent Posts widget. It turns out that if a post is missing a title, the widget falls back to just displaying the ID number. Sad!

It turns out that customizing the widget was fairly straightforward. Since I already have a child theme set up, all I had to do was copy the widget class into the child theme, make my tweaks, and add a few lines to my functions.php file.

The functions.php changes were incredibly straightforward. I added the following lines:

// Include Recent Posts Excluding Category widget
add_action( 'widgets_init', function(){
    register_widget( 'WP_Widget_Recent_Posts_Exclude_Cat' );

… where class-wp-widget-recent-posts-exclude-cat.php is the class of my new widget.

You can see the custom version of the widget on Github. The essence of the changes I made was to add one more filter to the code that retrieves the list of posts:

$r = new WP_Query( apply_filters( 'widget_posts_args', array(
            'posts_per_page'      => $number,
            'no_found_rows'       => true,
            'post_status'         => 'publish',
            'ignore_sticky_posts' => true,
            'cat'                 => $exclude_cat
        ) ) );

The last condition, 'cat' => $exclude_cat, is the one I added. If you pass a negative value to the cat filter, that becomes a category exclusion. In my case, I want to exclude the Micro category, which has an ID of 104, so $exclude_cat = -104.