diff options
Diffstat (limited to 'scripts/gist')
| -rwxr-xr-x | scripts/gist | 139 |
1 files changed, 72 insertions, 67 deletions
diff --git a/scripts/gist b/scripts/gist index 9d884d8..01f1cd0 100755 --- a/scripts/gist +++ b/scripts/gist | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | # | 10 | # |
| 11 | # [star | s] list your gists with format below, star for your starred gists: | 11 | # [star | s] list your gists with format below, star for your starred gists: |
| 12 | # [index_of_gist] [url] [file_num] [comment_num] [short description] | 12 | # [index_of_gist] [url] [file_num] [comment_num] [short description] |
| 13 | # update, u [star | s] update the local list of your gists, star for your starred gists | 13 | # fetch, f [star | s] update the local list of your gists, star for your starred gists |
| 14 | # <index_of_gist> [--no-action] show the path of local gist repo and do custom actions | 14 | # <index_of_gist> [--no-action] show the path of local gist repo and do custom actions |
| 15 | # new, n [-d | --desc <description>] [-p] <files>... create a new gist with files | 15 | # new, n [-d | --desc <description>] [-p] <files>... create a new gist with files |
| 16 | # new, n [-d | --desc <description>] [-p] [-f | --file <file_name>] create a new gist from STDIN | 16 | # new, n [-d | --desc <description>] [-p] [-f | --file <file_name>] create a new gist from STDIN |
| @@ -21,8 +21,8 @@ | |||
| 21 | # config, c [token | user | folder | auto_sync | EDITOR | action [value] ] do configuration | 21 | # config, c [token | user | folder | auto_sync | EDITOR | action [value] ] do configuration |
| 22 | # user, U <user> get gists from a given Github user | 22 | # user, U <user> get gists from a given Github user |
| 23 | # grep, g <pattern> grep gists by a given pattern | 23 | # grep, g <pattern> grep gists by a given pattern |
| 24 | # push, p <pattern> push changes by git (well, better to make commit by youself) | ||
| 24 | # github, G <index_of_gist> Import this gist as a new Github repo | 25 | # github, G <index_of_gist> Import this gist as a new Github repo |
| 25 | # push, p <pattern> push changes by git | ||
| 26 | # help, h show this help message | 26 | # help, h show this help message |
| 27 | # | 27 | # |
| 28 | # Example: | 28 | # Example: |
| @@ -36,18 +36,59 @@ | |||
| 36 | # It is your business to do git commit and git push | 36 | # It is your business to do git commit and git push |
| 37 | 37 | ||
| 38 | # TODO test on bats, mac and remote machine | 38 | # TODO test on bats, mac and remote machine |
| 39 | # TODO completion | 39 | currentVersion="1.23.0" |
| 40 | configuredClient="" | ||
| 41 | |||
| 42 | GITHUB_API=https://api.github.com | ||
| 43 | CONFIG=~/.config/gist.conf; mkdir -p ~/.config | ||
| 40 | 44 | ||
| 41 | # Shell configuration | 45 | # Shell configuration |
| 42 | set -o pipefail | 46 | set -o pipefail |
| 43 | [ "$TRACE" ] && set -x | 47 | [ "$TRACE" ] && set -x |
| 48 | [ $(uname) == 'Darwin' ] && alias tac='tail -r' | ||
| 44 | trap 'rm -f "$http_data" "$tmp_file"' EXIT | 49 | trap 'rm -f "$http_data" "$tmp_file"' EXIT |
| 45 | 50 | ||
| 46 | [ $(uname) == 'Darwin' ] && alias tac='tail -r' | 51 | # This function determines which http get tool the system has installed and returns an error if there isnt one |
| 52 | getConfiguredClient() { | ||
| 53 | if command -v curl &>/dev/null; then | ||
| 54 | configuredClient="curl" | ||
| 55 | elif command -v wget &>/dev/null; then | ||
| 56 | configuredClient="wget" | ||
| 57 | elif command -v http &>/dev/null; then | ||
| 58 | configuredClient="httpie" | ||
| 59 | else | ||
| 60 | echo "Error: This tool requires either curl, wget, or httpie to be installed." >&2 | ||
| 61 | return 1 | ||
| 62 | fi | ||
| 63 | } | ||
| 47 | 64 | ||
| 48 | GITHUB_API=https://api.github.com | 65 | # Allows to call the users configured client without if statements everywhere |
| 49 | CONFIG=~/.config/gist.conf; mkdir -p ~/.config | 66 | http_method() { |
| 50 | configuredClient="" | 67 | local METHOD=$1; shift |
| 68 | case "$configuredClient" in | ||
| 69 | curl) [[ -n $token ]] && local extra="--header" local header="Authorization: token $token" | ||
| 70 | [[ $METHOD =~ (POST|PATCH) ]] && extra2="--data" | ||
| 71 | curl -X $METHOD -A curl -s $extra "$header" $extra2 @$http_data "$@" ;; | ||
| 72 | wget) [[ -n $token ]] && local extra="--header" local header="Authorization: token $token" | ||
| 73 | [[ $METHOD =~ (POST|PATCH) ]] && extra2='--body-file' | ||
| 74 | wget --method=$METHOD -qO- $extra "$header" $extra2 $http_data "$@" ;; | ||
| 75 | httpie) [[ -n $token ]] && header="Authorization:token $token" | ||
| 76 | [[ $METHOD =~ (POST|PATCH) ]] && extra2="@$http_data" | ||
| 77 | http -b $METHOD "$@" "$header" $extra2 ;; | ||
| 78 | esac | ||
| 79 | } | ||
| 80 | |||
| 81 | # parse JSON from STDIN with string of commands | ||
| 82 | _process_json() { | ||
| 83 | PYTHONIOENCODING=utf-8 \ | ||
| 84 | python -c "from __future__ import print_function; import sys, json; $1" | ||
| 85 | return "$?" | ||
| 86 | } | ||
| 87 | |||
| 88 | # Displays version number | ||
| 89 | version() { | ||
| 90 | echo "Version $currentVersion" | ||
| 91 | } | ||
| 51 | 92 | ||
| 52 | # handle configuration cases | 93 | # handle configuration cases |
| 53 | _configure() { | 94 | _configure() { |
| @@ -127,36 +168,6 @@ _apply_config() { | |||
| 127 | INDEX=$folder/index; [[ -e $INDEX ]] || touch $INDEX | 168 | INDEX=$folder/index; [[ -e $INDEX ]] || touch $INDEX |
| 128 | } | 169 | } |
| 129 | 170 | ||
| 130 | # This function determines which http get tool the system has installed and returns an error if there isnt one | ||
| 131 | getConfiguredClient() { | ||
| 132 | if command -v curl &>/dev/null; then | ||
| 133 | configuredClient="curl" | ||
| 134 | elif command -v wget &>/dev/null; then | ||
| 135 | configuredClient="wget" | ||
| 136 | elif command -v http &>/dev/null; then | ||
| 137 | configuredClient="httpie" | ||
| 138 | else | ||
| 139 | echo "Error: This tool requires either curl, wget, or httpie to be installed." >&2 | ||
| 140 | return 1 | ||
| 141 | fi | ||
| 142 | } | ||
| 143 | |||
| 144 | # Allows to call the users configured client without if statements everywhere | ||
| 145 | http_method() { | ||
| 146 | local METHOD=$1; shift | ||
| 147 | case "$configuredClient" in | ||
| 148 | curl) [[ -n $token ]] && local extra="--header" local header="Authorization: token $token" | ||
| 149 | [[ $METHOD =~ (POST|PATCH) ]] && extra2="--data" | ||
| 150 | curl -X $METHOD -A curl -s $extra "$header" $extra2 @$http_data "$@" ;; | ||
| 151 | wget) [[ -n $token ]] && local extra="--header" local header="Authorization: token $token" | ||
| 152 | [[ $METHOD =~ (POST|PATCH) ]] && extra2='--body-file' | ||
| 153 | wget --method=$METHOD -qO- $extra "$header" $extra2 $http_data "$@" ;; | ||
| 154 | httpie) [[ -n $token ]] && header="Authorization:token $token" | ||
| 155 | [[ $METHOD =~ (POST|PATCH) ]] && extra2="@$http_data" | ||
| 156 | http -b $METHOD "$@" "$header" $extra2 ;; | ||
| 157 | esac | ||
| 158 | } | ||
| 159 | |||
| 160 | # TODO Split into 2 funcs for filter and display | 171 | # TODO Split into 2 funcs for filter and display |
| 161 | # Show the list of gist, but not updated time | 172 | # Show the list of gist, but not updated time |
| 162 | _show_list() { | 173 | _show_list() { |
| @@ -168,7 +179,8 @@ _show_list() { | |||
| 168 | [[ -z $1 ]] && local filter='/^ *s/ d; /^$/ d' | 179 | [[ -z $1 ]] && local filter='/^ *s/ d; /^$/ d' |
| 169 | [[ $1 == "s" ]] && local filter='/^ *[^ s]/ d; /^$/ d' | 180 | [[ $1 == "s" ]] && local filter='/^ *[^ s]/ d; /^$/ d' |
| 170 | 181 | ||
| 171 | while read index link blob_code file_num comment_num author description; do | 182 | sed -e "$filter" $INDEX \ |
| 183 | | while read index link blob_code file_num comment_num author description; do | ||
| 172 | [[ $1 == "s" ]] && local name=$author | 184 | [[ $1 == "s" ]] && local name=$author |
| 173 | local repo=$folder/$(echo $link | sed 's#.*/##') | 185 | local repo=$folder/$(echo $link | sed 's#.*/##') |
| 174 | local occupy=0 | 186 | local occupy=0 |
| @@ -184,8 +196,7 @@ _show_list() { | |||
| 184 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 | 196 | [[ -n $(cd $repo && git cherry) ]] 2>/dev/null && extra="\e[31m[ahead]\e[0m" && occupy=7 |
| 185 | 197 | ||
| 186 | echo -e "$(printf "% 3s" $index)" $link $name $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) | 198 | echo -e "$(printf "% 3s" $index)" $link $name $extra $(echo $description | cut -c -$(( 60 -$occupy -1 )) ) |
| 187 | done < $INDEX \ | 199 | done |
| 188 | | sed "$filter" | ||
| 189 | echo -e '\nrun "gist help" or "gist h" for more details' > /dev/tty | 200 | echo -e '\nrun "gist help" or "gist h" for more details' > /dev/tty |
| 190 | } | 201 | } |
| 191 | 202 | ||
| @@ -194,7 +205,6 @@ _grep_content() { | |||
| 194 | _show_list | grep -i $1 | 205 | _show_list | grep -i $1 |
| 195 | } | 206 | } |
| 196 | 207 | ||
| 197 | # TODO support filenames, file contents | ||
| 198 | _import_to_github() { | 208 | _import_to_github() { |
| 199 | _gist_id $1 | 209 | _gist_id $1 |
| 200 | echo put the folowing URL into webpage: | 210 | echo put the folowing URL into webpage: |
| @@ -208,15 +218,8 @@ _push_to_remote() { | |||
| 208 | && git commit --allow-empty-message -m '' && git push origin master | 218 | && git commit --allow-empty-message -m '' && git push origin master |
| 209 | } | 219 | } |
| 210 | 220 | ||
| 211 | # parse JSON from STDIN with string of commands | 221 | _parse_gists() { |
| 212 | AccessJsonElement() { | 222 | _process_json ' |
| 213 | PYTHONIOENCODING=utf-8 \ | ||
| 214 | python -c "from __future__ import print_function; import sys, json; $1" | ||
| 215 | return "$?" | ||
| 216 | } | ||
| 217 | |||
| 218 | _handle_gists() { | ||
| 219 | echo ' | ||
| 220 | raw = json.load(sys.stdin) | 223 | raw = json.load(sys.stdin) |
| 221 | for gist in raw: | 224 | for gist in raw: |
| 222 | print(gist["html_url"], end=" ") | 225 | print(gist["html_url"], end=" ") |
| @@ -230,10 +233,9 @@ for gist in raw: | |||
| 230 | } | 233 | } |
| 231 | 234 | ||
| 232 | # TODO check if a user has no gist | 235 | # TODO check if a user has no gist |
| 233 | # FIXME replace space with sed | ||
| 234 | # parse response from gists require | 236 | # parse response from gists require |
| 235 | _parse_response() { | 237 | _parse_response() { |
| 236 | | AccessJsonElement "$(_handle_gists)" \ | 238 | _parse_gists \ |
| 237 | | tac | sed -e 's/, /,/g' | nl -s' ' \ | 239 | | tac | sed -e 's/, /,/g' | nl -s' ' \ |
| 238 | | while read index link file_url_array public file_num comment_num author description; do | 240 | | while read index link file_url_array public file_num comment_num author description; do |
| 239 | local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E -e 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -s -d '-' -) | 241 | local blob_code=$(echo $file_url_array | tr ',' '\n' | sed -E -e 's#.*raw/(.*)/.*#\1#' | sort | cut -c -7 | paste -s -d '-' -) |
| @@ -246,7 +248,7 @@ _parse_response() { | |||
| 246 | # TODO pagnation for more than 30 gists | 248 | # TODO pagnation for more than 30 gists |
| 247 | # TODO add files and date of a gist | 249 | # TODO add files and date of a gist |
| 248 | # get latest list of gists from Github API | 250 | # get latest list of gists from Github API |
| 249 | _update() { | 251 | _fetch_gists() { |
| 250 | echo "fetching $user's gists from $GITHUB_API..." | 252 | echo "fetching $user's gists from $GITHUB_API..." |
| 251 | echo | 253 | echo |
| 252 | local route="users/$user/gists" | 254 | local route="users/$user/gists" |
| @@ -357,8 +359,8 @@ _clean_repos() { | |||
| 357 | } | 359 | } |
| 358 | 360 | ||
| 359 | # parse JSON from gist detail | 361 | # parse JSON from gist detail |
| 360 | _handle_gist() { | 362 | _parse_gist() { |
| 361 | echo ' | 363 | _process_json ' |
| 362 | raw = json.load(sys.stdin) | 364 | raw = json.load(sys.stdin) |
| 363 | print("site:", raw["html_url"]) | 365 | print("site:", raw["html_url"]) |
| 364 | print("description:", raw["description"]) | 366 | print("description:", raw["description"]) |
| @@ -369,12 +371,12 @@ print("updated_at:", raw["updated_at"]) | |||
| 369 | print("files:") | 371 | print("files:") |
| 370 | for file in raw["files"].keys(): | 372 | for file in raw["files"].keys(): |
| 371 | print(" ", file) | 373 | print(" ", file) |
| 372 | ' | 374 | ' |
| 373 | } | 375 | } |
| 374 | 376 | ||
| 375 | # equal to jq '.[] | {user: .user.login, created_at: .created_at, updated_at: .updated_at, body: .body}' | 377 | # equal to jq '.[] | {user: .user.login, created_at: .created_at, updated_at: .updated_at, body: .body}' |
| 376 | _handle_comment() { | 378 | _parse_comment() { |
| 377 | echo ' | 379 | _process_json ' |
| 378 | raw = json.load(sys.stdin); | 380 | raw = json.load(sys.stdin); |
| 379 | for comment in raw: | 381 | for comment in raw: |
| 380 | print() | 382 | print() |
| @@ -382,16 +384,16 @@ for comment in raw: | |||
| 382 | print("|", "created_at:", comment["created_at"]) | 384 | print("|", "created_at:", comment["created_at"]) |
| 383 | print("|", "updated_at:", comment["updated_at"]) | 385 | print("|", "updated_at:", comment["updated_at"]) |
| 384 | print("|", comment["body"]) | 386 | print("|", comment["body"]) |
| 385 | ' | 387 | ' |
| 386 | } | 388 | } |
| 387 | 389 | ||
| 388 | _show_detail() { | 390 | _show_detail() { |
| 389 | _gist_id $1 | 391 | _gist_id $1 |
| 390 | http_method GET $GITHUB_API/gists/$GIST_ID \ | 392 | http_method GET $GITHUB_API/gists/$GIST_ID \ |
| 391 | | AccessJsonElement "$(_handle_gist)" | 393 | | _parse_gist |
| 392 | 394 | ||
| 393 | http_method GET $GITHUB_API/gists/$GIST_ID/comments \ | 395 | http_method GET $GITHUB_API/gists/$GIST_ID/comments \ |
| 394 | | AccessJsonElement "$(_handle_comment)" | 396 | | _parse_comment |
| 395 | } | 397 | } |
| 396 | 398 | ||
| 397 | # set filename/description/permission for a new gist | 399 | # set filename/description/permission for a new gist |
| @@ -427,7 +429,7 @@ _new_file() { | |||
| 427 | } | 429 | } |
| 428 | 430 | ||
| 429 | _gist_body(){ | 431 | _gist_body(){ |
| 430 | echo " | 432 | _process_json " |
| 431 | import os.path | 433 | import os.path |
| 432 | files_json = {} | 434 | files_json = {} |
| 433 | files = sys.stdin.readline().split() | 435 | files = sys.stdin.readline().split() |
| @@ -449,7 +451,7 @@ _create_gist() { | |||
| 449 | http_data=$(mktemp) | 451 | http_data=$(mktemp) |
| 450 | 452 | ||
| 451 | echo -e "$files\n$description" \ | 453 | echo -e "$files\n$description" \ |
| 452 | | AccessJsonElement "$(_gist_body)" > $http_data \ | 454 | | _gist_body > $http_data \ |
| 453 | && http_method POST $GITHUB_API/gists \ | 455 | && http_method POST $GITHUB_API/gists \ |
| 454 | | sed -e '1 s/^/[/; $ s/$/]/' \ | 456 | | sed -e '1 s/^/[/; $ s/$/]/' \ |
| 455 | | _parse_response $(( $(sed -e '/^s/ d' $INDEX | wc -l) +1 )) \ | 457 | | _parse_response $(( $(sed -e '/^s/ d' $INDEX | wc -l) +1 )) \ |
| @@ -475,7 +477,7 @@ _edit_gist() { | |||
| 475 | http_data=$(mktemp) | 477 | http_data=$(mktemp) |
| 476 | echo { \"description\": \"$(echo $DESC | sed -e 's/"/\\"/g')\" } > $http_data | 478 | echo { \"description\": \"$(echo $DESC | sed -e 's/"/\\"/g')\" } > $http_data |
| 477 | http_method PATCH $http_data $GITHUB_API/gists/$GIST_ID > /dev/null \ | 479 | http_method PATCH $http_data $GITHUB_API/gists/$GIST_ID > /dev/null \ |
| 478 | && _update | 480 | && _fetch_gists |
| 479 | } | 481 | } |
| 480 | 482 | ||
| 481 | usage() { | 483 | usage() { |
| @@ -484,14 +486,14 @@ usage() { | |||
| 484 | 486 | ||
| 485 | _apply_config "$@" || exit 1 | 487 | _apply_config "$@" || exit 1 |
| 486 | getConfiguredClient | 488 | getConfiguredClient |
| 487 | if [[ $init ]]; then _update; exit 0; fi | 489 | if [[ $init ]]; then _fetch_gists; exit 0; fi |
| 488 | case "$1" in | 490 | case "$1" in |
| 489 | "") | 491 | "") |
| 490 | _show_list ;; | 492 | _show_list ;; |
| 491 | star | s) | 493 | star | s) |
| 492 | _show_list s ;; | 494 | _show_list s ;; |
| 493 | update | u) | 495 | fetch | f) |
| 494 | _update "$2" ;; | 496 | _fetch_gists "$2" ;; |
| 495 | new | n) | 497 | new | n) |
| 496 | shift | 498 | shift |
| 497 | _create_gist "$@" ;; | 499 | _create_gist "$@" ;; |
| @@ -522,6 +524,9 @@ case "$1" in | |||
| 522 | push | p) | 524 | push | p) |
| 523 | shift | 525 | shift |
| 524 | _push_to_remote "$1" ;; | 526 | _push_to_remote "$1" ;; |
| 527 | version) | ||
| 528 | echo "Version $currentVersion" | ||
| 529 | exit 0 ;; | ||
| 525 | help | h) | 530 | help | h) |
| 526 | usage ;; | 531 | usage ;; |
| 527 | *) | 532 | *) |