qBittorrent + Rclone 自动上传脚本

因为在设置 qBittorrent 的时候发现有一个“Torrent 完成时运行外部程序”的设置,我就在想能不能用这个方法下载 PT 然后自动传到 Google Drive,一番寻找找到了两种办法,在此记录一下过程。

方法一原文链接:https://www.hostloc.com/thread-612238-1-1.html

方法二原文链接:https://www.hostloc.com/thread-639215-1-1.html

脚本下载

 

首先先在设置中的 Web UI 中把“对本地主机上的客户端跳过身份验证”勾上,我一开始没有勾上,获取不了 cookie 加不了标签。先勾上有备无患。

没有勾上获取不了 cookie

方法一

新建一个qb_auto.sh 写入:

#!/bin/sh
torrent_name=$1
content_dir=$2
root_dir=$3
save_dir=$4
files_num=$5
torrent_size=$6
file_hash=$7

qb_version="4.2.0" #如4.0.4、4.1.9.1、4.2.0等,不支持3.1.X
qb_username="hostloc" #qb用户名
qb_password="hostloc.com" #qb密码
qb_web_url="https://hostloc.com" #QB web路径,可以填写本地http://localhost:8080
leeching_mode="true" #吸血模式 设为true 上传完后自动删除种子及数据 否则不删除,继续做种
log_dir="/root/qbauto" #日志目录
rclone_dest="gdrive" #rclone destination关键字 运行rclone config查看name字段即可
rclone_parallel="32" #rclone上传线程 默认4
auto_del_flag="rclone"#添加标签或者分类来标识已上传的种子 v4.0.4+版本添加标签“rclone”,低版本通过添加分类“rclone”标识

if [ ! -d ${log_dir} ]
then
mkdir -p ${log_dir}
fi

version=$(echo $qb_version | grep -P -o "([0-9].){2}[0-9]" | sed s/\.//g)

function qb_login(){
if [ versiongt404]thenqbv="1"cookie={version} -gt 404 ] then qb_v="1" cookie=(curl -i --header "Referer: qbweburl"data"username={qb_web_url}" --data "username={qb_username}&password=qbpassword""{qb_password}" "{qb_web_url}/api/v2/auth/login" | grep -P -o 'SID=\S{32}')
if [ -n cookie]thenecho"[{cookie} ] then echo "[(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}" >> ${log_dir}/autodel.log

            else
                    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败!" >> ${log_dir}/autodel.log
            fi
    elif [[ ${version} -le 404 && ${version} -ge 320 ]]
    then
            qb_v="2"
            cookie=$(curl -i --header "Referer: ${qb_web_url}" --data "username=${qb_username}&password=${qb_password}" "${qb_web_url}/login" | grep -P -o 'SID=\S{32}')
            if [ -n ${cookie} ]
            then
                    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}" >> ${log_dir}/autodel.log
            else
                    echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败" >> ${log_dir}/autodel.log
            fi
    elif [[ ${version} -ge 310 && ${version} -lt 320 ]]
    then
            qb_v="3"
            echo "陈年老版本,请及时升级"
            exit
    else
            qb_v="0"
            exit
    fi

}

function qb_del(){
if [ ${leeching_mode} == "true" ]
then
if [ qbv=="1"]thencurl"{qb_v} == "1" ] then curl "{qb_web_url}/api/v2/torrents/delete?hashes=${file_hash}&deleteFiles=true" --cookie cookieecho"[{cookie} echo "[(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子名称:${torrent_name}" >> ${log_dir}/qb.log
elif [ qbv=="2"]thencurlXPOSTd"hashes={qb_v} == "2" ] then curl -X POST -d "hashes={file_hash}" "${qb_web_url}/command/deletePerm" --cookie cookieelseecho"[{cookie} else echo "[(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子文件:${torrent_name}" >> logdir/qb.logecho"qbv={log_dir}/qb.log echo "qb_v={qb_v}" >> logdir/qb.logfielseecho"[{log_dir}/qb.log fi else echo "[(date '+%Y-%m-%d %H:%M:%S')] 不自动删除已上传种子" >> ${log_dir}/qb.log
fi
}

function rclone_copy(){
if [ type=="file"]thenrclonecopycmd={type} == "file" ] then rclone_copy_cmd=(rclone -v copy --transfers ${rclone_parallel} --log-file logdir/qbautocopy.log"{log_dir}/qbauto_copy.log "{content_dir}" ${rclone_dest}:qbauto/)
elif [ type=="dir"]thenrclonecopycmd={type} == "dir" ] then rclone_copy_cmd=(rclone -v copy --transfers ${rclone_parallel} --log-file logdir/qbautocopy.log"{log_dir}/qbauto_copy.log "{content_dir}"/ rclonedest:qbauto/"{rclone_dest}:qbauto/"{torrent_name}")
fi
}

function qb_add_auto_del_tags(){
if [ qbv=="1"]thencurlXPOSTd"hashes={qb_v} == "1" ] then curl -X POST -d "hashes={file_hash}&tags=autodelflag""{auto_del_flag}" "{qb_web_url}/api/v2/torrents/addTags" --cookie "${cookie}"
elif [ qbv=="2"]thencurlXPOSTd"hashes={qb_v} == "2" ] then curl -X POST -d "hashes={file_hash}&category=autodelflag""{auto_del_flag}" "{qb_web_url}/command/setCategory" --cookie cookieelseecho"qbv={cookie} else echo "qb_v={qb_v}" >> ${log_dir}/qb.log
fi
}

if [ -f "contentdir"]thenecho"[{content_dir}" ] then echo "[(date '+%Y-%m-%d %H:%M:%S')] 类型:文件" >> logdir/qb.logtype="file"rclonecopyqbloginqbaddautodeltagsqbdelelif[d"{log_dir}/qb.log type="file" rclone_copy qb_login qb_add_auto_del_tags qb_del elif [ -d "{content_dir}" ]
then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:目录" >> logdir/qb.logtype="dir"rclonecopyqbloginqbaddautodeltagsqbdelelseecho"[{log_dir}/qb.log type="dir" rclone_copy qb_login qb_add_auto_del_tags qb_del else echo "[(date '+%Y-%m-%d %H:%M:%S')] 未知类型,取消上传" >> ${log_dir}/qb.log
fi

echo "种子名称:${torrent_name}" >> logdir/qb.logecho"{log_dir}/qb.log echo "内容路径:{content_dir}" >> logdir/qb.logecho"{log_dir}/qb.log echo "根目录:{root_dir}" >> logdir/qb.logecho"{log_dir}/qb.log echo "保存路径:{save_dir}" >> logdir/qb.logecho"{log_dir}/qb.log echo "文件数:{files_num}" >> logdir/qb.logecho"{log_dir}/qb.log echo "文件大小:{torrent_size}Bytes" >> logdir/qb.logecho"HASH:{log_dir}/qb.log echo "HASH:{file_hash}" >> logdir/qb.logecho"Cookie:{log_dir}/qb.log echo "Cookie:{cookie}" >> ${log_dir}/qb.log
echo -e "-------------------------------------------------------------\n" >> ${log_dir}/qb.log

 

然后给脚本权限chmod +x qb_auto.sh

在 WEB UI 勾选“Torrent 完成时运行外部程序”填上:

bash /root/qb_auto.sh  "%N" "%F" "%R" "%D" "%C" "%Z" "%I"

即可下载完自动上传

 

方法二

先在 qBittorrent 中添加标签

然后安装jq

# debian & linux
apt-get install -y jq
# centos 下
yum install -y jq

新建脚本

#!/bin/sh

qb_version="4.2.5"
qb_username=""
qb_password=""
qb_web_url="http://127.0.0.1:1080"
log_dir="/root/log"
rclone_dest=""
from_dc_tag=""
rclone_parallel="4"

unfinished_tag="Wait_to_upload"
uploading_tag="Uploading"
finished_tag="Uploaded"
noupload_tag="Not_upload"

if [ ! -d ${log_dir} ]
then
mkdir -p ${log_dir}
fi

version=$(echo {qb_version} | grep -P -o "([0-9]\.){2}[0-9]" | sed s/\\.//g) startPat=`date +'%Y-%m-%d %H:%M:%S'` start_seconds=(date --date="$startPat" +%s);

function qb_login() {
if [ versiongt404]thenqbv="1"cookie={version} -gt 404 ] then qb_v="1" cookie=(curl -i --header "Referer: qbweburl"data"username={qb_web_url}" --data "username={qb_username}&password=qbpassword""{qb_password}" "{qb_web_url}/api/v2/auth/login" | grep -P -o 'SID=\S{32}')
if [ -n cookie]thenecho"[{cookie} ] then echo "[(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}"

	else
		echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败!" 
	fi
elif [[ ${version} -le 404 && ${version} -ge 320 ]]
then
	qb_v="2"
	cookie=$(curl -i --header "Referer: ${qb_web_url}" --data "username=${qb_username}&password=${qb_password}" "${qb_web_url}/login" | grep -P -o 'SID=\S{32}')
	if [ -n ${cookie} ]
	then
		echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录成功!cookie:${cookie}" 
	else
		echo "[$(date '+%Y-%m-%d %H:%M:%S')] 登录失败" 
	fi
elif [[ ${version} -ge 310 && ${version} -lt 320 ]]
then
	qb_v="3"
	echo "陈年老版本,请及时升级"
	exit
else
	qb_v="0"
	exit
fi

}

先移除指定tag,后增加自己的tag

function qb_change_hash_tag(){
file_hash=$1
fromTag=$2
toTag=$3
if [ {qb_v} == "1" ] then # 这里是添加某些tag的方法 curl -s -X POST -d "hashes={file_hash}&tags=fromTag""{fromTag}" "{qb_web_url}/api/v2/torrents/removeTags" --cookie "cookie"curlsXPOSTd"hashes={cookie}" curl -s -X POST -d "hashes={file_hash}&tags=toTag""{toTag}" "{qb_web_url}/api/v2/torrents/addTags" --cookie "${cookie}"
elif [ qbv=="2"]thencurlsXPOSTd"hashes={qb_v} == "2" ] then curl -s -X POST -d "hashes={file_hash}&category=fromTag""{fromTag}" "{qb_web_url}/command/removeCategories" --cookie cookiecurlsXPOSTd"hashes={cookie} curl -s -X POST -d "hashes={file_hash}&category=toTag""{toTag}" "{qb_web_url}/command/setCategory" --cookie cookieelseecho"qbv={cookie} else echo "qb_v={qb_v}"
fi
}

function rclone_copy(){
torrent_name=$1
torrent_hash=$2
torrent_path=$3

echo "${torrent_name}"  >> ${log_dir}/qb.log
echo "${torrent_hash}"  >> ${log_dir}/qb.log
echo "${torrent_path}"  >> ${log_dir}/qb.log

# tag = 待上传
# 这里执行上传程序
if [ -f "${torrent_path}" ]
then
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:文件"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:文件" >> ${log_dir}/qb.log
   type="file"
elif [ -d "${torrent_path}" ]
then
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:目录"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:目录" >> ${log_dir}/qb.log
   type="dir"
else
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 未知类型,取消上传"
   echo "[$(date '+%Y-%m-%d %H:%M:%S')] 未知类型,取消上传" >> ${log_dir}/qb.log
   # tag = 不上传
   qb_change_hash_tag ${torrent_hash} ${unfinished_tag} ${noupload_tag}
   return
fi
# tag = 上传中
qb_change_hash_tag ${torrent_hash} ${unfinished_tag} ${uploading_tag}
# 执行上传
if [ ${type} == "file" ]
then # 这里是rclone上传的方法
    rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file  ${log_dir}/qbauto_copy.log "${torrent_path}" ${rclone_dest}/${from_dc_tag})
elif [ ${type} == "dir" ]
then
	rclone_copy_cmd=$(rclone -v copy --transfers ${rclone_parallel} --log-file ${log_dir}/qbauto_copy.log "${torrent_path}"/ ${rclone_dest}/${from_dc_tag}/"${torrent_name}")
fi

# tag = 已上传
qb_change_hash_tag ${torrent_hash} ${uploading_tag} ${finished_tag}

endPat=`date +'%Y-%m-%d %H:%M:%S'`
end_seconds=$(date --date="$endPat" +%s);
use_seconds=$((end_seconds-start_seconds));
use_min=$((use_seconds/60));
use_sec=$((use_seconds%60));
echo "上传完成-耗时:${use_min}分${use_sec}秒"

}

function file_lock(){
(touch qbup.lock) } function can_go_lock(){ lockStatus=(ls | grep qbup.lock)
if [ -z "${lockStatus}" ]
then
noLock="1"
return
fi
noLock="0"
}
function file_unlock(){
$(rm -rf qbup.lock)
}

function doUpload(){
torrentInfo=$1
i=$2
echo $2
echo ${i}

# IFS保存,因为名字中可能出现多个空格
OLD_IFS=$IFS
IFS="\n"

torrent_name=$(echo "${torrentInfo}" | jq ".[$i] | .name" | sed s/\"//g)
torrent_hash=$(echo "${torrentInfo}" | jq ".[$i] | .hash" | sed s/\"//g)
save_path=$(echo "${torrentInfo}" | jq ".[$i] | .save_path" | sed s/\"//g)

IFS=$OLD_IFS

echo "${torrent_name}";

if [[ $save_path != /* ]]
then
	save_path="/${save_path}"
fi

torrent_path="${save_path}${torrent_name}" # 这里就是他的本地实际路径,尝试将这里上传上去

can_go_lock
if [[ ${noLock} == "1" ]] # 厕所门能开
then
    file_lock # 锁上厕所门
    echo '执行上传没事的~~~';
    echo ${torrent_name}
    echo ${torrent_hash}
    echo ${torrent_path}
    rclone_copy "${torrent_name}" "${torrent_hash}" "${torrent_path}"
else
    echo '已有程序在上传,退出'
    return # 打不开门,换个时间来
fi
file_unlock # 打开厕所门,出去

}

# 每次只查询一条数据,!!上传一条数据!!
function qb_get_status(){
qb_login
if [ qbv=="1"]thencompletedtorrentsnum={qb_v} == "1" ] then completed_torrents_num=(curl -s "qbweburl/api/v2/torrents/info?filter=completed"cookie"{qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "{cookie}" | jq '.[] | length' | wc -l)
echo "任务数:".{completed_torrents_num} for((i=0;i<{completed_torrents_num};i++));
do
curtag=(curls"(curl -s "{qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "cookie"jq".[{cookie}" | jq ".[i] | .tags" | sed s/"//g | grep -P -o "unfinishedtag")if[z"{unfinished_tag}") if [ -z "{curtag}" ]
then
curtag="null"
fi
if [ curtag=="{curtag} == "{unfinished_tag}" ]
then
torrentInfo=(curls"(curl -s "{qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "${cookie}")

			doUpload "${torrentInfo}" ${i}
            # 每次只上传一个数据,否则的话,可能会导致多线程的争用问题
            break
		fi
	done
elif [ ${qb_v} == "2" ]
then
	completed_torrents_num=$(curl -s "${qb_web_url}/query/torrents?filter=completed" --cookie "${cookie}" | jq '.[] | length' | wc -l)
	for((i=0;i<${completed_torrents_num};i++));
	do
		curtag=$(curl -s "${qb_web_url}/query/torrents?filter=completed" --cookie "${cookie}" | jq ".[$i] | .category" | sed s/\"//g)
		if [ -z "${curtag}" ]
		then
			curtag="null"
		fi
		if [ ${curtag} == "${unfinished_tag}" ]
		then
			torrentInfo=$(curl -s "${qb_web_url}/query/torrents?filter=completed" --cookie "${cookie}")

            doUpload "${torrentInfo}" ${i}
            # 每次只上传一个数据,否则的话,可能会导致多线程的争用问题
            break
		fi
	done
	echo "啥事都不干";
else
	echo "获取错误"
	echo "qb_v=${qb_v}"
fi

}

qb_get_status

 

设置定时任务crontab -e 在后面加上

*/1 * * * * bash /root/qb_auto_rclone.sh

 

然后把想要上传的种子任务打上标签,下载完坐等上传就行了