この記事は古いです
ここを開いて一番上に出てきた記事に最新版が貼ってあります、たぶんーーーーーーーーーー
だいぶソースを整理した
wgetとcurlの切り替え対応
OpenWrtではiconvが無いので投稿のみ
一時ファイルはrep.sedだけになりました
一度目の起動時にPIN等の取得を試みます
タイムライン表示
$ shtter.sh
投稿
$ shtter.sh update "foobar"
Fedora(12 x86_64)とOpenWrt(KAMIKAZE 8.09.2)で動作を確認しています
Fedoraで使用する場合はwgetをインストールしてください
OpenWrtで使用する場合はopenssl-utilとcurlをインストールして
HTTP_GETとHTTP_POSTをcurlに切り替えてください
使ってるコマンド (全部あるか確認してください)
dd md5sum cut date echo sed grep sort uniq hexdump rm printf iconv openssl read wget/curl
shtter.sh (last update 2010/05/22)
This script lisence is GPL.
#!/bin/sh
CKEY="U3DhP7CpPx0bNCzdAFShg"
CSECRET="eAQ13OTo7BhroXQc5dA5oOqEuXhAf7yABVKpkbR7so"
AKEY=""
ASECRET=""
HTTP_GET="wget -q -O -"
HTTP_POST="wget -q -O - --post-data"
#HTTP_GET="curl -s"
#HTTP_POST="curl -s --data"
TMPDIR="/tmp"
PREFIX=""
SUFFIX=" http://bit.ly/dsKezn #shtter"
GenerateNonce()
{
dd if=/dev/urandom bs=1024 count=1 2>/dev/null | md5sum | cut -c1-32
}
GetTimeStamp()
{
date +%s
}
Encode()
{
echo "$@" | sed 's/./\0\n/g' | grep '[^-._~0-9a-zA-Z]' | sort | uniq | while read l
do
if [ "$l" == "" ]; then l=" "; fi
HEX="`echo -n \"$l\" | hexdump -e '16/1 "%02X" "\n"'`"
if [ "$l" == "/" ]; then l="\/"; fi
echo "s/$l/$HEX"
done | sed 's/ *$//; s/\([0-9A-Z]\{2\}\)/%\1/g; s/$/\/g/' >"$TMPDIR/rep.sed"
echo "$@" | sed -f "$TMPDIR/rep.sed"
rm "$TMPDIR/rep.sed"
}
Decode()
{
HEX="`echo -e "$@" | sed 's/[0-9]\+;/\n\0\n/g' | sed '/^[0-9]\+;$/!d; s/[]//g' | sort | uniq`"
HEX="`echo -e \"$HEX\" | while read l; do echo -n \"$l\" | hexdump -e '8/1 "%02x00"'; printf '%04x\n' "$l"; done`"
HEX="`echo -e \"$HEX\" | sed 's/ 00//g; s/^/73002f0026002300/; s/\(..\)\(..\)$/3b002f00\2\12f0067000a00/'`"
HEX="`echo $HEX | sed 's/ //g; s/../\\\x\0/g'`"
printf "$HEX" | iconv -f UTF-16 -t UTF-8 >"$TMPDIR/rep.sed"
echo -e "$@" | sed -f "$TMPDIR/rep.sed"
rm "$TMPDIR/rep.sed"
}
GenerateHash()
{
EURL="`Encode $2`"
EPARAM="`Encode $3`"
QUERY="$1&$EURL&$EPARAM"
HASH="`echo -n \"$QUERY\" | openssl sha1 -hmac \"$CSECRET&$ASECRET\" -binary | openssl base64`"
Encode "$HASH"
}
GetRequestToken()
{
URL="http://twitter.com/oauth/request_token"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=`GenerateNonce`&oauth_signature_method=HMAC-SHA1&oauth_timestamp=`GetTimeStamp`&oauth_token=&oauth_version=1.0"
HASH="`GenerateHash \"GET\" \"$URL\" \"$PARAM\"`"
RTOKEN="`$HTTP_GET \"$URL?$PARAM&oauth_signature=$HASH\"`"
if [ "$RTOKEN" == "" ]; then
echo "can not get request token" >&2
exit 1
fi
RKEY="`echo \"$RTOKEN\" | sed 's/.*oauth_token=\([^&]*\).*/\1/'`"
RSECRET="`echo \"$RTOKEN\" | sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`"
echo "open this url in your browsser and input pin" >&2
echo "http://twitter.com/oauth/authorize?oauth_token=$RKEY" >&2
echo -n "pin > " >&2
read PIN
echo "$RKEY $RSECRET $PIN"
}
GetAccessToken()
{
RKEY="$1"
RSECRET="$2"
PIN="$3"
URL="http://twitter.com/oauth/access_token"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=`GenerateNonce`&oauth_signature_method=HMAC-SHA1&oauth_timestamp=`GetTimeStamp`&oauth_token=$RKEY&oauth_verifier=$PIN&oauth_version=1.0"
HASH="`GenerateHash \"GET\" \"$URL\" \"$PARAM\"`"
ATOKEN="`$HTTP_GET \"$URL?$PARAM&oauth_signature=$HASH\"`"
if [ "$ATOKEN" == "" ]; then
echo "can not get access token" >&2
exit 1
fi
AKEY="`echo $ATOKEN | sed 's/.*oauth_token=\([^&]*\).*/\1/'`"
ASECRET="`echo $ATOKEN | sed 's/.*oauth_token_secret=\([^&]*\).*/\1/'`"
sed -i "1,/^AKEY/ s/^\(AKEY=\).*/\1\"$AKEY\"/" "$0"
sed -i "1,/^ASECRET/ s/^\(ASECRET=\).*/\1\"$ASECRET\"/" "$0"
}
GetTimeLine()
{
URL="http://api.twitter.com/1/statuses/home_timeline.xml"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=`GenerateNonce`&oauth_signature_method=HMAC-SHA1&oauth_timestamp=`GetTimeStamp`&oauth_token=$AKEY&oauth_version=1.0&status="
HASH="`GenerateHash \"GET\" \"$URL\" \"$PARAM\"`"
XML="`$HTTP_GET \"$URL?$PARAM&oauth_signature=$HASH\"`"
if [ "$XML" == "" ]
then
echo "can not get TimeLine" >&2
exit 1
fi
XML="`echo $XML | sed 's/<text>/\n\0/g; s/<\/screen_name>/\0\n/g' | sed -n '/^<text>.*<\/screen_name>$/!d; s/<text>\([^<]*\).*<screen_name>\([^<]*\).*/\2: \1/; p'`"
Decode "$XML"
}
UpdateTimeLine()
{
TWEET="`Encode \"$PREFIX$@$SUFFIX\"`"
if [ "$TWEET" == "" ]
then
echo "can not decode tweet" >&2
exit 1
fi
URL="http://api.twitter.com/1/statuses/update.xml"
PARAM="oauth_consumer_key=$CKEY&oauth_nonce=`GenerateNonce`&oauth_signature_method=HMAC-SHA1&oauth_timestamp=`GetTimeStamp`&oauth_token=$AKEY&oauth_version=1.0&status=$TWEET"
HASH="`GenerateHash \"POST\" \"$URL\" \"$PARAM\"`"
XML="`$HTTP_POST \"$PARAM&oauth_signature=$HASH\" \"$URL\"`"
if [ "$XML" == "" ]
then
echo "can not post tweet" >&2
exit 1
fi
}
if [ "$AKEY" == "" -o "$ASECRET" == "" ]
then
RTOKEN="`GetRequestToken`"
GetAccessToken $RTOKEN
else
ARG="$1"
shift 1
case "$ARG" in
init)
sed -i "1,/^AKEY/ s/^\(AKEY=\).*/\1/" "$0"
sed -i "1,/^ASECRET/ s/^\(ASECRET=\).*/\1/" "$0"
;;
update)
UpdateTimeLine "$@"
;;
*)
GetTimeLine
;;
esac
fi
Hi!
返信削除I think this is really cool-I'm trying to use it on my wireless router. It's working..somewhat, not completely (I guess it might be related to http vs https).
If possible, it would be cool if you could manually translate this post into English.
Cheers
Dan
Hi Dan.
返信削除I was thought that nobody is using it.
Thank you for using this app.
About https had been simply forgotten... :P
When I can take time, research information about https and update this script.
I hope that can get across my English.
Bye.
I can't get it to work. I'm very frustrate. I get a "sh: closing paren expected" and I don't know where those parenthesis are. =/
返信削除Hi Massayoshi.
返信削除Sorry, please try bash or ash.
このコメントは投稿者によって削除されました。
返信削除nice app
返信削除Hello! icXu
返信削除Thanks!
Should I escape double quote char in the line 70 etc.?
返信削除oops. please ignore the previous comment.
返信削除Hi, This works very well for getting timelines, and seems to do the oauth properly for that, but I can't get it to post an update at all. I just get "Could not authenticate with OAuth." back, in a 401. I can't for the life of me work out what's different between the get and the post...
返信削除Mmm I cannot find a way to install iconv from the latest openwrt sources.
返信削除Any suggestion?
Hi Enrique.
返信削除Thank you for your comment.
But I'm not sure.
I'm not using for getting timeline this script on openwrt.
I think you can build from source.
http://downloads.openwrt.org/sources/libiconv-1.11.1.tar.gz
Download this file and extract it.
Move in to extracted directory.
and execute ./configure && make
Maybe you can get binary src/iconv_no_i18n.
素晴らしいスクリプト、ありがとうございます。とても重宝しております。
返信削除シェルだけで Twitter クライアントってできるのですね。
以前から shtter を活用させていただいておりました。ありがとうございます。
返信削除Twitter API 1.0 が完全停止され使えなくなったのですが、
試したところ、Twitter API 1.1 対応として、下記のパッチでプログラムを修正し、認証しなおせば、投稿できるようになりました。
(ただし、取得したタイムラインのパースは行っていないです。)
API 1.1 対応のお役に立てば幸いです。
70,74c70,75
< URL="http://twitter.com/oauth/request_token"
< PARAM="oauth_consumer_key=$CKEY&oauth_nonce=`GenerateNonce`&oauth_signature_method=HMAC-SHA1&oauth_timestamp=`GetTimeStamp`&oauth_token=&oauth_version=1.0"
< HASH="`GenerateHash \"GET\" \"$URL\" \"$PARAM\"`"
<
< RTOKEN="`$HTTP_GET \"$URL?$PARAM&oauth_signature=$HASH\"`"
---
> URL="https://api.twitter.com/oauth/request_token"
> NONCE="`GenerateNonce`"
> TIMESTAMP="`GetTimeStamp`"
> PARAM="oauth_callback=&oauth_consumer_key=$CKEY&oauth_nonce=$NONCE&oauth_signature_method=HMAC-SHA1&oauth_timestamp=$TIMESTAMP&oauth_version=1.0"
> HASH="`GenerateHash \"POST\" \"$URL\" \"$PARAM\"`"
> RTOKEN="`wget -q -O - --post-data=\"\" --header=\"Authorization: OAuth oauth_nonce=\"$NONCE\", oauth_callback=\"\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"$TIMESTAMP\", oauth_consumer_key=\"$CKEY\", oauth_signature=\"$HASH\", oauth_version=\"1.0\"\" $URL`"
116c117
< URL="http://api.twitter.com/1/statuses/home_timeline.xml"
---
> URL="https://api.twitter.com/1.1/statuses/home_timeline.json"
140c143
< URL="http://api.twitter.com/1/statuses/update.xml"
---
> URL="http://api.twitter.com/1.1/statuses/update.json"
うめさん
返信削除ありがとうございます
ソースをGithubに移動してパッチを当てたブランチを作成しました
https://github.com/lostman-github/shtter/tree/v1.1-patched