What we're gonna do and how we're gonna do it
I am often asked if there is a good way to sync two iTunes libraries, either between two or more users on a single machine or between two or more machines across a local network. Typical queries are something to the effect of "When I add new tracks to my iTunes, I want [some of] them to be added to the iTunes on my wife's machine/account" or "I'd like to easily send some of my iTunes tracks to my wife's/child's iTunes", or "I'm trying to consolidate my and my wife's and kids' music libraries..." and so on. A few years ago I posted some info and scripts regarding remote management which were strictly AppleScript. This time, I have devised four AppleScripts that can serve as the basis for your own projects. Rather than make these scripts available as downloads, I thought it would be a good way to illustrate--and perhaps even introduce to you--the technologies used to manipulate files over a network.
These projects will involve not only AppleScript, but also smatterings of perl and the UNIX programs rsync, ssh, and launchd, among others. I hope the approach I am using is not intimidating; although while I'm pretty sure I've laid things out as simply as possible, this project is not necessarily for the uninitiated 'scripter.
Caveats & apologia:
- You need not be familiar with ssh, rsync, launchd, perl, scp, oscscript, or any other of the programs and protocols I will be using below. While I can't give complete tutorials on these technologies, I hope to provide enough explanation of the coding examples so you can at least understand what is happening and why, even if not how.
- All of the technologies mentioned in this article are on your Mac(s) already so there is nothing to download or install.
- This project assumes a basic stock computer set-up using OS X 10.x. But if you have made modifications to your machines' rsync and ssh config files, for example, then I'll presume that you know more about this stuff than I and your mileage will vary.
- I cannot offer support for these routines. So, unless you spot a glaring or destructive error, please do not email me with issues or suggestions, improvements, and so on. No doubt some of the routines below can be suitably modified to taste and purpose. But I do not need to be apprised of every variation. Thank you.
- There is always more than one way to do anything. Most of the routines used in this project are written to be illustrative on the web page and are not necessarily to be regarded as examples of highly efficient coding; for users who are unfamiliar with perl or sed, for example, the more primitive the example, the better.
What We're Going To Do:
I have two machines, a Macbook Pro and an iMac, on a home wireless network. Whenever I add new files to my account's iTunes on the Macbook Pro I want them to be copied to the iMac and added to a particular account's iTunes. Each iTunes has its own discrete designated iTunes Music folder (the location set in iTunes Preferences > Advanced) where media files are located.
The first part of this tutorial will outline, rather broadly, some of the technologies being used. Later parts will build on these basics.
1. Set up ssh: Setting up ssh is an absolute prerequisite for much of what we will be doing. ssh (secure shell) is a networking protocol that allows secure communication between two machines. You can transfer files and send commands to a remote machine over a ssh connection. Since ssh is secure, a connection is established using the username and password of the user and machine you want to connect to. Thus, during a normal ssh connection to a remote machine (ssh is sometimes a verb: "I am going to ssh to my Macbook Pro") you would be asked for a password to that machine. However, you can set up your machines so that a password is not required each time--or ever; you essentially give each machine the "secret key" to another machine, and visa versa. We will perform some fairly standard and easy Terminal-fu to create public/private keys using ssh-keygen and scp (secure copy) to allow passwordless ssh sessions.
2. Develop the rsync routines: With a ssh connection able to be password-lessly established, we can use rsync. rsync is a powerful unix program that is able to detect and copy only the differences between two files or folders. It is used primarily in back-up and mirroring workflows. It has many versatile options which we will be taking advantage of. We will be creating two rsync routines. The first one will be run in "dry run" mode and will be able to report which files and folders would be transferred between two machines were it not in "dry run" mode. We'll parse this list for just the files that can be added to the remote iTunes. The second rsync routine will be the same as the first (more or less) and will be allowed to copy those files. (We need two rsync routines because only the "dry run" version lists files; the "live" version cannot, and we need that list of files.) Finally we will use ssh again to remotely command the remote iTunes to add the files we obtained from the first "dry run" rsync routine and which were actually copied to the remote machine with the second "live" rsync routine.
3. Make it all swing with an AppleScript: A compiled AppleScript will combine the rsync routines as well as some native and other shell routines to co-ordinate variables, filter files and folders, log information, and so on. This AppleScript can be called manually from the Scripts Menu or periodically--at login and every half-hour, for example--using launchd.
4. Finesse: additional mods to the script.
5. Automate running the script with launchd: launchd can be used to run scripts periodically at specific time intervals (it replaces the deprecated cron). We will create a launchd .plist for the Launch Agents folder that will run our AppleScript in the background at login and every sixty minutes thereafter while the computer is up.
6. "Pull" variation: Reverse the source and destination paths, add a couple of more modifications, and automatically "pull" new files from the remote user
7. Forget rsync and launchd--go manual: Send the selected tracks from the local user's iTunes to the remote user's iTunes.
8. Copy shared library tracks: Select tracks displayed in a local iTunes' "Shared" library and "pull" them from the associated remote user and add to the local user's iTunes. This full-featured script will require no hard-coding of usernames and IP addresses, instead using defaults to manage them in a preferences file.
Here are a few things you should do and have available before starting.
- Obviously, you must have two or more computers on the same network. Presumably, you are the administrator of these machines so that you have access to the usernames, passwords, and IP addresses for each user and machine you want to communicate with.
- The file paths to the iTunes Music library folder for each user. For example, the default location for this folder on my computer is "/Users/dougadams/Music/iTunes/iTunes Music/". An external drive would be something like "/Volumes/ExternalVolName/MyMusicFolder/". We will hard-code this into the script for convenience for now. Later I will have some routines that get this information automatically.
- "Remote Login" and "Remote Management" should be ticked on in the Sharing pane of System Preferences of the user on the machine you need to access. Do this for every user that you want to copy files to. Make a note of the IP address when "Remote Login" is selected; there is a label displaying something to the affect "To log in to this computer remotely, type "ssh firstname.lastname@example.org" (we will eventually be doing just that). The IP address is "192.168.1.212". We will not be using the ".local" address.
- AppleScript Editor and Terminal should be handy. Both are located in /Applications/Utilities/. Keep them in the Dock for easy access at least for the time being.