Friday, February 06, 2015

All the Info, None of that Pesky Reading - Adding Audio Widgets to X-Windows

Slowly but surely, I'm optimizing my new Linux environment. So far, I'm loving ratpoison as a front end experience. Sure, I love the clutter free experience and fast keyboard access, but I'm also enjoying how easy it is to configure and script. It's definitely a classic Unix tool that shines because it works well with other tools. One catch though I've found is that some of that "clutter" that ratpoison dispenses with does occasionally come in handy. For example, having a clock visible is often useful.

Ratpoison has this particular need covered with with the time command. Hitting Control-t a prints the current and date in the upper right hand corner. If you leverage ratpoison -c "echo SOMETEXT" you can actually convince ratpoison to display any message you want.

But c'mon, this is Linux. We've got to be able to better than that. So I decided this was the perfect use-case to leverage text-to-voice capability that comes with a typical Linux box. Combined with ratpoison's key shortcuts, I've now got quick access to all sorts of pieces of information. Best of all, my fingers don't have to leave the keyboard and my eyes don't have to search out a new location on the screen.

I've put these scripts together over the last couple days, with each one taking about 10 minutes to write. Here's the relevant lines from my .ratpoisonrc, which includes the list of scripts:

definekey top s-t exec saytime
definekey top s-f exec sayforecast
definekey top s-h exec sayheadlines
definekey top s-i exec sayinbox

Note that s-f stands for hitting the "Super" key followed by "f." On my keyboard hitting the Windows key is the equivalent of the Super key. Because, by default, nothing is bound to the Windows key, I've got the entire keyboard open to assign scripts to. Whooo!

Now onto the scripts:

saytime - Actually, I didn't write this script. It comes with festival and just works out of the box.

sayforecast - To hear the current weather in my location I query openweathermap.org. They provide a JSON API which didn't require any sort of sign up. I leveraged the jq command line tool, which makes manipulating JSON from the command line a breeze. This script, like all the rest, ends with sending text to festival --tts. Festival is the engine that does all the heavy lifting of converting text to speech.

#!/bin/bash

##
## Say the forecast outloud
##
json=`curl -s 'http://api.openweathermap.org/data/2.5/weather?q=Arlington,VA,USA&units=imperial'`
description=`echo $json | jq '.weather[0].description'`
temp=`echo $json | jq .main.temp | sed 's/[.].*//'`


echo "It is currently $temp degrees, with $description in Arlington" | festival --tts

sayheadlines - This guy reads off the top 10 latest headlines from CNN. This could be adapted to read off any RSS feed, I suppose. I've been less than impressed at the top stories CNN has mentioned, so perhaps I need to find a better new source. Still, I'll often go the whole day without checking the news. Often some horrific (or very occasionally terrific) event will happen and I'll be totally clueless until Shira arrives home. Not any more.

#!/bin/bash

##
## Announce CNN headlines
##

URL=http://rss.cnn.com/rss/cnn_us.rss

buffer=/tmp/headlines.$$

echo "CNN top headlines." >> $buffer
index=1
curl -s $URL | grep '<title>' |grep -v 'CNN.com' | head | 
  while read headline ; do
    clean=`echo $headline | sed  -e 's|<title>||' -e 's|</title>||'`
    echo "$index: $clean." >> $buffer
    index=`echo $index + 1 | bc`
  done

cat $buffer | festival --tts
rm $buffer

sayinbox - My first thought was that writing a script to read off my Gmail was going to require some sort of network hacking. Not so. All you need is this one trick: Google provides an RSS feed for your inbox. Now when a million dollar offer comes in from a Nigerian Prince comes in, I can get right on it.

#!/bin/bash

##
## Inspired by:
## http://www.commandlinefu.com/commands/view/3386/check-your-unread-gmail-from-the-command-line
##

USER='XXXXXXXXX'
PASS='XXXXXXXXX'

buffer=/tmp/email.$$
(echo '<?xml version="1.0" encoding="UTF-8"?>' ;
 curl -u "$USER:$PASS" -s "https://mail.google.com/mail/feed/atom" |
   sed -e 's|<?xml version="1.0" encoding="UTF-8"?>||') | xmllint -format - > $buffer

num_messages=`grep '<entry>' $buffer | wc -l`
first_subject=`grep '<title>' $buffer | head -2 | tail -1 | sed -e 's|<title>||' -e 's|</title>||'`

if [ $num_messages -eq 0 ] ; then
  message="You have no new messages"
else
  message="There are $num_messages new messages in your inbox. The subject of the most recent message is: $first_subject"
fi

echo $message | festival --tts 
rm -f $buffer

Of course, this is just the tip of the iceberg. Over time, I assume I'll add more scripts as I think of additional bits of info I want quick access to. Linux certainly makes this easy enough to do.

Any suggestions for what I should script next?

No comments:

Post a Comment