diff options
-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 | *) |