Repository: qbittorrent/qBittorrent

Issue #11419: Possibility of short announce intervals for racing torrents
Created: 2019-10-29T18:01:22Z
So i've been away from qBit for a while. Reasons being read/write performance for 1gbit connections. We've talked a lot about this on the forum, and the best suggestion was to try something else.
I've been running deluge for a while, it's fine but is not being updated for windows.
But deluge can do some things that i would not be able to live without.


A way/option to manually set libtorrent config, and having that config overwrite settings in qBit, allowing to set settings not available through the UI.
Like write_cache_line_size, close_file_interval, contiguous_recv_buffer, cache_size_volatile etc.


In deluge i have a script running performing:


#
# core.py
#
# Basic plugin template created by:
# Copyright (C) 2008 Martijn Voncken <mvoncken@gmail.com>
# Copyright (C) 2007-2009 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Damien Churchill <damoxc@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge.    If not, write to:
#    The Free Software Foundation, Inc.,
#    51 Franklin Street, Fifth Floor
#    Boston, MA  02110-1301, USA.
#
#    In addition, as a special exception, the copyright holders give
#    permission to link the code of portions of this program with the OpenSSL
#    library.
#    You must obey the GNU General Public License in all respects for all of
#    the code used other than OpenSSL. If you modify file(s) with this
#    exception, you may extend this exception to your version of the file(s),
#    but you are not obligated to do so. If you do not wish to do so, delete
#    this exception statement from your version. If you delete this exception
#    statement from all source files in the program, then also delete it here.
#

import time
import logging
from twisted.internet.task import LoopingCall

from deluge.log import LOG as log
from deluge.plugins.pluginbase import CorePluginBase
import deluge.component as component
import deluge.configmanager
from deluge.core.rpcserver import export
from deluge.ui.client import client

DEFAULT_PREFS = {
    "test":"NiNiNi"
}

class Core(CorePluginBase):

    timer = {}

    def update_tracker(self, torrent_id):
        tid = component.get('TorrentManager').torrents[torrent_id]
        tid_status = tid.get_status(['tracker_status','time_added'])
        log.info("[AddTrackerCheck](%s)(%s) : %s", torrent_id, time.time() - tid_status['time_added'], tid_status['tracker_status'])

        if tid_status['tracker_status'].find("Announce OK") != -1:
            Core.timer[torrent_id].stop();
        elif time.time() - tid_status['time_added'] > 300:
            Core.timer[torrent_id].stop();
        else:
            time.sleep(5)
            log.info("[AddTrackerCheck](%s) : Updating Tracker", torrent_id)
            tid.force_reannounce();
         
    def post_torrent_add(self, torrent_id, *from_state):
        if not component.get('TorrentManager').session_started:
            return
        log.info("[AddTrackerCheck](%s) : Adding New Torrent", torrent_id)
        Core.timer[torrent_id] = LoopingCall(self.update_tracker, torrent_id)
        Core.timer[torrent_id].start(2)

    def enable(self):
        # Go through the commands list and register event handlers
        self.config = deluge.configmanager.ConfigManager("addtorrentcheck.conf", DEFAULT_PREFS)
        component.get("EventManager").register_event_handler("TorrentAddedEvent", self.post_torrent_add)

    def disable(self):
        pass

    def update(self):
        pass

    @export
    def set_config(self, config):
        """Sets the config dictionary"""
        for key in config.keys():
            self.config[key] = config[key]
        self.config.save()

    @export
    def get_config(self):
        """Returns the config dictionary"""
        return self.config.config


Any way to do in newer versions of qBit?

Duplicate issue #10736: Rapidly update tracker when tracker returns unregistered torrent
Created: 2019-05-31T18:46:15Z
Please provide the following information
qBittorrent version and Operating System
All
If on linux, libtorrent and Qt version
All.
However, it appears the option has been available since libtorrent RC_1_1 arvidn/libtorrent#3250
What is the problem
When using autodl or RSS, if adding torrent too quickly and tracker returns unregistered torrent/torrent not registered/0 seeds/1 seed which is your self being reported back to you, qBittorent will not automatically refresh tracker but will wait ~60 min until next update.
rTorrent does not have this issue.
uTorrent does not have this issue.

  qBittorrent-nox: Script has been created to fix the issue.
  
nano reannounce.sh

#!/bin/sh

while true; do
  SID=$(curl -s -i --header 'Referer: http://localhost:8080' --data 'username=admin&password=adminadmin' http://localhost:8080/api/v2/auth/login|awk '/SID/{print $1}' FS=\;|awk '{print $2}')
  downloading=$(curl -s http://localhost:8080/api/v2/torrents/info?filter=downloading --cookie $SID|python3 -m json.tool|awk '/hash/{print $4}' FS=\")
  unregistered=$(for line in $downloading; do curl -s http://localhost:8080/api/v2/torrents/trackers?hash=$line --cookie $SID|python3 -m json.tool|awk '/unregistered/{print $4}' FS=\" IGNORECASE=1|sed "s/^.*$/$line/g"; done|sed ":a;N;s/\n/\|/g;$!ba")
  if [ "$(for line in $downloading; do curl -s http://localhost:8080/api/v2/torrents/trackers?hash=$line --cookie $SID|python3 -m json.tool|awk '/unregistered/{print $4}' FS=\" IGNORECASE=1; done|wc -l)" -ge 1 ];then
    curl -s http://localhost:8080/api/v2/torrents/reannounce?hashes=$unregistered --cookie $SID
  fi
  sleep 5
done



  Deluge: Script has been created to fix the issue. Only works for linux users, and requires you to ssh into deluge, and run script through deluged-console
  

cd files
nano autodldeluge.sh

#(paste the code below)

#!/bin/bash
 
torrentid=$1
torrentname=$2
torrentpath=$3
 
x=1
while [ $x -le 100 ]
do
sleep 2
echo "Running $x times" >> ~/script.log
echo "TorrentID: $torrentid" >> ~/script.log
line=$(deluge-console "connect 127.0.0.1:99999; info" $1 | grep "Tracker status")
echo $line >> ~/script.log
 
case "$line" in
*unregistered*|*Unregistered*|*Sent*|*End*of*file*|*Bad*Gateway*)
    deluge-console "connect 127.0.0.1:99999; pause '$torrentid'"
    sleep 3
    deluge-console "connect 127.0.0.1:99999; resume '$torrentid'"
;;
*)
    echo "Found working torrent: $torrentname $torrentpath $torrentid" >> ~/script.log
    exit 1;;
esac
 
x=$(( $x + 1 ))
 
done


What is the expected behaviour
When using autodl or RSS and torrent is added at a very early stage in the torrents life and the tracker returns unregistered torrent etc. qBittorrent will rapidly refresh the tracker once every second until tracker is responding with at a usable seed.
Example behaviour.

Torrent added, tracker returns unregistered torrent or other.
qBittorrent updates tracker once every second until tracker returns a usable seed.
When usable seed is detected the next 3 tracker updates before returning to normal 60 min behaviour are scheduled 5/15/30 seconds.

Additionally, the first 3 tracker updates at 5/15/30 seconds after being added is default behaviour when new torrent is added and or if <X seeders are detected.
Steps to reproduce
Add torrent within seconds of the torrent being available.
Issue is mentioned here #6268 but it is over 2 years old, which is why i am creating a new as a wishlist because i think this is rather important.
Related.
arvidn/libtorrent#3226
arvidn/libtorrent#315

Closing comment (2020-04-23T00:49:51Z): Dupe of #11419 (this is effectively a feature request for the racing capability discussed in that issue).