fedi-post.sh 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/bin/sh
  2. #―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
  3. # Name: fedi-post.sh
  4. # Desc: Makes a new post using an post archived with fedi-archive.sh.
  5. # Reqs: curl, jq
  6. # Date: 2023-05-06
  7. # Auth: @jadedctrl@jam.xwx.moe
  8. #―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
  9. sanitize_text() {
  10. grep -v ^media: \
  11. | grep -v ^spoiler: \
  12. | sed 's%\\%\\\\%g' \
  13. | sed 's%"%\\"%g' \
  14. | sed -z 's%\n%\\n%g'
  15. }
  16. # Outputs only the status text of a user's post, with a link to the original
  17. # appended to the bottom.
  18. file_status() {
  19. local file="$1"
  20. local id="$(head -1 "$file" | awk '{print $3}')"
  21. local url="$(head -1 "$file" | awk '{print $4}')"
  22. tail +2 "$file" \
  23. | sanitize_text
  24. if test -n "$url"; then
  25. printf '<br/>[<a href=\\"%s\\">Originala afiŝo</a>]\\n' "$url"
  26. fi
  27. }
  28. # Turns a space-delimited list of uploaded media-IDs into a JSON array.
  29. media_json() {
  30. local ids="$1"
  31. if test -n "$ids"; then
  32. echo "$ids" \
  33. | sed 's%^ %%' \
  34. | sed 's% $%%' \
  35. | sed 's%^%["%' \
  36. | sed 's% %","%g' \
  37. | sed 's%$%"]%'
  38. else
  39. echo ""
  40. fi
  41. }
  42. # Takes a post message and JSON-array of uploaded media-IDs, outputting
  43. # the post's appropriate JSON.
  44. post_json() {
  45. local message="$1"
  46. local media_ids="$2"
  47. local spoiler="$3"
  48. printf '{ "content_type": "text/html", "visibility": "unlisted",'
  49. if test -n "$spoiler"; then
  50. printf ' "spoiler_text": "%s", ' "$(echo "$spoiler" | sanitize_text)"
  51. fi
  52. if test -n "$media_ids"; then
  53. printf ' "media_ids": %s, ' "$media_ids"
  54. fi
  55. printf '"status": "%s" }\n' "$message"
  56. }
  57. # Upload a file to the fedi server with the given description.
  58. post_media() {
  59. local media_file="$1"
  60. local description="$2"
  61. curl --request POST \
  62. --header "Authorization: Bearer $FEDI_AUTH" \
  63. --header "Content-Type: multipart/form-data" \
  64. --form "file=@$media_file" \
  65. --form "description=$description" \
  66. "https://jam.xwx.moe/api/v1/media"
  67. }
  68. # Post a status of the given message and JSON-array of uploaded media-IDs.
  69. post_status() {
  70. local message="$1"
  71. local media_ids="$2"
  72. local spoiler="$3"
  73. curl --request POST \
  74. --header "Authorization: Bearer $FEDI_AUTH" \
  75. --header "Content-Type: application/json" \
  76. --data "$(post_json "$message" "$media_ids" "$spoiler" | tr -d '\n')" \
  77. "https://jam.xwx.moe/api/v1/statuses"
  78. }
  79. # Take a post file generated by fedi-archive.sh, and post it.
  80. # Just *do it*. Why not? What're you scared of? Huh, huh? Huh?!
  81. post_archived_post() {
  82. local file="$1"
  83. IFS="
  84. "
  85. local ids=""
  86. for media in $(grep "^media: " "$file"); do
  87. local url="$(echo "$media" | awk '{print $2}')"
  88. local desc="$(echo "$media" | awk '{ $1=$2=""; print}' | sed 's%^ %%')"
  89. curl -o "$(basename "$url")" "$url"
  90. ids="$ids $(post_media "$(basename "$url")" "$desc" | jq -r '.id')"
  91. rm "$(basename "$url")"
  92. done
  93. local spoiler="$(grep "^spoiler: " "$file" | sed 's%^spoiler: %%')"
  94. printf '%s ' "$(head -1 "$file" | awk '{print $1, $2}')"
  95. post_status "$(file_status "$file")" "$(media_json "$ids")" "$spoiler" \
  96. | jq -r .uri
  97. }
  98. usage() {
  99. echo "usage: $(basename "$0") ARCHIVED-POST" 1>&2
  100. echo "" 1>&2
  101. echo "Will post a new status with the same text and attachments as one" 1>&2
  102. echo "from an archived post (in fedi-archive.sh format)." 1>&2
  103. echo "Your authorization key must be borrowed from your web-browser and" 1>&2
  104. echo 'placed in the $FEDI_AUTH environment variable.' 1>&2
  105. exit 2
  106. }
  107. if test -z "$FEDI_AUTH"; then
  108. echo 'You need to set the environment variable $FEDI_AUTH!' 1>&2
  109. echo 'You can find your auth key by examining the "Authentication: Bearer" header' 1>&2
  110. echo "used in requests by your server's web-client." 1>&2
  111. echo 'In Firefox, F12→Network.' 1>&2
  112. echo "" 1>&2
  113. usage
  114. fi
  115. FILE="$1"
  116. if test -z "$FILE" -o "$1" = "-h" -o "$1" = "--help"; then
  117. usage
  118. fi
  119. post_archived_post "$FILE"