[#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:
parent
e6c61c3f8c
commit
e2c7716ce2
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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.')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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,
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -127,6 +127,7 @@ Deluge.Keys = {
|
|||
'prioritize_first_last',
|
||||
'move_completed',
|
||||
'move_completed_path',
|
||||
'super_seeding',
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
|
|
Loading…
Reference in New Issue