You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ix 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/usr/bin/env bash
  2. declare -r esc=$'\033'
  3. declare -r c_reset="${esc}[0m"
  4. declare -r c_red="${esc}[31m"
  5. declare OPTIND
  6. declare opts=( -# )
  7. declare id
  8. usage() {
  9. LESS=-FEXR less <<'HELP'
  10. ix [OPTIONS]
  11. -l list all pastes, uses fzf for interactive use
  12. -d [id] delete the paste at [id]
  13. -i [id] replaces the paste with stdin
  14. -h print this help
  15. HELP
  16. }
  17. err() {
  18. printf "${c_red}%s${c_reset}\n" "$*" >&2
  19. }
  20. die() {
  21. exit 1
  22. }
  23. has() {
  24. local verbose=0
  25. if [[ $1 == '-v' ]]; then
  26. verbose=1
  27. shift
  28. fi
  29. for c; do c="${c%% *}"
  30. if ! command -v "$c" &> /dev/null; then
  31. (( verbose > 0 )) && err "$c not found"
  32. return 1
  33. fi
  34. done
  35. }
  36. select_from() {
  37. local cmd='command -v'
  38. for a; do
  39. case "$a" in
  40. -c)
  41. cmd="$2"
  42. shift 2
  43. ;;
  44. esac
  45. done
  46. for c; do
  47. if $cmd "${c%% *}" &> /dev/null; then
  48. echo "$c"
  49. return 0
  50. fi
  51. done
  52. return 1
  53. }
  54. has_account() {
  55. grep -qF 'ix.io' ~/.netrc
  56. }
  57. create_account() {
  58. echo "It seems you don't have a ~/.netrc with ix.io in it. Let's make one!"
  59. read -r -p 'enter a username: ' username
  60. read -rs -p 'enter a password (this will be hashed with sha256sum): ' password
  61. password=$(sha256sum <<< "$password" | awk '{print $1}')
  62. echo ''
  63. tee -a ~/.netrc <<< "machine ix.io login $username password $password"
  64. chmod 600 ~/.netrc
  65. echo "$username"
  66. }
  67. get_user_name() {
  68. awk '"ix.io"==$2{print $4}' ~/.netrc
  69. }
  70. get_pastes() {
  71. curl -s "http://ix.io/user/$1" |
  72. grep -A1 -P '\<a href="\/[a-zA-Z0-9]+"\>' |
  73. awk -F'--' '
  74. BEGIN {FS="<a href=\""}
  75. /a href/{ sub(/\">\[r\]<\/a>/, "\t", $2); printf "http://ix.io" $2 }
  76. /@/{sub(/^\s+/, "", $0); print}
  77. '
  78. }
  79. list_pastes() {
  80. local highlighter
  81. highlighter=$(select_from 'highlight -q --force -O ansi' pygmentize cat)
  82. url=$(get_pastes "$(get_user_name)" | fzf \
  83. --inline-info --cycle \
  84. --header='Ctrl-E = edit; Ctrl-V = view; Ctrl-D = delete' \
  85. --preview="curl -s '{1}' | ${highlighter}" \
  86. --bind 'space:jump' \
  87. --bind 'q:abort' \
  88. --bind "Ctrl-V:execute:less -R < <(curl -s '{1}' ${highlighter:+ | $highlighter}) > /dev/tty" \
  89. --bind 'Ctrl-E:execute:p={1}; edit=$(curl -s "$p" | vipe); ix -i "${p##*/}" <<< "$edit"' \
  90. --expect='Ctrl-D')
  91. if [[ -n "$url" ]]; then
  92. mapfile -t res <<< "$url"
  93. if [[ "${res[0]}" = 'Ctrl-D' ]]; then
  94. ix -d "${res[1]}"
  95. list_pastes
  96. exit
  97. fi
  98. fi
  99. }
  100. has -v curl || die
  101. has_account || create_account
  102. [[ -e ~/.netrc ]] && opts+=( '-n' )
  103. while getopts ":hld:i:n:" x; do
  104. case "$x" in
  105. h) usage; exit ;;
  106. d) curl -s "${opts[@]}" -X DELETE "$OPTARG"; exit ;;
  107. l)
  108. if [[ -z "$OPTARG" && -e ~/.netrc ]]; then
  109. list_pastes | cut -d' ' -f1 | tee /dev/tty | xclip
  110. else
  111. die 'no netrc found'
  112. fi
  113. exit ;;
  114. i) opts+=( -X PUT ); id="$OPTARG" ;;
  115. n) opts+=( -F "read:1=$OPTARG" ) ;;
  116. esac
  117. done
  118. shift $(( OPTIND - 1))
  119. if [[ -t 0 ]]; then
  120. if [[ -n "$1" ]]; then
  121. filename="$1"
  122. shift
  123. curl "${opts[@]}" -F f:1=@"$filename" "$@" "ix.io/$id"
  124. exit
  125. fi
  126. echo "^C to cancel, ^D to send."
  127. fi
  128. curl "${opts[@]}" -F f:1='<-' "$@" "ix.io/$id"