and I'm all out of bubble gum…

For the past few years (well, since I’ve had an iPad), I’ve been exasperated by the time it takes whichever app Apple has streaming video from my iTunes library to my iPad to load my iTunes library. In the past, it has taken anywhere from 20-90 minutes to load the library each time I access it. Clearly, this isn’t really viable as a “streaming TV in bed” approach. I did some digging around, and it seems like the root issue is that my iTunes library is too big, so the iPad app can’t process the XML file it has to download (aside: this is ridiculous, of course).

Long story short, at the start of the summer, being blissfully unemployed, I took a moment to split my iTunes library in twain: one library of music and audiobooks to sync to my phone (not that that integration has been getting any better, mind you) and one library of movies and TV shows to stream to the AppleTV and my iPad and whatnot. (Note: this whole time the AppleTV could load my gigundous library… but not the iPad. Oy.)

Much metadata cleaning later (because it turns out that iTunes doesn’t actually write all the fields it should write to video files, because, well… it’s lousy), I now have two libraries. Most of the time I want the movies and TV library open, but I want to regularly open the music and audiobooks to sync podcasts (not that I trust Apple for that either: greg is in charge of syncing, iTunes just adds the new files to the library).

In the past, I’ve noted that I’ve found CLI defaults tool to be useful for managing a remote iTunes library. This proves not to be the case here — in fact, the solution is one of simple symlinking. I’ve written three scripts: a “master” script that just toggles between libraries and two “client” scripts that just pass a specific parameter to the master script (depending on which library should be opened).

It’s worth noting a few things here:

  1. I initially tried to do this using system accessibility scripting but found that to be unreliable (pasting the path into the “go to folder” dialog as iTunes opened was flaking reliably).
  2. Along the way, while I could have used the CLI osascript command to open the “master” script with appropriate parameters in the crontab… I couldn’t figure out how to give osascript appropriate permissions in the accessibility section of the Security & Privacy system preferences. Frustrating.
  3. There may be a better way of detecting whether parameters have been passed into the master script than checking if the the on run parameters are a list… or something else (list = a list of parameters, something else = no parameters), but I haven’t seen it. And it works.

July 30th, 2017

Posted In: How To

Tags: , , , ,

There seems to be some discussion online, but no actual, y’know… documentation regarding these two server variables.

Apparently they were introduced in Apache 2.3, and they are wicked useful, it turns out. At least, wicked useful if what you want to do is figure out what the URL of a to a specific file on the server is, assuming that you have only its path and some other file’s URL.

What follows seems to be empirically correct, but I welcome corrections:

DOCUMENT_ROOT is the system file path to the root of the web server’s document directory (usually something like '/var/www/')

But, imagine that per-user web directories have been enabled on your server. That is, if my user is foo, then there is a directory /home/foo/public_html in which all of foo’s web documents are stored (and served from). This is (probably) outside of the main server document root directory. The URL of foo’s web files would be something like

And this is where our variables enter the story.

The Empirically-based Theory

CONTEXT_PREFIX is the portion of the REQUEST_URI that triggered the server to serve up a file outside of the document root. And CONTEXT_DOCUMENT_ROOT is the root directory that that particular CONTEXT_PREFIX is rooted at. Nota bene: conveniently CONTEXT_DOCUMENT_ROOT contains the path the document root for whichever context this particular script was accessed through (so it would be the same as DOCUMENT_ROOT within the server’s document root, while CONTEXT_PREFIX would be an empty string, since there is no context prefix within the server’s document root.

A file in a user web directory

Consider this extended example:

User foo has placed files in that user’s public_html directory. There are nested directories within that public_html directory, and we are accessing a file at this URL:

This file is stored at the following path in the file system:


Thus, a sampling of relevant server variables (presented in $_SERVER for the PHP users amongst us) would be:

REQUEST_URI is /~foo/dir1/dir2/dir3/file.php?paramA

SCRIPT_NAME is /~foo/dir1/dir2/dir3/file.php


CONTEXT_DOCUMENT_ROOT is /home/foo/public_html

A file within server’s document root

Alternatively, a similar example within the server’s document root:

is a URL that access a file at:


This results in the following values:

REQUEST_URI is /dir1/dir2/dir3/file.php?paramA

SCRIPT_NAME is /dir1/dir2/dir3/file.php

CONTEXT_PREFIX is (the empty string)


For giggles, I cooked up some code to generate the URL of particular directory based on this information. I used the following little snippet to do this in DataUtilities::overlap() in battis/data-utilities:

March 30th, 2016

Posted In: How To

Tags: ,

So, my students in Advanced CS are working on their second semester projects. One project group is working on mastering Unity to build an iPhone game, and they just spent several days struggling with getting Unity Remote to work with their iPhones.

After much Googling and exasperation, they figured out the answer (which was not, prior to this post.

They had been able to see the iPhone in the Unity editor. They had been able to set up the remote to use the iPhone in the Unity editor in project settings. But when they “played” their game in the editor, it just sat there inertly, waiting for a connection. Consternation. Rending of garments. So forth and so on.

The trick, it turns out, is that when one installs the Unity editor, one must install iOS development support. Not a shocker. But certainly worth mentioning in an error message somewhere.

March 11th, 2016

Posted In: How To

Tags: , , ,

I just mentioned that my wife switches between two different iTunes libraries, including one that lives on a shared volume on our home server. There’s a great tip on Stack Overflow for writing a script to automate that swap between iTunes libraries (rather than having to hold down option while iTunes loads and then click around to find the library you want). But it seemed like it might be nice to document for posterity the full script that we’ve built, since it handles not just the library swapping, but also the mounting of the shared volume as well.

This script takes a little prep work, both generating the library location property and storing the authentication information in the user keychain. The Stack Overflow tip explains the former, and the latter is as easy as connecting to the server and remembering to check the “Save Authentication” checkbox during the authentication process.

March 18th, 2014

Posted In: How To

Tags: , ,

A bit of background: my wife has an iTunes library that is too large to fit comfortably on her MacBook Air (in all fairness: I have an iTunes library that is too large to fit on her MacBook Air, my MacBook Pro and several other laptops as well). She maintains a local library on her laptop for use at school (useful movies, songs, etc.) and stores her “real” library on our home server. Which involves a bit of fiddling to get it to work. The key issue is that she needs iTunes to load her library off of a shared disk. And, periodically (maybe every couple of months), something goes haywire and she gets this error:

The iTunes library Library file is locked, on a locked disk, or you do not have write permission for this file.

Needless to say, this is exasperating.

There are a number of suggested solutions out there, and I keep forgetting to bookmark “the one” that works. On my last search, I realized that this was because none of them are really the answer that works in our situation. Here’s what works (and I’m posting this as a note for self):

  1. Disconnect the laptop from the server (quitting iTunes first, of course).
  2. On the server, unset the nouchg flag (not 100% that this is necessary 100% of the time, but it’s necessary at least some of the time):
    sudo chflags -R nouchg
  3. Reboot the server.
  4. Reconnect from the laptop and rejoice.

At least, that’s what worked this evening, and it felt really familiar. (There’s an unspoken step 2a, of course: cancel the multi-hour process on the server that you had queued up moments before iTunes started misbehaving. Argh.)

March 18th, 2014

Posted In: How To

Tags: , , ,

So many of these entries are really just an attempt to make sure that the next time I go searching for an answer to some question, by gum there will be a search result. That is: I write up things that I couldn’t find an easy answer to, so that someone else reaps the benefit of my suffering.

But, sometimes, it’s just about admitting that I’m dumb.

Case in point: I’ve been grousing on Twitter about a number of things in the past week, one of which was that, for much of the fall, many of my Google calendars have been showing up in iCal doubled. Every event shows up twice. Sometimes more than that, when Google has a hiccup. And birthdays from my contacts have shown up as many as 34 times — no joke: I counted. But the core problem has been that I’ve been seeing many of my Google calendars twice in iCal. It makes me feel busy, but otherwise it serves no purpose.

And then it hit me this evening, as I was looking at the list of calendars in iCal: with the launch of Mountain Lion, Apple revised how it handled Mail, Contacts & Calendars — so much so, in fact, that they created a separate prefpane for it. That connects to iCal, Mail and the Address Book pretty transparently. Before that upgrade, to see secondary Google calendars (the ones other than your primary calendar — a distinction about which I have some more grousing to do at a later date), you had to enable calendar delegates in the Accounts section of the iCal preferences. It was messy, and ugly (you had both the delegate and the calendar nested in the delegate… for each and every calendar). But it worked.

I never turned off the delegates when Apple upgraded to Mail, Contacts & Calendars. So I was seeing both the delegate calendar and the calendar associated with my Google account in Mail, Contacts & Calendars.

For dumb.

I just turned off delegates and everything got better. Except maybe those duplicated birthdays… we’ll see what happens with them.

December 9th, 2012

Posted In: How To

Tags: , , , , ,

YouTube has changed their embed codes (several years ago) to IFRAMEs, replacing the old object embed codes. Turns out that on older web-based WYSIWYG-editors, such as Blackboard 8, the IFRAME embed codes get munged up, often with deleterious effects. In Blackboard, for example, you might lose the ability to see, edit or use a content area in which an IFRAME has been embedded. This. Is. Bad.

YouTube lets you switch to their old embed code for individual videos, but no so to embed a playlist. I wanted to embed a playlist, so I took a look at the object tag specs and the IFRAME embed code and came up with a simple script that generates an old-style object embed code for a YouTube playlist IFRAME embed code, thus:

Paste a YouTube playlist embed code below.

November 30th, 2012

Posted In: How To

Tags: , , , , , , , ,

I’m about to embark on a group video project in my New Media class. To that end, it’s a hassle when the video (and script!) exist only in the account of one of the group members. I saw one suggestion for how to store the iMovie events and projects on an external drive, which seemed deeply convoluted and, well… a hassle. I’m not interested in purchasing or setting up external drives, or in going through that rigamarole to set it up.

So, it occurred to me that /Users/Shared/ is a pretty fine place to store shared files. And that the modern Mac OS X seems to honor symlinks pretty regularly (something I use all the time to sync my life across machines using dropbox — symlinking whole directories to sync preferences, settings and documents that the developers haven’t — yet — moved to the cloud.)

It seems to work for iMovie as well. Here’s how I did it (stay tuned to see if it blows up on my students!):

  1. Trash the iMovie Events folder in the user’s Movies folder. (This assumes that this is, essentially, a clean install of iMovie — no previous events or projects to worry about. That’s my situation).
  2. Create a new iMovie Events folder in /Users/Shared/ (note that it is created there, not moved or copied there, so that it will inherit permissions from the Shared directory).
  3. Set the permissions on iMovie Events to let everyone read and write. I like the terminal for this:

    chmod -R a+rw /Users/Shared/iMovie\ Events
  4. In the terminal, create the symlink:

    ln -s /Users/Shared/iMovie\ Events ~/Movies/iMovie\ Events

    (Note that the space in “iMovie Events” needs to be escaped with a backslash!)

  5. In iMovie, create new projects on the hard drive (probably called Macintosh HD), rather than the user’s home folder. This will put the projects in /User/Shared/ (I didn’t know that until this experiment — cool!)

In my limited testing, this seems to work transparently. The biggest caveat is the permissions change. When creating events, iMovie seems to strip the write permissions off of the inherited permissions for the iMovie Events folder (but other users can still read and execute, which should be fine). Similarly, it’s possible that other users can only read (but not edit) the shared project.

We shall see.

October 31st, 2012

Posted In: How To

Tags: , , ,

Because I can’t stop playing with something that already works fine, I’ve continued to tweak my syllabus-generating spreadsheet. With the addition of an external script, I’m able to link directly to a specific cell in the spreadsheet — letting me share a link to my syllabi that takes people not just to the overall document, but to the current day (or the next day that’s closest to the current day) in the syllabus. The script could be used to link to any cell in any published Google Spreadsheet, with the caveat that if there are multiple cells with that match that value, the link will take you to the first appearance of the value in the spreadsheet.

This takes a GET URL of the format http://server/script?url=[url]&key=[key]&anchor=[anchor]#[anchor], where…

  • The URL is the URL of the published Google spreadsheet location.
  • The key is the text to search for in the spreadsheet (so you could link to anything in the published HTML, but it’s easiest to link to a unique value in a cell).
  • The anchor is the name of the HREF anchor you will be creating (note that you then need to, well… link to that anchor).
Enjoy. You can try it out on my server:

Nota Bene: You have to add your own link to the anchor — this is a quick, slapped-together connection to my script.

Update: I was sitting here staring at the script, trying to figure out why I hadn’t put the anchor tag around the key, and then I realized what’s going on. The key (on my spreadsheet) is formatted to be white text on a white background (Rothko-style, if you will). If it gets converted to an anchor, its styling is affected and (without more work in the script) it turns blue and underlined. Lame. So… the anchor goes before the key, so the key’s CSS style won’t be affected.

This is why you document your code. Even when it’s short.

October 31st, 2012

Posted In: How To

Tags: , , , , ,

Click to download a PDF of this. Feel free to reuse it — just let me know, especially if you make any particularly effective tweaks.

This policy has been gestating for some time, and I started to formulate it in conversation with one of my students who had had a brush with the academic dishonesty fairy. I presented it in class last week, and I realized that it is as good a representation as I have of my homework policy. I’m not really interested in coming up with a suitably punitive formula for docking grades for lateness, and I don’t particularly care about negotiating reasonable extensions. Mostly, like my students, I just don’t want to be bothered. But, by golly, there are things that bother me, and it would be good to steer clear of them. And it’s worth knowing how they rank in my worldview. And this expresses it.

Better not to do your work than to cheat or plagiarize to finish your work. Better to ask for an extension at the last minute than to just not do the work. But noticeably better to ask for the extension in a timely manner.

I’m pretty sure that this both made sense to and stuck with my ninth graders.

October 29th, 2012

Posted In: Teaching

Tags: , , , ,

Next Page »