Monday, April 4, 2011

Flex 360

Will be attending the conference this year down in Denver -- we convinced my employer to send two of us from the team. Should have some very interesting topics.

Sunday, March 20, 2011

OSX, Login Screens, and Battery Information

I know it's probably weird, but I really don't like it when I boot up my Macbook and don't know if I should plug it in or not.  Sometimes, if it's very low on battery power, I'll just turn it back off again and get on my PC (I do a lot of coding from the couch :).

So, I asked myself, why not try and find a way to dynamically update my login screen with battery information?  There are a number of posts for updating the login text.  I took this basic idea and combined it with a Python script I wrote for parsing out the battery status.

Some of the content in the battery script was taken from a recent post on Lifehacker, showing how you can build a script which will vocally alert you when your battery status is getting critical.

Anyway, the first step was to build a script (I prefer Python) which will gather battery stats from ioreg and parse it for the current battery capacity, maximum battery capacity, and external charge capability.  The last option (yes/no) lets us know if the laptop is plugged into the wall.

Here's the script I came up with

#!/usr/bin/python
import subprocess
import os, sys

BATTERY_CMD = ["/usr/sbin/ioreg", "-l"]
GREP_CMD    = ["/usr/bin/egrep", "Capacity|ExternalChargeCapable"]

def main(argv):
    content      = getBatteryStatus()
    print(content)

    return 0

def getBatteryStatus():
    process = subprocess.Popen(BATTERY_CMD, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    grep    = subprocess.Popen(GREP_CMD, stdin=process.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    grep.wait()
    output  = grep.communicate()[0]
    batteryStatus = output.split("\n")
    if len(batteryStatus) < 3:
        print(batteryStatus)
        return "Could not get battery status"
   
    if "Yes" in batteryStatus[0]:
        return "Laptop is plugged into the wall"
    else:
        maxCapacity = float(batteryStatus[1].split("=")[1].lstrip())
        curCapacity = float(batteryStatus[2].split("=")[1].lstrip())
        remaining   = 100 * (curCapacity / maxCapacity)
        return "Battery Remaining: %.02f%s" % (remaining, "%")

if __name__ == "__main__":
    sys.exit(main(sys.argv))


 This script basically runs the following command: ioreg -l | egrep Capacity|ExternalChargeCapable.  This bundles the content into a large string, delimited by "\n" characters.  Parsing this is a simple value of extracting everything after the "=" sign.

Anyway, this script prints either the percentage or the status of the wall plug.

The second part of this exercise was to create a StartupItem for my Macbook.  This was actually very easy (as the upper link shows).  Create a new directory in "/Library/StartupItems" called logintext.  Inside this directory, you'll need to copy the above script, and add 2 new scripts:

Call the first one, StartupParameters.plist, and add the following content:

{
Description = "Sets LoginwindowText";
Provides = ("logintext");
}


This script informs the startup process of which script to execute when starting up. This guarantees all initializations of the Macbook will have up-to-date knowledge of the battery life.

The last script is called "logintext". In this script, put the following content:

#!/bin/sh
batteryText=`/Library/StartupItems/logintext/batteryScript.py`
defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$batteryText"


This script executes the Python script and sets the loginwindow's preference (LoginwindowText) to the output from the script.

Log in as root (sudo su -) and add a new cronjob to execute this script every 2 minutes:

*/2 * * * * /Library/StartupItems/logintext/logintext


And it should keep your system relatively up-to-date!

Monday, January 3, 2011

Pianobar, iTunes, and GeekTool

For those of you who haven't seen Pianobar, it's a great little terminal-based player for Pandora.  It was featured on Lifehacker as a Flash-free player for Mac and Linux (and Cygwin-based Windows installations).

Of course, being the fan of Conky that I am, my first thoughts were to find a way to parse out the content from Pianobar and display them on the desktop.  This, it turns out, was a bit harder than it seemed.  The content streaming into the terminal is littered with extra characters, which are great when viewing from the console.  These characters, however, need to be extracted from the content so the raw data is accessible.  Moreover, Pianobar has a nice feature which prints the time remaining for the currently playing song.  This information is printed to the console using the '\r' character so the time overwrites itself.  When diverted to a file, this results in excessively long lines which need to be parsed.

With this in mind, I started my latest project was to extract this information and print it so tools like Conky and GeekTool could print them to the desktop while they are running.  The result, though a bit hacky, was fairly nice.

Once this was finished, however, another idea struck me: what if I'm playing iTunes rather than Pianobar?  I'd still like to display this content on the desktop.  What's more, I'd like to use the same program to do both.

So, my next project was to extend this script so it could handle multiple musical inputs.

I've posted the results to SourceForge.  Let me know what you think!