Last active
August 2, 2019 11:57
-
-
Save hacolab/d7d56fba88cde1d5519416d9128f4cf0 to your computer and use it in GitHub Desktop.
hatenablog's AtomPub request command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
################################################################################ | |
# This script is only send HTTP request to HatenaBlog's AtomPub API service, | |
# and output received HTTP response body to stdout. | |
# If GET request to entry collection page, auto try GET to next page. | |
# | |
#-[Usage] | |
#- $0 GET {Path} [-a Auth-File][-v][-n FD][-l Num[:Target]] | |
#- $0 DELETE {Path} [-a Auth-File][-v] | |
#- $0 PUT {Path} [-a Auth-File][-v][-f Tx-File] | |
#- $0 POST {Path} [-a Auth-File][-v][-f Tx-File] | |
#- | |
# [Parameters] | |
# {Path} Send request URL. | |
# If start with 'https://', {Path} | |
# Else, https://blog.hatena.ne.jp/{HatenaID}/{BlogID}/atom[/{Path}] | |
# [Options] | |
# -a Auth-File Read service auth-fino from Auth-File. see [Auth-File]. | |
# | |
# -v Print HTTP header to stderr.(use curl -v option) | |
# | |
# -n FD Next page URL output to FD. | |
# FD is file descriptor(1 or 2), or file path. default 2. | |
# If file exist, overwrite file. | |
# | |
# -l Num[:Target] Limit count of match 'Target' pattern count. | |
# If match count >= Num, don't get next link page, command exit. | |
# If 'Target' is not set, count to "<entry>". pattern is grep -E use. | |
# If not set '-l', get next page while found for '<link rel="next"' | |
# | |
# -f Tx-File POST or PUT HTTP request body contents from Tx-File. | |
# If not set `-f`, read from stdin. | |
# contents format is XML. See [Reference]. | |
# [STDIN] | |
# - | |
# [STDOUT] | |
# HatenaBlog AtomPub response body | |
# [STDERR] | |
# see '-n', '-v' in [Options] | |
# [Auth-File] | |
# Default path $HOME/.local/share/hateblog/auth | |
# Format BLOG_ID={YourHatenaID} exp.) example.hatenablog.com | |
# HATENA_ID={YourHatenaID} | |
# API_KEY={YourKey} | |
# [Dependency] | |
# curl https://curl.haxx.se/ | |
# | |
# [Reference] | |
# http://developer.hatena.ne.jp/ja/documents/blog/apis/atom | |
# | |
################################################################################ | |
CMD_NAME=`basename $0` | |
VERSION=0.1.0 | |
# Help & Error | |
usage_exit() { | |
echo "$1" 1>&2 | |
sed -n '/^#-/s/^#-//p' "$0" | sed "s/\$0/$CMD_NAME/g" 1>&2 | |
exit 200 | |
} | |
version_exit() { | |
echo "VERSION: $VERSION" && exit 0 | |
} | |
error_exit() { | |
echo "ERROR: $1" 1>&2 && exit 200 | |
} | |
# Local config | |
LOCAL_DIR="$HOME/.local/share/hateblog" | |
AUTH_FILE="$LOCAL_DIR/auth" | |
TMP_HEADER="$LOCAL_DIR/$CMD_NAME.header.$$" | |
TMP_BODY="$LOCAL_DIR/$CMD_NAME.body.$$" | |
[ ! -d "$LOCAL_DIR" ] && mkdir -p "$LOCAL_DIR" | |
if [ ! -f "$AUTH_FILE" ]; then | |
cat <<- AUTHEND > "$AUTH_FILE" | |
BLOG_ID= | |
HATENA_ID= | |
API_KEY= | |
AUTHEND | |
chmod 600 "$AUTH_FILE" | |
fi | |
# Fetch Parameters | |
HTTP_METHOD="$1" | |
REQUEST_URL="$2" | |
if [ `echo "$REQUEST_URL" | grep -c '^-'` -ne 0 ]; then | |
usage_exit 'few parameter!' | |
fi | |
shift 2 | |
# Analyze options | |
TX_FILE=- | |
LIMIT_COUNT=0 | |
PRINT_HEADER= | |
PRINT_NEXT_URL= | |
FD_OF_NEXT_URL=2 | |
while getopts a:f:l:n:vV OPT; do | |
case "$OPT" in | |
a ) AUTH_FILE="$OPTARG" | |
;; | |
f ) TX_FILE="$OPTARG" | |
[ ! -f "$TX_FILE" ] && error_exit "Tx-File dose not found: '$TX_FILE'" | |
;; | |
l ) # -l Limit-Count[:pattern] | |
if [ `echo "$OPTARG" | grep -c ":"` -eq "0" ]; then | |
LIMIT_COUNT=$OPTARG | |
COUNT_PATTERN="<entry>" | |
else | |
LIMIT_COUNT="${OPTARG%%:*}" | |
COUNT_PATTERN="${OPTARG##*:}" | |
fi | |
;; | |
n ) PRINT_NEXT_URL=true | |
FD_OF_NEXT_URL="$OPTARG" | |
;; | |
v ) PRINT_HEADER=true | |
;; | |
V ) version_exit | |
;; | |
\?) usage_exit | |
;; | |
esac | |
done | |
shift `expr $OPTIND - 1` | |
# Load default auth info | |
[ ! -f "$AUTH_FILE" ] && error_exit "Auth-File does not found: '$AUTH_FILE'" | |
get_value() { | |
sed -n "s/^$1=\(.*\)[^ ]*$/\1/p" | |
} | |
BLOG_ID=`get_value BLOG_ID < "$AUTH_FILE"` | |
HATENA_ID=`get_value HATENA_ID < "$AUTH_FILE"` | |
API_KEY=`get_value API_KEY < "$AUTH_FILE"` | |
# Check user auth info | |
[ -z "$BLOG_ID" ] && error_exit "'BLOG_ID' is null!" | |
[ -z "$API_KEY" ] && error_exit "'API_KEY' is null!" | |
[ -z "$HATENA_ID" ] && error_exit "'HATENA_ID' is null!" | |
# If not full path given. | |
HATENA_ROOT='https://blog.hatena.ne.jp' | |
if [ `echo "$REQUEST_URL" | grep -c "^https://"` -eq 0 ]; then | |
REQUEST_URL="$HATENA_ROOT/$HATENA_ID/$BLOG_ID/atom${REQUEST_URL:+"/$REQUEST_URL"}" | |
fi | |
# Send request | |
CURL_OPT="-s -H 'Content-Type: applicatoin/xml' -X $HTTP_METHOD -u $HATENA_ID:$API_KEY" | |
[ -n "$PRINT_HEADER" ] && CURL_OPT="$CURL_OPT -v" | |
get_request_pages() { | |
# Clear temp | |
>| "$TMP_HEADER" | |
# Get collection pages | |
next_page=$1 | |
limit_count=$3 | |
while : | |
do | |
# Send HTTP request | |
curl $CURL_OPT "$next_page" | tee "$TMP_BODY" | |
# Next page exist? | |
next_page=`grep '<link rel="next"' < "$TMP_BODY" | sed 's/^.*href="\([^"]*\)".*/\1/'` | |
[ -z "$next_page" ] && break | |
# No limit? | |
[ "$limit_count" -eq 0 ] && continue | |
# Over limit? | |
match_count=`grep -Ec "$2" "$TMP_BODY"` | |
[ "$limit_count" -le "$match_count" ] && break; | |
limit_count=`expr $limit_count - $match_count` | |
done >&1 | |
# Print next page URL | |
[ -z "$PRINT_NEXT_URL" ] && return | |
fomated_next_url="NEXT>$next_page" | |
case "$FD_OF_NEXT_URL" in | |
1 ) echo "$fomated_next_url" >&1 ;; | |
2 ) echo "$fomated_next_url" 1>&2 ;; | |
* ) echo "$fomated_next_url" > "$FD_OF_NEXT_URL" ;; | |
esac | |
} | |
case "$HTTP_METHOD" in | |
GET ) get_request_pages "$REQUEST_URL" "$COUNT_PATTERN" "$LIMIT_COUNT" ;; | |
DELETE ) curl $CURL_OPT "$REQUEST_URL" ;; | |
PUT|POST ) curl $CURL_OPT --data-binary @"$TX_FILE" "$REQUEST_URL" ;; | |
* ) error_exit "Invalid method '$HTTP_METHOD'" ;; | |
esac | |
# Clean up | |
rm "$TMP_HEADER" "$TMP_BODY" 2>/dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment