qbittorrent / qBittorrent

qBittorrent BitTorrent client
https://www.qbittorrent.org
Other
26.99k stars 3.88k forks source link

Highlight torrents with no working trackers/Tracker status column/Trackers not working filter/"Unregistered torrent" filter #9849

Open Ryrynz opened 5 years ago

Ryrynz commented 5 years ago

Please provide the following information

qBT 4.2.4 x64

What is the problem

The only way I can tell if a torrent has been deleted from the tracker or is not working currently is by scrolling through my entire list of torrents while viewing the 'Tracker' tab and look for the 'Status' column to show 'Not working'

What is the expected behavior

Color the torrent red and use an exclamation mark like when qBittorrent is missing files so I can see at a glance all trackers for a particular torrent are not working. This only needs to occur when there are no working trackers. This is the current behavior in uTorrent.

Ryrynz commented 5 years ago

@thalieht Any chance of getting this into 4.1.x and 4.2? It would be a pretty simple addition and hella useful anyone seeding hundreds or even thousands of torrents, easily spotting those that are not working is very useful for cleanup and seeding maintenance.

thalieht commented 5 years ago

I don't (deliberately) use or care about trackers so i don't know how stuff concerning them are supposed to work. Isn't the Error filter on the TRACKERS sidepanel what you ask for?

Ryrynz commented 5 years ago

Hi, thanks for your reply. The status column in the tracker panel is what I currently have to use to determine if a tracker is Not working or not. I'd like to be able to tell this by having the the torrent line in the main window changed red. In the same way as say pausing the torrent changes the line to orange. Alternatively even just having the Status column say Error would be useful as this could be sorted so that these torrents would show above /below "Missing files" in the Status column.

thalieht commented 5 years ago

Here's a patch which is probably wrong because i add another torrent state... and because of that i have to add a specific Status for that state (or i just don't know how to not need to do that). In its current form it gets out of the "Tracker Error" state if an errored tracker is no longer errored and shortly re-enters it if there are more errored trackers. Dunno if it's common/possible to have more than one tracker in private torrents though so it may not be an issue. It works only on private torrents.

p.s. I will not make a PR because i don't want to deal with fixing it.

diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp
index 537525b17..998f2e21f 100644
--- a/src/base/bittorrent/torrenthandle.cpp
+++ b/src/base/bittorrent/torrenthandle.cpp
@@ -183,6 +183,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
     , m_seedingTimeLimit(params.seedingTimeLimit)
     , m_tempPathDisabled(params.disableTempPath)
     , m_hasMissingFiles(false)
+    , m_hasErroredTracker(false)
     , m_hasRootFolder(params.hasRootFolder)
     , m_needsToSetFirstLastPiecePriority(false)
     , m_needsToStartForced(params.forced)
@@ -818,6 +819,9 @@ void TorrentHandle::updateState()
         else
             m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading;
     }
+    else if (isPrivate() && m_hasErroredTracker) {
+        m_state = TorrentState::ErroredPrivateTracker;
+    }
     else {
         if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) {
             m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading;
@@ -1484,6 +1488,7 @@ void TorrentHandle::handleTrackerReplyAlert(const libtorrent::tracker_reply_aler
     // Connection was successful now. Remove possible old errors
     m_trackerInfos[trackerUrl].lastMessage.clear(); // Reset error/warning message
     m_trackerInfos[trackerUrl].numPeers = p->num_peers;
+    m_hasErroredTracker = false; // should probably be somewhere else where is tests if torrent has any errored trackers

     m_session->handleTorrentTrackerReply(this, trackerUrl);
 }
@@ -1507,6 +1512,7 @@ void TorrentHandle::handleTrackerErrorAlert(const libtorrent::tracker_error_aler
     m_trackerInfos[trackerUrl].lastMessage = message;

     m_session->handleTorrentTrackerError(this, trackerUrl);
+    m_hasErroredTracker = true;
 }

 void TorrentHandle::handleTorrentCheckedAlert(const libtorrent::torrent_checked_alert *p)
diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h
index 7a0b0d29b..ae20f53cc 100644
--- a/src/base/bittorrent/torrenthandle.h
+++ b/src/base/bittorrent/torrenthandle.h
@@ -124,7 +124,9 @@ namespace BitTorrent
         Moving,

         MissingFiles,
-        Error
+        Error,
+
+        ErroredPrivateTracker
     };

     class TorrentHandle : public QObject
@@ -430,6 +432,7 @@ namespace BitTorrent
         bool m_hasRootFolder;
         bool m_needsToSetFirstLastPiecePriority;
         bool m_needsToStartForced;
+        bool m_hasErroredTracker;

         QHash<QString, TrackerInfo> m_trackerInfos;

diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp
index d64d74e35..d08e33856 100644
--- a/src/gui/transferlistdelegate.cpp
+++ b/src/gui/transferlistdelegate.cpp
@@ -275,6 +275,9 @@ QString TransferListDelegate::getStatusString(const BitTorrent::TorrentState sta
     case BitTorrent::TorrentState::Error:
         str = tr("Errored", "torrent status, the torrent has an error");
         break;
+    case BitTorrent::TorrentState::ErroredPrivateTracker:
+        str = tr("Tracker Error");
+        break;
     default:
         str = "";
     }
diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp
index eb98486ac..23c3dc617 100644
--- a/src/gui/transferlistmodel.cpp
+++ b/src/gui/transferlistmodel.cpp
@@ -350,6 +350,7 @@ QIcon getIconByState(BitTorrent::TorrentState state)
     case BitTorrent::TorrentState::Unknown:
     case BitTorrent::TorrentState::MissingFiles:
     case BitTorrent::TorrentState::Error:
+    case BitTorrent::TorrentState::ErroredPrivateTracker:
         return getErrorIcon();
     default:
         Q_ASSERT(false);
@@ -392,6 +393,7 @@ QColor getColorByState(BitTorrent::TorrentState state)
             return {79, 148, 205}; // Steel Blue 3
     case BitTorrent::TorrentState::Error:
     case BitTorrent::TorrentState::MissingFiles:
+    case BitTorrent::TorrentState::ErroredPrivateTracker:
         return {255, 0, 0}; // red
     case BitTorrent::TorrentState::QueuedDownloading:
     case BitTorrent::TorrentState::QueuedUploading:
Ryrynz commented 5 years ago

Personally I'm only interested in knowing if all trackers are errored, say if there's one tracker tracker and the torrent is no longer registered. As long as some trackers are working on the torrent then I don't see a need to display anything.

thalieht commented 5 years ago

One working tracker coming up (i still won't make PR).

diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp
index 537525b17..26982af85 100644
--- a/src/base/bittorrent/torrenthandle.cpp
+++ b/src/base/bittorrent/torrenthandle.cpp
@@ -186,6 +186,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle
     , m_hasRootFolder(params.hasRootFolder)
     , m_needsToSetFirstLastPiecePriority(false)
     , m_needsToStartForced(params.forced)
+    , m_hasWorkingTracker(hasWorkingTracker())
 {
     if (m_useAutoTMM)
         m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
@@ -377,6 +378,20 @@ QList<TrackerEntry> TorrentHandle::trackers() const
     return entries;
 }

+bool TorrentHandle::hasWorkingTracker() const
+{
+    const auto trackers = m_nativeHandle.trackers();
+    if (trackers.empty())
+        return false;
+
+    for (const auto &entry : trackers) {
+        if (entry.is_working())
+            return true;
+    }
+
+    return false;
+}
+
 QHash<QString, TrackerInfo> TorrentHandle::trackerInfos() const
 {
     return m_trackerInfos;
@@ -390,8 +405,10 @@ void TorrentHandle::addTrackers(const QList<TrackerEntry> &trackers)
             addedTrackers << tracker;
     }

-    if (!addedTrackers.isEmpty())
+    if (!addedTrackers.isEmpty()) {
+        m_hasWorkingTracker = hasWorkingTracker();
         m_session->handleTorrentTrackersAdded(this, addedTrackers);
+    }
 }

 void TorrentHandle::replaceTrackers(const QList<TrackerEntry> &trackers)
@@ -418,6 +435,8 @@ void TorrentHandle::replaceTrackers(const QList<TrackerEntry> &trackers)
         if (!addedTrackers.isEmpty())
             m_session->handleTorrentTrackersAdded(this, addedTrackers);
     }
+
+    m_hasWorkingTracker = hasWorkingTracker();
 }

 bool TorrentHandle::addTracker(const TrackerEntry &tracker)
@@ -426,6 +445,7 @@ bool TorrentHandle::addTracker(const TrackerEntry &tracker)
         return false;

     m_nativeHandle.add_tracker(tracker.nativeEntry());
+    m_hasWorkingTracker = hasWorkingTracker();
     return true;
 }

@@ -818,6 +838,9 @@ void TorrentHandle::updateState()
         else
             m_state = isSeed() ? TorrentState::PausedUploading : TorrentState::PausedDownloading;
     }
+    else if (isPrivate() && !m_hasWorkingTracker) {
+        m_state = TorrentState::NoWorkingTracker;
+    }
     else {
         if (m_session->isQueueingSystemEnabled() && isQueued() && !isChecking()) {
             m_state = isSeed() ? TorrentState::QueuedUploading : TorrentState::QueuedDownloading;
@@ -1484,6 +1507,7 @@ void TorrentHandle::handleTrackerReplyAlert(const libtorrent::tracker_reply_aler
     // Connection was successful now. Remove possible old errors
     m_trackerInfos[trackerUrl].lastMessage.clear(); // Reset error/warning message
     m_trackerInfos[trackerUrl].numPeers = p->num_peers;
+    m_hasWorkingTracker = hasWorkingTracker();

     m_session->handleTorrentTrackerReply(this, trackerUrl);
 }
@@ -1505,6 +1529,7 @@ void TorrentHandle::handleTrackerErrorAlert(const libtorrent::tracker_error_aler
     const QString message = p->error_message();

     m_trackerInfos[trackerUrl].lastMessage = message;
+    m_hasWorkingTracker = hasWorkingTracker();

     m_session->handleTorrentTrackerError(this, trackerUrl);
 }
diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h
index 7a0b0d29b..a48514a11 100644
--- a/src/base/bittorrent/torrenthandle.h
+++ b/src/base/bittorrent/torrenthandle.h
@@ -124,7 +124,9 @@ namespace BitTorrent
         Moving,

         MissingFiles,
-        Error
+        Error,
+
+        NoWorkingTracker
     };

     class TorrentHandle : public QObject
@@ -261,6 +263,7 @@ namespace BitTorrent
         bool hasFilteredPieces() const;
         int queuePosition() const;
         QList<TrackerEntry> trackers() const;
+        bool hasWorkingTracker() const;
         QHash<QString, TrackerInfo> trackerInfos() const;
         QList<QUrl> urlSeeds() const;
         QString error() const;
@@ -430,6 +433,7 @@ namespace BitTorrent
         bool m_hasRootFolder;
         bool m_needsToSetFirstLastPiecePriority;
         bool m_needsToStartForced;
+        bool m_hasWorkingTracker;

         QHash<QString, TrackerInfo> m_trackerInfos;

diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp
index d64d74e35..9cf542aae 100644
--- a/src/gui/transferlistdelegate.cpp
+++ b/src/gui/transferlistdelegate.cpp
@@ -275,6 +275,9 @@ QString TransferListDelegate::getStatusString(const BitTorrent::TorrentState sta
     case BitTorrent::TorrentState::Error:
         str = tr("Errored", "torrent status, the torrent has an error");
         break;
+    case BitTorrent::TorrentState::NoWorkingTracker:
+        str = tr("No Working Tracker");
+        break;
     default:
         str = "";
     }
diff --git a/src/gui/transferlistmodel.cpp b/src/gui/transferlistmodel.cpp
index eb98486ac..9ffecf4eb 100644
--- a/src/gui/transferlistmodel.cpp
+++ b/src/gui/transferlistmodel.cpp
@@ -350,6 +350,7 @@ QIcon getIconByState(BitTorrent::TorrentState state)
     case BitTorrent::TorrentState::Unknown:
     case BitTorrent::TorrentState::MissingFiles:
     case BitTorrent::TorrentState::Error:
+    case BitTorrent::TorrentState::NoWorkingTracker:
         return getErrorIcon();
     default:
         Q_ASSERT(false);
@@ -392,6 +393,7 @@ QColor getColorByState(BitTorrent::TorrentState state)
             return {79, 148, 205}; // Steel Blue 3
     case BitTorrent::TorrentState::Error:
     case BitTorrent::TorrentState::MissingFiles:
+    case BitTorrent::TorrentState::NoWorkingTracker:
         return {255, 0, 0}; // red
     case BitTorrent::TorrentState::QueuedDownloading:
     case BitTorrent::TorrentState::QueuedUploading:
Ryrynz commented 5 years ago

Thanks. I'm hoping for something along the lines of this as a result https://i.imgur.com/jo1ns6U.jpg @glassez any chance you could look this one over when you get some time? Thanks. @Chocobo1? Can we get this functionality added? It's quite useful.

phant commented 5 years ago

Maybe merge this ticket with #8408 ? I have seen your posts there.

Ryrynz commented 4 years ago

@FranciscoPombal can you merge this with #8408 please?

FranciscoPombal commented 4 years ago

Scripted workarounds: https://github.com/qbittorrent/qBittorrent/issues/11469#issuecomment-553459887 https://github.com/qbittorrent/qBittorrent/issues/11469#issuecomment-618116632

Ryrynz commented 4 years ago
$url = 'http://127.0.0.1:8080'
$result = Invoke-RestMethod -Uri "$url/api/v2/auth/login?username=admin&password=hunter2" -SessionVariable session
if ( $result -and $result -ne 'Fails.' ) {
    $hashes = @()
    (Invoke-RestMethod -Uri "$url/api/v2/torrents/info" -WebSession $session) | % {
        $trackers = Invoke-RestMethod -Uri "$url/api/v2/torrents/trackers?hash=$($_.hash)" -WebSession $session

        if ( ($trackers | ? { $_.status -eq 4 }).msg -ilike '*unregistered torrent*') {
            "[$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")] $($_.name) ($($_.hash)) [$($_.save_path)]" | Out-File 'deleted-torrents.log' -Append
            $hashes += $_.hash
        }
    }
    if ( $hashes ) {
        Invoke-RestMethod -Uri "$url/api/v2/torrents/delete?hashes=$($hashes -join '|')&deleteFiles=false" -WebSession $session
    }
    Invoke-RestMethod -Uri "$url/api/v2/auth/logout" -WebSession $session
} else {
    exit 1
}

for any other nooblords who spent too much time trying to make this work, there's an R missing in one of the $trackers (corrected in my quote). You'll still need to edit your url and user/pass of course

@cassock Rather than delete the torrents can we move them into another category say called "Not Working" instead? What would be the command to do this?

Makishima commented 4 years ago

To be honest, deleting torrents is not what we want from this feature :) So it is hard to call it as workaround

Ryrynz commented 4 years ago

Yeah I'd rather do this manually when and if required.

FranciscoPombal commented 4 years ago

To be honest, deleting torrents is not what we want from this feature :) So it is hard to call it as workaround

The mechanism is similar if you just want to display the affected torrents. These are not "official" workarounds, just a general idea. You can further modify the scripts based on your specific needs.

Makishima commented 4 years ago

You can further modify the scripts based on your specific needs.

Yes, but I would prefer to see its implementation in qBittorrent. In uTorrent this feature is super useful

FranciscoPombal commented 4 years ago

Yes, but I would prefer to see its implementation in qBittorrent. In uTorrent this feature is super useful

Well, when it's done it's done™.

jp8311 commented 4 years ago

+1 , being able to see the tracker info in the sidebar (a feature the standalone client has) in the webui would make my life easier

ghost commented 4 years ago

@thalieht can I use your patch to make a PR? It seemed like a good approach to me.

thalieht commented 4 years ago

@thalieht can I use your patch to make a PR? It seemed like a good approach to me.

Yes of course.

FranciscoPombal commented 4 years ago

@an0n666 be mindful of how this would interact/conflict with https://github.com/qbittorrent/qBittorrent/pull/12173 or something similar (not saying it would be a problem, just thinking out loud).

mchamp00 commented 4 years ago

Not sure if this solution works for everyone's issues, but here's a workaround the meets my needs using the webUI:

-On the webUI, right click on one of the column headers above the torrent list and select 'Tracker' to add this column to the display -Any torrent that is no longer seeded on any tracker will have a blank entry for this column, whereas active torrents will have the tracker listed -If you click the 'Tracker' column header to sort by that column, it will group all torrents that are no longer seeding on a tracker -You can adjust/remove these torrents as needed

Not as simple as having them turn red or change symbols to alert you that they are no longer active, but a pretty simple workaround.

ghost commented 4 years ago

@FranciscoPombal this one should be pinned and not the closed one.

Cassock commented 4 years ago

Not sure if this solution works for everyone's issues, but here's a workaround the meets my needs using the webUI:

-On the webUI, right click on one of the column headers above the torrent list and select 'Tracker' to add this column to the display -Any torrent that is no longer seeded on any tracker will have a blank entry for this column, whereas active torrents will have the tracker listed -If you click the 'Tracker' column header to sort by that column, it will group all torrents that are no longer seeding on a tracker -You can adjust/remove these torrents as needed

Not as simple as having them turn red or change symbols to alert you that they are no longer active, but a pretty simple workaround.

Except there are a few other reasons why the Tracker field wouldn't have an entry such as: tracker hasn't been contacted or tracker is down. Not crapping on your workflow, just noting for others who may accidentally delete items that are still legitimate.

sataris commented 3 years ago

If this does get implemented, please bring it to the WEBUI at the same time.

Pentaphon commented 3 years ago

I am shocked that this feature hasn't been available since 1.x. This should be added ASAP.

Ryrynz commented 3 years ago

Just needs someone to take it on, and devs are busy with other things atm, I have no doubt it will be added eventually.

JakeWharton commented 3 years ago

Just throwing my external tool-based solution in the ring: https://github.com/JakeWharton/qbt-tracker-hound. It maintains a tag for torrents with no functioning trackers.

Would of course prefer a built-in solution, though!

zero77 commented 3 years ago

@JakeWharton Would you be able to create a qBittorrent PR for this.

AlexKMDev commented 3 years ago

There are also advanced solutions to mark torrents with not just not working trackers, but with trackers that only removed them too: https://gitlab.com/AlexKM/qbittools

withoutgettingwet commented 3 years ago

I just want to throw my hat in the ring and say that this seems like a basic feature that should be added.

If you've got a few hundred torrents (like me) it becomes very hard to keep track of any problems. mchamp00's suggestion is a good stop gap measure, though.

SleptOver commented 2 years ago

Any progress on this?

Simpuhl commented 2 years ago

Any updates on this? I have qbitorrent on synology and this is an issue. No point is seeding torrents with status of "not working"/torrent not registered with this tracker.

Kha-kis commented 1 year ago

I know this has been a long ongoing issue. I came up with my own work around using tagging to identify unregistered torrent. This works for most cases. I hope this helps https://github.com/Kha-kis/qbitunregistered

Pentaphon commented 1 year ago

Shouldn't this issue have a "help wanted" tag if we want somebody to take it on?

b0ril commented 1 year ago

May be I should get back to transmission this is hopeless !!

GKHWB commented 1 year ago

Do we know if there are any plans relating to this?

kambala-decapitator commented 1 year ago

I saw that in desktop GUI such torrents appear under the Errored Status in sidebar, but in WebUI it's still not the case

IevgenSobko commented 1 year ago

I don't see that in my latest version of qBittorrent in Windows. Any screenshots?

kambala-decapitator commented 1 year ago

I don't see that in my latest version of qBittorrent in Windows. Any screenshots?

sorry, can't comment on this. Last time I used v4.5.3 for macOS (self-built against Qt 5) and "broken" torrents appeared under Errored Status in sidebar correctly.

giosann commented 1 year ago

immagine

@IevgenSobko here it is. The torrent is not working because it was removed from the tracker but the ui still marks it as "Seeding", it should be in "Errored"

IevgenSobko commented 1 year ago

immagine

@IevgenSobko here it is. The torrent is not working because it was removed from the tracker but the ui still marks it as "Seeding", it should be in "Errored"

I asked for proof it is marked as Errored in GUI not proof of the issue :)

IRainman commented 1 year ago

@giosann This is wrong position. This error on the tracker and error category, it's need to be in the tracker's category.

kambala-decapitator commented 1 year ago

I saw that in desktop GUI such torrents appear under the Errored Status in sidebar, but in WebUI it's still not the case

so, yeah, WebUI has no Errored category under Trackers:

Screenshot 2023-07-27 at 10 46 20

simonbcn commented 1 year ago

Same problem. The "official" webUI should have the same sections/appearance as the GUI (as far as technically possible).

Maybe this should be reported as a new issue? Since it is something that only affects the webUI.

cliffy2015 commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

Simpuhl commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

I just sort by tracker. The empty ones are the errores ones unless it's a download that hasn't started.

cliffy2015 commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

I just sort by tracker. The empty ones are the errores ones unless it's a download that hasn't started.

That does not work for me on one private tracker

Simpuhl commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

I just sort by tracker. The empty ones are the errores ones unless it's a download that hasn't started.

That does not work for me on one private tracker

What are the abbreviations of that pt? I'm curious if I use it to test. I have quite a few pt and it works for them all

cliffy2015 commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

I just sort by tracker. The empty ones are the errores ones unless it's a download that hasn't started.

That does not work for me on one private tracker

What are the abbreviations of that pt? I'm curious if I use it to test. I have quite a few pt and it works for them all

Sent you an email

Simpuhl commented 1 year ago

I have the same problem and sadly the work arounds posted I don't have the know how to get working, I am using qb via my nas in a docker it seems.

I just sort by tracker. The empty ones are the errores ones unless it's a download that hasn't started.

That does not work for me on one private tracker

What are the abbreviations of that pt? I'm curious if I use it to test. I have quite a few pt and it works for them all

Sent you an email

Didn't get anything