Page 1 of 1

Relocate and sort script

Posted: Sat Oct 30, 2010 7:26 am
by chmistry
Last week I have been busy writing the following code.
It runs nicely on my Ubuntu 10.04 headless server, I access it through ssh.

If anybody has comments, or adjustments, please post in this forum.
If I can, I will modify the script.
You can of course use this as a starting point for your own killer script.

As a starting point for this script, I used: http://1000umbrellas.com/2010/10/05/upd ... -downloads

Code: Select all

#!/bin/bash

# Copyright (C) 2010 by Arie van Dobben
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Version: 0.01
#
# This script takes a list of torrents from transmission-daemon and iterates through it.
# Each torrent is examined if its files still reside in the transmission-finished dir, or not.
# If a torrent is completed, the user is asked if he/she wants to move it. The files 
# the torrent are referring to can be moved to a predifined folder, or the user can specify
# a subfolder, which then will be created if not existent.
# When the files are successfully moved, Transmission will verify the files in their new location.
#
# I started creating this script, because I felt that the gui options were too tedious and time consuming
# to do the same thing. Also Transmission daemon crashed often when trying to move large files.
# Above all, I was trying to keep seeding my files, and on the other hand have them nicely ordered so that 
# other programs (like XBMC) could put them in their library properly.
#
# Presumptions:
# * Transmission-daemon is installed
# * Transmission-remote is installed on the same host
# * The user running this script has rights to move all files involved
# * Bash is installed (/bin/bash)
#
# How to run:
# Make sure the configuration below matches your system
# Make this script executable
# run it by typing: ./move_torrents.sh

# Directory locations NOTE: whitespaces are not allowed!
dirloc[0]='/home/media/Downloads/transmission-finished'  #directory where transmission stores finished downloads
dirloc[1]='/home/media/Videos/Movies'                    #root directory of Movies - m
dirloc[2]='/home/media/Videos/Series'                    #root directory of Series - s
dirloc[3]='/home/media/Music'                            #root directory of Music  - a
dirloc[4]=''                                             #user defined
dirloc[5]=''                                             #user defined

# Shortcodes corresponding with directory locations NOTE: singe character shortcodes only
shortcode[0]='h'    #shortcode for directory where transmission stores finished downloads
shortcode[1]='m'    #shortcode for Movies - m
shortcode[2]='s'    #shortcode for Series - s
shortcode[3]='a'    #shortcode for Music  - a
shortcode[4]=''     #user defined
shortcode[5]=''     #user defined

# Short names for directory locations
dirnames[0]='Home'
dirnames[1]='Movies'
dirnames[2]='Series'
dirnames[3]='Music'
dirnames[4]=''
dirnames[5]=''

# authentication to transmission
auth="user:pass"

# End of config

#create a define location string
definestring="Define location ("
for i in `seq 1 ${#shortcode[@]:1}`
do
  if [ ${#shortcode[$i]} -gt 0 ]; then
    definestring=$definestring${shortcode[$i]}" = "${dirnames[$i]}", "
  fi
done
definestring=$definestring"n = Do Nothing(default)): "

#create a string with all possible shortcodes + n without h
shortcodes="${shortcode[@]}"
shortcodes=${shortcodes// /}"n"
shortcodes=${shortcodes//h/}

#test if directories exist
count_d=0
while [ "x${dirloc[count_d]}" != "x" ]
do
  if [ ! -d "${dirloc[count_d]}" ]; then
    echo "${dirloc[count_d]} dir does not exist"
    exit
  fi
  count_d=$(( $count_d + 1 ))
done

# get torrent list from transmission-remote list
# delete first / last line of output
# remove leading spaces
# get first field from each line

torrentlist=`transmission-remote --auth $auth --list | sed -e '1d;$d;s/^ *//' | cut --only-delimited --delimiter " " --fields 1`

# for each torrent in the list
for torrentid in $torrentlist
do
  echo "* ID = $torrentid"

  # to decrease the amount of calls to the deamon we run the info command once and store that in a variable
  torrent_info=`transmission-remote --torrent $torrentid --info --auth $auth`

  # the following variables are retrieved from $torrent_info

  # get Torrent Name
  torrent_name=`echo "$torrent_info" | grep '\<Name\>' | sed -e 's/^[ \t]*Name: //'`
  #echo "- torrent name = $torrent_name" #debug message *verified

  # check if torrent download is completed
  torrent_complete=`echo "$torrent_info" | grep "Percent Done:" | sed -e 's/^[ \t]*Percent Done: //'`
  #echo "- completed state = $torrent_complete" # debug message *verified

  # check torrent's current state is "Stopped"
  torrent_state=`echo "$torrent_info" | grep "State:" | sed -e 's/^[ \t]*State: //'`
  #echo "- torrent state = $torrent_state" # debug message *verified
  
  # get File location
  file_location=`echo "$torrent_info" | grep "Location:" | sed -e 's/^[ \t]*Location: //'`
  #echo "- file Location = $file_location" #degub message *verified

  if [ "$torrent_complete" = "100%" ] && [ "$file_location" = "${dirloc[0]}" ]; then
    echo "- torrent name = $torrent_name"
    echo "Torrent is finished, but not relocated yet"

    input_condition=0
    # get action for torrent
    while [ $input_condition -eq 0 ];do
      echo -n "Define action (r = Relocate, n = Do Nothing(default)): "
      read torrent_action
      case "$torrent_action" in
        [rn] ) input_condition=1 ;;
        ""   ) input_condition=1; torrent_action="n" ;;
        *    ) input_condition=0; echo "Invalid input" ;;
      esac
    done

    # if we want to relocate, define location
    if [ "$torrent_action" != "n" ]; then
      input_condition=0
      # get new file location code
      while [ $input_condition -eq 0 ];do
        echo -n "$definestring"
        read new_location_code
        case "$new_location_code" in
          ["$shortcodes"] ) input_condition=1 ;;
          ""              ) input_condition=1; new_location_code="n" ;;
          *               ) input_condition=0; echo "Invalid input" ;;
        esac
      done
      
      if [ "$new_location_code" != "n" ]; then
        #lookup indexnr of $new_location_code, it must be the same for dirlocs as well
        count=0
        while [ "x${shortcode[count]}" != "x$new_location_code" ]
        do
           count=$(( $count + 1 ))
        done
        new_dir=${dirloc[$count]}
        
        # Give information about the torrent, file, or direcotory
        if [ -d "$file_location/$torrent_name" ]; then
          echo $file_location"/"$torrent_name" is a directory"
        elif [ -f "$file_location/$torrent_name" ]; then
          echo $file_location"/"$torrent_name" is a file"
        else
          echo "$file_location/$torrent_name is not a directory or file, please move this by hand"
          exit
        fi
        
        #check if the torrent is stopped, if not, stop it.
        if [ $torrent_state != "Stopped" ]; then
          stopped=`transmission-remote --torrent $torrentid --stop --auth $auth | grep "success"` #stop the torrent
          if [[ $stopped != *success* ]]; then
            echo "Torrent could not be stopped, check your settings"
            exit
          fi
        fi
        
        echo "New location will be $new_dir/$torrent_name"
        echo -n "Please specify a sub-directory without end slash, or press Enter to skip: "
        read sub_directory
        echo "The files will be moved from "
        echo "$file_location to"
        echo "$new_dir/$sub_directory"
        input_condition=0        
        # get new file location code
        while [ $input_condition -eq 0 ];do
          echo -n "Is this correct? y/n (Default y): "
          read confirm_move
          case "$confirm_move" in
            [yn] ) input_condition=1 ;;
            ""   ) input_condition=1; confirm_move="y" ;;
            *    ) input_condition=0; echo "Invalid input" ;;
          esac
        done
        
        if [[ $confirm_move == "y" ]]; then
          if [[ ${#sub_directory} > 0 ]]; then
            # if all is ok, create directory if not already exist
            if [ ! -d "$new_dir/$sub_directory" ]; then
              mkdir --parents "$new_dir/$sub_directory"
              move_dir="$new_dir/$sub_directory/$torrent_name"
            else
              move_dir="$new_dir/$sub_directory/$torrent_name"
            fi
          else
            move_dir="$new_dir/$torrent_name"
          fi
          
          #move the torrent files and directory
          mv "$file_location/$torrent_name" "$move_dir"
          mv_success=$?

          #if moved successfull, set new location and verify
          if [[ $mv_success = 0 ]]; then
            echo "File(s) moved successfully"
            find_torrent=`transmission-remote --torrent $torrentid --find "$new_dir/$sub_directory" --auth $auth | grep "success"`
            if [[ $find_torrent != *success* ]]; then
              echo "Torrent could not be found, please relocate manually"
            else
              verify_torrent=`transmission-remote --torrent $torrentid --verify --auth $auth | grep "success"`
            fi
          fi
        fi
      fi
    fi
  elif [ "$torrent_complete" != "100%" ]; then
    echo "- torrent name = $torrent_name"
    echo "Torrent is not finished"
  elif [ "$file_location" != "${dirloc[0]}" ]; then
    echo "- torrent name = $torrent_name"
    echo "Torrent is already relocated"
  fi

done