-
-
Save ProBackup-nl/3971a45b21749cfff6c0069d3dad1dde to your computer and use it in GitHub Desktop.
Gister to POST or PATCH a single file as public gist. PATCH does gist ID lookup: no need to remember gist ID's
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 | |
# -------------------------------------------------------- | |
# Shell gister to POST or PATCH a single file as public gist. | |
# PATCH does gist ID lookup: no need to remember gist ID's | |
# -------------------------------------------------------- | |
# usage: $ pgist file_to_post_or_patch.extension | |
# | |
# installation: $ curl -O https://gist.githubusercontent.com/ProBackup-nl/3971a45b21749cfff6c0069d3dad1dde/raw/pgist.sh && chmod 755 pgist.sh && mv pgist.sh /opt/usr/sbin/pgist | |
# | |
# tested with Busybox (ash shell) + Entware (opkg) | |
# Limitation #1: 300 files per gist <- Github API | |
# Limitation #2: 30 (maybe 100) gists per user <- Github API && pagination is not implemented in this script | |
# Limitation #3: requires your gist filenames to be user unique (= not any of your gists can have an identical filename; otherwise filename to gist matching fails) | |
# ToDo: test large files; expect 4 MiB to fail. | |
# Dependencies | |
which jq > /dev/null || { echo 'Error: dependency jq not found. Install it with: ''$ opkg install jq''. Exiting'; exit 1 ; } | |
[ -z "$GITHUB_TOKEN" ] && { echo 'Error: GITHUB_TOKEN is empty. For example ''export GITHUB_TOKEN=replace_this_with_your_token'' in your ''~/.profile''. Create a personal access token <https://developer.github.com/v3/guides/getting-started/#oauth> Exiting'; exit 2; } | |
[ -z "$1" ] && { echo 'Error: no file supplied as argument. Exiting'; exit 3 ; } | |
which sed > /dev/null || { echo 'Error: dependency ''sed'' not found. Install it. Exiting'; exit 4 ; } | |
which awk > /dev/null || { echo 'Error: dependency ''awk'' not found. Install it. Exiting'; exit 5 ; } | |
which basename > /dev/null || { echo 'Error: dependency ''basename'' not found. Install it. Exiting'; exit 6 ; } | |
which curl > /dev/null || { echo 'Error: dependency ''curl'' not found. Install it with ''$ opkg install curl ca-certificates''. Exiting'; exit 7 ; } | |
# ToDo: ca-certificates /opt/etc/ssl/certs/ | |
# Supply filename on the command-line as first argument | |
[ -f $1 ] && readonly FNAME=$1 || { echo "Error: file '$1' not found. Exiting" ; exit 8 ; } | |
readonly BNAME=`basename $FNAME` | |
# Lookup: authenticated user's gists | select matching filename | return parent gist id | |
# api.github.com/gists?filename=$FNAME doesn't filter results | |
# curl -I will show headers | |
readonly GIST_ID=`curl --silent -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/gists?per_page=100 |jq --raw-output '.[]|select(.files["'$BNAME'"])|.id'` | |
# Count results | |
id_count=0 ; for i in $GIST_ID ; do let id_count++ ; done | |
if [ $id_count -gt 1 ]; then | |
echo "Error: Duplicate filename found. The file names of your gists do need to be unique. Exiting" | |
exit 10 | |
else | |
# POST or PATCH | |
# Sanitize file content | |
# Replace \ with \\ | |
# Remove \r (from Windows end-of-lines), | |
# Replace tabs by \t | |
# Replace " with \" | |
# Replace EOL by \n (note: awk is not bullet-proof on busybox; awk '{ printf($0 "\\n") }' fails; slow od alternative <https://stackoverflow.com/questions/1251999/how-can-i-replace-a-newline-n-using-sed#answer-23166624>) | |
[ -n "$FNAME" ] && readonly CONTENT=$(sed -e 's/\\/\\\\/g' -e 's/\r//' -e's/\t/\\t/g' -e 's/"/\\"/g' "${FNAME}" | awk '{ printf("%s\\n", $0) } END { print "" }') || { echo 'Error: at this point the filename can''t be empty. Exiting' ; exit 11 ; } | |
#echo $CONTENT | |
if [ $id_count = 1 ] ; then | |
echo PATCH | |
# Use curl to send an explicit PATCH request to an existing gist | |
readonly TDATA="{ \"files\": { \"${BNAME}\": { \"content\": \"${CONTENT}\" } } }" | |
curl --silent --request PATCH -d "$TDATA" -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/gists/$GIST_ID | |
elif [ $id_count = 0 ] ; then | |
echo POST | |
read -p 'Give a description: ' DESCRIPTION | |
# Use curl to send an implicit POST request to create a new gist | |
curl -d "{ \"description\": \"${DESCRIPTION}\", \"public\": true, \"files\": { \"${BNAME}\": { \"content\": \"${CONTENT}\" } } }" -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/gists | |
else | |
echo "Logic error. Exiting" | |
exit 20 | |
fi | |
fi | |
echo 'Done' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As a result of being unable to update an existing gist file with the answers of "upload-a-file-to-a-gist-with-bash" without installing significant dependencies (like ruby) on a mips router, this script found its existence.
Notes: Tested with scripts that use Heredoc notation. Not expected to handle with 4MiB large files.