- To: slug <slug@xxxxxxxxxxx>
- Subject: [SLUG] tweet from bash using your fave editor...
- From: Daniel Bush <dlb.id.au@xxxxxxxxx>
- Date: Tue, 25 Aug 2009 13:12:23 +1000
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:date:message-id:subject :from:to:content-type; bh=UYq+n9SoaVUpkFBwETBfLqgZIk8aLc+jHGqr8VQuIiM=; b=JwDkTtLTHPslmyA7y70DEM4uWxjkTq1sZpTKfh+dj+SdmxmygK0g8Hb5QgHhPqs5ZK U0nDoi8Db+uhKNVZB4v7v6l3FwyVbeKEwx+63AuiMHKTC3GwmmNA9huAIATHTorgFovl Mb1IPQQuikM8QUDi9Angb0PrvN8sCf0eoMgTA=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; b=vaH5xu4MtfUxHTLXqNZv+5TiMQVFmdJM3Uedd/8yCiXy/imaYd4YvDDpqJYQbi7kFi joakQ7kEgSicXnxRRA4DWzDZREwbDRQtCwE5xAfMwU6n8FYZoUGETmL6eKm3jmBmkUGR z9JnDsaC94w09IQsx+T5yasg9cmWb+fTjNYO0=
There's life in the old shell yet. Now you can use bash and your favorite
text editor to let everyone know what you had for breakfast this morning...
Put it on cron and ... um, well I dunno, use it kind of like a deadman's
tweet if something goes wrong?
Just edit the variables at the top of the file to taste, make sure MY_HOME
and ARCHIVE exist, save and then source it into your current shell
% . twitter.sh
% h # For help
Try
% post
to test it.
% edit # To edit a message
% send # To send edited message
'send' is a bit more clever, launches your editor and breaks up long posts
into the 140 char limit (uses gnu's 'fold' utility for the black magic bit).
'send.reverse' reverses the lines which has the effect of making long
broken-up posts read top to bottom on the twitter website but probably
breaks some basic idea about how you're supposed to use it or something...
Here's the file (half of which is the help message):
--
# Requirements: curl, less, fold (gnu coreutils)
# Variables here:
MY_HOME=/home/danb/twitter
TMP_FILE=$MY_HOME/tmp_file.txt
# File you use to write your tweets.
TEST_FILE=$MY_HOME/lorem.para1
# For testing 'send'. See test.* functions.
USERNAME=twitter_username
PASSWORD=twitter_password
COOKIEJAR=$MY_HOME/cookie.txt
ARCHIVE=$MY_HOME/archive/previous
# File to dump previous tweets.
EDITOR=vim
# Editor shouldn't detach from the shell.
POST_URL=https://twitter.com/statuses/update.xml
# The url you post your updates to.
# I use https, probably should be http.
STATUS_URL=http://twitter.com/statuses/user_timeline
# Used to fetch your tweets or someone else
# STATUS_URL.format # you
# STATUS_URL/username.format # someone else
FOLLOWING=$MY_HOME/following.db
# Text file listing people you follow.
# See h() below.
DEFAULT_FORMAT=xml
# Default format of output from twitter REST api.
# Options are: xml|json|rss|atom
delete_blank_lines='sed -e /^$/d'
# Deletes blank lines which are of no use to us.
html_entities='sed -e s/</\</g;s/>/\>/g'
# Twitter api will convert '>','<' to html entities which
# count towards 140 char limit. We do it instead.
xml_filter='egrep <text>|<created_at>'
h() {
less <<-EOF
Twitter via the REST API
See:
http://apiwiki.twitter.com/Things-Every-Developer-Should-Know
See point 8.
http://www.sakana.fr/blog/2007/03/18/scripting-twitter-with-curl/
See "status update" for normal twitter posting.
Functions:
go
last - edit your tmp_file without sending anything
browser - open twitter in firefox
recent - view recent tweets in ARCHIVE
format [format]
Display current output format that will be requested from twitter.
Options: xml|json|atom|rss
If [format] given, set format to this.
Use with 'status' or 'checkon' to get your twitter posts in various
formats. You could pipe json into javascript, ruby, python etc...
Current output format from twitter is: $DEFAULT_FORMAT
status
Get your twitter posts in xml
checkon nickname
Get status on someone else.
You first need to add someone to the FOLLOWING file.
See 'following' herein.
following
Edits FOLLOWING; a text file listing people you follow.
Format:
nickname:username
nickname must be unique; is your shorthand for username
which is the name used by twitter.
edit
edit message
Also use: 'go last'
send
Send a message.
Long messages will be broken up to meet the 140 char limit.
Currently <,> will be converted to html entities.
Uses 'post'.
send.reverse
Reverses the lines you are sending which has the effect of making long
broken-up posts read from top to bottom on the twitter website.
Uses 'tac' instead of cat which will reverse lines.
post "your message"
If no message given, post will post a test message to twitter for you to
check.
NOTE: 'post' doesn't check the 140 character limit, or html entities
etc.
In general, use 'send' to post your stuff.
test.send
test.send.dry
Send TEST_FILE to twitter.
'dry' doesn't send to twitter; just prints output
test.send.reverse
test.send.reverse.dry
Test send.reverse.
test.entities
Test html entities.
EOF
}
go() {
case "$1" in
last) $EDITOR $TMP_FILE;;
browser) firefox http://twitter.com;;
recent) less $ARCHIVE;;
*) cd $MY_HOME ;;
esac
}
edit() {
go last
}
format() {
case "$1" in
atom) DEFAULT_FORMAT=atom;;
rss) DEFAULT_FORMAT=rss;;
xml) DEFAULT_FORMAT=xml;;
json) DEFAULT_FORMAT=json;;
"") echo "Current format is: $DEFAULT_FORMAT";;
*) echo "Don't know this format." ;;
esac
}
status() {
test -n "$1" && format="$1" || format=$DEFAULT_FORMAT
curl --basic --user $USERNAME:$PASSWORD \
$STATUS_URL.$format | less
}
following() {
$EDITOR $FOLLOWING
}
checkon() {
test ! -f $FOLLOWING && echo "Need to setup $FOLLOWING." \
&& return 1
format=$DEFAULT_FORMAT
nickname=$1
test -z "$nickname" && echo "Need a nickname." && return 1
line=$(grep '\<'$nickname'\>' $FOLLOWING)
test -z "$line" && echo "Don't know '$nickname'." && return 1
username=${line/#*:/}
curl $STATUS_URL/$username.$format | less
}
post() {
test -z "$1" && status="cURL test!" || status="$1"
curl --basic --user $USERNAME:$PASSWORD \
--data status="$status" \
$POST_URL
return $? # If http error, curl returns >0
}
send() {
testing=no
order=cat
file=$TMP_FILE
while true; do
test -z "$1" && break
case "$1" in
# Don't send to twitter.
dry) file=$TEST_FILE; testing=dry ;;
# Send to twitter.
test) file=$TEST_FILE; testing=yes ;;
reverse) order="tac";;
esac
shift
done
if ask $file; then
echo "POSTing...."
cat $file | $html_entities | fold -s -b -w 140 $file | \
$delete_blank_lines | $order | \
while read line; do
case "$testing" in
dry) echo $line; continue ;;
*)
if post "$line"; then
echo "(posted a line!)"
else
echo "(might have been an error posting this line: $line)"
fi
;;
esac
done;
test "$testing" = "no" && (echo '-'; date; cat $file) >>$ARCHIVE
else
echo "NOT posting!"
fi
}
send.reverse() {
send reverse
}
ask() {
echo '--------------'
cat $1
echo '--------------'
echo -n "Post to twitter? [y] "
read r
case "$r" in
n*|N*) return 1;;
*) return 0;;
esac
}
test.send() {
send test
}
test.send.dry() {
send dry
}
test.send.reverse() {
send test reverse
}
test.send.reverse.dry() {
send dry reverse
}
test.entities() {
echo "><" | $html_entities
echo 'should be: ><'
}
-- end of file
--
Daniel Bush