transmission-ob 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #!/bin/bash
  2. # access transmission-cli through openbox menu
  3. # by ondoho/ohnonot 2015-2021
  4. # Depends on:
  5. # - transmission-daemon and transmission-remote
  6. # - xclip for various actions
  7. # - notify-send (optional - the actions are executed regardless, you just don't get a notification)
  8. # - timeout (coreutils)
  9. usage() {
  10. if [ -t 0 ]; then [[ "$*" != "" ]] && echo "$*
  11. "
  12. cat <<EOF
  13. Openbox pipemenu to create a list of recent files with or without icons.
  14. Usage: $0 [options]
  15. Options:
  16. -t int Set timeout in seconds for transmission-remote commands. Default: $timeout
  17. -x str Choose different clipboard for copying from & pasting to. Possible
  18. values: primary, secondary, clipboard. Default: $sel
  19. -g str Full command to open the (web) UI with options. The URL to connect to
  20. transmission-remote is inserted whereever you place the string %URL%
  21. (if required at all). Can also be defined through the TR_GUI environemnt
  22. variable. No default - if you leave this empty, the according menu
  23. options won't be displayed.
  24. -u str URL for transmission-remote. If the environment variable TR_AUTH is
  25. defined it will be inserted at the right place.
  26. Default: $url
  27. -T str Terminal to use for stats. It is possible to append options.
  28. Can also be defined through the XTERMINAL environemnt variable.
  29. Current default: $XTERMINAL
  30. -S Path or link to a document with information (e.g. about torrent search
  31. sites). No quality control!
  32. Default: ${tsearch//"$HOME"/\~}
  33. -b Browser or document viewer to display the former. Default: $browser
  34. No quality control!
  35. If any option string contains spaces, enclosing it in quotes might not work due
  36. to how openbox' xml works. Try escaping spaces with a backslash \ instead.
  37. -h This text.
  38. Internal options (access through the pipemenu):
  39. -l List all torrents with some minimal stats.
  40. Clicking/activating each entry will toggle start/pause.
  41. -s Print out statistics in terminal window
  42. Dependencies:
  43. bash, transmission-cli/transmission-daemon and timeout (coreutils).
  44. Optional:
  45. - sed for stats.
  46. - A notification daemon that provides the notify-send executable
  47. - one of urxvt or xterm (other terminals not tested).
  48. - xclip to add torrents from the clipboard.
  49. EOF
  50. else
  51. echo "<openbox_pipe_menu>"
  52. [[ "$*" != "" ]] && echo "<item label=\"$*\"/></openbox_pipe_menu>"
  53. fi
  54. exit 1
  55. }
  56. sepchar="─";sep=''
  57. sel=primary
  58. timeout=3
  59. XTERMINAL="xterm"
  60. action=""
  61. authenv=""
  62. url="http://127.0.0.1:9091"
  63. TR_GUI=""
  64. browser=surf
  65. tsearch="$XDG_CONFIG_HOME/openbox/pipemenus/torrentsearchsites.html"
  66. while getopts "t:x:g:u:T:lshb:S:" opt; do
  67. case "$opt" in
  68. t) [[ "$OPTARG" =~ [0-9]+ ]] && (( OPTARG >= 0 )) && (( OPTARG <= 65535 )) || usage "Option -${opt}: invalid number $OPTARG"
  69. timeout="$OPTARG"
  70. ;;
  71. x) sel="$OPTARG"
  72. ;;
  73. g) TR_GUI="$OPTARG"
  74. ;;
  75. u) url="$OPTARG"
  76. ;;
  77. T) type "${OPTARG%% *}" >/dev/null || usage "$OPTARG not found in PATH"
  78. XTERMINAL="$OPTARG"
  79. ;;
  80. l) action=list
  81. ;;
  82. s) action=stats
  83. ;;
  84. b) browser="$OPTARG"
  85. ;;
  86. S) tsearch="$OPTARG"
  87. ;;
  88. h) usage
  89. ;;
  90. esac
  91. done
  92. # environment variable TR_AUTH for login to web page
  93. if [[ "$TR_AUTH" == ?*:?* ]]; then
  94. # if defined, insert into URL:
  95. url="${url%%:*}://$TR_AUTH@${url#*://}"
  96. authenv="--authenv"
  97. fi
  98. cmd=( timeout $timeout transmission-remote $authenv )
  99. case "$action" in
  100. list) mapfile -t info <<<"$(${cmd[@]} -t all -i | grep -E 'Id: |Name: |State: |Percent Done: |Download Speed: |Upload Speed: ')"
  101. if [[ "$info" != "" ]]; then
  102. list=""
  103. for ((i=0;i<${#info[@]};i+=6)); do
  104. id="${info[i]#*: }"
  105. name="${info[$((i+1))]#*: }"
  106. state="${info[$((i+2))]#*: }"
  107. case "$state" in
  108. Seeding) state=Seed;;
  109. Downloading) state=Dnld;;
  110. Uploading) state=Upld;;
  111. "Up & Down") state=UpDn;;
  112. Stopped) state=Stop;;
  113. Paused) state=Paus;;
  114. esac
  115. perc="${info[$((i+3))]#*: }"
  116. perc="${perc/.?/}"
  117. down="${info[$((i+4))]#*: }"
  118. down="${down/B\/s/}"
  119. down="${down/ /}"
  120. down="${down/.??/}"
  121. up="${info[$((i+5))]#*: }"
  122. up="${up/B\/s/}"
  123. up="${up/ /}"
  124. up="${up/.??/}"
  125. #~ label="$(printf "%-30s %4s %s ↓%s" "${name:0:30}" "$perc" "$state" "$down↑$up")" # looks good with monospaced font
  126. label="$(printf "%s %4s ↓%s — %s" "$state" "$perc" "$down↑$up" "${name:0:30}")"
  127. [[ "$state" == Stop || "$state" == Paus ]] && option="start" || option="stopp"
  128. list="$list<item label=\"$label\"><action name=\"Execute\"><command><![CDATA[sh -c 'notify-send \"Torrent ${option}ed:\" \"$name\n\$(${cmd[@]} -t $id --${option%p})\"']]></command></action></item>"
  129. done
  130. else
  131. list="<item label=\"Couldn&apos;t get list of torrents.\"/>"
  132. fi
  133. echo "<openbox_pipe_menu>${list}</openbox_pipe_menu>"
  134. exit
  135. ;;
  136. stats) mapfile stats <<<"$(${cmd[@]} -st -si | sed '/^$/d')"
  137. [[ "$stats" != CURRENT* ]] && stats="COULDN'T GET INFO - TIMEOUT ($timeout}s) REACHED? "
  138. members=${#stats[@]}
  139. longest=0
  140. for i in "${stats[@]}"; do (( ${#i} > longest )) && longest=${#i}; done
  141. #~ for ((i=0;i<longest;i++)); do sep="$sep$sepchar"; done
  142. #~ stats[0]="${stats[0]^^}$sep"
  143. $XTERMINAL -geometry "$longest"x$((members+1)) -title "Session & statistical info from transmission-daemon" -e bash -c 'echo -n "$@"; read -n1' non "${stats[@]}"
  144. exit
  145. ;;
  146. esac
  147. [ -n "$TR_GUI" ] && TR_GUI="${TR_GUI//%URL%/"$url"}"
  148. title=""
  149. ismagnet() {
  150. [[ "$1" == "magnet:"* ]] || return 1
  151. title="${1##*dn=}"
  152. title="${title%%&*}"
  153. title="$(printf "%b" "${title//%/\\x}")"
  154. }
  155. daemoncount=( $(pidof transmission-daemon) )
  156. count=0
  157. case ${#daemoncount[@]} in
  158. 0) item[count++]="<item label=\"Start Daemon\">
  159. <action name=\"Execute\">
  160. <command>
  161. transmission-daemon --log-error
  162. </command>
  163. </action>
  164. </item>"
  165. [ -n "$TR_GUI" ] && item[count++]="<item label=\"Start Daemon + Open UI\">
  166. <action name=\"Execute\">
  167. <command>
  168. sh -c 'transmission-daemon --log-error; sleep 2; exec $TR_GUI'
  169. </command>
  170. </action>
  171. </item>"
  172. ;;
  173. 1) [ -n "$TR_GUI" ] && item[count++]="<item label=\"Open UI\">
  174. <action name=\"Execute\">
  175. <command>
  176. $TR_GUI
  177. </command>
  178. </action>
  179. </item>"
  180. type xclip >/dev/null && ismagnet "$(xclip -o -selection $sel)" &&\
  181. item[count++]="<menu label=\"Add torrent from magnet link (clipboard)\" id=\"addtorrentfromclipboard\">
  182. <item label=\"Add paused: $title\">
  183. <action name=\"Execute\">
  184. <command>
  185. sh -c 'notify-send \"Add paused: $title\" \"\$(${cmd[@]} -a \"\$(xclip -selection $sel -o)\" --start-paused)\"'
  186. </command>
  187. </action>
  188. </item>
  189. <item label=\"Add and start: $title\">
  190. <action name=\"Execute\">
  191. <command>
  192. sh -c 'notify-send \"Add and start: $title\" \"\$(${cmd[@]} -a \"\$(xclip -selection $sel -o)\" --no-start-paused)\"'
  193. </command>
  194. </action>
  195. </item>
  196. </menu>"
  197. item[count++]="<menu label=\"List all torrents\" execute=\"$0 -l\" id=\"listalltorrents\"/>"
  198. item[count++]="<item label=\"List transmission-daemon stats in $XTERMINAL\">
  199. <action name=\"Execute\">
  200. <command>
  201. $0 -s
  202. </command>
  203. </action>
  204. </item>"
  205. item[count++]="<separator/><item label=\"Stop Daemon\">
  206. <action name=\"Execute\">
  207. <command>
  208. sh -c 'notify-send \"Transmission daemon stopped\" \"\$(${cmd[@]} --exit)\"'
  209. </command>
  210. </action>
  211. </item>"
  212. ;;
  213. *) item[count++]="<separator label=\"Warning, ${#daemoncount[@]} daemons detected!\" />
  214. <item label=\"Kill all daemons\">
  215. <action name=\"Execute\">
  216. <command>
  217. killall transmission-daemon
  218. </command>
  219. </action>
  220. </item>"
  221. ;;
  222. esac
  223. # lastly, add a list of torrent search sites
  224. [ -n "$browser" ] && [ -n "$tsearch" ] && item[count]="<separator/><item label=\"Torrent Search Sites\">
  225. <action name=\"Execute\">
  226. <command>
  227. $browser \"$tsearch\"
  228. </command>
  229. </action>
  230. </item>"
  231. echo "<openbox_pipe_menu>${item[@]}</openbox_pipe_menu>"