Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How I prefer to view the output of 'gbt torrent list' #94

Open
PriamX opened this issue Oct 13, 2023 · 0 comments
Open

How I prefer to view the output of 'gbt torrent list' #94

PriamX opened this issue Oct 13, 2023 · 0 comments

Comments

@PriamX
Copy link

PriamX commented Oct 13, 2023

#!/bin/bash
#
# A humble script to format qbitorrent-cli's "qbt torrent list"
# the way I like to view it.
#
# PriamX@github 10/5/23

#
# Handle optional debug flag (-d) or exit on bad flag
#
[ $@ ] && getopts :hdns FLAG
case "${FLAG}" in
        h)
                echo "Usage: $0 [-h] [-d] [-n] [-s]"
                echo "  -h: this help"
                echo "  -d: print debug output"
                echo "  -n: no header"
                echo "  -s: summary only"
                exit 0
                ;;
        d)
                DEBUG=1
                echo "Printing DEBUG output..."
                ;;
        n)
                HEADER=1
                ;;
        s)
                SUMMARY=1
                ;;
        \?)
                echo "ERROR: Invalid option -$OPTARG"
                exit 1
                ;;
        *)
                ;;
esac

#
# Text colors
# Most are unused but I include them if you'd like
# to add more colors or make changes
#
BLK='\033[0;30m'     # Black
RED='\033[0;31m'     # Red
GRN='\033[0;32m'     # Green
BLU='\033[0;34m'     # Blue
CYA='\033[0;36m'     # Cyan
WHI='\033[0;37m'     # White
YEL='\033[0;33m'     # Yellow
PUR='\033[0;35m'     # Purple
PLX='\033[38;5;220m' # Plex Yellow
NOC='\033[0m'        # No Color

#
# Normal, Bold and Underline text
#
NO="\e[0m"
BD="\e[1m"
UL="\e[4m"

#
# Get the terminal dimensions, we'll use the width later to maximize the
# torrent name column.
#
read ROWS COLS <<< $(stty size < `tty`)

#
# Run the "qbt torrent list" command and grab the csv output for fields we want
#
TLIST=`qbt torrent list -F csv | cut -d',' -f1,2,4,5,6,7,8,9,10,11,12,13,14,15,18`

#
# A rounding function based on 'bc'
#
round()
{
        echo $(printf %.$2f $(echo "scale=$2;(((10^$2)*$1)+0.5)/(10^$2)" | bc))
};

#
# A function to Scale the speed to be more human readable
#
fmt_speed()
{
        local -n speed=$1

        if ((speed == 0))
        then
                speed=""
        elif ((speed >= 1073741824))
        then
                speed=$(echo "scale=2; $speed / 1024 / 1024 / 1024" | bc)
                speed="$speed Gb"
        elif ((speed >= 1048576))
        then
                speed=$(echo "scale=2; $speed / 1024 / 1024" | bc)
                speed="$speed Mb"
        elif ((speed >= 1024))
        then
                speed=$(echo "scale=2; $speed / 1024" | bc)
                speed="$speed Kb"
        else
                speed="$speed b"
        fi
};

#
# A fuction to scale down the file size to be more human-readable
#
fmt_size()
{
        local -n lsize=$1

        if ((lsize >= 1099511627776))
        then
                lsize=$(echo "scale=2; $lsize / 1024 / 1024 / 1024 / 1024" | bc)
                lsize="$lsize TB"
        elif ((lsize >= 1073741824))
        then
                lsize=$(echo "scale=2; $lsize / 1024 / 1024 / 1024" | bc)
                lsize="$lsize GB"
        elif ((lsize >= 1048576))
        then
                lsize=$(echo "scale=2; $lsize / 1024 / 1024" | bc)
                lsize="$lsize MB"
        elif ((lsize >= 1024))
        then
                lsize=$(echo "scale=2; $lsize / 1024" | bc)
                lsize="$lsize KB"
        else
                lsize="$lsize B "
        fi
};

#
# Variables we collect for the summary output
#
tottorrent=0
totsize=0
totpercent=0
totupspeed=0
totdlspeed=0
totratio=0
fauxratio=0

#
# Loop through each line of the output
#
while read TOR
do
        #
        # Assign the output to variables
        #
        IFS=$','
        read hash name size progress dlspeed upspeed priority num_seeds num_complete num_leechs num_incomplete ratio eta state category <<<$TOR
        unset IFS

        #
        # Skip the row with column titles
        #
        if [ "$hash" == "Hash" ]
        then
                continue
        fi

        #
        # Just use the first six characters of the hash (this is what qbittorrent-cli uses)
        #
        hash="${hash:0:6}"

        #
        # Rough hack, replace some characters with '?' that were messing with layout
        # (I'm sure there's a better way to do this, but don't care right now)
        #
        name=$(echo $name | sed 's/[长白山天池水怪]/?/g')

        #
        # Augment the cumulative download speed variable
        #
        ((totsize += size))

        #
        # Scale down the file size to be more human-readable
        #
        fmt_size size

        #
        # Augment the total percent
        #
        totpercent=$(echo "scale=8; $totpercent + $progress" | bc)

        #
        # Change progress to a percent
        #
        progress=$(round "$progress * 100" 0)

        #
        # We'll color progress
        #
        if ((progress == 100))
        then
                progcol=$GRN
        elif ((progress == 0))
        then
                progcol=$RED
        else
                progcol=$NOC
        fi

        #
        # Add the percent sign
        #
        progress="${progress}%"

        #
        # Augment the cumulative download speed variable
        #
        ((totdlspeed += dlspeed))

        #
        # Scale the download speed to be more human readable
        #
        fmt_speed dlspeed

        #
        # Augment the cumulative upload speed variable
        #
        ((totupspeed += upspeed))

        #
        # Scale the upload speed to be more human readable
        #
        fmt_speed upspeed

        #
        # Format the seeds and peers variables to be qbitorrentish
        #
        seeds="${num_seeds}/${num_complete}"
        peers="${num_leechs}/${num_incomplete}"

        #
        # Augment the cumulative ratio (dropping 0.00)
        #
        if (( $(echo "$ratio != 0" | bc -l) ))
        then
                totratio=$(echo "scale=8; $totratio + $ratio" | bc)
        else
                ((fauxratio++))
        fi

        #
        # Round the ratio to two decimal places
        #
        ratio=$(round "$ratio" 2)

        #
        # Pre-formatted ETA (for debugging)
        #
        origeta=$eta

        #
        # Convert the ETA to a friendlier format
        #
        if [[ $eta == "100.00:00:00" ]]
        then
                # "Infinity" character
                #eta="\u221E" This messed up formatting, so commented it out
                eta="-"
        else
                #
                # If it has a 'days' component, separate that
                #
                if [[ $eta =~ '.' ]]
                then
                        days=$(echo "$eta" | cut -s -d'.' -f1)
                        time=$(echo "$eta" | cut -s -d'.' -f2)
                else
                        days=0
                        time=$eta
                fi

                #
                # Split up the time string
                #
                hours=$(echo "$time" | cut -d':' -f1)
                mins=$(echo "$time" | cut -d':' -f2)
                secs=$(echo "$time" | cut -d':' -f2)

                #
                # Get rid of leading zeros
                #
                hours=$(echo $hours | sed 's/^0//')
                mins=$(echo $mins | sed 's/^0//')
                secs=$(echo $secs | sed 's/^0//')

                #
                # Format the ETA string to look nice
                #
                if ((days >= 365))
                then
                        years=$(echo "scale=1; $days / 365" | bc)
                        eta="${years}y"
                elif ((days >= 1))
                then
                        eta="${days}d ${hours}h"
                elif ((hours >= 1))
                then
                        eta="${hours}h ${mins}m"
                elif ((mins >= 1))
                then
                        eta="${mins}m ${secs}s"
                else
                        eta="${secs}s"
                fi
        fi

        #
        # Convert the status to an abbreviated string.
        # This is the same conversion qbittorrent-cli does.
        #
        case "$state" in
                "State")
                        state="ST"
                        ;;
                "Error")
                        state="E"
                        ;;
                "PausedUpload")
                        state="PU"
                        ;;
                "PausedDownload")
                        state="PD"
                        ;;
                "QueuedUpload")
                        state="QU"
                        ;;
                "QueuedDownload")
                        state="QD"
                        ;;
                "Uploading")
                        state="U"
                        ;;
                "StalledUpload")
                        state="SU"
                        ;;
                "CheckingUpload")
                        state="CU"
                        ;;
                "CheckingDownload")
                        state="CD"
                        ;;
                "Downloading")
                        state="D"
                        ;;
                "StalledDownload")
                        state="SD"
                        ;;
                "FetchingMetadata")
                        state="MD"
                        ;;
                "ForcedUpload")
                        state="FU"
                        ;;
                "ForcedDownload")
                        state="FD"
                        ;;
                "MissingFiles")
                        state="MF"
                        ;;
                "Allocating")
                        state="A"
                        ;;
                "QueuedForChecking")
                        state="QC"
                        ;;
                "CheckingResumeData")
                        state="CR"
                        ;;
                "Moving")
                        state="MV"
                        ;;
                "Unknown")
                        state="?"
                        ;;
                *)
                        state="??"
                        ;;
        esac

        #
        # If there's no category assigned...
        #
        if [ -z "$category" ]
        then
                category="(none)"
        fi

        #
        # Calculate the size of the field for the torrent name
        #
        namesize=12 # Minimum size

        leeway=$(echo "$COLS - 101" | bc) # 101 is the size of our printf format string + 3 spaces at the end

        if [ "$leeway" -gt "0" ]
        then
                namesize=$(echo "$namesize + $leeway" | bc)
        fi

        #
        # We'll print the header once, it'll be the first line, nothing if '-n' option is used
        #
        if [ ! $HEADER ] && [ ! $SUMMARY ] && [ ! $DEBUG ]
        then
                printf "${PLX}${UL}%-6.6s${NO} ${PLX}${UL}%-${namesize}.${namesize}b${NO} ${PLX}${UL}%-2.2s${NO} ${PLX}${UL}%4.4s${NO} ${PLX}${UL}%9.9s${NO} ${PLX}${UL}%7.7s${NO} ${PLX}${UL}%7.7s${NO} ${PLX}${UL}%9.9s${NO} ${PLX}${UL}%9.9s${NO} ${PLX}${UL}%-7.7s${NO} ${PLX}${UL}%5.5s${NO} ${PLX}${UL}%-8.8s${NO} ${PLX}${UL}%1.1s${NO}${NOC}\n" "Hash" "Name" "ST" "Prog" "Size" "Seeds" "Peers" "DL Speed" "UL Speed" "ETA" "Ratio" "Cat" "#"
                HEADER=1
        fi

        #
        # Print the pretty format unless the '-d' option is used
        #
        if [ $DEBUG ]
        then
                echo "hash: $hash"
                echo "name: $name"
                echo "size: $size"
                echo "progress: $progress"
                echo "dlspeed: $dlspeed"
                echo "upspeed: $upspeed"
                echo "priority: $priority"
                echo "num_seeds: $num_seeds"
                echo "num_complete: $num_complete"
                echo "seeds: $seeds"
                echo "num_leechs: $num_leechs"
                echo "num_incomplete: $num_incomplete"
                echo "peers: $peers"
                echo "ratio: $ratio"
                echo "eta1: $origeta"
                echo -e "eta2: $eta"
                echo "state: $state"
                echo "category: $category"
                echo ""
        elif [ ! $SUMMARY ]
        then
                #name=$(printf '%.12b' "$name")
                #echo -e "$hash $name $state $progress $size $seeds $peers $dlspeed $upspeed $eta $ratio $category $priority"
                printf "%6.6s ${CYA}%-${namesize}.${namesize}b${NOC} %-2.2s ${progcol}%4.4s${NOC} %9.9s %7.7s %7.7s %9.9s %9.9s %-7.7b %5.2f %-8.8s %1.1s\n" "$hash" "$name" "$state" "$progress" "$size" "$seeds" "$peers" "$dlspeed" "$upspeed" "$eta" "$ratio" "$category" "$priority"
        fi

        ((tottorrent++))

done <<< ${TLIST}

#
# Summary
#
if [ $SUMMARY ]
then
        #
        # Total count of torrents
        #
        echo "total torrents: ${tottorrent}"

        #
        # Total size of all torrents
        #
        fmt_size totsize
        echo "total size: ${totsize}"

        #
        # Average percent
        #
        totprogress=$(echo "scale=8; $totpercent / $tottorrent" | bc)
        echo "overall progress: $(round "$totprogress * 100" 0)%"

        #
        # Total download speed
        #
        fmt_speed totdlspeed
        echo "download speed: ${totdlspeed}"

        #
        # Total upload speed
        #
        fmt_speed totupspeed
        echo "upload speed: ${totupspeed}"

        #
        # Average ratio (excluding 0.00)
        #
        avgratio=$(echo "scale=8; $totratio / ($tottorrent - $fauxratio)" | bc)
        echo "average ratio: $(round $avgratio 2)"
fi

#
# Debug things
#
if [ $DEBUG ]
then
        echo "rows:    ${ROWS}"
        echo "columns: ${COLS}"
fi

#
# Exit nicely
#
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant