Open lordvalium opened 4 years ago
I believe this is available in the web API. I was able to do this via a python script when I had to change my token on a tracker.
As a workaround, I re-wrote this Fish shell snippet to update all torrents with a bulk tracker list:
set username "my_username"
set password "my_password"
set url "my_url"
set trackers (curl --silent --stderr -- "https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_best.txt")
qbt torrent list --url "$url" --username "$username" --password "$password" -F json | jq ".[].hash" -r | parallel --eta --bar -N1 echo $trackers '|' xargs qbt torrent tracker add --url "$url" --username "$username" --password "$password" {}
It requires qbittorrent-cli, jq, GNU Parallel, and xargs
.
Now updated to support many trackers and many torrents! Previously, too many trackers would reach the shell's argument limit. Now, they get split by xargs
if they're too long. Also, each torrent is now updated in parallel, with a progress bar. Increase the job limit with -j100
if your server can handle it!
For a bash
or probably any other shell version, replace set x y
with x=y
and set x (y)
with x=$(y)
.
The same script also works for removing trackers! Replace xargs qbt torrent tracker add
with xargs -n1 qbt torrent tracker delete
and specify which trackers to delete using $trackers
!
As a workaround, I wrote this Fish shell snippet to update all torrents with an up-to-date tracker list:
set trackers (curl --silent --stderr -- "https://newtrackon.com/api/stable") for hash in (qbt torrent list --url "$url" --username "$username" --password "$password" -F json | jq ".[].hash" -r) echo "Processing $hash" qbt torrent tracker add --url "$url" --username "$username"--password "$password" "$hash" "$trackers" end
It requires qbittorrent-cli and jq.
I also basically did the same thing on 1000 mixed torrents to update just some trackers from http to https.
qbt torrent list -F json | jq ".[].hash" -r >> hash_list
#! /bin/bash
for x in $(cat hash_list); do
trackerurl=$(qbt torrent tracker list $x -F json | jq '.[]."Url"')
if [[ $trackerurl == *http://oldtracker.com* ]]; then
echo "Updating $x for https"
qbt torrent tracker add $x "https://newtracker.com/announce"
qbt torrent tracker delete $x "http://oldtracker.com/announce"
else
echo "$x has tracker $trackerurl"
fi;
done;
Would still love to see this functionality in the WebUI. Although the time it took to loop through and change all of these via API might not work well in the WebUI.
As a workaround, I wrote this Fish shell snippet to update all torrents with an up-to-date tracker list:
set trackers (curl --silent --stderr -- "https://newtrackon.com/api/stable") for hash in (qbt torrent list --url "$url" --username "$username" --password "$password" -F json | jq ".[].hash" -r) echo "Processing $hash" qbt torrent tracker add --url "$url" --username "$username"--password "$password" "$hash" "$trackers" end
It requires qbittorrent-cli and jq.
I also basically did the same thing on 1000 mixed torrents to update just some trackers from http to https.
- Got a list of the hashes with
qbt torrent list -F json | jq ".[].hash" -r >> hash_list
- Iterated through all the hashes with a shell script
#! /bin/bash for x in $(cat hash_list); do trackerurl=$(qbt torrent tracker list $x -F json | jq '.[]."Url"') if [[ $trackerurl == *http://oldtracker.com* ]]; then echo "Updating $x for https" qbt torrent tracker add $x "https://newtracker.com/announce" qbt torrent tracker delete $x "http://oldtracker.com/announce" else echo "$x has tracker $trackerurl" fi; done;
Would still love to see this functionality in the WebUI. Although the time it took to loop through and change all of these via API might not work well in the WebUI.
Need a JavaScript version to run on the browser console:
I did use the following code from the browser console.
let qbit_url=window.location.href
let old_url='https://oldurl.com'
let new_url='https://newurl.xyz'
// Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#edit-trackers
var change_url = (torrent) => fetch(qbit_url + 'api/v2/torrents/editTracker?' + new URLSearchParams({
hash: torrent.hash,
origUrl: torrent.tracker,
newUrl: torrent.tracker.replace(old_url, new_url)
}))
// Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list
fetch(qbit_url + 'api/v2/torrents/info')
.then(response => response.json())
// Filter torrents with your url
.then(torrents => torrents.filter(({tracker}) => tracker.startsWith(old_url)))
// request change for each torrent
.then(torrents => torrents.map(change_url))
In case the tracker url no longer works (tracker status 'Not Working') by qBittorrent: This version is probably slower, but I added some feddback to the console.
⚠️ The API torrent/removeTrackers
doesn't work properly on 4.5 and will return ok (200
) even when it didn't removed a tracker. This script is not safe if you have trackers from a different domain on qB 4.5
var PID = 'myPID'
var old_url = 'https://olddomain/announce/' + PID
var new_url = 'https://newdomain/announce/' + PID
var qbit_url = window.location.href
var recreate_tracker = (torrent) => fetch(qbit_url + 'api/v2/torrents/removeTrackers?' + new URLSearchParams({
hash: torrent.hash,
urls: old_url,
})).then((response) => response.status == 200 ? fetch(qbit_url + 'api/v2/torrents/addTrackers?', {
"body": new URLSearchParams({
hash: torrent.hash,
urls: new_url,
}),
"method": "POST"
}).then(response.status == 200 ? console.log(`✔️ ${torrent.name}`) : console.log(`❌ ERROR: ${torrent.name}`)
) : console.log(`❗️ NOT MODIFIED: ${torrent.name}`))
// optionally, use tags to filter
// var tag = 'script'
// fetch(qbit_url + 'api/v2/torrents/info?tag=' + tag)
fetch(qbit_url + 'api/v2/torrents/info')
.then(response => response.json())
.then(torrents => torrents.map(recreate_tracker))
I did use the following code from the browser console.
let qbit_url=window.location.href let old_url='https://oldurl.com' let new_url='https://newurl.xyz' // Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#edit-trackers var change_url = (torrent) => fetch(qbit_url + 'api/v2/torrents/editTracker?' + new URLSearchParams({ hash: torrent.hash, origUrl: torrent.tracker, newUrl: torrent.tracker.replace(old_url, new_url) })) // Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list fetch(qbit_url + 'api/v2/torrents/info') .then(response => response.json()) // Filter torrents with your url .then(torrents => torrents.filter(({tracker}) => tracker.startsWith(old_url))) // request change for each torrent .then(torrents => torrents.map(change_url))
I see that you are a victim of Redbits domain change. Working perfectly. Thank you so much @Ameb .
If the tracker url no longer works, qbittorrent doesn't return it on the torrents/info
endpoint so i had to made a different script. Edited my previous message
The simple way
var editTracker = (torrent) => fetch(
'http://qbittorrent.example:8080/api/v2/torrents/editTracker',
{
body: new URLSearchParams({
hash: torrent.hash,
origUrl: 'http://old.tracker.example/xxxxx/announce',
newUrl: 'http://new.tracker.example/xxxxx/announce'
}),
method: 'POST'
}
)
fetch('http://qbittorrent.example:8080/api/v2/torrents/info')
.then(response => response.json())
.then(torrents => torrents.map(editTracker))
On v4.5.0, it works when the old tracker is offline, and it does not change other trackers
works well ! thank you both @jcassette and @Ameb.
We really need a WebUI implementation. Hopeful that someone build that feature one day
+1
I did use the following code from the browser console.
let qbit_url=window.location.href let old_url='https://oldurl.com' let new_url='https://newurl.xyz' // Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#edit-trackers var change_url = (torrent) => fetch(qbit_url + 'api/v2/torrents/editTracker?' + new URLSearchParams({ hash: torrent.hash, origUrl: torrent.tracker, newUrl: torrent.tracker.replace(old_url, new_url) })) // Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list fetch(qbit_url + 'api/v2/torrents/info') .then(response => response.json()) // Filter torrents with your url .then(torrents => torrents.filter(({tracker}) => tracker.startsWith(old_url))) // request change for each torrent .then(torrents => torrents.map(change_url))
If your qb version ≥ 4.4.4,POST method should be used.
let url_qbit = location.protocol + '//' + location.host;
let url_base = 'https://basedomain.com';
let str_old = 'wwww';
let str_new = 'mmmm';
// Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#edit-trackers
var change_url = (torrent) => fetch(url_qbit + '/api/v2/torrents/editTracker', {
// POST must be used in ≥ v4.4.4 https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#general-information
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8;"
},
body: new URLSearchParams({
hash: torrent.hash,
origUrl: torrent.tracker,
newUrl: torrent.tracker.replace(str_old, str_new)
})
}).then(function(r) {
console.log(torrent.hash + ': ' + r.status)
});
// Calls https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list
fetch(url_qbit + '/api/v2/torrents/info')
.then(response => response.json())
// Filter torrents with your url
.then(torrents => torrents.filter(({tracker}) => tracker.startsWith(url_base)))
// request change for each torrent
.then(torrents => torrents.map(change_url))
For 4.6.0, this works:
var old_url = 'https://tracker.gg/announce/oldannounce'
var new_url = 'https://tracker.gg/announce/newannounce'
var tag = 'tag-to-filter'
var qbit_url = window.location.href
fetch(qbit_url + 'api/v2/torrents/info?tag='+tag)
.then(response => response.json())
.then(torrents => torrents?.map( response => {
if(response.tags.indexOf(tag) != -1) {
var deleteResponse = fetch(qbit_url + 'api/v2/torrents/editTracker?',
{
"body": new URLSearchParams({
hash: response.hash,
origUrl: old_url,
newUrl: new_url
})
,
"method": "POST"
})
console.log(deleteResponse)
return deleteResponse
}
}))
Without a tag to filter (will go over all your 1000s of torrents):
var qbit_url = window.location.href
var old_url = 'https://tracker.cc/announce/old-pass-key'
var new_url = 'https://tracker.cc/announce/new-pass-key'
fetch(qbit_url + 'api/v2/torrents/info)
.then(response => response.json())
.then(torrents => torrents?.map( response => {
var deleteResponse = fetch(qbit_url + 'api/v2/torrents/editTracker?',
{
"body": new URLSearchParams({
hash: response.hash,
origUrl: old_url,
newUrl: new_url
})
,
"method": "POST"
})
console.log(deleteResponse)
return deleteResponse
}))
Untested, but should work for any "remote" instances that you're not currently logged into:
var qbit_url = 'http://qbit.url:8080/'
var username = 'username'
var pw = 'password'
var old_url = 'https://tracker.cc/announce/old-pass-key'
var new_url = 'https://tracker.cc/announce/new-pass-key'
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#making_cross-origin_requests
fetch(qbit_url + 'api/v2/torrents/info)
.then(response => response.json())
.then(torrents => torrents?.map( response => {
var headers = new Headers({
'Authorization': `Basic ${btoa(username + ':' + pw)}`
})
var deleteResponse = fetch(qbit_url + 'api/v2/torrents/editTracker?',
{
"body": new URLSearchParams({
hash: response.hash,
origUrl: old_url,
newUrl: new_url
}),
"method": "POST",
"headers": headers,
"mode": 'no-cors'
})
console.log(deleteResponse)
return deleteResponse
})
)
For 4.6.0, this works:
var old_url = 'https://tracker.gg/announce/oldannounce' var new_url = 'https://tracker.gg/announce/newannounce' var tag = 'tag-to-filter' var qbit_url = window.location.href fetch(qbit_url + 'api/v2/torrents/info?tag='+tag) .then(response => response.json()) .then(torrents => torrents?.map( response => { if(response.tags.indexOf(tag) != -1) { var deleteResponse = fetch(qbit_url + 'api/v2/torrents/editTracker?', { "body": new URLSearchParams({ hash: response.hash, origUrl: old_url, newUrl: new_url }) , "method": "POST" }) console.log(deleteResponse) return deleteResponse } }))
Is there a version of this that will just let you add a new URL when one does not exist? Trying to recover from a crash, and adding the torrents back from a backup I'm seeing that for some reason the announce URL is missing. So I just need to be able to add it to all of them.
https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#add-trackers-to-torrent There's someone already using it here: https://github.com/qbittorrent/qBittorrent/issues/11868#issuecomment-1338173074
Replace editTracker
with addTrackers
Inside the body, remove origUrl
and newUrl
, just use urls
https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#add-trackers-to-torrent There's someone already using it here: #11868 (comment)
Replace
editTracker
withaddTrackers
Inside the body, removeorigUrl
andnewUrl
, just useurls
I tried this, but it gave me a 404 error for each:
var new_url = 'https://tracker.gg/announce/newannounce'
var tag = 'tag-to-filter'
var qbit_url = window.location.href
fetch(qbit_url + 'api/v2/torrents/info?tag='+tag)
.then(response => response.json())
.then(torrents => torrents?.map( response => {
if(response.tags.indexOf(tag) != -1) {
var deleteResponse = fetch(qbit_url + 'api/v2/torrents/addTracker?',
{
"body": new URLSearchParams({
hash: response.hash,
urls: new_url
})
,
"method": "POST"
})
console.log(deleteResponse)
return deleteResponse
}
}))
I'm having trouble following this thread since the image in the OP is broken. Could someone help me understand what the desired functionality is?
If we have a bunch of torrents from a single tracker, and the tracker url changes. We would like a way to edit all selected torrent tracker urls, instead of doing it one by one. That’s lame when you gotta do it 1000 times or more.
I see, thank you. How do you achieve this today in the GUI? I was expecting an edit option in the Trackers filter menu, but I don't see one.
You simply don't. This is a feature request because it's not possible. You can only select single torrents and then edit their tracker URL.
You cannot select 1000 torrents and change the URL for all of them. That's why people are using Javascript snippets to query the API and do do exactly that, but from within the browser, logged into the web ui
The OP is describing a feature that's available in the GUI but not in the WebUI.
Has been implemented in Application but not WebUi. Can that please be updated?
https://github.com/qbittorrent/qBittorrent/issues/2428#issuecomment-573396594