↓ Twitter is updated more often, so read it! ↓

13″ MacBook Pro: I choose you

A month ago, I mused purchasing a 13″ MacBook Pro. My primary reasons for considering the MBP were the freedom of OS choice, “seeing what all the fuss is about,” premium hardware for just a couple hundred dollars more, excellent customer support, and a healthy dose of nostalgia.

Approximately a week after writing the post, a friend let me know of a rare deal: a friend of his who just so happens to be an Apple authorized reseller was in jeopardy of losing her authorization because her sales were really low. In order to meet her goal, she was selling Apple hardware at cost. You can’t beat cost! Combine that ~$300 savings with putting the purchase on a credit card with excellent rewards, and it would put me over the edge of my reward amount needed to get myself with a free flight worth about $400.

So, I bought a stock mid-level 13″ MacBook Pro, the one with a 2.53 GHz Core2Duo, 4 GB of DDR3, and a 250 GB HDD. I did get AppleCare and a remote, although the remote was backordered and mysteriously hasn’t arrived yet (should hear why on Monday).

My thoughts?

Summary

I’ll never go back. Apple has a solid hardware product with bells and whistles which themselves make me glad I bought it, plus a slick operating system which appeases my desire for an easy-to-use, on-the-go environment.

TL;DR version

and it had been on for ~20 minutes

and it had been on for ~20 minutes

Hardware. Seven hours of battery life. Seriously. I got right around that many hours the day I took this screenshot about a week after I bought it. The multitouch touchpad with its gestures are amazing and have seriously changed how I use a touchpad–even more once I enabled tap-to-click I miss them when I use a non-Mac laptop. The magnetic power cord connector should be on every computer: it’s saved my ass twice now. The graphics card is enough to handle Left4Dead with most of the settings on medium, and it’ll certainly handle the older games and casual games I tend to play more often these days. The screen color is amazing and the keyboard is the most welcoming keyboard I’ve ever used. This is the first line of Mac laptops with an SD card reader, and that’s indispensable for me these days with the dog show photography I’ve been doing.

Downsides? I’m not too hot about the non-removable battery, but I’ve never needed a second battery even on my old Averatec which had approximately two hours of battery life. Apple made a data-driven design decision when choosing this path. I’ve not heard many complains except from people who are resistant to change. Folks who really need another battery can suffice for the hour-long charge time while plugged into something like a HyperMac battery. I also wish it had a real microphone port, but how often do I actually use a microphone? Never. The built-in mic is sufficient for almost everything I’d ever use it for. I’m also not too hot about the lack of a DVI or HDMI port and a mini-Displayport instead, but it’s another data-driven design decision and technically Displayport is a better standard for video. I ordered an adapter from Amazon; it’ll arrive this week.

Software. Mac OS X isn’t new to me. I used 10.5 on Jon’s Macbook when I borrowed it for a few months last year, and used 10.1 back in high school. It’s not a huge adjustment for me, so I’ll not go over such nuances. However, there are a few things I must highlight, primarily so that Linux folks like myself can mirror these features in Ubuntu, Fedora, and the like.

Time Machine is indispensible. I configured Time Machine to work with my QNAP NAS and it backs up regularly. The whole system! Efficiently! Recoverably! With an excellent interface for both setup and browsing and recovery. rdiff-backup pulls this off on Linux, but there’s no “don’t make me thing” GUI for it like there is for Time Machine.

Drag-and-drop installation of programs has always been one of my favorite things about OSX. No complicated installer program with click-through EULAs, no broken packages or forced upgrades. Sure, the packages are larger because of universal binaries and statically linked libraries, but I’d rather take up another 10 MB if it means I can simply drop an icon in a directory to install it, or move it to the recycle bin to remove it. I’ve been using iUseThis to track my used programs and combining it with AppFresh for version updates.

OSX is just Unix-y enough for a lot of the stuff I do. MacPorts gives me access to a lot of utilities, especially Synergy, which allows me to use the mouse and keyboard of one computer on another via a network connection. I’ve also used it for up-to-date Python and other scripting and development tools. I use Visor to give me a drop-down, Quake-style terminal in which I do lots of command line stuff, primarily via an SSH connection to one of my many Linux computers.

Perhaps one of the most care-free benefits of OSX for me is painless hibernate, sleep, and suspend. I can shut the lid and forget about it. I’ve rebooted the Mac maybe thrice in the month I’ve had it (outside of OSX updates). I’ve never seen Linux or Windows hibernate/suspend working this well on any hardware.

Downsides? There aren’t many. Sometimes I get frustrated when I can’t find an OSX analogue for a Linux program I’ve used. I have yet to find a decent microblogging client which I like as much as Gwibber on Linux. Despite being written in the highly-portable Python language, Gwibber depends on a few things that OSX just doesn’t provide. I’ve tried Tweetdeck, Nambu, Spry, and a host of others, but just can’t find the feature set I want (eveything most clients have, plus Identica, Facebook, and Flickr plugins). Twirl comes the closest, so I’ve been using it. Eventbox is showing promise as it becomes Socialite, but I’ve yet to actually see it in action.

I’ll eventually get around to trying out Virtualbox’s 3D acceleration for some Windows games, or Wine and WineBottler for some others.

A major problem I have with my OS choices is that I like to tinker. OSX gives me the freedom to tinker with a lot of things, but its defaults suffice for almost everything. I think it’ll be more difficult for me to screw up OSX than it is for me to screw up Linux or Windows.

TL;DR summary:

I’m pleased with my purchase and haven’t had the buyer’s remorse I’ve had sometimes when making such a giant purchase. The MacBook Pro laptop was designed with both low-level and power users in mind, and I highly appreciate it. It’s just enough to not be too much.

How to rapidly expunge Facebook’s Friend Suggestions

I really admire Facebook’s Friend Suggestions feature. It has on rare occasion shown someone to whom I’d really like to connect. Most of the time, though, it shows people who I don’t know at all and have maybe one mutual friend. So, it’s largely useless to me.

However, being the often mindless user, when I see a suggestion that may be relevant to my interests, I do visit the full friend suggestion page and see if there are any others. Rarely am I presented with anyone to whom I find a dreadful desire to connect. I still feel obligated to click that damned little [X] as if to say, “I don’t know this person.” Unfortunately, I have to repeat this approximately 25 times in order to full expunge this list of people.

So, I decided to write a little script which takes care of clicking that button for me. Navigate to the Find Friends page on Facebook and execute this script in your Firebug console. Or, prefix it with javascript: and execute it in the URL bar.

d = document.getElementsByClassName("fg_action_hide"); for (var i in d){ d[i].onclick() }

The first part gets an array (a list) of all of the clickable elements with that class, the class used to denote the [X]. The next part loops over them and executes each’s onclick() function just like as if you’d clicked it yourself.

Please note that I tested this ONLY on Firefox and Chromium, but it should work on any modern browser (read: anything but IE).

HOWTO: Add CACert Root Certificates to Chromium

CACert Logo + Chromium Logo

I’ve recently begun using Chromium for most of my day-to-day browsing tasks. It recently gained support for Adobe Flash and other plugins. I’ll be excited to when it picks up Java, as well—then I’ll have little reason to use Firefox except for development. I’ve enjoyed watching the daily builds go from a virtually a crash-on-click shell to the wonderfully quick tool I’m using right now to type this post.

However, I’m a CACert user (and assurer!) and have several sites and/or utilities which rely on CACert-issued free SSL certificates.

Chromium on Linux doesn’t have its own certificate management system, but instead uses Mozilla’s Network Security Services (NSS) Public Key Infrastructure (PKI). The LinuxCertManagement article on Chromium’s wiki gives some instructions on how to import certificates.

I’ve reproduced these instructions for Ubuntu with some of my own additions below.

sudo apt-get install libnss3-tools
wget http://www.cacert.org/certs/root.crt
wget http://www.cacert.org/certs/class3.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "TCu,Cu,Tuw" -n "CACert Class 1 Root Certificate" -i root.crt
certutil -d sql:$HOME/.pki/nssdb -A -t "TCu,Cu,Tuw" -n "CACert Class 3 Root Certificate" -i class3.crt
rm root.crt class3.crt

You’ll now be able to log in to sites using CACert SSL certificates without needing to click through the red screen of hate.

Note that as of the daily build for August 11, 2009, it is not yet possible to accept and/or present a certificate for use with certificate login. Hopefully, this won’t be too far off. Fortunately, I don’t use this login style very often.

HOWTO Add btnx repository to sources

Olli Salonen made a PPA on Launchpad yesterday, following my request for btnx in a PPA.

There are two ways to get the repository configured: the GUI way and the command line way. I think the command line way is a little quicker, but I’ll give you both. Remember, if you are not running Hardy, you will need to change all instances of hardy throughout these instructions to feisty or gutsy, whichever you are using. Olli did packages for all three versions. If you don’t know which you’re running, go to System > About Ubuntu and read the window that spawns. Your version will be in there somewhere.

First the command line way.

echo -e "deb http://ppa.launchpad.net/daou/ubuntu hardy main\ndeb-src http://ppa.launchpad.net/daou/ubuntu hardy main" | sudo tee /etc/apt/sources.list.d/btnx.list
sudo apt-get update && sudo apt-get install btnx btnx-config

Then, I’d recommend using btnx-config from Applications > System Tools > btnx to configure the tool. You could also do gksu btnx-config at the command line to bring it up.

Next, the GUI way.

If you already have btnx installed, go to System > Administration > Software Sources. Go to the Third Party Software tab. Click +Add and paste the line for each of the two APT lines: deb http://ppa.launchpad.net/daou/ubuntu hardy main and deb-src http://ppa.launchpad.net/daou/ubuntu hardy main. When you click Close, it will ask if you want to reload the sources. Confirm the reload.

If you do not already have btnx installed, go to System > Administration > Synaptic Package Manager. Go to Settings > Repositories and follow the above instructions. One the list finishes reloading, Search for “btnx” and the two packages will be shown in the main screen. Click each to mark it for installation, then click Apply. When it’s finished, you can access btnx-config through Applications > System Tools > btnx from the top panel.

Check out my prior updates on btnx for more information, including how to compile btnx and btnx-config from source.

HOWTO Update Twitter from the console or GUI

I’ve gone and added to the script, checking for errors and making it more slick.

Check it out at twitter-gx or read the code contained herein.


#!/bin/bash
#@Name: twitter-gx
#@Author: Colin Dean <cad@cad.cx>
#@URL: http://cad.cx/twitter
#CHANGE THESE
EMAIL=you@yours.com
PASSWORD=lolz
#PATHS
ZENITY=/usr/bin/zenity
CURL=/usr/bin/curl
ICON=/usr/share/pixmaps/gnome-irc.png
#can someone suggest a better icon?
#STRINGS--someone want to localize?
WHAT="What are you doing? "
SORRY="Sorry, that was too long."
UPDATED="Tweet submitted:"
FAILED="Tweet failed. Check output for why."

CURL_MISSING="curl was not found at ${CURL}. Please install curl."
ZENITY_MISSING="zenity was not found at ${ZENITY}. Please install zenity."
#-------Woe to those who make changes below unless they know what it does------#

#META
NAME="twitter-gx"
VERSION="1.0"
URL="http://cad.cx/twitter/twitter.xml"
#functions galore
function check_for_deps {

#I'm not going to bother checking for awk. Does any sane distro omit it?
  if [ ! -x ${CURL} ]; then

    CURL=`which curl`
    if [ "$?" = 1 ]; then

      warn_user "${CURL_MISSING}"
      exit 1
    fi
  fi

  if [ ! -x ${ZENITY} ]; then

    ZENITY=`which zenity`
    if [ "$?" = 1 ]; then

      warn_user "${ZENITY_MISSING}"
      exit 1
    fi
  fi

}

function getinput {
  if [ ${TERM} = "xterm" ]; then echo -n "${WHAT}"; read TWEET
    else TWEET=$(${ZENITY} --entry --text="${WHAT}" --entry-text="${1}")

  fi
}

function check_length {
  TWEETLENGTH=$(echo -n "${TWEET}" | wc -m)

  if [ ${TWEETLENGTH} -gt 140 ]; then

    warn_user "${SORRY} (${TWEETLENGTH} > 140)"
    getinput "${TWEET}"

    check_length
  fi
}

function warn_user {
  if [ ${TERM} = "xterm" ]; then echo "${1}"

    else ${ZENITY} --warning --text="${1}"
  fi

}

function urlencode () {
#one day, I will understand awk
#got this from somewhere
  echo "$@" | awk '

  BEGIN {
   # with inspiration from Heiner Steven and Rick Richardson
      split ("1 2 3 4 5 6 7 8 9 A B C D E F", hexit, " ")
      hexit [0] = 0 # setup the hex values we will use..
      for (i = 1 ; i <= 255 ; ++i) ord[ sprintf ("%c", i) "" ] = i + 0

    } {
      encoded = ""
      for (i = 1 ; i <= length ($0) ; ++i) {
        c = substr ($0, i, 1)
        if ( c ~ /[a-zA-Z0-9.-]/ ) { # allow only basic chrs
          encoded = encoded c

        } else { # encode everything else..
          lo = ord[c] % 16
          hi = int (ord[c] / 16);
          encoded = encoded "%" hexit [hi] hexit [lo]
        }

      }
#printf encoded
    }
  END {
    printf ("%s", encoded)
  }

'
}

function submit_tweet {
  OUTFILE="/tmp/twitter_response-`date +%Y%m%d%H%M%S`.txt"

  ${CURL} -s \
       -u ${EMAIL}:${PASSWORD} \
       -o ${OUTFILE} \
       -d status="$(urlencode "${TWEET}")" \
       -H "X-Twitter-Client: ${NAME}" \
       -H "X-Twitter-Client-Version: ${VERSION}" \
       -H "X-Twitter-Client-URL: ${URL}" \
       http://twitter.com/statuses/update.xml

}

function notify_user {
  if [ "${1}" = "success" ]; then

    TERM_MESSAGE="${UPDATED} ${TWEET}"
    GUI_MESSAGE="${UPDATED}\n\n${TWEET}"

    ICON_STR="--window-icon=${ICON}"
  fi
  if [ "${1}" = "failed" ]; then

    TERM_MESSAGE="${FAILED}"
    GUI_MESSAGE="${FAILED}"
    ICON_STR=""

  fi

  if [ ${TERM} = "xterm" ]; then echo "${TERM_MESSAGE}"

    else
      exec 3> >(${ZENITY} --notification --listen ${ICON_STR})

      echo "message: ${GUI_MESSAGE}" >&3
      sleep 10
      exec 3>&-
  fi

}

TWEET=$@ #see if it was supplied on the command line
if [ "${TWEET}" = "-v" ]; then echo "${NAME} ${VERSION}" && exit; fi

check_for_deps
if [ -z "${TWEET}" ]; then getinput; fi #if it wasn't, prompt for it

check_length #make sure it's less than 140 characters
submit_tweet #submit it since we got past the check

if [ "$?" == 0 ]; then notify_user success && exit 0;

else notify_user fail && exit 1; fi

HOWTO Write a script to update Twitter from Linux

I just signed up for Twitter as colindean. I don’t know what use I’ll have for it, as I’m not one who is much for microblogging or partying.

Anyway, the API caught my eye, and after having read Wayne’s post at Fsckin w/ Linux regarding Twitter clients for Linux, I decided to roll my own rather than use what’s out there. I wanted something simple and bashful.


#!/bin/bash
EMAIL=youremail@yourdomain.com
PASSWORD=yourpassword

WHAT="What are you doing? "
SORRY="Sorry, that was too long."
UPDATED="Tweet submitted:"

function getinput {
  if [ ${TERM} = "xterm" ]; then echo -n "${WHAT}"; read TWEET
    else TWEET=$(zenity --entry --text="${WHAT}" --entry-text="${1}")
  fi
}

function check_length {
  TWEETLENGTH=$(echo -n "${TWEET}" | wc -m)
  if [ ${TWEETLENGTH} -gt 140 ]; then
    warn_user
    getinput ${TWEET}
    check_length
  fi
}

function warn_user {
  if [ ${TERM} = "xterm" ]; then echo "${SORRY}"
    else zenity --warning --text="${SORRY}"
  fi
}
function submit_tweet {
  curl -u ${EMAIL}:${PASSWORD} \
       -d status="${TWEET}" \
       http://twitter.com/statuses/update.xml \
  > /dev/null
}

TWEET=$@ #see if it was supplied on the command line
if [ -z "${TWEET}" ]; then getinput; fi #if it wasn't, prompt for it
check_length #make sure it's less than 140 characters
submit_tweet #submit it since we got past the check

if [ ${TERM} = "xterm" ]; then echo "${UPDATED} ${TWEET}"
  else
    exec 3> >(zenity --notification --listen --window-icon=/usr/share/pixmaps/gnome-irc.png)
    echo "message: ${UPDATED}\n\n${TWEET}" >&3
    sleep 10
    exec 3>&-
fi

Just replace the EMAIL and PASSWORD variables and drop it into a directory in your $PATH. You can add it to the panel, too—it will detect if it’s been executed at a terminal or from the panel or other GUI element. It could also very easily be internationalized.

Let me know what you think of this script—it’s 4:00 am and I’m about to pass out.

Sorry, that one line might overflow the box on slim resolutions. I’ll get that fixed one of these days. Update: That was an easy fix. Added overflow: auto; to the codeblock CSS.

HOWTO Run a game or other program on another display

For some reason probably related to Compiz-Fusion, I could not get Warsow working just now. When I started it, my mouse would be locked in the center of the screen. I had four virtual desktops going within Compiz, so I figured that it was somewhat related.

Rather than figure out the bug or close everything I had open, I decided to simply start another X server to handle Warsow.

I did this with startx ./warsow -- :1. I had to modify /etc/X11/Xwrapper.config and change where it says “console” to “anyone” before it would work, though.

This can be done for any program or game, but it’s best suited for those that occupy the whole screen.

In order to switch back to the regular desktop, hit CTRL+ALT+F7. To go back to your game, hit CTRL+ALT+F8. This is useful for switching between a game and work when it’s not your turn or you’re waiting for a long respawn. In fact, I wrote this post switching between Firefox on :0 (F7) and Warsow on :1 (F8).

Oh how I love the things I can do on Ubuntu that I could never do on Windows.

HOWTO Encode a video for an LG VX-8300 phone using FFmpeg

This script might work for other phones, as well. I only have access to an LG VX-8300. Presumably, this would work on all phones newer than it.

#!/bin/bash
echo "Encoding ${1}..."
ffmpeg -i "${1}" -acodec aac -ab 64K -ac 1 -ar 22050 \
                 -vcodec mpeg4 -s qcif -r 15 \
                 "${1}.3gp"

This works perfectly for me, reducing certain YouTube videos to something portable ;-)

HOWTO: Astronomy Picture of the Day for GNOME

Astronomy Picture of the Day is a really neat page which is generated daily by NASA. It shows a single picture captured by some NASA-affiliated person and some text to describe it.

These pictures are perfect for desktop backgrounds. There’s a program to automatically set it as the background for Windows, but we Linux, or more specifically, GNOME, users can do it in a simple script.

Drop this script somewhere on your system and create a cron schedule with crontab -e for it. The cron lines are in the script. I’d recommend the four hour intervals if you don’t keep your computer on all the time, or the twelve or once-a-day intervals if you do.

Oh, and you might need to install cron. Gutsy doesn’t have it by default, so you can do it through Synaptic or using sudo apt-get install cron at a command line.


#!/bin/bash
#Filename: apodwallpaper
#Location: ${HOME}/.bin
#Purposes: Downloads NASA Astronomy Picture of the Day and displays it as the
#          GNOME background 
#Author(s): acvwJosh of Ubuntu Forums, modified by Colin Dean <http://cad.cx>

#add the following line to your crontab if you want to run this hourly
#10   *  *   *   *     apodwallpaper

#add this line if you want to run it every four hours
#10 0,4,8,12,16,20 * * * apodwallpaper

#add this line if you want to run it every twelve hours
#10 0,12 * * * apodwallpaper

#add this line if you want to run it daily 
#10 0 * * * apodwallpaper

#don't forget to put this script in your $PATH.
#I usually add ${HOME}/.bin to my path in .bash_profile and put my scripts there

#change this if you want the image to be in a different directory
FILENAME=apodwallpaper
APODWALLPAPER=${HOME}/.${FILENAME}

mkdir -p ${APODWALLPAPER} && cd ${APODWALLPAPER}

# download image from apod site
wget -A.jpg -R.txt -r -l1 --no-parent -nH http://antwrp.gsfc.nasa.gov/apod/astropix.html

# move image from obscure folder to main folder, rename image
find ./apod -name "*.jpg" | while read line ; do
mv "$line" "${FILENAME}.jpg"
done

# set image to wallpaper
gconftool-2 -t string -s /desktop/gnome/background/picture_filename "blank.jpg"
gconftool-2 -t string -s /desktop/gnome/background/picture_filename \
                         "${APODWALLPAPER}/${FILENAME}.jpg"
gconftool-2 -t string -s /desktop/gnome/background/picture_options "zoom"

#get rid of cruft
rm -rf apod robots.txt

There’s a thread about this functionality at Ubuntu Forums entitled, APOD? anyone.

HOWTO: Fixing gnome-vfs ssh support in Firefox

In theory, the package firefox-gnome-support handles GNOME’s Virtual File System URLs. However, out-of-the-box, it lacks support for the ssh handler used when connecting to something via ssh.

To fix this, go to about:config and find the key called network.gnomevfs.supported-protocols. Append ;ssh:, thus changing it to smb:,sftp:,ssh:. It will magically work!