1、创建脚本
新建一个qb_auto_upload.sh文件,比如说我是放在qb安装目录下
#!/bin/sh
qb_version="4.6.3" # 改:改为你的实际qb的版本号
qb_username="admin" # 改:该为你的qb登录用户名
qb_password="adminadmin" # 改:改为你qb登录的密码
qb_web_url="http://192.168.1.100:8080" # 查:改为qb的登录地址,一般可以不改
log_dir="/root/logs" # 改:改为你日志运行的路径
rclone_dest="alist:Emby/Animes" # 运行rclone config查看name字段即可;格式就是"XX:"
from_dc_tag="" # 存放路径,自动获取
rclone_parallel="32" # rclone上传线程 默认4
save_path_prefix="/root/downloads/qb/Bangumi" #上传目录需替换路径,最终路径为/downloads,如原保存路径为/mnt/sda3/download,需上传到/downloads 则填写/mnt/sda3/download
leeching_mode="true" # 吸血模式,true下载完成后自动删除本地种子和文件
rclone_bwlimit="off" #限制速率 即限制, "08:00,2.5M:off 23:00,off"为8点开始限制为上传2.5m/s下载不限制 23点后不限制
upload_dir_files_flag="false"
upload_dir_files_index=-1
# 下面的也可以自定义,但是推荐不改动
unfinished_tag="待上传" # 这个是手动设置某些tag,因为有用才上传
uploading_tag="正在上传"
finished_tag="上传完成"
noupload_tag="无效-不上传"
if [ ! -d ${log_dir} ]
then
mkdir -p ${log_dir}
fi
version=$(echo ${qb_version} | grep -E -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 [ ${version} -gt 404 ]
then
qb_v="1"
cookie=$(curl -i --header "Referer: ${qb_web_url}" --data "username=${qb_username}&password=${qb_password}" "${qb_web_url}/api/v2/auth/login" | grep -E -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} -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 -E -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}" "${qb_web_url}/api/v2/torrents/removeTags" --cookie "${cookie}"
curl -s -X POST -d "hashes=${file_hash}&tags=${toTag}" "${qb_web_url}/api/v2/torrents/addTags" --cookie "${cookie}"
elif [ ${qb_v} == "2" ]
then
curl -s -X POST -d "hashes=${file_hash}&category=${fromTag}" "${qb_web_url}/command/removeCategories" --cookie ${cookie}
curl -s -X POST -d "hashes=${file_hash}&category=${toTag}" "${qb_web_url}/command/setCategory" --cookie ${cookie}
else
echo "qb_v=${qb_v}"
fi
}
function del_file(){
path=$1
rm -rf "${path}"
}
function qb_del(){
torrent_name=$1
file_hash=$2
if [ ${leeching_mode} == "true" ]
then
if [ ${qb_v} == "1" ]
then
curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子名称:${torrent_name}" >> ${log_dir}/qb.log
elif [ ${qb_v} == "2" ]
then
curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
else
curl -X POST -d "hashes=${file_hash}&deleteFiles=true" "${qb_web_url}/api/v2/torrents/delete" --cookie ${cookie}
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 删除成功!种子文件:${torrent_name}" >> ${log_dir}/qb.log
# echo "qb_v=${qb_v}" >> ${log_dir}/qb.log
fi
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 不自动删除已上传种子" >> ${log_dir}/qb.log
fi
}
function upload_dir_files(){
torrent_hash=$1
upload_dir_files_index=$(($upload_dir_files_index+1)) # 自增
echo "torrent_hash:${torrent_hash},torrent_path:${fix_torrent_path},noLock:${noLock},上传索引:${upload_dir_files_index}"
if [ ${upload_dir_files_index} -eq ${files_length} ];then
echo "当前目录【${fix_torrent_path}】符合要求的文件已全部上传完毕" >> ${log_dir}/qb.log
upload_dir_files_flag="false"
rclone_fin
return
fi
# echo "${files}"
file_name=$(echo "${files}" | jq ".[$upload_dir_files_index] | .name" | sed s/\"//g) # 获取文件名
echo "原始filename---------------${file_name}"
file_name=${file_name##*/} #截取最后一个/后的真正的文件名
echo "替换后filename-------------------${file_name}"
file_formatter=$(echo "${file_name##*.}") # 获取文件后缀
formatters=("mkv" "ass" "mp4") # 定义符合的后缀
if echo "${formatters[@]}" | grep -qw "$file_formatter"; then
# 符合后缀的文件上传
echo "开始上传【${fix_torrent_path}】目录中的【${file_name}】" >> ${log_dir}/qb.log
rclone_copy "${file_name}" "${torrent_hash}" "${fix_torrent_path}/${file_name}"
else
echo "当前文件【${file_name}】不符合上传要求,开始上传下一个" >> ${log_dir}/qb.log
upload_dir_files "${torrent_hash}" "${fix_torrent_path}"
fi
}
function rclone_copy(){
torrent_name=$1
torrent_hash=$2
torrent_path=$3
# tag = 待上传
# 这里执行上传程序
echo "----------------${torrent_path}"
if [ -f "${torrent_path}" ]
then
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:文件"
type="file"
elif [ -d "${torrent_path}" ]
then
# echo "[$(date '+%Y-%m-%d %H:%M:%S')] 类型:目录"
type="dir"
# 获取文件夹内容
files=$(curl -s "${qb_web_url}/api/v2/torrents/files?hash=${torrent_hash}" --cookie "${cookie}")
files_length=$(echo "${files}" | jq '.[] | length' | wc -l)
if [ ${files_length} -gt 0 ];then
upload_dir_files_flag="true"
fix_torrent_path="${torrent_path}"
upload_dir_files "${torrent_hash}" "${fix_torrent_path}"
return
fi
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 文件未知类型,取消上传"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 取消上传,原因:文件未知类型" >> ${log_dir}/qb.log
# tag = 不上传
if [ ${upload_dir_files_flag} == "true" ];then
upload_dir_files "${torrent_hash}" "${fix_torrent_path}"
else
qb_change_hash_tag ${torrent_hash} ${unfinished_tag} ${noupload_tag}
fi
return
fi
# 更改为上传中
qb_change_hash_tag ${torrent_hash} ${unfinished_tag} ${uploading_tag}
upload_full_path="${rclone_dest}${from_dc_tag}"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始上传,类型为【${type}】" >> ${log_dir}/qb.log
# 执行上传
if [ ${type} == "file" ]
then # 这里是rclone上传的方法
echo "完整上传后路径:${upload_full_path}"
rclone_copy_cmd=$(rclone -v copy --bwlimit "${rclone_bwlimit}" --transfers ${rclone_parallel} --log-file ${log_dir}/qbauto_copy.log "${torrent_path}" "${upload_full_path}")
elif [ ${type} == "dir" ]
then
rclone_copy_cmd=$(rclone -v copy --bwlimit "${rclone_bwlimit}" --transfers ${rclone_parallel} --log-file ${log_dir}/qbauto_copy.log "${torrent_path}"/ "${upload_full_path}")
fi
# 如果当前为上传文件夹则继续上传下一个
if [ ${upload_dir_files_flag} == "true" ];then
upload_dir_files "${torrent_hash}" "${fix_torrent_path}"
return
fi
rclone_fin
}
function rclone_fin(){
# 上传完成
# tag = 已上传
echo "上传完成,更改状态,当前torrent_hash:${torrent_hash}"
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 "[$(date '+%Y-%m-%d %H:%M:%S')] 上传完成-耗时:${use_min}分${use_sec}秒" >> ${log_dir}/qb.log
# 自定义发送消息 接口地址请自行替换
curl -H "Content-Type: application/json" -s -X POST -d "{\"type\":\"text\",\"msg\":\"${fix_torrent_name}已上传完成!耗时:${use_min}分${use_sec}秒\"}" "http://xxx/api/sendMsg/"
}
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=$(echo -en "\n\b") # IFS="\n"
torrent_name=$(echo "${torrentInfo}" | jq ".[$i] | .name" | sed s/\"//g) # 文件名
fix_torrent_name="${torrent_name}"
torrent_hash=$(echo "${torrentInfo}" | jq ".[$i] | .hash" | sed s/\"//g) # 文件hash
save_path=$(echo "${torrentInfo}" | jq ".[$i] | .save_path" | sed s/\"//g) # 存储路径
#save_path=$(echo "${save_path}" | sed 's/\/mnt\/sda3\/download/\/downloads/') #替换掉/mnt/sda3/download
save_path="${save_path/${save_path_prefix//\//\\/}/}" #把变量save_path_prefix替换成/download
content_path=$(echo "${torrentInfo}" | jq ".[$i] | .content_path" | sed s/\"//g) # 最终完整文件路径(包括重命名后)
torrent_path="${content_path}" # 这里就是他的本地实际路径,尝试将这里上传上去
IFS=$OLD_IFS
can_go_lock
if [[ ${noLock} == "1" ]] # 厕所门能开
then
echo "【${torrent_path}】" >> ${log_dir}/qb.log
file_lock # 锁上厕所门
from_dc_tag="${save_path}"
rclone_copy "${torrent_name}" "${torrent_hash}" "${torrent_path}"
else
echo '已有程序在上传,退出'
return # 打不开门,换个时间来
fi
file_unlock # 打开厕所门,出去
echo "运行结束"
echo "----------------------分割线-----------------------------" >> ${log_dir}/qb.log
}
# 每次只查询一条数据,!!上传一条数据!!
function qb_get_status(){
qb_login
if [ ${qb_v} == "1" ]
then
completed_torrents_num=$(curl -s "${qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "${cookie}" | jq '.[] | length' | wc -l)
torrentInfo=$(curl -s "${qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "${cookie}")
echo "任务数:"${completed_torrents_num}
for((i=0;i<${completed_torrents_num};i++));
do
tag_str=$(curl -s "${qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "${cookie}" | jq ".[$i] | .tags" | sed s/\"//g) # 获取所有标签信息
curtag=$(echo "${tag_str}" | sed s/\"//g | grep -E -o "${unfinished_tag}") # 筛选待上传
# curtag=$(curl -s "${qb_web_url}/api/v2/torrents/info?filter=completed" --cookie "${cookie}" | jq ".[$i] | .tags" | sed s/\"//g | grep -E -o "${unfinished_tag}")
if [ -z "${tag_str}" ]
then
curtag="无标签"
fi
if [ -z "${curtag}" ]
then
curtag="null"
fi
# echo "当前标签:${curtag}"
if [ ${curtag} == "${unfinished_tag}" ]
then
doUpload "${torrentInfo}" ${i}
#每次只上传一个数据,否则的话,可能会导致多线程的争用问题
break
elif [ ${curtag} == "无标签" ]
then
# 没有标签的更改为待上传
torrent_name=$(echo "${torrentInfo}" | jq ".[$i] | .name" | sed s/\"//g)
torrent_hash=$(echo "${torrentInfo}" | jq ".[$i] | .hash" | sed s/\"//g)
echo "把【${torrent_name}】状态更改为待上传"
qb_change_hash_tag ${torrent_hash} ${curtag} ${unfinished_tag}
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
2、添加定时任务
*/1 * * * * bash /root/docker/qb/qb_auto.sh>/root/logs/crontab_qb_upload.log
运行日志如下
root@iStoreOS:~# bash /root/docker/qb/qb_auto.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 40 100 3 100 37 15 189 --:--:-- --:--:-- --:--:-- 205
[2024-03-08 22:56:12] 登录成功!cookie:SID=xxx
任务数:101
0
0
已有程序在上传,退出
评论区