Skip to content

Instantly share code, notes, and snippets.

@paius1
Last active October 14, 2020 14:08
Show Gist options
  • Save paius1/85b594a4bd8bab001c71e3fb0f65c62d to your computer and use it in GitHub Desktop.
Save paius1/85b594a4bd8bab001c71e3fb0f65c62d to your computer and use it in GitHub Desktop.
Conky Monitor for transmission-remote
#!/bin/bash
#
# prints conky formatted output from running transmission-daemons
# add the following line to the conky config file e.g. .conkyrc
# ${texecpi 3 /path/to/script/monitor_transmission_remote.sh}
# set narrow to any value to print a narrow version
# vnstats assumes you can ssh into host w/o password
# see: http://www.linuxproblem.org/art_9.html
# output with two lines per torrent
narrow=1
# show a progress bar when downloading
showBAR='1'
# Check for multiple remotes
if transmission-remote HOST:9091 --auth=USER:PASSWORD -st > /dev/null 2>&1; then
hosts+=('HOST'); users+=('USER'); ports+=('9091'); passwords+=('password')
interfaces+=( 'tun0' ); hostCOLORS+=("\${color F49D9D}")
marker+=('somemark')
fi
#if transmission-remote HOST2:9091 --auth=USER2:PASSWORD2 -st > /dev/null 2>&1; then
#hosts+=('HOST2'); users+=('USER2'); ports+=('9091'); passwords+=('password2')
#interfaces+=( 'eth0' ); hostCOLORS+=("\${color green}")
#marker+=('somemark2')
#fi
# to colorize up and down speeds
function gradient {
cat <<- EOL
ff3200
ff3c00
ff4600
ff5000
ff5a00
ff6400
ff6e00
ff7800
ff8200
ff8c00
ff9600
ffa000
ffaa00
ffb400
ffbe00
ffc800
ffd200
ffdc00
ffe600
fff000
fffa00
fdff00
d7ff00
b0ff00
8aff00
65ff00
3eff00
17ff00
00ff10
00ff36
00ff5c
00ff83
00ffa8
00ffd0
00fff4
00e4ff
00d4ff
EOL
}
maxuP=1300
maxdN=6000
steps=$(wc -l <<< $(gradient))
stepuP=$((maxuP/steps))
stepdN=$((maxdN/steps))
# Color coding names from rgb.txt or Hex RRGGBB
colorID='grey80'
colorIdle='grey80'; barIdle='765353'
colorStop='A5142C'; barStop='000000'
colorSeed='A6DAF7'; barSeed='0B5D8A'
colorUpDn='A1F4A1'; barUpDn='088A08'
colorDown='7EF47E'; barDown='084408'
colorUp='B3F3F7'; barUp='049FA7'
colorVerify='F4EEFE'; barVerify='B28FF7'
# trim torrent name to this many characters
trim=28
# Fonts
# https://github.com/source-foundry/Hack
font='Hack:size=9'
fontHeading='Hack:size=8'
fontName='Hack:size=11'
# appx character width in pixels
pxCHR=8
# hack to adjust eta right in wide mode
adjETA=9
# Columns
colID=5
colSTATE=27
colNAME=50
colETA=$(echo "((($trim + $adjETA)*$pxCHR)+$colNAME-$adjETA)/1" | bc)
((narrow)) && colETA=$((colNAME+5))
colRAT=$((colETA+55))
colLEEC=$((colRAT+40))
colSEED=$((colLEEC+20))
colDN=$((colSEED+10))
((narrow)) && colDN=$((colSEED+40))
colUP=$((colDN+60))
tSPEED=$((colDN+50))
# Icons for torrent state
iconUD="\${font Hack:bold:size=10}⇅\${font}"
iconDN="\${font Hack:bold:size=10}↓\${font}"
iconUP="\${font Hack:bold:size=10}↑\${font}"
iconIDLE="\${font Hack:bold:size=10}≠\${font $font}"
# from img.dafont.com/dl/?f=pizzadude_bullets
iconSTOP="\${font PizzaDude Bullets:size=9}\${color red4}F\${font $font}"
# Filter Torrents
filter="Seedi\|Downloading\|Uploading\|Up "
filter=$filter"\|Verify"
filter=$filter"\|Will"
# filter=$filter"\|Queued"
# filter=$filter"\|Idle"
# filter=$filter"\|Stopped"
ignore="ipMagnet+Tracking+Link"
#ignore=''
# for vnstat
month="$(date +%b)"
stats=()
function human_netspeed() {
awk -v sum="$1" ' BEGIN {hum[1024^2]="G"; hum[1024]="M"; for (x=1024^2; x>=1024; x/=1024) { if (sum>=x) { printf "%4.1f%s\n",sum/x,hum[x]; break; } } if (sum<1024) { printf "%4.0f%s\n",sum,"K"; } } '
}
# get listing of torrent info from daemon(s) and print interface totals
for ((host=0;host<${#hosts[@]};host++)); do
transmission-remote "${hosts[$host]}":"${ports[$host]}" --auth="${users[$host]}":"${passwords[$host]}" -l -st -t 1-199 -i | csplit -s --prefix=/tmp/tr. - /NAME/
dN='0'; uP='0'
eval "$( grep 'Sum: ' /tmp/tr.00 | awk '{printf "%s%.0f %s%0.f",a,$4,b,$5}' a='uP=' b='dN=' )"
# prettify up/down speed
if [[ "${dN}" = "0" ]]; then
dN=''
else
colordN="\${color $( gradient | tail -n "$(bc <<< "${dN} / $stepdN +1" )" | head -1)}"
dN=$(human_netspeed "${dN}")
fi
if [[ "${uP}" = "0" ]]; then
uP=''
else
coloruP="\${color $( gradient | tail -n "$(bc <<< "${uP} / $stepuP +1" )" | head -1)}"
uP=$(human_netspeed "${uP}")
fi
# Name of host
echo -n "\${font Hack:size=9}\${goto 14}${hostCOLORS[$host]}${hosts[$host]}"
# Upload speed
echo -n "\${goto 80}\${color grey80}Up: ${coloruP}${uP}"
# Download speed
echo -n "\${goto 165}\${color grey70}Dn: ${colordN}${dN}"
# Total ratio
echo "\${alignr}\${color grey70}Ratio: ${hostCOLORS[$host]}$( grep Ratio /tmp/tr.00 | tail -n 1 |cut -d' ' -f9 )"
# data for individual torrents
sometorrents="${sometorrents}"$'\n'$( grep "${filter}" /tmp/tr.00 | sed -n '2,$p' )
# remove blank lines
sometorrents=$( sed '/^$/d' <<< "${sometorrents}" )
nb_torrents+=( $( grep -c '^' < <( echo -n "${sometorrents}") ) )
info="$info"$'\n'$( grep -E 'State:|Peers:' /tmp/tr.01| grep -A1 "${filter}" | sed -n "/$filter/{n;p}" | sed '/^$/d' )
# if monitoring interface statistics
# add */Xmin * * * * ssh "user"@"host" vnstat -s -i "interface" > /tmp vnstats-"host"
# to crontab to generate recent file
if [ -f /tmp/vnstats-"${hosts[$host]}" ]; then
stats+=("'$(</tmp/vnstats-"${hosts[$host]}")'")
else
stats+=( "$( ssh "${users[$host]}"@"${hosts[$host]}" /opt/bin/vnstat -s -i "${interfaces[$host]}" &>/dev/null )")
fi
# daily totals
awk ' /today/ {printf "%s %s %8.1f %s %s %8.1f %s ",DAY,TX,$5,$6,RX,$2,$3}' DAY="\${goto 30}${hostCOLORS[$host]}Tdy\${goto 85}" TX="" RX="\${goto 180}" <<< "${stats[$host]}"
# monthly totals
if ((narrow)); then
echo -ne "\n\${goto 30}"
awk -v month="${month}" ' $0~month {printf "%s %s %7.1f %s %s %7.1f %s\n",MTH,TX,$6,$7,RX,$3,$4}' MTH="${month}\${goto 85}" TX="" RX="\${goto 180}" <<< "${stats[$host]}"
else
awk -v month="${month}" ' $0~month {printf "%s %s %7.1f %s %s %7.1f %s\n",MTH,TX,$6,$7,RX,$3,$4}' MTH="\${goto 250}${month}\${goto 265}" TX="" RX="\${goto 366}" <<< "${stats[$host]}"
fi
# end of interface monitoring
done
echo "\${voffset -6}\${color3}\${hr 1}"
# test to check we actually got some data back
# if not, print error message if you like, and/or exit
[ -z "${sometorrents}" ] && { echo -e "\${voffset 0}\\${color cyan}Transmission Inactive\n"; exit 255; }
# PRINT COLUMN HEADINGS
((narrow)) && vOFFSET=13
echo "\${color ${colorID}}\${voffset 1}\${goto 5}\${font ${fontHeading}}\${goto $((colID+5))}id\${goto ${colNAME}}TITLE\${goto ${colETA}}\${voffset ${vOFFSET}}eta\${goto ${colRAT}} %\${goto ${colLEEC}}\${font Hack:size=8}↓\${goto ${colSEED}}↑\${goto $((colDN+30))}↓\${goto ${tSPEED}}SPEED\${goto $((colUP+35))}↑\${voffset 5}"
# PARSE OUTPUT TO GET PER TORRENT DATA
n="${nb_torrents[-1]}"; host=0
# No active torrents
[ "$n" == " 1" ] && exit 1
declare eta progress status
for i in $(seq "$n"); do
# data for individual torrent
torrent[$i]=$( sed -n ''"$i"'p' <<< "${sometorrents}" | sed "s/ \+/!/g; s/^ /!/; s/'//g; s/!/ /g10" | tr -d "[]")
# assign values id progress eta up down ratio status name
eval "$(awk -F! '{printf "\n%s%02s%s %s%d%s %s%.6s%s %s%8.0f%s %s%8.0f%s %s%.1f%s %s%s%s %s%s%s\n",a,$2,cq,b,$3,cq,c,$5,cq,d,$6,cq,e,$7,cq,f,$8,cq,g,$9,cq,h,$10,cq}' cq="'" a="id[$i]='" b="progress[$i]='" c="eta[$i]='" d="up[$i]='" e="down[$i]='" f="ratio[$i]='" g="status[$i]='" h="name[$i]='" <<< "${torrent[$i]}" )"
[[ "${eta[$i]:0:2}" =~ "1 " ]] && eta[$i]=$(sed 's/s$//' <<< "${eta[$i]}")
# trim and add ellipsis if name is too long
(( "${#name[$i]}" > "${trim}" )) && name[$i]="$(cut -c -${trim} <<< "${name[$i]}")..."
# if still downloading show download percent instead of ratio
[ "${eta[$i]}" != "Done" ] && { ratio[$i]=$(echo "${progress[i]} 100" | awk '{printf "%.2f",$1 / $2}'); }
# get number and state active of peers
leech[$i]=$( head -n "$i" <<< "${info}" | tail -1 | grep -Po '(?<=g from )[0-9]*')
seeds[$i]=$( head -n "$i" <<< "${info}" | tail -1 | grep -Po '(?<=g to )[0-9]*')
# add mark to ID for individual hosts
[[ "$i" -gt "${nb_torrents[$host]}" ]] && ((host++))
id[$i]="\${color cyan}${id[$i]}${marker[$host]}"
done
# format and output to conky
# field to sort on
sort=16; (($showBAR)) && sort=22
{
for i in $(seq "$n")
do
[[ "${name[$i]}" = "$ignore" ]] && continue
case "${progress[$i]}" in
100|0|n/a)
barHEIGHT=0; barWIDTH=1
;;
*)
barHEIGHT=12; barWIDTH=$( bc <<< "(($trim + 4)*$pxCHR)/1" )
;;
esac
case "${status[$i]}" in
"Idle")
color="$colorIdle"
barCOLOR="$barIdle"
#icon="\${font JetBrains Mono:size=9:Regular}≠\${font $font}" #↮ ⚸ ≠ ∉ ↹ 闲 ♉ 😹
icon="${iconIDLE}"
;;
"Stopped")
color="${colorStop}"
barCOLOR="${barStop}"
#icon="\${font PizzaDude Bullets:size=9}\${color red4}F\${font $font}"
icon="${iconSTOP}"
;;
"Up & Down")
color="$colorUpDn"
barCOLOR="${barUpDn}"
icon="${iconUD}"
;;
"Downloading")
color="${colorDown}"
barCOLOR="${barDown}"
icon="${iconDN}"
;;
"Seeding")
color="${colorSeed}"
barCOLOR="${barSeed}"
icon="${iconUP}"
;;
"Uploading")
color="${colorUp}"
barCOLOR="${barUp}"
icon="${iconUP}"
;;
*)
color="${colorVerify}"
barCOLOR="${barVerify}"
icon="\${font Liberation:size=10}✔\${font $font}"
;;
esac
# colorize speed
colorUp[$i]="$( gradient | tail -n "$(bc <<< "${up[$i]} / ${stepuP} +1" )" | head -1)"
colorDown[$i]="$( gradient | tail -n "$(bc <<< "${down[$i]} / ${stepdN} +1" )" | head -1)"
# remove zero values
if [[ "${down[$i]}" == *" 0" ]]; then
down[$i]=""
elif [[ "${down[$i]}" -ge "1000" ]]; then
down[$i]=$(awk '{$1/=1024;printf "%s%.2fM"," ",$1}' <<< "${down[$i]}" )
else
down[$i]="${down[$i]}K"
fi
if [[ "${up[$i]}" == *" 0" ]]; then
up[$i]=""
elif [[ "${up[$i]}" -ge "1000" ]]; then
up[$i]=$(awk '{$1/=1024;printf "%s%.2fM"," ",$1}' <<< "${up[$i]}" )
else
up[$i]="${up[$i]}K"
fi
[[ -z "${up[$i]}" && -z "${down[$i]}" ]] && { color="${colorIdle}"; barCOLOR="${barIdle}"; }
[[ "${color}" = "0" ]] && color='white'
case "${showBAR}" in
1|TRUE) ## SHOW PROGRESS BAR
echo "\${color ${colorID}}\${font ${font}}\${goto ${colID}}${id[$i]}\${voffset -0}\${goto ${colSTATE}}\${color ${color}}${icon}\${color ${barCOLOR}}\${voffset -4}\${goto ${colNAME}}\${execibar 4 ${barHEIGHT},${barWIDTH} echo ${progress[$i]}}\${voffset -1}\${font ${fontName}}\${color ${color}}\${goto ${colNAME}}${name[$i]}\${font ${font}}\${voffset ${vOFFSET}}\${goto ${colETA}}${eta[$i]}\${goto ${colRAT}}${ratio[$i]}\${goto ${colSEED}}${seeds[$i]}\${goto ${colLEEC}}${leech[$i]}\${goto ${colDN}}\${color ${colorDown[$i]}}${down[$i]} \${goto ${colUP}}\${color ${colorUp[$i]}}${up[$i]}\${voffset 3}"
;;
*) # NO PROGESS BAR
echo "\${color ${colorID}}\${font ${font}}\${goto ${colID}}${id[$i]} \
\${voffset -2}\${goto ${colSTATE}}\${color ${color}}${icon} \
\${font ${fontName}}\${color ${color}}\${goto ${colNAME}}${name[$i]} \
\${font ${font}}\${voffset ${vOFFSET}}\${goto ${colETA}}${eta[$i]} \
\${goto ${colRAT}}${ratio[$i]} \
\${goto ${colSEED}}${leech[$i]} \
\${goto ${colLEEC}}${seeds[$i]} \
\${goto ${colDN}}\${color ${colorUp[$i]}}${up[$i]} \
\${goto ${colUP}}\${color ${colorDown[$i]}}${down[$i]}"
;;
esac
done
} | sort --version-sort -t'}' -k "$sort" # sort on Ratio/Percent Field
echo "\${voffset -$( echo $(( ${nb_torrents[$host]} * 4 )))}"
exit 0
@paius1
Copy link
Author

paius1 commented Dec 23, 2019

Complete rewrite with color progress bars and heat for upload and download speed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment