├── Demontration.png ├── README.md └── transmission-vskip.sh /Demontration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iaurman/transmission-vskip/e622112539b3f7a785bce9c5a8fea40e51b48a79/Demontration.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## transmission-vskip 2 | transmission-vskip is a shell script for skipping hash verification when using transmission-cli . It is very useful for seeding identical big torrents on different trackers . 3 | 4 | ![Preview](https://github.com/1ndeed/transmission-vskip/blob/master/Demontration.png) 5 | 6 | ## Simple to Use: 7 | transmission-vskip is based on shell script . Creat a symbolic link at `/usr/bin/` . Then configure at most 3 lines for it . Then it is ready to work . 8 | 9 | ## Installation: 10 | download transmission-vskip.sh to your current directory and: 11 | 12 | $ sudo mv ./transmission-vskip/transmission-vskip.sh /etc/ 13 | $ sudo chmod +x /etc/transmission-vskip.sh 14 | $ sudo ln -s /etc/transmission-vskip.sh /usr/bin/transmission-vskip 15 | $ sudo vim /etc/transmission-vskip.sh 16 | 17 | ## Configuration: 18 | Open the file you downloaded , you should see `User Configuration` part between `line 3 and 19` . 19 | * "config_dir" is the location of your `transmission-daemon configuration directory` . Usually in `~/.config/transmission-daemon/` . 20 | It contains "torrents" and "resume" files . Using `full path` is recommended . End with `'/'` please . 21 | * "start_cmd" and "shutdown_cmd" are commands for shutting down and start transmission-daemon . Please `use Tab as separators` . 22 | If your system use `systemd` and you use systemd to active transmission-daemon , you don't have to modify these two ; 23 | If your system don't use systemd , change it in your way . Just make sure you have the permission ; 24 | If you don't nedd this function , add '#' in the front of these two lines to disable them . 25 | 26 | 27 | ## Ready to Run: 28 | before you run it , using `check` to check if there is any obstructs is recommended . 29 | 30 | $ transmission-vskip check 31 | 32 | ## Example: 33 | Lets say you have Completed downloading a 100GB video file from `website A` . Then you noticed `website B` and `website C` have the `same torrent` . After you `added two new torrents to transmission` . You can do this to skip hash verification: 34 | 35 | $ sudo transmission-vskip 'Transformers.The.Last.Knight.2017.2160p.EUR.UHD.BluRay.HEVC.Atmos.TrueHD.7.1-DiY' --base 'website A' 36 | 37 | ## Tips: 38 | * You can add `abbreviation` for your trackers between line 79 and 84 . 39 | * Always use `' '` to add the task name to avoid special symbol issues . 40 | * You can write `alias vskip='transmission-vskip'` into ~/.bashrc . 41 | * The first argument is `task name` instead of torrent name , transmission-skip only skip verification for the tasks have the same task name . 42 | 43 | ## Issues: 44 | * While skipping verification , transmission-daemon must be stopped . After restart transmission-daemon , It is normal for some torrents to report errors . But don't worry , errors usually would disappear in 10 min . 45 | * Sometimes "systemctl stop transmission" doesn't work with no respond . Open htop on other terminal , find transmission-daemon , and kill all of them: 46 | ``` 47 | $ sudo htop 48 | ``` 49 | -------------------------------------------------------------------------------- /transmission-vskip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ########################################################################################### 4 | ################################## User Configuration ##################################### 5 | ########################################################################################### 6 | # your transmission home directory , please use full path like the on lelow 7 | # end with '/' please 8 | config_dir='/var/lib/transmission/.config/transmission-daemon/' 9 | 10 | # [ Optional ] 11 | # Please usr "\t"(tab) as separator !!! 12 | # If your system don't use systemd , change them below , or comment them 13 | # the command to start transmission-daemon 14 | start_cmd='sudo systemctl start transmission' 15 | # the command to shut transmission-daemon down 16 | shutdown_cmd='sudo systemctl stop transmission' 17 | ########################################################################################### 18 | ########################################################################################### 19 | ########################################################################################### 20 | 21 | based_tracker="" 22 | tmp_tracker="" 23 | based_torrent="" 24 | resume_torrents="" 25 | resume_files="" 26 | based_file="" 27 | input="" 28 | temp="" 29 | tmp="" 30 | vnr="" 31 | cnr="" 32 | finished=0 33 | 34 | print_version() { 35 | echo "transmission-vskip 1.1" 36 | } 37 | 38 | tell_usage() { 39 | cat << EOF 1>&2 40 | Usage: 41 | transmission-vskip [TASK_NAME] --base [TRACKER_NAME] 42 | 43 | Example: 44 | transmission-vskip check 45 | transmission-vskip 'Transformers.The.Last.Knight.2017.2160p.EUR.UHD.BluRay.HEVC.Atmos.TrueHD.7.1-DiY@HDHome' --base hdhome 46 | 47 | Options: 48 | check check environment to print all WARNINGS 49 | --base base on which tracker of task to verify 50 | -h, --help print this help page 51 | -V, --version print version massage 52 | EOF 53 | } 54 | 55 | torrent_to_tracker() { 56 | func_tmp="" 57 | func_tracker="" 58 | 59 | input=$IFS ; IFS=$'\t\n' 60 | func_tmp="$(transmission-show "$config_dir"torrents/"$1")" 61 | IFS="$input" 62 | func_tracker="$(echo "$func_tmp" | grep -n ' Tier #1' | awk -F ':' '{print $1}')" 63 | func_tracker=$(($func_tracker+1)) 64 | func_tracker="$(echo "$func_tmp" | awk NR==$func_tracker)" 65 | func_tracker="$(echo "$func_tracker" | awk -F '/' '{print $3}')" 66 | if [ -z "$(echo "$func_tracker" | awk -F '.' '{print $3}')" ];then 67 | func_tracker="$(echo "$func_tracker" | awk -F '.' '{print $1}')" 68 | else 69 | func_tracker="$(echo "$func_tracker" | awk -F '.' '{print $2}')" 70 | fi 71 | echo "$func_tracker" 72 | } 73 | 74 | torrent_translater() { 75 | if [ -z "$1" ];then 76 | tell_usage 77 | exit 1 78 | # Add / Replace your Abbreviation below like the first one below 79 | # elif [ "$1"x == "lpt"x ];then 80 | # based_tracker='loveprivatetracker' 81 | # elif [ "$1"x == ""x ];then 82 | # based_tracker='' 83 | # elif [ "$1"x == ""x ];then 84 | # based_tracker='' 85 | else 86 | based_tracker="$1" 87 | fi 88 | } 89 | 90 | start_transmission() { 91 | if [ -z "$start_cmd" ];then 92 | exit 0 93 | fi 94 | read -sp ":: Restart transmission-daemon? [Y/n] " input < /dev/tty ; echo "" 95 | if [ -z "$input" ];then 96 | input='y' 97 | elif [ "${#input}" -gt 1 ];then 98 | input=`echo "$input" | cut -c 1` 99 | fi 100 | 101 | tmp="" 102 | if [ "$input" == 'y' ] || [ "$input" == 'Y' ];then 103 | $start_cmd && tmp="$(ps -A | grep transmission-da)" 104 | if [ -z "$tmp" ];then 105 | echo "FATAL error: failed to start transmission-daemon , please check your \$start_cmd !!!" 1>&2 106 | exit 1 107 | fi 108 | else 109 | echo "exiting ..." 110 | exit 0 111 | fi 112 | } 113 | 114 | check_and_system() { 115 | if [ $1 == 'check' ];then 116 | temp=0 117 | elif [ $1 == 'system' ];then 118 | exit 1 119 | fi 120 | } 121 | 122 | environment_check() { 123 | temp=1 124 | ####################################### Checking ########################################## 125 | ############################################### whether you have installed transmission-cli 126 | if [ -z "$(transmission-show -V 2>&1 | grep 'transmission-show')" ];then 127 | echo "WARNING: you haven't installed transmission-cli , transmission-show is missiong !!!" 1>&2 128 | check_and_system "$1" 129 | fi 130 | if [ -z "$(transmission-daemon -V 2>&1 | grep 'transmission-daemon')" ];then 131 | echo "WARNING: you haven't installed transmission-cli , transmission-daemon is missiong !!!" 1>&2 132 | check_and_system "$1" 133 | fi 134 | ################################################################################ */torrents 135 | input=$IFS ; IFS=$'\t\n' 136 | if test -d "$config_dir"torrents ;then 137 | if [ "$(whoami)"x != 'root'x ];then 138 | vnr="$(ls -ld "$config_dir"torrents/ | awk '{print $3}')" 139 | IFS=$input 140 | if [ "$vnr"x != "$(whoami)"x ];then 141 | echo "WARNING: current user doesn't own "$config_dir"torrents/" 1>&2 142 | check_and_system "$1" 143 | fi 144 | fi 145 | else 146 | IFS=$input 147 | echo "WARNINHG: "$config_dir"torrents/ doesn't exist , please check your \$config_dir !!!" 1>&2 148 | check_and_system "$1" 149 | fi 150 | ################################################################################## */resume 151 | input=$IFS ; IFS=$'\t\n' 152 | if test -d "$config_dir"resume ;then 153 | if [ "$(whoami)"x != 'root'x ];then 154 | cnr="$(ls -ld "$config_dir"resume/ | awk '{print $3}')" 155 | IFS=$input 156 | if [ "$cnr"x != "$(whoami)"x ];then 157 | echo "WARNING: current user doesn't own "$config_dir"resume/" 1>&2 158 | check_and_system "$1" 159 | fi 160 | fi 161 | else 162 | IFS=$input 163 | echo "WARNINHG: "$config_dir"resume/ doesn't exist , please check your \$config_dir !!!" 1>&2 164 | check_and_system "$1" 165 | fi 166 | IFS=$input 167 | ####################################################### whether transmission-daemon is down 168 | tmp="$(ps -A | grep transmission-da)" 169 | if [ -n "$tmp" ];then 170 | if [ -z "$shutdown_cmd" ] || [ -n "$shutdown_cmd" -a "$1"x == 'check'x ];then 171 | echo "WARNING: please shudown transmission-daemon !!!" 1>&2 172 | check_and_system "$1" 173 | elif [ -n "$shutdown_cmd" ] && [ "$1" == 'system' ];then 174 | echo -e ">>>\tTransmission-daemon is still running:\n$tmp" 175 | read -sp ":: Shutdown transmission-daemon? [Y/n] " input < /dev/tty ; echo "" 176 | if [ -z "$input" ];then 177 | input='y' 178 | elif [ "${#input}" -gt 1 ];then 179 | input=`echo "$input" | cut -c 1` 180 | fi 181 | 182 | if [ "$input" == 'y' ] || [ "$input" == 'Y' ];then 183 | $shutdown_cmd && tmp="$(ps -A | grep transmission-da)" 184 | if [ -n "$tmp" ];then 185 | echo "FATAL error: failed to shutdown transmission-daemon , please check your \$shutdown_cmd !!!" 1>&2 186 | exit 1 187 | fi 188 | else 189 | echo "exiting ..." 190 | exit 0 191 | fi 192 | fi 193 | fi 194 | ############################################################### whether there is no mistake 195 | if [ $1 == 'check' ] && [ $temp == 1 ];then 196 | echo -e ">>>\tEverything is fine , ready to run !!!" 197 | fi 198 | ########################################################################################### 199 | } 200 | 201 | exist_test() { 202 | if [ ! -f "$1" ];then 203 | if [ "$2"x == 'based'x ];then 204 | echo "FATAL error: based .resume file missing !!!" 1>&2 205 | exit 1 206 | fi 207 | echo -e "WARNING: the file below doesn't exist !!!\n\t$1" 208 | read -sp ':: Do you want to proceed ? [Y/n] ' input < /dev/tty ; echo "" 209 | if [ -z "$input" ];then 210 | input='y' 211 | elif [ "${#input}" -gt 1 ];then 212 | input=`echo "$input" | cut -c 1` 213 | fi 214 | if [ "$input" != 'y' ] && [ "$input" != 'Y' ];then 215 | echo 'exiting ...' 216 | exit 0 217 | fi 218 | fi 219 | } 220 | ########################################################################################### 221 | ######################################## Main ############################################# 222 | ########################################################################################### 223 | ######################################################################### Check Environment 224 | if [ "$#" == 3 ] && [ "$2"x == '--base'x ];then 225 | environment_check system 226 | torrent_translater "$3" 227 | elif [ "$#" == 1 ] && [ "$1"x == '-h'x -o "$1"x == '--help'x ];then 228 | tell_usage 229 | exit 0 230 | elif [ "$#" == 1 ] && [ "$1"x == '-V'x -o "$1"x == '--version'x ];then 231 | print_version 232 | exit 0 233 | elif [ "$#" == 1 ] && [ "$1"x == 'check'x ];then 234 | environment_check check 235 | exit 0 236 | else 237 | tell_usage 238 | exit 1 239 | fi 240 | ############################################################### Calculate the torrents name 241 | cd "$config_dir" 242 | cd torrents 243 | tmp=`ls -l "$1"* | tr -s ' ' | cut -d ' ' -f 9-` 244 | while read LINE 245 | do 246 | if [ "$(torrent_to_tracker "$LINE")" != "$based_tracker" ];then 247 | if [ -z "$resume_torrents" ];then 248 | resume_torrents="$LINE" 249 | else 250 | resume_torrents="$(echo "$LINE" ; echo "$resume_torrents")" 251 | fi 252 | else 253 | based_torrent="$LINE" 254 | fi 255 | done <<< "$tmp" 256 | if [ -z "$resume_torrents" ];then 257 | echo 'FATAL error: failed to calculate matches, please check the task name !!!' 1>&2 258 | exit 1 259 | fi 260 | if [ -z "$based_torrent" ];then 261 | echo 'FATAL error: failed to match the base torrent, please check your tracker !!!' 1>&2 262 | exit 1 263 | fi 264 | #################################### Torrents Found !!! ################################### 265 | echo '>>> Torrents Found:' 266 | while read LINE 267 | do 268 | echo -e "\t$LINE" 269 | done <<< "$resume_torrents" 270 | echo -e ">\t$based_torrent" 271 | ############################################################### Calculate resume files name 272 | cd ../resume 273 | while read LINE 274 | do 275 | if [ -z "$resume_files" ];then 276 | resume_files="$(echo "$LINE" | awk -F '.' -v OFS='.' '{$NF="resume";print $0}')" 277 | else 278 | LINE="$(echo "$LINE" | awk -F '.' -v OFS='.' '{$NF="resume";print $0}')" 279 | resume_files="$(echo "$LINE" ; echo "$resume_files")" 280 | fi 281 | done <<< "$resume_torrents" 282 | based_file="$(echo "$based_torrent" | awk -F '.' -v OFS='.' '{$NF="resume";print $0}')" 283 | while read LINE 284 | do 285 | exist_test "$LINE" 286 | done <<< "$resume_files" 287 | exist_test "$based_file" 'based' 288 | ################################## Resume Files List !!! ################################## 289 | echo '>>> Resume Files List:' 290 | while read LINE 291 | do 292 | echo -e "\t$LINE" 293 | done <<< "$resume_files" 294 | echo -e ">\t$based_file" 295 | ######################################## Run !!! ########################################## 296 | cnr=1 297 | vnr="$(echo "$resume_files" | awk 'END{print NR}')" 298 | while read LINE 299 | do 300 | tmp="cp '$based_file' '$LINE'" 301 | temp="$(torrent_to_tracker "${LINE%??????}torrent")" 302 | echo -e ">>>\tRuning for $temp ($cnr/$vnr)\n#\t$tmp" ; cnr=$(($cnr+1)) 303 | read -sp ':: Proceed with the command ? [Y/n] ' input < /dev/tty ; echo "" 304 | if [ -z "$input" ];then 305 | input='y' 306 | elif [ "${#input}" -gt 1 ];then 307 | input=`echo "$input" | cut -c 1` 308 | fi 309 | tmp="cp $based_file $LINE" 310 | if [ "$input" == 'y' ] || [ "$input" == 'Y' ];then 311 | temp=$IFS ; IFS=$'\t' ; $tmp ; tmp="$?" ; IFS=$temp 312 | if [ "$tmp" != 0 ];then 313 | echo "FATAL error: couldn't complete file copy !!!" 1>&2 314 | exit 1 315 | else 316 | finished=$(($finished+1)) 317 | fi 318 | else 319 | : 320 | fi 321 | done <<< "$resume_files" 322 | 323 | if [ "$finished" == 0 ];then 324 | echo "no resume file has updated ..." 1>&2 325 | start_transmission 326 | exit 0 327 | else 328 | echo -e ">>>\tSuccessfully updated ($finished/$vnr) !!!" 329 | cd "$config_dir" 330 | chown -hR transmission:transmission torrents 331 | chown -hR transmission:transmission resume 332 | start_transmission 333 | exit 0 334 | fi 335 | --------------------------------------------------------------------------------