[#1903|UI] Add super seeding option to interfaces

- Fix applying the setting to libtorrent, passing the value without
  modification so it decide when to enable it.
- Enable super_seeding option when adding torrents to core.
- Update UIs with option in tabs and add dialogs.
This commit is contained in:
Calum Lind 2018-10-21 14:07:48 +01:00
parent e6c61c3f8c
commit e2c7716ce2
15 changed files with 134 additions and 56 deletions

View File

@ -454,11 +454,8 @@ class Torrent(object):
Args:
super_seeding (bool): Enable super seeding.
"""
if self.status.is_seeding:
self.options['super_seeding'] = super_seeding
self.handle.super_seeding(super_seeding)
else:
self.options['super_seeding'] = False
self.options['super_seeding'] = super_seeding
self.handle.super_seeding(super_seeding)
def set_stop_ratio(self, stop_ratio):
"""The seeding ratio to stop (or remove) the torrent at.

View File

@ -489,6 +489,10 @@ class TorrentManager(component.Component):
) ^ lt.add_torrent_params_flags_t.flag_auto_managed
if options['seed_mode']:
add_torrent_params['flags'] |= lt.add_torrent_params_flags_t.flag_seed_mode
if options['super_seeding']:
add_torrent_params[
'flags'
] |= lt.add_torrent_params_flags_t.flag_super_seeding
return torrent_id, add_torrent_params

View File

@ -115,6 +115,7 @@ TORRENT_DATA_FIELD = {
'owner': {'name': _('Owner'), 'status': ['owner']},
'pieces': {'name': _('Pieces'), 'status': ['num_pieces', 'piece_length']},
'seed_rank': {'name': _('Seed Rank'), 'status': ['seed_rank']},
'super_seeding': {'name': _('Super Seeding'), 'status': ['super_seeding']},
}
TRACKER_STATUS_TRANSLATION = [

View File

@ -16,26 +16,12 @@ from twisted.internet import defer
import deluge.component as component
from deluge.ui.client import client
from deluge.ui.console.utils.common import TORRENT_OPTIONS
from . import BaseCommand
log = logging.getLogger(__name__)
torrent_options = {
'max_download_speed': float,
'max_upload_speed': float,
'max_connections': int,
'max_upload_slots': int,
'private': bool,
'prioritize_first_last': bool,
'is_auto_managed': bool,
'stop_at_ratio': bool,
'stop_ratio': float,
'remove_at_ratio': bool,
'move_completed': bool,
'move_completed_path': str,
}
class Command(BaseCommand):
"""Show and manage per-torrent options"""
@ -92,12 +78,12 @@ class Command(BaseCommand):
request_options = []
for opt in options.values:
if opt not in torrent_options:
if opt not in TORRENT_OPTIONS:
self.console.write('{!error!}Unknown torrent option: %s' % opt)
return
request_options.append(opt)
if not request_options:
request_options = list(torrent_options)
request_options = list(TORRENT_OPTIONS)
request_options.append('name')
d = client.core.get_torrents_status({'id': torrent_ids}, request_options)
@ -110,11 +96,11 @@ class Command(BaseCommand):
val = ' '.join(options.values)
torrent_ids = self.console.match_torrent(options.torrent)
if key not in torrent_options:
if key not in TORRENT_OPTIONS:
self.console.write('{!error!}Invalid key: %s' % key)
return
val = torrent_options[key](val)
val = TORRENT_OPTIONS[key](val)
def on_set_config(result):
self.console.write('{!success!}Torrent option successfully updated.')

View File

@ -116,6 +116,7 @@ class TorrentDetail(BaseMode, PopupsHandler):
'last_seen_complete',
'completed_time',
'time_since_transfer',
'super_seeding',
]
self.file_list = None
self.current_file = None
@ -587,6 +588,8 @@ class TorrentDetail(BaseMode, PopupsHandler):
row = add_field('download_location', row)
# Seed Rank
row = add_field('seed_rank', row)
# Super Seeding
row = add_field('super_seeding', row)
# Last seen complete
row = add_field('last_seen_complete', row)
# Last activity

View File

@ -19,27 +19,13 @@ from deluge.ui.client import client
from deluge.ui.common import TORRENT_DATA_FIELD
from deluge.ui.console.modes.torrentlist.queue_mode import QueueMode
from deluge.ui.console.utils import colors
from deluge.ui.console.utils.common import TORRENT_OPTIONS
from deluge.ui.console.widgets.popup import InputPopup, MessagePopup, SelectablePopup
from . import ACTION
log = logging.getLogger(__name__)
torrent_options = [
'max_download_speed',
'max_upload_speed',
'max_connections',
'max_upload_slots',
'prioritize_first_last',
'sequential_download',
'is_auto_managed',
'stop_at_ratio',
'stop_ratio',
'remove_at_ratio',
'move_completed',
'move_completed_path',
]
def action_error(error, mode):
mode.report_message('Error Occurred', error.getErrorMessage())
@ -156,7 +142,7 @@ def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
border_off_north=1,
base_popup=kwargs.get('base_popup', None),
)
for field in torrent_options:
for field in TORRENT_OPTIONS:
caption = '{!info!}' + TORRENT_DATA_FIELD[field]['name']
value = options[field]
if isinstance(value, ''.__class__):
@ -178,7 +164,7 @@ def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
callbacks = []
for tid in torrents:
deferred = component.get('SessionProxy').get_torrent_status(
tid, torrent_options
tid, list(TORRENT_OPTIONS)
)
callbacks.append(deferred.addCallback(on_torrent_status))

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
#
# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
# the additional special exception to link portions of this program with the OpenSSL library.
# See LICENSE for more details.
#
from __future__ import unicode_literals
TORRENT_OPTIONS = {
'max_download_speed': float,
'max_upload_speed': float,
'max_connections': int,
'max_upload_slots': int,
'prioritize_first_last': bool,
'is_auto_managed': bool,
'stop_at_ratio': bool,
'stop_ratio': float,
'remove_at_ratio': bool,
'move_completed': bool,
'move_completed_path': str,
'super_seeding': bool,
}

View File

@ -145,6 +145,7 @@ class AddTorrentDialog(component.Component):
'move_completed',
'move_completed_path',
'move_completed_paths_list',
'super_seeding',
]
# self.core_keys += self.move_completed_path_chooser.get_config_keys()
self.builder.get_object('notebook1').connect(
@ -471,6 +472,9 @@ class AddTorrentDialog(component.Component):
self.builder.get_object('chk_move_completed').set_active(
options['move_completed']
)
self.builder.get_object('chk_super_seeding').set_active(
options['super_seeding']
)
def save_torrent_options(self, row=None):
# Keeps the torrent options dictionary up-to-date with what the user has
@ -519,6 +523,9 @@ class AddTorrentDialog(component.Component):
'chk_move_completed'
).get_active()
options['seed_mode'] = self.builder.get_object('chk_seed_mode').get_active()
options['super_seeding'] = self.builder.get_object(
'chk_super_seeding'
).get_active()
self.options[torrent_id] = options
@ -578,6 +585,9 @@ class AddTorrentDialog(component.Component):
self.core_config['move_completed']
)
self.builder.get_object('chk_seed_mode').set_active(False)
self.builder.get_object('chk_super_seeding').set_active(
self.core_config['super_seeding']
)
def get_file_priorities(self, torrent_id):
# A list of priorities

View File

@ -503,6 +503,17 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkHSeparator" id="separator1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox6">
<property name="visible">True</property>
@ -589,6 +600,22 @@ used sparingly.</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chk_super_seeding">
<property name="label" translatable="yes">Super Seeding</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="tooltip_markup">Useful if adding a complete torrent for seeding.</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chk_pre_alloc">
<property name="label" translatable="yes">Preallocate Disk Space</property>
@ -601,22 +628,15 @@ used sparingly.</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label15">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
@ -806,7 +826,7 @@ used sparingly.</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
@ -923,7 +943,7 @@ used sparingly.</property>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
</object>

View File

@ -1475,6 +1475,25 @@
<property name="position">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkCheckButton" id="chk_super_seeding">
<property name="label" translatable="yes">Super Seeding</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_chk_toggled" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="chk_move_completed">
<property name="label" translatable="yes">Move completed:</property>
@ -1487,7 +1506,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
<child>
@ -1501,7 +1520,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
<property name="position">6</property>
</packing>
</child>
</object>

View File

@ -89,6 +89,15 @@
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_super_seeding">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="use_action_appearance">False</property>
<property name="label" translatable="yes">_Super Seeding</property>
<property name="use_underline">True</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuitem_change_owner">
<property name="use_action_appearance">False</property>

View File

@ -46,6 +46,7 @@ class OptionsTab(Tab):
self.add_tab_widget('chk_move_completed', 'active', ['move_completed'])
self.add_tab_widget('chk_shared', 'active', ['shared'])
self.add_tab_widget('summary_owner', 'text', ['owner'])
self.add_tab_widget('chk_super_seeding', 'active', ['super_seeding'])
# Connect key press event for spin widgets.
for widget_id in self.tab_widgets:

View File

@ -127,6 +127,7 @@ Deluge.Keys = {
'prioritize_first_last',
'move_completed',
'move_completed_path',
'super_seeding',
],
};

View File

@ -113,7 +113,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
);
fieldset = panel.add({
title: _('General'),
// title: _('General'),
border: false,
autoHeight: true,
defaultType: 'checkbox',
@ -154,6 +154,15 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
labelSeparator: '',
})
);
this.optionsManager.bind(
'super_seeding',
fieldset.add({
name: 'super_seeding',
boxLabel: _('Super Seed'),
fieldLabel: '',
labelSeparator: '',
})
);
this.optionsManager.bind(
'pre_allocate_storage',
fieldset.add({
@ -197,6 +206,7 @@ Deluge.add.OptionsTab = Ext.extend(Ext.form.FormPanel, {
prioritize_first_last_pieces:
config.prioritize_first_last_pieces,
seed_mode: false,
super_seeding: false,
};
this.optionsManager.options = options;
this.optionsManager.resetAll();

View File

@ -48,6 +48,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
move_completed_path: '',
private: false,
prioritize_first_last: false,
super_seeding: false,
},
});
@ -287,6 +288,13 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
id: 'prioritize_first_last',
});
this.fields.super_seeding = this.fieldsets.general.add({
fieldLabel: '',
labelSeparator: '',
boxLabel: _('Super Seeding'),
id: 'super_seeding',
});
// Bind the fields so the options manager can manage them.
for (var id in this.fields) {
this.optionsManager.bind(id, this.fields[id]);