hzclish.old 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. #!/bin/bash
  2. #
  3. # hzclish - Hubzilla (ex Red Matrix) cli bash script.
  4. # Version 1.2 (legacy. Wont be updated)
  5. # Source: https://notabug.org/uzver/hzclish
  6. #
  7. # License: WTFPL2 http://wtfpl2.com/
  8. # uzver(at)protonmail.ch
  9. #
  10. # Deps: curl, jq, markdown or pandoc or discount, grep, sed, awk, tr, mkdir, mktemp, rm, wc, which
  11. thispath="$(realpath $0)"
  12. thisdir="$(dirname "$thispath")"
  13. dotdir=~/'.hzclish'
  14. verbose=0
  15. ssl=1
  16. markdown='markdown'
  17. useragent='Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0'
  18. # FUNCTIONS
  19. USAGE(){
  20. exec=$(basename "$0"); [[ "$exec" ]] || exec="${0##*/}"
  21. cat << EOF
  22. $exec - CLI bash wrapper script for the Hubzilla (Red Matrix) twitter API.
  23. USAGE: $exec [OPTIONS] [-u LOGIN:DOMAIN[:PASSWORD]] [<<<"MESSAGE"]
  24. OPTIONS:
  25. -c config Specify config file.
  26. (use different configs for different accounts).
  27. -d Set config file as default auth (requires: -s|-g|-p).
  28. -D Delete config and cookie files.
  29. -g ID Get post of given ID.
  30. -h, --help Show this help.
  31. -i Post from standart input.
  32. -m <str> Set your custom markdown engine (overwrites: -P).
  33. -p Post the message.
  34. -P Use pandoc instead of markdown
  35. (it's short for:
  36. -m "pandoc -f markdown_strict+footnotes+definition_lists+hard_line_breaks -t html").
  37. -q Less verbose printing.
  38. -R Renew auth token.
  39. -s Set new authentification (save login, password).
  40. -S yes|no Use or not https (default: yes) (useful for inline auth: -u).
  41. -t Convert very last line (of your post) with hashtags to categories,
  42. and post with the same hashtags and categories.
  43. -T Convert very last line (of your post) with hashtags to categories,
  44. and drop hashtags. Post only with categories.
  45. -u LOGIN:DOMAIN[:PASSWORD] Specify auth inline, e.g.:
  46. "inbox@example.com:hubdomain.com:password",
  47. or:
  48. "channelname@hubdomain.com:password", or:
  49. "channelname@hubdomain.com"
  50. (use it if you do not want to save auth)
  51. (implies not to use with: -c, -D, -r, -s).
  52. -v Verbose mode.
  53. Notice: For now length of message limited by bash variable size limit.
  54. EXAMPLES:
  55. Save new authentification to config file and set it default:
  56. $exec -s
  57. or save new auth and set it default:
  58. $exec -vds # verbose
  59. or to custom place or name:
  60. $exec -vc ~/myConfig -s # save to myConfig file in home
  61. directory
  62. $exec -vc myConfig -s # save to "$dotdir"/myConfig file
  63. or to custom place or name and set default:
  64. $exec -vdc ~/myConfig -s # save to myConfig file in home
  65. directory
  66. $exec -vdc myConfig -s # save to "$dotdir"/myConfig file
  67. Post message:
  68. $exec
  69. $exec -vp
  70. $exec -c myConfig # with custom config
  71. $exec -dc myNewDefaultConfig # with custom config & set it
  72. default
  73. Post message from stdin:
  74. $exec <<<"Hello world!"
  75. echo "Hello world!" | $exec
  76. cat myPost.md | $exec
  77. Read post by id:
  78. $exec -g 1234567
  79. $exec -qg 1234567
  80. $exec -c myConfig -g 1234567 # with custom config
  81. $exec -dc myNewDefaultConfig -g 1234567 # with custom config & set it
  82. default
  83. EOF
  84. }
  85. CONFIG(){
  86. # Check for config file and create new one if it does not exist
  87. if ! (($custconfig)) && ! (($setnew)); then
  88. confdir="$dotdir"
  89. if [[ -f "${confdir}/defaultconfig" ]]; then
  90. source "${confdir}/defaultconfig"
  91. else
  92. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Can't find defaultconfig" >&2
  93. exitstatus=1
  94. fi
  95. else
  96. ! (($quiet)) && (($verbose)) && [[ $config ]] && echo -e "\e[0;36m""Using config: $config""\e[m"
  97. # Find directory of config file if '$config' is file and set it as config directory '$confdir'
  98. [[ -f "$config" ]] && confdir=$(dirname "$config")
  99. # In case '$config' is zid:
  100. # set config directory to script dot directory '$dotdir'
  101. [[ -d "$confdir" ]] || confdir="$dotdir"
  102. # Create path to config file and set it as '$config'
  103. if [[ -f "$config" ]]; then
  104. true
  105. else
  106. if [[ -f "${confdir}/$config" ]]; then
  107. config="${confdir}/$config"
  108. elif [[ -f "${confdir}/${config}.config" ]]; then
  109. config="${confdir}/${config}.config"
  110. fi
  111. fi
  112. # echo confdir "$confdir"
  113. # echo config "$config"
  114. # exit
  115. fi
  116. if [[ -f "$config" ]]; then
  117. ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Using config: $config""\e[m"
  118. # (($custconfig)) && confdir=$(dirname "$config")
  119. if (($setdefconf)); then
  120. ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Setting default config to: $config""\e[m"
  121. echo "config=\"$config\"">"${confdir}/defaultconfig" && [[ -f "${confdir}/defaultconfig" ]] && chmod 600 "${confdir}/defaultconfig"
  122. fi
  123. else
  124. mkdir -p "$confdir" && chmod 700 "$confdir"
  125. echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Creating new config file:"
  126. read -p "Enter hub domain (example.com): " domain
  127. domain=$(echo "${domain%/*}" | sed 's|^[[:space:]]*https\?://||g')
  128. if ! (($sslsetted)); then
  129. validsslres=0
  130. sslres=y
  131. while ! (($validsslres)); do
  132. read -n 1 -p "Does your hub use SSL? (Y/n): " sslres
  133. if [[ "${sslres,,}" == [Nn] ]]; then
  134. validsslres=1
  135. ssl=0
  136. hub="http://$domain"
  137. elif [[ "${sslres,,}" == [Yy] || -z "$sslres" ]]; then
  138. validsslres=1
  139. ssl=1
  140. hub="https://$domain"
  141. else
  142. validsslres=0
  143. echo -e "\e[0;31m\nResponse not valid, please answer y or n\e[m"
  144. fi
  145. done
  146. echo
  147. fi
  148. if (($ssl)); then
  149. hub="https://$domain"
  150. else
  151. hub="http://$domain"
  152. fi
  153. read -p "Enter login e-mail: " login
  154. read -p "Enter nickname (channel nickname) (or leave blank): " channel
  155. if [[ "$channel" ]]; then
  156. zid="${channel}@$domain"
  157. elif [[ "$login" ]]; then
  158. zid="${login}@$domain"
  159. fi
  160. if ! [[ "$login" ]]; then
  161. echo 'Please specify login'
  162. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  163. exit 1
  164. fi
  165. if ! (($custconfig)); then
  166. config="${confdir}/${zid}.config"
  167. fi
  168. # if [[ "$(grep 'token=.\+' "$config")" ]]; then
  169. [[ -f "$config" ]] && source "$config"
  170. if [[ "$token" ]]; then
  171. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Script appears to be registered previously" >&2
  172. echo " Use: "$exec" '-D ${zid}' to delete auth and then '-s' option to try again" >&2
  173. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  174. exit 1
  175. fi
  176. if (($setdefconf)) || [[ ! -f "${confdir}/defaultconfig" || "$(wc -m "${confdir}/defaultconfig"|cut -d ' ' -f 1)" == 0 ]]; then
  177. ! (($quiet)) && (($verbose)) && echo -e "\e[0;36m""Setting default config to: $config""\e[m"
  178. echo "config=\"$config\"">"${confdir}/defaultconfig" && [[ -f "${confdir}/defaultconfig" ]] && chmod 600 "${confdir}/defaultconfig"
  179. fi
  180. cookie="${zid}.cookie"
  181. {
  182. cat << EOF
  183. hub="$hub"
  184. login="$login"
  185. channel="$channel"
  186. zid="$zid"
  187. useragent="$useragent"
  188. cookie="\${zid}.cookie"
  189. EOF
  190. }>"$config"
  191. [[ -f "$config" ]] && chmod 600 "$config"
  192. if ! (($quiet)) && (($verbose)); then
  193. echo -e "\e[0;36m""These variables have been saved to ${config}:""\e[m"
  194. echo -e "\e[0;36m"; cat "$config"; echo -e "\e[m"
  195. fi
  196. fi
  197. source "$config"
  198. # scookie="${confdir}/${zid}.cookie"
  199. [[ -f "${confdir}/${zid}.cookie" ]] || (touch "${confdir}/${zid}.cookie" && chmod 600 "${confdir}/${zid}.cookie")
  200. if [[ "$(which jq >& /dev/null; echo $?)" == 0 ]]; then
  201. jq="jq"
  202. elif [[ -f ~/"bin/jq" ]]; then
  203. jq=~/"bin/jq"
  204. elif [[ -f "${thisdir}/jq" ]]; then
  205. jq="jq"
  206. elif [[ -f "${confdir}/jq" ]]; then
  207. jq="jq"
  208. elif [[ -f "${dotdir}/jq" ]]; then
  209. jq="jq"
  210. fi
  211. }
  212. PASSWORD(){
  213. unset password
  214. if [[ "$config" ]] && [[ "$(grep 'password=' "$config")" ]]; then
  215. source "$config"
  216. else
  217. echo ""
  218. prompt="What is your password?: "
  219. while IFS= read -p "$prompt" -r -s -n 1 char
  220. do
  221. if [[ $char == $'\0' ]]; then
  222. break
  223. fi
  224. prompt='*'
  225. password+="$char"
  226. done
  227. echo -e "\n"
  228. fi
  229. }
  230. SETAUTH(){
  231. CONFIG
  232. source "$config"
  233. if ! [[ "$password" ]]; then
  234. echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "This is the only time you asked for your password"
  235. echo "Your password will be stored plain in config file"
  236. PASSWORD
  237. fi
  238. sed -i '/password=/d' "$config"
  239. echo password=\"$(sed 's/\"/\\"/g'<<<"$password")\">>"$config"
  240. if (($verbose)); then
  241. echo -e "\e[0;36m""Password have been saved to $config""\e[m"
  242. fi
  243. source "$config"
  244. echo "Getting token..."
  245. getauth=$(curl -ksSi --trace-ascii - -u "${login}:${password}" \
  246. -H "User-Agent: $useragent" \
  247. "${hub}/api/account/verify_credentials" \
  248. --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
  249. token=$(echo "$getauth"|sed -n 's/^.*[aA]uthorization: [Bb]asic \(.*\)/\1/p1')
  250. # unset getauth
  251. if [[ "$token" ]]; then
  252. sed -i '/token=/d' "$config"
  253. echo "token=\"${token}\"">>"$config"
  254. # unset token
  255. if (($verbose)); then
  256. echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Token saved"
  257. fi
  258. else
  259. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Getting token failed. Check/set your login/password/connection"
  260. (($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$getauth"
  261. unset getauth
  262. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  263. exitstatus=1
  264. fi
  265. local error=''
  266. error=$(echo "$getauth" | grep -io '^This api requires login')
  267. [[ "$error" ]] || error=$(echo "$getauth" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  268. if [[ "$error" ]]; then
  269. [[ "$token" ]] && echo 'but'
  270. unset token
  271. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  272. echo "Check/set your login/password/server and try again"
  273. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  274. exitstatus=1
  275. fi
  276. if (($exitstatus)); then
  277. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  278. exit $exitstatus
  279. fi
  280. }
  281. RETOKEN(){
  282. CONFIG
  283. source "$config"
  284. while [[ ! $retokened ]]; do
  285. if ! (($quiet)) && (($verbose)); then
  286. echo -e "\e[0;36m""Getting new token...""\e[m"
  287. fi
  288. if ! [[ "$password" ]]; then
  289. PASSWORD
  290. fi
  291. getauth=$(curl -ksSi --trace-ascii - -u "${login}:$password" \
  292. -H "User-Agent: $useragent" \
  293. "${hub}/api/account/verify_credentials" \
  294. --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
  295. body=$(echo -n "$getauth"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
  296. [[ "$body" ]] || body=$(echo -n "$getauth"|grep -i 'error')
  297. unset password
  298. token=$(echo "$getauth"|sed -n 's/^.*[aA]uthorization: [Bb]asic \(.*\)/\1/p1')
  299. # unset getauth
  300. if [[ "$token" ]]; then
  301. sed -i '/token/d' "$config"
  302. echo "token=\"${token}\"">>"$config"
  303. # unset token
  304. if (($verbose)); then
  305. echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Token saved"
  306. fi
  307. else
  308. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "Getting new token failed. Check/set your login/password/server"
  309. (($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$getauth"
  310. unset getauth
  311. # (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  312. exitstatus=1
  313. fi
  314. local error=''
  315. error=$(echo "$getauth" | grep -io '^This api requires login')
  316. [[ "$error" ]] || error=$(echo "$getauth" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  317. if [[ "$error" ]]; then
  318. [[ "$token" ]] && echo 'but'
  319. unset token
  320. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  321. (($verbose)) && [[ "$body" ]] && echo -en "\e[0;31m" && echo -n "$body" && echo -e "\e[m"
  322. echo "Check/set your login/password/server"
  323. # (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  324. exitstatus=1
  325. fi
  326. if (($exitstatus)); then
  327. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  328. exit $exitstatus
  329. fi
  330. ((retokened++))
  331. done
  332. }
  333. GETPOST(){
  334. if ! (($inlineauth)); then
  335. CONFIG
  336. source "$config"
  337. unset password
  338. fi
  339. if [[ "$1" ]]; then
  340. local pid="$1"
  341. else
  342. echo 'Please specify the post id'
  343. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  344. exit 1
  345. fi
  346. [[ "$2" == 'urlonly' ]] && local urlonly=1
  347. local post=''
  348. GETPOSTINIT(){
  349. if (($inlineauth)); then
  350. ! [[ "$password" ]] && PASSWORD
  351. (($verbose)) && echo -e "\e[0;36m""Getting post $pid...""\e[m"
  352. post=$(
  353. curl -ksSi -u "${login}:$password" \
  354. -H "User-Agent: $useragent" \
  355. -H "Content-Type: application/json" \
  356. -H 'Accept: application/json' \
  357. "${hub}/api/statuses/show.json?id=$pid")
  358. # "${hub}/api/z/1.0/item/full?item_id=$pid"
  359. # "${hub}/api/z/1.0/item/full?mid=$mid"
  360. unset password
  361. else
  362. (($verbose)) && echo -e "\e[0;36m""Getting post $pid...""\e[m"
  363. post=$(
  364. curl -ksSi \
  365. -H "Authorization: Basic $token" \
  366. -H "User-Agent: $useragent" \
  367. -H "Content-Type: application/json" \
  368. -H 'Accept: application/json' \
  369. "${hub}/api/statuses/show.json?id=$pid" \
  370. --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
  371. # "${hub}/api/z/1.0/item/full?item_id=$pid"
  372. # "${hub}/api/z/1.0/item/full?mid=$mid"
  373. unset password
  374. unset token
  375. fi
  376. postbody=$(echo -n "$post"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
  377. mid=$(echo -n "$postbody"|"$jq" -r '.message_id')
  378. posturl=$(echo -n "$postbody"|"$jq" -r '.url')
  379. posturl2="$(echo -n "$posturl"|sed 's|^.*\(https\?://[^/]\+\)/.*|\1|')/display/$mid"
  380. if ! (($urlonly)); then
  381. username=$(echo -n "$postbody"|"$jq" -r '.user.screen_name')
  382. userurl=$(echo -n "$postbody"|"$jq" -r '.user.url')
  383. userhub=$(echo "$userurl"|sed 's|^.*https\?://\([^/]\+\)/.*|\1|')
  384. posttxt=$(echo -n "$postbody"|"$jq" -r '.text')
  385. fi
  386. }
  387. GETPOSTINIT
  388. local error=''
  389. error=$(echo "$post" | grep -io '^This api requires login')
  390. [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  391. if [[ "$error" ]]; then
  392. if [[ $retokened != 1 ]] && [[ $inlineauth != 1 ]]; then
  393. if ! (($quiet)); then
  394. # echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  395. # echo -e '\e[37;32m'"\e[1m[warning] \e[0m" "$error"
  396. echo -en "\e[0;33m[warning] \e[m"; echo "$error"
  397. echo "Error or invalid token, requesting new one..."
  398. fi
  399. RETOKEN
  400. GETPOSTINIT
  401. local error=''
  402. error=$(echo "$post" | grep -io '^This api requires login')
  403. [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  404. if [[ "$error" ]]; then
  405. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  406. echo "Can't get post due authorization issue"
  407. echo "Check/set your login/password/server and try to get post again"
  408. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  409. exit 1
  410. fi
  411. else
  412. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  413. echo "Can't get post due authorization issue"
  414. echo "Check/set your login/password/server and try to get post again"
  415. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  416. exit 1
  417. fi
  418. fi
  419. if [[ "$mid" ]]; then
  420. if ! (($urlonly)); then
  421. echo -e "\e[0;36m""${username}@${userhub}:""\e[m\n"
  422. echo "$posttxt"
  423. if ! (($quiet)); then
  424. echo -e "\n\e[0;36m""post url: $posturl2""\e[m"
  425. fi
  426. else
  427. echo -e "\n\e[0;36m""$posturl2""\e[m"
  428. fi
  429. else
  430. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "No post returned, please try again or give up"
  431. (($verbose)) && echo -e '\e[37;31m'"\e[1m[post]\e[0m" && echo "$post"
  432. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  433. exit 1
  434. fi
  435. }
  436. POST(){
  437. if ! (($inlineauth)); then
  438. CONFIG
  439. source "$config"
  440. unset password
  441. fi
  442. if ! (($hasmsg)); then
  443. local postfile=$(mktemp /tmp/hzpost.XXXXXX)
  444. local message=$(mktemp /tmp/hzmessage.XXXXXX)
  445. else
  446. local postfile="$postfile"
  447. local message="$message"
  448. # echo HAS MESSAGE
  449. # echo
  450. # echo verbose "$verbose"
  451. # echo hasmsg "$hasmsg"
  452. # echo postfile "$postfile"
  453. # echo message "$message"
  454. # echo tagline "$tagline"
  455. # echo tags "$tags"
  456. # echo catline "$catline"
  457. # cat "$message"
  458. # exit
  459. fi
  460. [[ -f "$message" && -f "$postfile" ]] && chmod 600 "$postfile" "$message"
  461. local post=''
  462. local pid=''
  463. POSTINIT(){
  464. if ! (($hasmsg)); then
  465. if ! [[ -t 0 ]] || (($stdin)); then
  466. eval 'stdin=$(cat); echo "$stdin"' >"$message"
  467. else
  468. $EDITOR "$message"
  469. fi
  470. msglength=$(wc -m "$message"|cut -d ' ' -f 1)
  471. if ! (($msglength)); then
  472. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "The message is empty. Not posting message"
  473. echo "Not deleting the file \"$message\" in case it is not empty"
  474. /bin/rm -f "$postfile"
  475. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  476. exit 1
  477. fi
  478. ## Delete leading blank lines
  479. sed -i '/./,$!d' "$message"
  480. msglines=$(wc -l "$message"|cut -d ' ' -f 1)
  481. fi
  482. # Make tags only if message length more than 1 line
  483. if [[ ! "$tagline" ]] && [[ "$msglines" -gt 1 ]]; then
  484. tagline=$(tail -n 1 "$message" | grep -io '^[[:space:]]*\?\#.*\?')
  485. [[ "$tagline" ]] && hastagline="$tagline"
  486. ! (($catonly)) && tags=$(echo "$tagline" | sed 's|^[[:space:]]*||; s|,||g')
  487. fi
  488. if [[ ! "$catline" ]]; then
  489. catline=$(head -n 1 "$message" | grep -iom1 '^[[:space:]]*\?\*.*\?')
  490. [[ "$catline" ]] && hascatline=1
  491. (($tagtocat)) && catline=$(echo "$tagline" | sed 's|^[[:space:]]*\?\#|\*|g; s|[[:space:]]*\?\#| \*|g')
  492. fi
  493. catsarr=($(echo "$catline" | sed 's|[\*]| |g; s|^[[:space:]]*||; s|,||g; s/\"/\\"/g'))
  494. local category=''
  495. for c in "${catsarr[@]}"; do category+="${c},"; done
  496. # (($catonly)) && tagline='' && tags=''
  497. # echo verbose "$verbose"
  498. # echo hasmsg "$hasmsg"
  499. # echo postfile "$postfile"
  500. # echo message "$message"
  501. # echo tagline "$tagline"
  502. # echo tags "$tags"
  503. # echo catline "$catline"
  504. # echo catsarr "${catsarr[@]}"
  505. # echo category "$category"
  506. # cat "$message"
  507. # echo
  508. msg=$(cat "$message")
  509. # echo msg "$msg"
  510. # echo
  511. # echo
  512. if ! (($catonly)); then
  513. if [[ "$tagline" || "$hastagline" ]]; then
  514. msg=$(echo "$msg" | awk -F "$tagline" '{print $1}')
  515. fi
  516. else
  517. tagline='' && tags=''
  518. [[ "$hastagline" ]] && msg=$(echo "$msg" | awk -F "$hastagline" '{print $1}')
  519. fi
  520. # echo msg "$msg"
  521. # echo hasmsg $hasmsg
  522. # echo hastagline $hastagline
  523. # echo hascatline $hascatline
  524. # echo catline "$catline"
  525. # exit
  526. if ! (($hasmsg)) && ! (($tagtocat)) && (($hascatline)); then
  527. # FIXME: slow part
  528. [[ "$catline" ]] && msg=$(echo "$msg" | awk -v cl="$catline" '$0 == cl {i=1;next};i && i++ <= 999')
  529. ## Delete leading blank lines
  530. sed -i '/./,$!d' "$message"
  531. fi
  532. title=$(echo "$msg" | head -n 1 | grep -iom1 '^[[:space:]]*\?\#[[:space:]]\+.*\?' | sed 's/\"/\\"/g; s/^[[:space:]]*\?\#[[:space:]]\+//g')
  533. [[ "$title" ]] && msg=$(echo "$msg" | sed 1d)
  534. ## Delete leading blank lines
  535. sed -i '/./,$!d' "$message"
  536. # echo hasmsg $hasmsg
  537. # echo hastagline $hastagline
  538. # echo hascatline $hascatline
  539. # echo message "$message"
  540. # echo tagline "$tagline"
  541. # echo tags "$tags"
  542. # echo catline "$catline"
  543. # echo catsarr "${catsarr[@]}"
  544. # echo title "$title"
  545. # echo -n 'message '; cat "$message"; echo
  546. # echo msg "$msg"
  547. # exit
  548. [[ "$title" ]] && echo "title=\"$title\"">"$postfile"
  549. [[ "$category" ]] && echo "category=\"${category%,}\"">>"$postfile"
  550. if (($pandoc)); then
  551. # markdown="pandoc -f markdown -t html" # (pandoc's extended markdown)
  552. # markdown="pandoc -f markdown_phpextra -t html" # (PHP Markdown Extra extended markdown)
  553. # markdown="pandoc -f markdown_github -t html" # (github extended markdown)
  554. markdown="pandoc -f markdown_strict+footnotes+definition_lists+hard_line_breaks -t html" # (original unextended markdown + with footnotes and definition lists and hard line breaks)
  555. elif [[ "$mdexec" ]]; then
  556. markdown="$mdexec"
  557. fi
  558. htmlstatus=$(echo -n "$msg" | $markdown | sed 's/\"/\\"/g' | tr -d "\n"; [[ "$tags" ]] && echo "<br><br>$tags" | sed 's/\"/\\"/g' || echo "")
  559. [[ "$htmlstatus" ]] && echo "htmlstatus=\"$htmlstatus\"">>"$postfile"
  560. # echo msg "$msg"
  561. # exit
  562. source "$postfile"
  563. # echo " export token='$token'"
  564. # echo " export useragent='$useragent'"
  565. # echo " export hub='$hub'"
  566. # echo " export title='$title'"
  567. # echo " export category='$category'"
  568. # echo " export channel='$channel'"
  569. # echo " export htmlstatus='$htmlstatus'"
  570. # echo " export cookie='$cookie'"
  571. # exit
  572. if (($inlineauth)); then
  573. ! [[ "$password" ]] && PASSWORD
  574. (($verbose)) && echo -e "\e[0;36m""Posting...""\e[m"
  575. post=$(curl -ksSi \
  576. -u "${login}:$password" \
  577. -H "User-Agent: $useragent" \
  578. -X POST \
  579. -d "title=${title}&category=$category" \
  580. --data-urlencode "htmlstatus=$htmlstatus" \
  581. "${hub}"/api/statuses/update)
  582. unset password
  583. else
  584. (($verbose)) && echo -e "\e[0;36m""Posting...""\e[m"
  585. post=$(curl -ksSi \
  586. -H "Authorization: Basic $token" \
  587. -H "User-Agent: $useragent" \
  588. -X POST \
  589. -d "title=${title}&category=${category}&channel=$channel" \
  590. --data-urlencode "htmlstatus=$htmlstatus" \
  591. "${hub}"/api/statuses/update \
  592. --cookie-jar "${confdir}/$cookie" --cookie "${confdir}/$cookie")
  593. unset password
  594. unset token
  595. fi
  596. # echo "$post"
  597. # exit
  598. postbody=$(echo -n "$post"|grep -iom1 '{\".*[^\]\(["}]\|\]\)}')
  599. mid=$(echo -n "$postbody"|"$jq" -r '.message_id')
  600. if [[ "$mid" ]]; then
  601. posturl=$(echo -n "$postbody"|"$jq" -r '.url')
  602. posturl2="$(echo -n "$posturl"|sed 's|^.*\(https\?://[^/]\+\)/.*|\1|')/display/$mid"
  603. fi
  604. pid=$(echo -n "$postbody"|"$jq" -r '.id')
  605. username=$(echo -n "$postbody"|"$jq" -r '.user.screen_name')
  606. userurl=$(echo -n "$postbody"|"$jq" -r '.user.url')
  607. userhub=$(echo "$userurl" | sed 's|^.*https\?://\([^/]\+\)/.*|\1|')
  608. }
  609. POSTINIT
  610. local error=''
  611. error=$(echo "$post" | grep -io '^This api requires login')
  612. [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  613. if [[ "$error" ]]; then
  614. if ! (($retokened)) && ! (($inlineauth)); then
  615. if ! (($quiet)); then
  616. # echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  617. # echo -e '\e[37;32m'"\e[1m[warning] \e[0m" "$error"
  618. echo -en "\e[0;33m[warning] \e[m"; echo "$error"
  619. echo "Error or invalid token, requesting new one..."
  620. fi
  621. RETOKEN
  622. POSTINIT
  623. local error=''
  624. error=$(echo "$post" | grep -io '^This api requires login')
  625. [[ "$error" ]] || error=$(echo "$post" | grep -o '^HTTP/[[:digit:]]\.[[:digit:]] \+[3-9]\{1,3\}.*')
  626. if [[ "$error" ]]; then
  627. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  628. echo "Can't post due authorization issue"
  629. echo "Check/set your login/password/server and try to post again"
  630. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  631. exit 1
  632. fi
  633. else
  634. echo -en '\e[37;31m'"\e[1m[error] \e[0m"; echo -en "\e[0;31m"; echo -n "$error"; echo -e "\e[m"
  635. echo "Can't post due authorization issue"
  636. echo "Check/set your login/password/server and try to post again"
  637. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  638. exit 1
  639. fi
  640. fi
  641. if [[ "$mid" || "$pid" ]]; then
  642. if ! (($quiet)); then
  643. if [[ "$pid" ]]; then
  644. local id="$pid"
  645. elif [[ "$mid" ]]; then
  646. local id="$mid"
  647. fi
  648. echo -e '\e[37;32m'"\e[1m[success]\e[0m" "Message "$id" posted"
  649. echo -en "\e[0;36m""post url: ""\e[m"
  650. # (($verbose)) && echo -e '\e[37;32m'"\e[1m[post]:\n$post\e[0m"
  651. fi
  652. if [[ "$mid" ]]; then
  653. echo -e "\e[0;36m""$posturl2""\e[m"
  654. else
  655. GETPOST "$pid" urlonly
  656. fi
  657. /bin/rm -f "$postfile" "$message"
  658. else
  659. echo -e '\e[37;31m'"\e[1m[error]\e[0m" "No post id returned, please try again or give up"
  660. (($verbose)) && echo -e '\e[37;31m'"\e[1m[post]:\n" && echo -n "$post" && echo -e "\e[0m"
  661. echo "Message should still be saved in the file $message"
  662. /bin/rm -f "$postfile"
  663. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  664. exit 1
  665. fi
  666. }
  667. # DELETE CONFIG & COOKIE
  668. DELETE(){
  669. # [[ "$config" ]] && source "$config" && unset password
  670. # ! (($quiet)) && echo Deleting: cookie: "${confdir}/${zid}.cookie", config: "$config"
  671. # [[ "$confdir" && "$zid" ]] && [[ -f "${confdir}/${zid}.cookie" ]] && /bin/rm -f "${confdir}/${zid}.cookie"
  672. # [[ "$config" ]] && [[ -f "$config" ]] && /bin/rm -f "$config"
  673. ! (($quiet)) && (($verbose)) && [[ $zid ]] && echo -e "\e[0;36m""Using config: $zid""\e[m"
  674. # Find directory of config file if '$config' is file and set it as config directory '$confdir'
  675. [[ -f "$zid" ]] && local confdir=$(dirname "$zid")
  676. # In case '$config' is zid:
  677. # set config directory to script dot directory '$dotdir'
  678. [[ -d "$confdir" ]] || local confdir="$dotdir"
  679. # Create path to config file and set it as '$config'
  680. if [[ -f "$zid" ]]; then
  681. true
  682. else
  683. if [[ -f "${confdir}/${zid}" ]]; then
  684. local config="${confdir}/$zid"
  685. local cookie="${confdir}/${zid%.config}.cookie"
  686. elif [[ -f "${confdir}/${zid}.config" ]]; then
  687. local config="${confdir}/${zid}.config"
  688. local cookie="${confdir}/${zid%.config}.cookie"
  689. fi
  690. fi
  691. ! (($quiet)) && echo Deleting cookie: "$cookie"
  692. [[ -f "$cookie" ]] && /bin/rm -f "$cookie"
  693. ! (($quiet)) && echo Deleting config: "$config"
  694. [[ -f "$config" ]] && /bin/rm -f "$config"
  695. }
  696. if [[ $# -lt 1 ]]; then
  697. exe=1
  698. POST
  699. elif [[ "$1" == '--help' ]]; then
  700. USAGE
  701. exit 0
  702. fi
  703. # RUN OPTIONS
  704. while getopts ":c:d:D:g:him:pPqrsS:tTu:v" OPTION
  705. do
  706. case $OPTION in
  707. c)
  708. if [[ "$OPTARG" ]]; then
  709. config="$OPTARG"
  710. custconfig=1
  711. fi
  712. ;;
  713. d)
  714. #if [[ "$OPTARG" ]]; then
  715. # config="$OPTARG"
  716. # custconfig=1
  717. #fi
  718. setdefconf=1
  719. ;;
  720. D)
  721. exe=1
  722. zid="$OPTARG"
  723. DELETE
  724. ;;
  725. g)
  726. exe=1
  727. pid="$OPTARG"
  728. GETPOST "$pid"
  729. # echo "$pid"
  730. ;;
  731. h)
  732. exe=1
  733. USAGE
  734. ;;
  735. i)
  736. stdin=1
  737. ;;
  738. m)
  739. mdexec="$OPTARG"
  740. ;;
  741. p)
  742. exe=1
  743. POST
  744. ;;
  745. P)
  746. pandoc=1
  747. ;;
  748. q)
  749. quiet=1
  750. ;;
  751. r)
  752. exe=1
  753. RETOKEN
  754. ;;
  755. s)
  756. exe=1
  757. setnew=1
  758. setdefconf=1
  759. SETAUTH
  760. ;;
  761. S)
  762. sslarg="$OPTARG"
  763. if [[ "$sslarg" ]]; then
  764. if [[ "$sslarg" == [nN][oO] ]]; then
  765. ssl=0
  766. sslsetted=1
  767. elif [[ "$sslarg" == [yY][eE][sS] ]]; then
  768. ssl=1
  769. sslsetted=1
  770. fi
  771. else
  772. ssl=1
  773. sslsetted=1
  774. fi
  775. ;;
  776. t)
  777. tagtocat=1
  778. ;;
  779. T)
  780. tagtocat=1
  781. catonly=1
  782. ;;
  783. u)
  784. if [[ "$OPTARG" ]]; then
  785. # "user@example.com:hubdomain.com:password"
  786. haspass=$(echo "$OPTARG" | awk -F':' '{print $3}')
  787. login="${OPTARG%%:*}"
  788. if [[ "$haspass" ]]; then
  789. domainandpass="${OPTARG#*:}"
  790. domain="${domainandpass%%:*}"
  791. password="${domainandpass#*:}"
  792. unset haspass
  793. unset domainandpass
  794. else
  795. domain="${OPTARG##*:}"
  796. fi
  797. if (($ssl)); then
  798. hub="https://$domain"
  799. else
  800. hub="http://$domain"
  801. fi
  802. zid=""
  803. inlineauth=1
  804. fi
  805. ;;
  806. v)
  807. verbose=1
  808. ;;
  809. \?)
  810. # echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Invalid option: -$OPTARG" >&2
  811. echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Invalid option" >&2
  812. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  813. exit 1
  814. ;;
  815. :)
  816. echo -e '\e[37;34m'"\e[1m[notice]\e[0m" "Option -$OPTARG requires an argument" >&2
  817. (($verbose)) && echo -e "\e[0;36m""Exiting""\e[m"
  818. exit 1
  819. ;;
  820. esac
  821. done
  822. shift $(($OPTIND -1))
  823. # echo $exe; exit
  824. ## Post if no other functional commands was given
  825. if ! (($exe)); then
  826. exe=1
  827. POST
  828. fi
  829. exit 0
  830. ### TODO:
  831. # message size limit (bash var)
  832. # read post + comments
  833. # read by mid
  834. # private post
  835. # use keyring
  836. # delete post
  837. # comment post
  838. # delete comment
  839. # reshare post
  840. # like, dislike
  841. # attach image to post
  842. # notifications
  843. # debug
  844. # version option
  845. # webdav files
  846. # more errors handle
  847. # >&2