All posts tagged OS X

Scheduled automatic local backups/versioning using Git on OS X

I have some sensitive data that I want to be backed up frequently and also on the go or at work when my Time Machine disk is not available. The reason is not that I want to protect that data from being lost due to a disk crash or something, more like protecting it from stupid changes I make or an application that might corrupt it. The idea came to me when Evernote – which is really great, I use it for a lot for notes and ideas – somehow magically erased several of my notes. I could restore them from my Time Machine backup, but I thought “Wouldn’t it make sense to automatically backup my notes every some minutes and be able to do diffs and all the other nice things with them? And wouldn’t it be great if all this could work offline?”.

Aha, a Git repository!
And a shell script!
And some automated periodic calling of that script!

I’ll show you how to do it, here we go.

Step One

In your ~/Library/Scripts folder create a file git-backup.sh and put this code inside:

#!/bin/sh

echo "\n---"

# Abort if any command fails
set -e

# Print current date and working directory
echo "$(date)  -  $(pwd)"

# Add all files to index -> also track new files
echo "Adding all changes..."
git add --all .

# Commit all
echo "Committing all changes..."
git ci -m "<< launchd auto-commit >>"

(Doubleclick the code to select all)

Step Two

Then in ~/Library/LaunchAgents create a file like yourdomain.yourbackup.plist – e.g. for my Evernote backup I used net.ptrbrtz.evernote-git-backup.plist – and put this inside:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
     <key>Debug</key>
     <false/>

     <key>Label</key>
     <string>net.ptrbrtz.evernote-git-backup</string>

     <key>LowPriorityIO</key>
     <true/>

     <key>WorkingDirectory</key>
     <string>/Users/peter/Library/Application Support/Evernote</string>

     <key>ProgramArguments</key>
     <array>
          <string>/Users/peter/Library/Scripts/git-backup.sh</string>
     </array>

     <key>StandardErrorPath</key>
     <string>/Users/peter/Library/Application Support/Evernote/net.ptrbrtz.evernote-git-backup.log</string>
     <key>StandardOutPath</key>
     <string>/Users/peter/Library/Application Support/Evernote/net.ptrbrtz.evernote-git-backup.log</string>

     <key>StartInterval</key>
     <integer>1800</integer>
</dict>
</plist>

You’d have to change the marked lines to your needs.

  • WorkingDirectory names the directory whose content will be backed up. You’ll have to create a Git repository there using git init yourself, I guess you know how to do that.
  • StandardErrorPath/StandardOutPath should name a file where you want the shell output to be routed to.
  • StartInterval sets how often the backup runs. It’s given in seconds, 30 minutes * 60 = 1800 seconds. If you want to set  specific dates and times here instead, have a look at the documentation.

Step Three

Now for the automated calling of the launch agent you just created. We use launchctl for that.
Tell launchctl about your task by doing:

launchctl load ~/Library/LaunchAgents

Now check if launchctl really knows about your launch agent now:

launchctl list | grep "net.ptrbrtz.evernote-git-backup"

You should see something like:

- 0 net.ptrbrtz.evernote-git-backup

Depending on the interval you set, you soon should see your StandardErrorPath/StandardOutPath file popping up – better go check if everything went fine. If you placed it in the repository directory like I did it, you could also go ahead and put it on the Git ignore list to prevent it from being backed up, too.

If you ever make changes to your launch agent plist, make sure you remove it from lauchctl and put it back in to apply your changes:

launchctl remove net.ptrbrtz.diploma-thesis-git-backup
launchctl load ~/Library/LaunchAgents

 

You can create as many automated backups as you want. For every new repository just repeat steps two and three.

Keyboard shortcut/script to toggle “screensaver unlock password protection” on OS X

When I’m at work I usually enable the password protection to unlock the screen after the screensaver was on or the screen was turned off. But at home I wanted it off and all this switching back and forth was getting on my nerves.
So I wanted a shortcut to do it.
And there is none.
But there is AppleScript!
Yay!

I opened the AppleScript Editor, wrote this code…

tell application "System Events"
  set require password to wake of security preferences to not (require password to wake of security preferences)
end tell

…and saved it as a .scpt Script File to /Library/Scripts.

Now all I needed was some way to assign a keyboard short to run this script. I used Quicksilver, but there are plenty of others, e.g. Butler.

Happy switching!

Enable Finder to QuickLook all unknown files

Ever wanted to be able to QuickLook into README files that have no file extension or other text files that Finder normally doesn’t know how to handle – like .nfo, .log, etc?
Here is one trick to rule them all:

Download and install qlcolorcode, normally this is just a QuickLook source code highlighting plugin. But very useful by itself already.
Change Info.plist inside the QLColorCode.qlgenerator bundle you downloaded by adding the public.data content type:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <array>
    <dict>
      <key>CFBundleTypeRole</key>
      <string>QLGenerator</string>
      <key>LSItemContentTypes</key>
      <array>
        <string>public.source-code</string>
        <string>public.xml</string>
        <string>com.apple.property-list</string>
        <string>org.tug.tex</string>
        <string>public.plain-text</string>
        <string>public.data</string>
        </array>
    </dict>
  </array>
</plist>

Every file OS X does not know how to handle should have the public.data content type, so we just ruled them all.
To apply your changes, you have make OS X rescan it by moving the Plugin out of /Library/QuickLook and putting it back in.

Now take a file that should be QuickLookable now and execute:

qlmanage -d 1 -p file.ext

The last two lines of the answer should read something like this:

[DEBUG] Loading <QLGenerator /Library/QuickLook/QLColorCode.qlgenerator>
[DEBUG] Previewing /Path/to/your/file.ext finished

Also useful, to find out about the content type of a given file:

mdls yourfile.ext

System-wide environment variables in OS X 10.6 Snow Leopard

Normally adding variables to .profile/bash.rc/etc. only makes them visible to Terminal, but not to GUI Applications. This is how to make them global:

launchctl setenv MY_VAR MY_VALUE

But they’ll only last until next login.
How to make persistent environment vars?
This post at stackoverflow suggests to put them into ~/.launchd.conf like this:

echo setenv MY_VAR MY_VALUE >> ~/.launchd.conf

But I found, that defining or appending PATH in ~/.launchd.conf doesn’t work on 10.6. PATH is overwritten by ~/.MacOSX/environment.plist. So I stick with the latter file, simply editing it using the Property List Editor that comes with OS X.
After editing it you have to either log in again or do…

launchctl setenv MY_VAR MY_VALUE

…to set it just for the current session.

Batch convert animated GIFs to videos using AppleScript/Automator/QuickTime 7 on OS X

When I was doing a VJ thing, the software I used couldn’t handle the animated GIF files I wanted to play. I had a hard time finding a free tool to batch convert animated GIF to movie and not the other way round.

Since I just made that video AppleScript/QuickTime batch converter I thought I could do the same thing with GIFs too. It turned out the standard QuickTime X can’t open them. But QuickTime 7 can! And you can still install it from your OS X Install Disk – at least with Snow Leopard.

So just install QuickTime Player 7 and put this Automator .workflow file into your ~/Library/Services folder. Now select one or more animated GIF files in Finder, right-click them, and choose Services → Convert animated .gif to .mov using QuickTime 7. It will use the most recent QuickTime 7 export settings. You should convert/export one file by hand to adjust the settings.

You’ll see QuickTime Player 7 starting and magically converting one file after another. I found it’s better to leave it alone while it’s doing that.

 

How to do this from scratch?

See my AppleScript/QuickTime batch converter post on how to create a Service for Finder Contextual Menu (the thing that pops up when you do a right-click). But in step 2 use image files instead of movie files and in step 4 use this code:

on run {inputFiles}
	if inputFiles is equal to {} then
		set inputFiles to (choose file with prompt "Select the file(s) to convert:" with multiple selections allowed without invisibles)
	end if
	open inputFiles
end run

on open droppedItems
	tell application "Finder" to set inputFolder to (container of first item of droppedItems) as Unicode text
	set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text

	display dialog "Most recent QuickTime 7 export settings will be used.
Existing files will be overwritten/moved to trash!
Beware of evil QT7 Gamma shift!"

	tell application "QuickTime Player 7"
		activate
		close every window
	end tell

	repeat with currentItem in droppedItems
		tell application "Finder" to set fileName to name of currentItem as Unicode text

		tell application "QuickTime Player 7"
			open currentItem
			tell front document to set frameCount to count of frames of first track
		end tell

		set outputFileName to (outputFolder & fileName & ".mov")

		tell application "Finder"
			if exists file outputFileName then
				delete file outputFileName
			end if
		end tell

		tell application "QuickTime Player 7"
			if frameCount is greater than 1 then
				with timeout of 86400 seconds -- 24 hours
					export front document to outputFileName as QuickTime movie using most recent settings
				end timeout
			end if
			close front document
		end tell
	end repeat

	quit application "QuickTime Player 7"
end open

Batch convert AVI and other videos files via the Contextual Menu in Finder using AppleScript/Automator/QuickTime on OS X

I really like my Canon IXUS camera, but when it comes to making videos it always bugged me having these huge uncompressed .avi files filling up my disk. QuickTime is free and has a .H264 export option with some presets built in, but no batch mode. You have to convert videos by hand – one at a time.

If I had lots of files, wouldn’t it be much easier to just select some video files in Finder, right-click and convert them?
Yes!
And it is all possible using AppleScript, Automator and the Contextual Menu – a.k.a. Services.

Just put this Automator .workflow file into your ~/Library/Services folder. Now select one or more movies in Finder, right-click them, and choose Services → Convert video(s) using QuickTime. You can choose between the presets QuickTime offers… try them and see what they do. I usually use 480p and 720p.

You’ll see QuickTime Player starting and magically converting one video file after another. I found it’s better to leave it alone while it’s doing that. Your files will be output as original-filename.original-extension.mov.

 

How to do this from scratch?

1. Open up Automator, which comes with OS X. Create a new Service with FileNew… and choose the Service template.

 

2. At the top of the window, set up the Service to receive movie files from Finder.

 

3. From the left side, drag a Run AppleScript action into your workflow in the middle.

 

4. Insert this AppleScript into your action:

on run {inputFiles}
	if inputFiles is equal to {} then
		set inputFiles to (choose file with prompt "Select the file(s) to convert:" with multiple selections allowed without invisibles)
	end if
	open inputFiles
end run

on open droppedItems
	tell application "Finder" to set inputFolder to (container of first item of droppedItems) as Unicode text
	set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text

	set exportPreset to (choose from list {"Movie", "iPhone", "iPod", "HD 480p", "HD 720p"} with prompt "Choose QuickTime Export Preset:") as Unicode text
	if exportPreset is equal to "false" then
		return
	end if

	repeat with currentItem in droppedItems
		repeat until getProcessPercentCPU("CoreMediaAuthoringSessionHelper") is equal to ""
			delay 30
		end repeat

		tell application "Finder" to set fileName to name of currentItem as Unicode text
		convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
		delay 30
	end repeat
end open

on convertFile(inputFile, outputFile, exportPreset)
	tell application "QuickTime Player"
		set thisMovie to open inputFile
		export thisMovie in (outputFile) using settings preset exportPreset
		close thisMovie
	end tell
end convertFile

on getProcessPercentCPU(processName)
	do shell script "/bin/ps -xco %cpu,command | /usr/bin/awk '/" & processName & "$/ {print $1}'"
end getProcessPercentCPU

Then save – I used Convert video(s) using QuickTime as file name. Automator then automatically saves your workflow to your user service directory at ~/Library/Services. If you don’t want it any more, just delete it.