Deluge: Modify AutoRemovePlus Plugin to delete dead torrents based on Availability

Deluge has this great plugin AutoRemovePlus:
https://github.com/omaralvarez/deluge-autoremoveplus

It can remove torrents based on certain conditions:
– Remove by ratio, seed time, date added, seeders.

It only works if a torrent is completed. Also, it will remove based on a ‘Minimum’ condition.
e.g. remove torrent if it has minimum x seeds: means remove all torrents with more than x seeds.

Sometimes some torrents are dead and there are no longer any seeds available.
‘Availability’ means how many actual copies of the torrent exist.
Even if you can’t find seeders at a certain time but if availability is more than 1 means eventually the torrent will complete because seeders do exist.

So, suppose we need to be able to remove torrents with availability lower than say 0.8 and for date added more than 5 days. This will remove all dead torrents – torrents which have’t got any copies for 5 days.

This post will give you a step by step guide to modify the Deluge plugin AutoRemovePlus to add this feature.
I am using Ubuntu 12.04 running on KDE and Deluge 1.3.15.
And at the end of post is a download link with the modified plugin.
All modified code is between comments: #ABIROID MOD and #ABIROID MOD END
At the time of writing this post the latest AutoRemovePlus version is: AutoRemovePlus-0.6.1-py2.7.egg

 

UNZIP and ZIP:
If by the time you are reading the post, a new plugin is available then just get a fresh copy from github.

– .egg file is just a zip file renamed to egg.
– Unzip the egg file to any folder:

unzip AutoRemovePlus-0.6.1-py2.7.egg -d myautoremovedir

– Go to myautoremovedir and you’ll see 2 folders:
autoremoveplus and EGG-INFO

– We will be making changes to files inside autoremoveplus folder then we’ll zip the file and replace the original egg file like so:

zip -r AutoRemovePlus-0.6.1-py2.7.egg autoremoveplus EGG-INFO/
mv AutoRemovePlus-0.6.1-py2.7.egg ~/.config/deluge/plugins/

Note that everytime you make any changes to plugin, you’ll need to restart Deluge.
Just Ctrl+Q (exit) in deluge and re-run it. Should be very quick.

 

Understanding the File Structure:

– autoremoveplus/core.py file contains the main functionality.
– autoremoveplus/ –> gtkui.py and webui.py files contain how the plugin will look in the deluge app and the web page.
– The Desktop app look is based in: data/config.glade and the WebUI look is based in: data/autoremoveplus.js

 

Making Changes:

Firstly open core.py.
‘filter_funcs’ contains all the remove rules like: remove based on ratio, date added, seed time, etc.
These are all lambda functions. Here we need to add a rule for availability.
In libtorrent availability is denoted by the variable: ‘distributed_copies’

– So add this line to the end of ‘filter_funcs’:

'func_availability': lambda (i, t): t.get_status(['distributed_copies'])['distributed_copies']

If any confusion please refer to line 90 in the code files (bottom of this post).

– Next, inside def get_remove_rules(self): add this:

'func_availability': 'Availability'

(Line: 159)

– If you want to be able to remove incomplete torrents as well then comment these lines of code:

            #try:
            #    finished = t.is_finished
            #except:
            #    continue
            #else:
            #    if not finished:
            #        continue

(Line 303)

The above piece of code checks if torrent is finished, and only then run the remove functions. Commenting it will prevent the check.

– Then find this part of code:

                filter_1 = filter_funcs.get(
                    self.config['filter'],
                    _get_ratio
                )((i, t)) >= min_val
                # Get result of second condition test
                filter_2 = filter_funcs.get(
                    self.config['filter2'], _get_ratio
                )((i, t)) >= min_val2

Here filter 1 and 2 both check for values ‘Greater than’ MIN specified values.
Like remove torrent of seeders more than MIN
Or
Remove torrents if Date Added more than MIN.

For date added this is fine. But for Availability, we need it to remove if Availability ‘Less than’ MIN.
Or for seeders less than MIN.

So, just change the condition for filter 1 to <=

– Now since we have changed the condition, we also need to change the labels in GUI so that it is not confusing.

Open config.glade and find the text ‘Min:’
You’ll find it at 2 places. At first place change Min: text to ‘Remove Less than:’
And at second place change text ‘Min:’ to ‘Remove More than:’

So it should look like:

  
	True
	False
	True
	Minimum age and seed time is measured in days
	Remove Less than:
  

– Also, go to autoremoveplus.js file and find same text ‘Min:’. Once again it will be at 2 places and make a similar change and code should look like:

	xtype: 'spinnerfield',
	//anchor: '20%',
	//margins: '0 0 0 0',
	name: 'min',
	fieldLabel: _('Remove Less than'),
	value: 0.0,
	maxValue: 10000.0,
	minValue: 0.0,
	allowDecimals: true,
	decimalPrecision: 3,
	incrementValue: 0.5,
	alternateIncrementValue: 1.0,
	flex: 0.35

– In core.py you can also add some debug/warning statements to check the values for torrents being removed or paused:
Find code with ‘remove_cond’ and add log statements:

if remove_cond:
    if not remove:
        self.pause_torrent(t)
        log.warn(
            "AutoRemovePlus: Pause torrent %s, %s, %s, %.3f"
            % (i, t.get_status(['name'])['name'], t.get_status(['distributed_copies'])['distributed_copies'], (time.time() - t.time_added) / 86400.0)
    )
    else:
        if self.remove_torrent(torrentmanager, i, remove_data):
            changed = True
            log.warn(
                "AutoRemovePlus: Delete torrent %s, %s, %s, %.3f"
                % (i, t.get_status(['name'])['name'], t.get_status(['distributed_copies'])['distributed_copies'], (time.time() - t.time_added) / 86400.0)
            )

You can add log.debug if you want to keep these as debug statements. I prefer log.warn.
Running deluge with debug creates a lot of logs and we just need to check our autoremoveplus plugin logs.

Now that all changes are done, just zip up the file as shown in the above UNZIP and ZIP section.
And run deluge from command line like so:

deluge -L warning -l /var/log/deluge.log

Open up another terminal and tail the logs like so:

tail -f /var/log/deluge.log | grep -i autoremove

– Go to deluge and set your settings something similar to:

At first make sure that the ‘Remove Torrent’ checkbox is unchecked, so that it will only pause your torrents.
Then, whenever you click apply the plugin will run. Make sure to look at the debug values in the tailed logs.
Once you are sure it’s absolutely working, only then check the ‘Remove Torrent’ and ‘Remove Torrent Data’ checkbox.

Here’s the link to the modified egg file:
abiroid modified AutoRemovePlus-0.6.1-py2.7 (224 downloads)

Usage:
– Rename abiroid.com_AutoRemovePlus-0.6.1-py2.7.zip to AutoRemovePlus-0.6.1-py2.7.egg
– Copy to your deluge plugins directory:
~/.config/deluge/plugins/

6 Responses

  1. TomH says:

    When deluge starts it does not have all availability yet and so it’s 0.0 and it pauses most of my torrents.
    So, I’m afraid to use it with remove torrents because alive torrents might get deleted along with the dead ones.
    Any way to start this plugin maybe 5 minutes after deluge starts?

    • Abir Pathak says:

      Actually that shouldn’t be happening. In core.py on line 117 as the comments explain, they have used deferLater.

              # it appears that if the plugin is enabled on boot then it is called
              # before the torrents are properly loaded and so do_remove receives an
              # empty list. So we must listen to SessionStarted for when deluge boots
              #  but we still have apply_now so that if the plugin is enabled
              # mid-program do_remove is still run
              self.looping_call = LoopingCall(self.do_remove)
              deferLater(reactor, 5, self.start_looping)
      

      This means that it should start looping after 5 seconds. You can try increasing the number of seconds to more to see if that helps. Do you have a lot of torrents running?

      • TomH says:

        Yes, actually I have about 500 torrents running. I’ll try increasing the deferLater time to maybe 20 seconds and see. Thanks.

        • Abir Pathak says:

          Ok. I see. This large number of torrents could be why deluge is taking so long to identify the Availability for all torrents. Try increasing the seconds to however long you think it takes for deluge to analyze all your torrents. Hope it works šŸ™‚

  2. Ryan says:

    Is there any way to make this a standalone plugin? I already utilize AutoRemovePlus and don’t want to lose that.

    On another note, I’m trying to use this through the webui on a headless rpi3 and can’t seem to get it to work even replacing the original.

  3. Jools says:

    Why not make a pull request to the original?

Leave a Reply

Your email address will not be published. Required fields are marked *


The maximum upload file size: 5 MB.
You can upload: image, text, archive.
Links to YouTube, Facebook, Twitter and other services inserted in the comment text will be automatically embedded.

%d bloggers like this: