Monthly Archives: August 2010

CSS3 Snippets in TextMate – Linear Gradients

Gradients are great. Linear gradients are super-great, because (as long as you don’t want funky angles) they work on pretty much all current browsers if you can remember the syntax. I can’t remember the syntax, but with a little home-schooling TextMate can…

Create these 2 snippets within TextMate’s CSS scope:

background: vertical linear gradient
Tab trigger:
Scope Selector:
background: ${1:top-color};
background: -webkit-gradient(linear, left top, left bottom, from(${1:top-color}), to(${2:bottom-color}));
background: -moz-linear-gradient(top, ${1:top-color}, ${2:bottom-color});
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:top-color}, endColorstr=${2:bottom-color});
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:top-color}, endColorstr=${2:bottom-color})";

background: horizontal linear gradient
Tab trigger:
Scope Selector:
background: ${1:left-color};
background: -webkit-gradient(linear, left top, right top, from(${1:left-color}), to(${2:right-color}));
background: -moz-linear-gradient(left top, ${1:left-color}, ${2:right-color});
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:left-color}, endColorstr=${2:right-color}, GradientType=1);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=${1:left-color}, endColorstr=${2:right-color}, GradientType=1)";

Now, typing background within a CSS context and pressing tab should show something like this:


Choosing one of the two new options at the bottom will give you all the code you need for most browsers to show a horizontal or vertical linear gradient. The first colour you enter (either the top-most or left-most colour) will become the default background for browsers that don’t support gradients, which is hopefully usually what you want. In case you were wondering, -ms-filter is specifically for IE8 (in IE8-mode) which requires quotes around the contents.

The Growling Doorbell

As promised in my previous post, I now have my doorbell sending growl notifications. Sending just one to my mac mini in the living room would be a bit pointless, since at that point I am within three metres of the front door – but, I have the notifications forwarding to every other mac in the house, and even with push notifications to my iPhone. This means that I now get three notifications on my iPhone when the doorbell is rung… One for the Twitter direct message, one for the email for the Twitter direct message, and one for the Growl notification, but they are non-sticky notifications so I can live with that.

Firstly, I installed Prowl – the excellent forwarding mechanism to get growl notifications on your iphone. I had to install on the iPhone as well, of course. I set it up to still show regular notifications, and to only forward items with a priority of at least “High” to my phone so I don’t get inundated with DropBox and Hardware Growler updates vibrating my phone all the time. It doesn’t support the icon images sadly that Growl does, but you can’t have everything (and I imagine this is an iPhone shortcoming rather than a Prowl restriction).

The next step is to install growlnotify (thanks to ZeissS for pointing this out). I had seen growlnotify in the Extras folder for Growl many times, but never really messed with it before. It’s a command line interface for sending local (or networked) growl notifications. It turns out the syntax is pretty simple.

For my purposes I was interested in showing a title saying the doorbell had been rung, a picture of the person ringing the bell, and the date and time that it occurred. According to the documentation the switch -n or --name should identify the application that is sending the notification, as well as showing the title for the notification. It states also:

To be compatible with gNotify the following switch is accepted:
    -t,--title      Does nothing. Any text following will be treated as the
                    title because that's the default argument behaviour

I found that -n did not work as I expected, and I actually had to use -t as well. Perhaps the documentation is outdated? YMMV.

So, to the AppleScript. The only thing I needed to pass was the image which we have already located in the script in the previous post.

 on growlNotify(img)
	set date_ to (current date) as string
	set scriptpath to "/usr/local/bin/growlnotify -p High -n Doorbell -t "Doorbell Rung!"  --image " & img & " -m "" & date_ & """
	do shell script (scriptpath)
end growlNotify

Nice and easy. This displays a notification something like this:


Then, I just modified the original script to include a call to this immediately after this line:

set the item_path to quoted form of the POSIX path of itemadded


set the item_path to quoted form of the POSIX path of itemadded

Job done? Almost. Now, I needed to forward the growl notifications to any other Macs I have. Unfortunately, there is no “global announce to subnet method” I could figure out easily, but Growl does have this functionality built-in. In your Growl preference pane, under “Network”, enable “Listen for incoming notifications on each machine”. You can add passwords if you share your network with other people. Then, on the machine that will be forwarding the notifications, in this pane check “Forward notifications to other computers”. The computers should automagically show up in the list (via Bonjour) then you can just check “Use” for each one.

Job done! Your doorbell is now probably better connected than some politicians.

The next step is to implement proper authentication with Twitter, and try to find a service rather than TwitPic so everyone ringing my doorbell isn’t presented to anyone who wants to spend the (minimal) time trying to figure out how to see them.

The Tweeting Doorbell

If you’re anything like me (which you are probably thankfully not) you have a dream. A dream that you make all of your friends listen to you endlessly discussing in the pub. A dream that has long ago ceased being based in logic or sense, but is now just something you have to achieve if only to make up for never shutting up about it.

My dream, was to have my doorbell tweet me when someone rang it. Not much of a dream, I’ll admit, but still something I wanted. Before I got my iPhone I used BluePhone Elite with every phone I had (the iPhone doesn’t support the best bits, though). Aside from the main benefits such as texting and answering the phone from my mac, it also alerted me when my phone was ringing and who was calling. This was very unexpectedly useful – often my phone would be on silent and in the pocket of my jacket somewhere, and I would know firstly that it was ringing at all, and secondly whether or not it was worth answering. It solved a problem I didn’t realise I had.

I decided at this point, that everything in my house must be able to send me notifications. Preferably Growl notifications. If you don’t know what Growl is, follow that link and then come back. We’ll wait.

Recently I got a new front door put in. Part of the deal was a Yale “Electronic Door Viewer” which I got cheap since I get on well with the builder that fitted it. It consists of a small box, and a camera that looks like a regular spyhole – except it also has a doorbell button underneath. This little box and camera, both play doorbell chimes and display a picture of the person ringing the bell on a small (poor quality, but good enough) screen. What pleased me most though, was that the pictures are stored with a date/time stamp on an SD card inside the box, so that I can see who rang the bell at what time when I return home. There are a few issues with the setup… people seem to have difficulty locating the bell even with a sticker underneath it saying “this is the doorbell”, the LED lights that light up when the bell are rung blind people, very short people appear to be invisible and I never remember to check the box for pictures when I get home (much like when my phone answering machine became a phone-based service instead of hardware – with no blinking light, I don’t realise I have a message and forget to check). I can’t do much about some of these issues. People can’t find the bell – I might make another, bigger sticker. I will stick some kind of filter over the LED lights to save me from lawsuits. Short people will just have to remain invisible. But forgetting to check the box for new pictures, this seemed impossible to overcome.

Then I came across the Eye-Fi range of SD cards. These have an 802.11n wireless network adapter – built-in. I have no idea how they do that. But they do. The smallest was 4GB, which is excessive for my plans, but that was the smallest. I bought one from Amazon for £50 with free delivery.

Setting up the Eye-Fi card is really easy. It comes with a USB adapter and the software worked fine and was reasonably intuitive. Whenever the card has power and it can find one of the wifi networks you have setup on it with USB it automatically transfers any images (or videos) stored upon it to your mac/PC. I was worried that the doorbell wouldn’t keep power to the card for long enough to make the transfer, but the default setting of 20 seconds or so is apparently enough time to set up a network connection and copy the file across. You can set it up to automatically post them to Facebook or Flickr (or various other services), but that wasn’t what I wanted to achieve. To get the pictures to Twitter was going to take a few extra steps.

As a quick note, I am not 100% sure of the legal position of posting pictures of people on the Internet without their permission. Since it says “CCTV Recording In Operation” above the camera, and the people are outside in plain view, I am pretty sure I’m okay – but I wouldn’t want you to cite me as the person that gave you the go ahead to do this. So if you’re not sure, find out.

So, now the Eye-Fi was automatically putting pictures in a folder (I think ~/Pictures/EyeFi/). It was also adding date information to the folder structure, so in the Eye-Fi software settings I changed this to just stick them all in the root of the directory that was set. OS X has something built-in called “Folder Actions” which allows it to react to changes to a folder. Normally you just locate the folder, right-click it (or control-click for you really old school people) and choose “Folder Actions Setup…”. For some reason, that wasn’t working on my machine so I had to locate the app manually at /System/Library/CoreServices/Folder Actions Until you have a script written though, there’s not yet much you can do except use the provided scripts which are no good to me. So, I started writing the AppleScript. First I needed to be able to send direct messages. Using curl, this is pretty easy:

on dm(user, pwd, recipient, msg)
	do shell script ("curl -k -u " & user & ":" & pwd & " -d 'text=" & msg & "&user=" & recipient & "'")
end dm

Posting a picture online was a bit trickier. For the time being I have used TwitPic but this seems a bit open for my liking. I may revisit that in the future. So, I created another Twitter account (set to private) and made that and my normal account follow each other so they were able to send direct messages to each other. Then I created this script to post images to TwitPic:

on twitpic(filepath, user, pwd)
	set scriptpath to "curl -k -F media=@" & filepath & " -F username=" & user & " -F password=" & pwd & " -F message="
	set xmlValue to (do shell script scriptpath)
	--Parse the result for whether the upload was successful
	if xmlValue contains "<rsp stat="ok">" then
		tell application "System Events"
			set xmlData to make new XML data with data xmlValue
			set URI to value of (XML element "mediaurl" of XML element "rsp" of xmlData)
		end tell
		return URI
		display dialog "TWITPIC ERROR " & xmlResponse as string
	end if
end twitpic

It’s not the most bug resistant code in the world, but it will at least show an error message on the machine if it fails, saying (hopefully) why it failed.

Finally, I needed to hook these altogether. I added to my fast growing script:

on adding folder items to this_folder after receiving added_items
	set twitteruser to "twitteruser" --amend this to be the user name of your doorbell
	set twitterpwd to "password" --amend this to be the password of your doorbell
	repeat with itemadded in added_items
		set the item_path to quoted form of the POSIX path of itemadded
		set mediauri to postPicture(item_path, twitteruser, twitterpwd)
		sendDirectMessage(twitteruser, twitterpwd, "username", mediauri as string) --amend this to be the username you want to be alerted. Duplicate the line if you want to alert more users.
	end repeat
end adding folder items to

I saved this as eyefi.scpt in Macintosh HD/Library/Scripts/Folder Action Scripts/. Now I was ready to open up the Folder Actions Setup… again. I located the folder Eye-Fi was downloading into (uploading to? Whatever), right clicked it, and chose Folder Actions Setup…. I selected eyefi.scpt from the list, and made sure that the right folder was in the left-hand column, and that Enable Folder Actions was ticked. Finally, I pressed the doorbell (while ducking out of the way like a coward). Success! I received a direct message with this attached:


I also received an email about it, since it was a direct message and I have Twitter configured that way. I was living the dream! Perhaps a shallow, superficial, superfluous and ridiculous dream, but the dream nonetheless.

My next job is to make it send Growl notifications.

I hope you love this as much as I do, and if not, keep it to yourself. What do you think? How could I make this more epic? Let me know in the comments.

Update: I now have growl notifications working too! Read about that here.