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

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.