www.wallcity.org | Zack Smith

Simple Little Warranty Parser


if anyone is interested I have a python prototype of @glarriza’s warranty ruby script that spits all keys out as a dict http://gist.github.com/1357622

I would have used his but I am writing something in python that needed this directly and I did not want to call an external command.

-Z

system-type a new little command line

I just made a little command line grab it here:

https://github.com/acidprime/system-type

This little binary will tell you if you have a Laptop or Desktop.
It reads this value using the system-type in IOKit (IOPlatformExpertDevice).
You can parse this value your self using the ioreg (-l) command but Its not
formatted well, so I decided to make this as its a pretty common request.
For instance I once had a school district that wanted to turn off wireless
on all Desktops as they were having MYNAME(37) bonjour name conflict issues.

There is a little example.command shell script to show you the two ways you
would use this in your scripts. laptops are value 2 (exit 1) and Desktops are
value 1 (exit 0). The exit values allow you to use standard logic built-in to
run the command and use its exit value. Or if you think thats lame you can
parse the text. To each there own but I like exit values

Known Issues:
As I recall this does not cover PowerPC machines, but I have not seen an intel
that does not use this value. Maybe iPad 3 will be 3 ;)

To Do:
I will make a little installer for it as some point and put it in
/usr/local/bin/system-type
Could use some options as well such as controlling behaviour
Maybe XML output, and put some other values?

Replacement for:

#!/bin/bash
declare -x awk="/usr/bin/awk"
declare -x ioreg="/usr/sbin/ioreg"
# Intel and future systems test
declare IOREG="$("$ioreg" -l |
	"$awk" 'BEGIN {FS="[<>]"}
	/.*\"system-type\".=./{
	systype=$2
	if ( systype == 1 )
		{ print "D" ; exit 0 }
	# System type 1 is a Desktop
	else if ( systype == 2 )
		{ print "L" ; exit 0 }
	# System type 2 is a Laptop
	}')"

Sample NSStatusItem Application

ScriptMenu

Here is the sample NSStatusItem Application
mentioned in my slides at Mac Tech Conf 2011 can be found here:

https://github.com/acidprime/StatusItem/downloads

Fun with Textmate URI links

So I have been doing allot of custom cocoa URL code over the last week, so I thought I would go look around for applications that have custom URL types. In my search I found the following url type for TextMate (txtmt). Here is an example that will open up text mates own info.plist and show you were these are declared.

txmt://open?url=file:///Applications/TextMate.app/Contents/Resources/Info.plist&line=&column=36
Here is an example of this link
There is a quick blog post about it here on their site. All in all I can see some pretty cool ideas for this, such as what I am big fan of which is interactive documentation. I am a big URL nerd and to mention one other cool one I knew about previously is transmit’s transmitreg:// which they use for serial numbers ,an awesome way to fill in serials that every vendor should do.

Converting a Check Box value to Boolean

Here is simple little objective c method that will take a IBOutlet and query its value to return a boolean. I typically need to do this to run a logical test on the interface value. My guess is properties & bindings are the better way to do this but as BOOL is not an object I am not quite sure how that would be done.

-(BOOL)evaluateCheckBox:(NSButton *)evalButton
{
	// Gather data from interface
	if ( [evalButton state] == NSOnState ){
		return YES;
	}
	if ( [evalButton state] == NSOffState ){
		return NO;
	}
}

Pull the Script Name in BASH

I very often use the Script Name as the log file name, it allows me to make the logs
always match up to the script even though the code is the same in all scripts
here is a quick example on how to do that

#!/bin/bash
declare -x SCRIPT_PATH="$0"
declare -x SCRIPT_NAME="${0##*/}"

echo $SCRIPT_PATH

echo $SCRIPT_NAME

A more raw example (Same Output):

#!/bin/bash
echo $0
echo ${0##*/}

Output:

/Users/acid/Dropbox/code/bash/scriptname.sh
scriptname.sh

Simple Folder Loop with Exclusions

Here is a little loop that can exclude folders, I started it for some find
code that would exclude "system" files during a permissions change.
#!/bin/bash
OLDIFS="$IFS"
IFS=$'\n'
for FOLDER in /* ; do
 [ -L "$FOLDER" ] && continue
 if [ -d "$FOLDER" ] ; then
 if  [ "$FOLDER" != '/Volumes' ] &&
 [ "$FOLDER" != '/System' ] &&
 [ "$FOLDER" != '/Network' ] &&
 [ "$FOLDER" != '/Recycled' ] &&
 [ "$FOLDER" != '/cores' ] &&
 [ "$FOLDER" != '/dev' ] &&
 [ "$FOLDER" != '/net' ]
 then
 echo "$FOLDER"
 fi
 fi
done
IFS="$OLDIFS"

Simple BASH Console User Check

I have seen this in done pretty much the same way in all languages, so my continued effort to give away all my bash scripts so I never have to use it again, here is a quick little example of who to check for console users with bash,who and awk.

#!/bin/bash
declare -x who="${who:="/usr/bin/who"}"
declare -x awk="${awk:="/usr/bin/awk"}"
declare -xi CONSOLE_USERS="$($who |
		$awk '/.*console/{++n}END{print n}')"
declare -x CONSOLE_USER="$($who |
		$awk '/console/{print $1;exit}' )"
if [ $CONSOLE_USERS -eq 0 ] ; then
	echo "No console users present"
else
	echo "$CONSOLE_USER is logged in"
fi

Simple BASH command check

So I declare all my commands in every language, the rational is that I can only test what I know and if I don’t know its not tested. To Give you a practical example I often have macports installed and always forget to fix my PATH variable. This means ports will override the default binaries. I ran into this the other day with curl, some port I grabbed also downloaded curl. This version of curl installed in /opt/local/bin/curl and in my case it does not have SSL support. This tripped me up while testing some small script , but its an easy fix in scripts by pathing to places you know will exist. This is habit I have always had with bash as I learned bash scripting using the book Linux Shell Scripting with Bash* which does this for a non-Mac OS X reason that different platforms may have software installed in different locations. One of my co-authors beau hunter often gives me crap about this as he thinks fail over using the PATH system is better, which honestly if you just want your scripts to run always, it is. But I am much more paranoid, I like the option explicts of the languages and try keep as much control about run time variables as possible.

So here is a quick example that came up today if your curious.

#!/bin/bash
declare -x basename="/usr/bin/basename"
declare -x hdid="/usr/bin/hdid"
declare -x mkdir="/bin/mkdir"
declare -x rm="/bin/rm"
declare -x rmdir="/bin/rmdir"
declare -x mount_afp="/sbin/mount_afp"
# Does not work for spaces in path names
for command in $basename $hdid $mkdir $rm $rmdir $mount_afp ; do
	if [ -x "$command" ] ; then
		echo "Verified command: $command is executable"
	else
		echo "Missing command: $command!"
		exit 1
	fi
done

*(My Amazon Link embeded)

Fun with Schlage Link & Python

So I have a Schlage LiNK Wireless Keypad Entry Lever Lock Starter Kit System*. I am trying to take the whole thing apart call by call but until I am ready to post that I wanted a quick easy way to interface with the system in a semi cool way. Basically I wanted anyone who types the code in the door to hear “Welcome home” $First $last. So I decided that I could at least in the time being before I figure out Zwaves command classes, just check my email (Special notification Inbox) and parse the name from there. This works pretty well, I mark it as read so I don’t see it the second time around and then set it on a launchd job. Though really you could use this to run any command based on a special subject line, so its a quick easy example of something sorta cool. I have not had a chance to make a youtube video of it, but I will when its a little more sexy ( and I get the arduino hooked up to the metal skull servos, yes I am totally not joking that I have a metal skull that I am teaching to speak).

Grab the script here

#!/usr/bin/python
import imaplib
import string, random
import StringIO, rfc822
import email, sys
import os
from datetime import datetime, timedelta
import plistlib
SERVER = "mail.wallcity.org"

USER  = "home"
PASSWORD = "mypassword"

lastcheck = datetime.now ()
print lastcheck
# connect to server
server = imaplib.IMAP4_SSL(SERVER)

# login
server.login(USER, PASSWORD)
server.select()

#typ, data = server.search(None, 'ALL')
typ, data = server.search(None, '(FROM "alerts@schlagelink.com")','UNSEEN')
for num in data[0].split():
resp, data = server.fetch(num, "(RFC822)")
text = data[0][1]
file = StringIO.StringIO(text)
message = rfc822.Message(file)
subject = message['Subject']
if subject == 'Schlage LiNK Alert':
#body = server.fetch(num,"(UID BODY[TEXT])")
body = server.fetch(num,"(BODY[TEXT])")
imaptolken = body[1]
bodytolken = imaptolken[0]
textbody = bodytolken[1]
words = textbody.split()
first_name = words[8]
print words
last_name = words[9]
cmd = '/usr/bin/say' + ' ' + 'Welcome home ' + first_name + ' ' + last_name
# Turn the volume up
set_volume_command='/usr/bin/osascript -e \'set volume 10\''
os.system(set_volume_command)
os.system(cmd)
server.logout()

* Please note my Amazon Link

Here is an example of what these emails look like: