シェルスクリプトでFlickrに画像をアップロードする

#!/bin/zsh

CURRENT_DIR=$(cd $(dirname $0);pwd)
. $CURRENT_DIR/../conf/config

TITLE=$1
DESC=$2
TAGS=$3
PHOTO=$4

LANG=ja_JP.UTF-8
API_URL="http://api.flickr.com/services/upload"
METHOD="POST"
NONCE=`uuidgen | tr -d '-' | shasum | awk '{print $1}'`
TIMESTAMP=`date +%s`

function url_encode() {
    perl -MURI::Escape -lne 'print uri_escape($_, "^0-9A-Za-z\-._~")';
}

BASE="$METHOD&`echo $API_URL | url_encode`&"$(printf "description=%s&oauth_consumer_key=%s&oauth_nonce=%s&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%s&oauth_token=%s&tags=%s&title=%s" "`echo "$DESC" | url_encode`" $OAUTH_CONSUMER_KEY $NONCE $TIMESTAMP $OAUTH_TOKEN "`echo "$TAGS" | url_encode`" "`echo "$TITLE" | url_encode`" | url_encode)
SIGNATURE=`echo -n "$BASE" | openssl sha1 -hmac "$OAUTH_CONSUMER_SECRET&$OAUTH_TOKEN_SECRET" -binary | openssl base64 | url_encode | sed 's/%20/+/g'`

HEADERS=`printf "Authorization: OAuth oauth_consumer_key=\"%s\", \"oauth_nonce=\"%s\", oauth_signature=\"%s\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"%s\", oauth_token=\"%s\"" $OAUTH_CONSUMER_KEY $NONCE $SIGNATURE $TIMESTAMP $OAUTH_TOKEN`
curl --request "$METHOD" "$API_URL" --header "$HEADERS" -F "photo=@$PHOTO" -F "title=$TITLE" -F "description=$DESC" -F "tags=$TAGS"

OAuth の仕様には詳しくないけど、Flickr OAuth API は NONCE の値が呼び出し毎に違わないと怒られました。
あと、Authorization Header にちゃんとダブルクォートを使わないと認識してくれないです。厳しい。
それと signature のソース文字列は、値単位でそれぞれ二重URLエンコードしないといけないんですねー。知らなかった。

使い方

$ ./upload.sh "タイトル" "description" "タグA タグB" /Public/Photos/IMG2011202.png
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok">
<photoid>1000000</photoid>
</rsp>

最後の curl に --trace-ascii、--verbose など付ければ通信内容が分かるので、トレースしたい場合はこれを。
それと大前提なんですが、4行目で OAuth パラメータを読み込んでいるので、事前に認証済みの設定を書いた config を置いてください。
こんなファイルです。

$ cat ../conf/config
OAUTH_TOKEN=******
OAUTH_TOKEN_SECRET=******
OAUTH_CONSUMER_KEY=******
OAUTH_CONSUMER_SECRET=******
USER_NSID=******
USERNAME=******
広告を非表示にする