mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-04 15:38:43 +00:00
[UI|Core] Fix problems with file priorities
- Fixed the core not correctly settings the current file_priority settings and added a test. - Fixed the console not setting file priorities. - Change the label for not downloading of a file to 'Skip'.
This commit is contained in:
parent
2104b9831c
commit
6655fe67c3
9 changed files with 83 additions and 66 deletions
|
@ -135,7 +135,7 @@ class TorrentOptions(dict):
|
||||||
auto_managed (bool): Set torrent to auto managed mode, i.e. will be started or queued automatically.
|
auto_managed (bool): Set torrent to auto managed mode, i.e. will be started or queued automatically.
|
||||||
download_location (str): The path for the torrent data to be stored while downloading.
|
download_location (str): The path for the torrent data to be stored while downloading.
|
||||||
file_priorities (list of int): The priority for files in torrent, range is [0..7] however
|
file_priorities (list of int): The priority for files in torrent, range is [0..7] however
|
||||||
only [0, 1, 5, 7] are normally used and correspond to [Do Not Download, Normal, High, Highest]
|
only [0, 1, 4, 7] are normally used and correspond to [Skip, Low, Normal, High]
|
||||||
mapped_files (dict): A mapping of the renamed filenames in 'index:filename' pairs.
|
mapped_files (dict): A mapping of the renamed filenames in 'index:filename' pairs.
|
||||||
max_connections (int): Sets maximum number of connections this torrent will open.
|
max_connections (int): Sets maximum number of connections this torrent will open.
|
||||||
This must be at least 2. The default is unlimited (-1).
|
This must be at least 2. The default is unlimited (-1).
|
||||||
|
@ -504,38 +504,35 @@ class Torrent(object):
|
||||||
Args:
|
Args:
|
||||||
file_priorities (list of int): List of file priorities.
|
file_priorities (list of int): List of file priorities.
|
||||||
"""
|
"""
|
||||||
|
if not self.has_metadata:
|
||||||
|
return
|
||||||
|
|
||||||
if log.isEnabledFor(logging.DEBUG):
|
if log.isEnabledFor(logging.DEBUG):
|
||||||
log.debug(
|
log.debug(
|
||||||
'Setting %s file priorities to: %s', self.torrent_id, file_priorities
|
'Setting %s file priorities to: %s', self.torrent_id, file_priorities
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if file_priorities and len(file_priorities) == len(self.get_files()):
|
||||||
self.handle.has_metadata()
|
|
||||||
and file_priorities
|
|
||||||
and len(file_priorities) == len(self.get_files())
|
|
||||||
):
|
|
||||||
self.handle.prioritize_files(file_priorities)
|
self.handle.prioritize_files(file_priorities)
|
||||||
else:
|
else:
|
||||||
log.debug('Unable to set new file priorities.')
|
log.debug('Unable to set new file priorities.')
|
||||||
file_priorities = self.handle.file_priorities()
|
file_priorities = self.handle.file_priorities()
|
||||||
|
|
||||||
if not self.options['file_priorities']:
|
if 0 in self.options['file_priorities']:
|
||||||
self.options['file_priorities'] = file_priorities
|
# Previously marked a file 'skip' so check for any 0's now >0.
|
||||||
elif 0 in self.options['file_priorities']:
|
|
||||||
# Previously marked a file 'Do Not Download' so check if changed any 0's to >0.
|
|
||||||
for index, priority in enumerate(self.options['file_priorities']):
|
for index, priority in enumerate(self.options['file_priorities']):
|
||||||
if priority == 0 and file_priorities[index] > 0:
|
if priority == 0 and file_priorities[index] > 0:
|
||||||
# Changed 'Do Not Download' to a download priority so update state.
|
# Changed priority from skip to download so update state.
|
||||||
self.is_finished = False
|
self.is_finished = False
|
||||||
self.update_state()
|
self.update_state()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Store the priorities.
|
||||||
|
self.options['file_priorities'] = file_priorities
|
||||||
|
|
||||||
# Set the first/last priorities if needed.
|
# Set the first/last priorities if needed.
|
||||||
if self.options['prioritize_first_last_pieces']:
|
if self.options['prioritize_first_last_pieces']:
|
||||||
self.set_prioritize_first_last_pieces(
|
self.set_prioritize_first_last_pieces(True)
|
||||||
self.options['prioritize_first_last_pieces']
|
|
||||||
)
|
|
||||||
|
|
||||||
@deprecated
|
@deprecated
|
||||||
def set_save_path(self, download_location):
|
def set_save_path(self, download_location):
|
||||||
|
@ -1032,6 +1029,10 @@ class Torrent(object):
|
||||||
status (libtorrent.torrent_status): a libtorrent torrent status
|
status (libtorrent.torrent_status): a libtorrent torrent status
|
||||||
"""
|
"""
|
||||||
self.status = status
|
self.status = status
|
||||||
|
# Ensure that the file_priorities are kept in sync with libtorrent.
|
||||||
|
# We do this here as file_priorities is async and can't call it
|
||||||
|
# immediately after setting priorities.
|
||||||
|
self.options['file_priorities'] = self.handle.file_priorities()
|
||||||
|
|
||||||
def _create_status_funcs(self):
|
def _create_status_funcs(self):
|
||||||
"""Creates the functions for getting torrent status"""
|
"""Creates the functions for getting torrent status"""
|
||||||
|
|
|
@ -44,6 +44,7 @@ class TorrentTestCase(BaseTestCase):
|
||||||
self.rpcserver = RPCServer(listen=False)
|
self.rpcserver = RPCServer(listen=False)
|
||||||
self.core = Core()
|
self.core = Core()
|
||||||
self.core.config.config['lsd'] = False
|
self.core.config.config['lsd'] = False
|
||||||
|
self.core.config.config['new_release_check'] = False
|
||||||
self.session = self.core.session
|
self.session = self.core.session
|
||||||
self.torrent = None
|
self.torrent = None
|
||||||
return component.start()
|
return component.start()
|
||||||
|
@ -80,6 +81,25 @@ class TorrentTestCase(BaseTestCase):
|
||||||
atp['duplicate_is_error'] = True
|
atp['duplicate_is_error'] = True
|
||||||
return atp
|
return atp
|
||||||
|
|
||||||
|
def test_set_file_priorities(self):
|
||||||
|
atp = self.get_torrent_atp('dir_with_6_files.torrent')
|
||||||
|
handle = self.session.add_torrent(atp)
|
||||||
|
torrent = Torrent(handle, {})
|
||||||
|
|
||||||
|
result = torrent.get_file_priorities()
|
||||||
|
self.assertTrue(all(x == 4 for x in result))
|
||||||
|
|
||||||
|
new_priorities = [3, 1, 2, 0, 5, 6, 7]
|
||||||
|
torrent.set_file_priorities(new_priorities)
|
||||||
|
self.assertEqual(torrent.get_file_priorities(), new_priorities)
|
||||||
|
|
||||||
|
# Test with handle.piece_priorities as handle.file_priorities async
|
||||||
|
# updates and will return old value. Also need to remove a priority
|
||||||
|
# value as one file is much smaller than piece size so doesn't show.
|
||||||
|
piece_prio = handle.piece_priorities()
|
||||||
|
result = all(p in piece_prio for p in [3, 2, 0, 5, 6, 7])
|
||||||
|
self.assertTrue(result)
|
||||||
|
|
||||||
def test_set_prioritize_first_last_pieces(self):
|
def test_set_prioritize_first_last_pieces(self):
|
||||||
piece_indexes = [
|
piece_indexes = [
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -139,7 +139,7 @@ PREFS_CATOG_TRANS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_PRIORITY = {
|
FILE_PRIORITY = {
|
||||||
0: 'Ignore',
|
0: 'Skip',
|
||||||
1: 'Low',
|
1: 'Low',
|
||||||
2: 'Low',
|
2: 'Low',
|
||||||
3: 'Low',
|
3: 'Low',
|
||||||
|
@ -147,7 +147,7 @@ FILE_PRIORITY = {
|
||||||
5: 'High',
|
5: 'High',
|
||||||
6: 'High',
|
6: 'High',
|
||||||
7: 'High',
|
7: 'High',
|
||||||
_('Ignore'): 0,
|
_('Skip'): 0,
|
||||||
_('Low'): 1,
|
_('Low'): 1,
|
||||||
_('Normal'): 4,
|
_('Normal'): 4,
|
||||||
_('High'): 7,
|
_('High'): 7,
|
||||||
|
|
|
@ -232,11 +232,10 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
col_priority = ' {!info!}Priority: '
|
col_priority = ' {!info!}Priority: '
|
||||||
|
|
||||||
file_priority = FILE_PRIORITY[status['file_priorities'][index]].replace(
|
file_priority = FILE_PRIORITY[status['file_priorities'][index]]
|
||||||
'Priority', ''
|
|
||||||
)
|
|
||||||
if status['file_progress'][index] != 1.0:
|
if status['file_progress'][index] != 1.0:
|
||||||
if file_priority == 'Do Not Download':
|
if file_priority == 'Skip':
|
||||||
col_priority += '{!error!}'
|
col_priority += '{!error!}'
|
||||||
else:
|
else:
|
||||||
col_priority += '{!success!}'
|
col_priority += '{!success!}'
|
||||||
|
@ -251,9 +250,7 @@ class Command(BaseCommand):
|
||||||
# Check how much space we've got left after writing all the info
|
# Check how much space we've got left after writing all the info
|
||||||
space_left = cols - tlen(col_all_info)
|
space_left = cols - tlen(col_all_info)
|
||||||
# And how much we will potentially have with the longest possible column
|
# And how much we will potentially have with the longest possible column
|
||||||
maxlen_space_left = cols - tlen(
|
maxlen_space_left = cols - tlen(' (1000.0 MiB) 100.00% Priority: Normal')
|
||||||
' (1000.0 MiB) 100.00% Priority: Do Not Download'
|
|
||||||
)
|
|
||||||
if maxlen_space_left > tlen(col_filename) + 1:
|
if maxlen_space_left > tlen(col_filename) + 1:
|
||||||
# If there is enough space, pad it all nicely
|
# If there is enough space, pad it all nicely
|
||||||
col_all_info = ''
|
col_all_info = ''
|
||||||
|
@ -264,7 +261,7 @@ class Command(BaseCommand):
|
||||||
spaces_to_add = tlen(' 100.00%') - tlen(col_progress)
|
spaces_to_add = tlen(' 100.00%') - tlen(col_progress)
|
||||||
col_all_info += ' ' * spaces_to_add
|
col_all_info += ' ' * spaces_to_add
|
||||||
col_all_info += col_progress
|
col_all_info += col_progress
|
||||||
spaces_to_add = tlen(' Priority: Do Not Download') - tlen(col_priority)
|
spaces_to_add = tlen(' Priority: Normal') - tlen(col_priority)
|
||||||
col_all_info += col_priority
|
col_all_info += col_priority
|
||||||
col_all_info += ' ' * spaces_to_add
|
col_all_info += ' ' * spaces_to_add
|
||||||
# And remember to put it to the left!
|
# And remember to put it to the left!
|
||||||
|
|
|
@ -385,7 +385,7 @@ class TorrentDetail(BaseMode, PopupsHandler):
|
||||||
|
|
||||||
priority_fg_color = {
|
priority_fg_color = {
|
||||||
-2: 'white', # Mixed
|
-2: 'white', # Mixed
|
||||||
0: 'red', # Ignore
|
0: 'red', # Skip
|
||||||
1: 'yellow', # Low
|
1: 'yellow', # Low
|
||||||
2: 'yellow',
|
2: 'yellow',
|
||||||
3: 'yellow',
|
3: 'yellow',
|
||||||
|
@ -678,13 +678,13 @@ class TorrentDetail(BaseMode, PopupsHandler):
|
||||||
# not selected, just keep old priority
|
# not selected, just keep old priority
|
||||||
ret_list.append((f[1], f[6]))
|
ret_list.append((f[1], f[6]))
|
||||||
|
|
||||||
def do_priority(self, name, data, was_empty):
|
def do_priority(self, priority, was_empty):
|
||||||
plist = []
|
plist = []
|
||||||
self.build_prio_list(self.file_list, plist, -1, data)
|
self.build_prio_list(self.file_list, plist, -1, priority)
|
||||||
plist.sort()
|
plist.sort()
|
||||||
priorities = [p[1] for p in plist]
|
priorities = [p[1] for p in plist]
|
||||||
client.core.set_torrent_options(
|
client.core.set_torrent_options(
|
||||||
[self.torrent_id], {'file_priorities': priorities}
|
[self.torrentid], {'file_priorities': priorities}
|
||||||
)
|
)
|
||||||
|
|
||||||
if was_empty:
|
if was_empty:
|
||||||
|
@ -693,36 +693,34 @@ class TorrentDetail(BaseMode, PopupsHandler):
|
||||||
|
|
||||||
# show popup for priority selections
|
# show popup for priority selections
|
||||||
def show_priority_popup(self, was_empty):
|
def show_priority_popup(self, was_empty):
|
||||||
def popup_func(data, *args, **kwargs):
|
def popup_func(name, data, was_empty, **kwargs):
|
||||||
if data is None:
|
if not name:
|
||||||
return
|
return
|
||||||
return self.do_priority(data, kwargs[data], was_empty)
|
return self.do_priority(data[name], was_empty)
|
||||||
|
|
||||||
if self.marked:
|
if self.marked:
|
||||||
popup = SelectablePopup(
|
popup = SelectablePopup(
|
||||||
self, 'Set File Priority', popup_func, border_off_north=1
|
self,
|
||||||
|
'Set File Priority',
|
||||||
|
popup_func,
|
||||||
|
border_off_north=1,
|
||||||
|
cb_args={'was_empty': was_empty},
|
||||||
)
|
)
|
||||||
popup.add_line(
|
popup.add_line(
|
||||||
'ignore_priority',
|
'skip_priority',
|
||||||
'_Ignore',
|
'_Skip',
|
||||||
cb_arg=FILE_PRIORITY['Ignore'],
|
|
||||||
foreground='red',
|
foreground='red',
|
||||||
|
cb_arg=FILE_PRIORITY['Low'],
|
||||||
|
was_empty=was_empty,
|
||||||
)
|
)
|
||||||
popup.add_line(
|
popup.add_line(
|
||||||
'low_priority',
|
'low_priority', '_Low', cb_arg=FILE_PRIORITY['Low'], foreground='yellow'
|
||||||
'_Low Priority',
|
|
||||||
cb_arg=FILE_PRIORITY['Low Priority'],
|
|
||||||
foreground='yellow',
|
|
||||||
)
|
|
||||||
popup.add_line(
|
|
||||||
'normal_priority',
|
|
||||||
'_Normal Priority',
|
|
||||||
cb_arg=FILE_PRIORITY['Normal Priority'],
|
|
||||||
)
|
)
|
||||||
|
popup.add_line('normal_priority', '_Normal', cb_arg=FILE_PRIORITY['Normal'])
|
||||||
popup.add_line(
|
popup.add_line(
|
||||||
'high_priority',
|
'high_priority',
|
||||||
'_High Priority',
|
'_High',
|
||||||
cb_arg=FILE_PRIORITY['High Priority'],
|
cb_arg=FILE_PRIORITY['High'],
|
||||||
foreground='green',
|
foreground='green',
|
||||||
)
|
)
|
||||||
popup._selected = 1
|
popup._selected = 1
|
||||||
|
|
|
@ -34,10 +34,10 @@ from .torrentview_data_funcs import cell_data_size
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
CELL_PRIORITY_ICONS = {
|
CELL_PRIORITY_ICONS = {
|
||||||
'Ignore': 'action-unavailable-symbolic',
|
FILE_PRIORITY['Skip']: 'action-unavailable-symbolic',
|
||||||
'Low': 'go-down-symbolic',
|
FILE_PRIORITY['Low']: 'go-down-symbolic',
|
||||||
'Normal': 'go-next-symbolic',
|
FILE_PRIORITY['Normal']: 'go-next-symbolic',
|
||||||
'High': 'go-up-symbolic',
|
FILE_PRIORITY['High']: 'go-up-symbolic',
|
||||||
}
|
}
|
||||||
|
|
||||||
G_ICON_DIRECTORY = Gio.content_type_get_icon('inode/directory')
|
G_ICON_DIRECTORY = Gio.content_type_get_icon('inode/directory')
|
||||||
|
@ -58,7 +58,7 @@ def cell_priority_icon(column, cell, model, row, data):
|
||||||
cell.set_property('icon-name', None)
|
cell.set_property('icon-name', None)
|
||||||
return
|
return
|
||||||
priority = model.get_value(row, data)
|
priority = model.get_value(row, data)
|
||||||
cell.set_property('icon-name', CELL_PRIORITY_ICONS[FILE_PRIORITY[priority]])
|
cell.set_property('icon-name', CELL_PRIORITY_ICONS[priority])
|
||||||
|
|
||||||
|
|
||||||
def cell_filename(column, cell, model, row, data):
|
def cell_filename(column, cell, model, row, data):
|
||||||
|
@ -160,7 +160,7 @@ class FilesTab(Tab):
|
||||||
|
|
||||||
self.file_menu = self.main_builder.get_object('menu_file_tab')
|
self.file_menu = self.main_builder.get_object('menu_file_tab')
|
||||||
self.file_menu_priority_items = [
|
self.file_menu_priority_items = [
|
||||||
self.main_builder.get_object('menuitem_ignore'),
|
self.main_builder.get_object('menuitem_skip'),
|
||||||
self.main_builder.get_object('menuitem_low'),
|
self.main_builder.get_object('menuitem_low'),
|
||||||
self.main_builder.get_object('menuitem_normal'),
|
self.main_builder.get_object('menuitem_normal'),
|
||||||
self.main_builder.get_object('menuitem_high'),
|
self.main_builder.get_object('menuitem_high'),
|
||||||
|
@ -559,9 +559,9 @@ class FilesTab(Tab):
|
||||||
[self.torrent_id], {'file_priorities': priorities}
|
[self.torrent_id], {'file_priorities': priorities}
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_menuitem_ignore_activate(self, menuitem):
|
def on_menuitem_skip_activate(self, menuitem):
|
||||||
self._set_file_priorities_on_user_change(
|
self._set_file_priorities_on_user_change(
|
||||||
self.get_selected_files(), FILE_PRIORITY['Ignore']
|
self.get_selected_files(), FILE_PRIORITY['Skip']
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_menuitem_low_activate(self, menuitem):
|
def on_menuitem_low_activate(self, menuitem):
|
||||||
|
|
|
@ -91,19 +91,19 @@
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="menuitem_ignore">
|
<object class="GtkImageMenuItem" id="menuitem_skip">
|
||||||
<property name="label" translatable="yes">_Ignore</property>
|
<property name="label" translatable="yes">_Skip</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="image">image2</property>
|
<property name="image">image2</property>
|
||||||
<property name="use_stock">False</property>
|
<property name="use_stock">False</property>
|
||||||
<signal name="activate" handler="on_menuitem_ignore_activate" swapped="no"/>
|
<signal name="activate" handler="on_menuitem_skip_activate" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="menuitem_low">
|
<object class="GtkImageMenuItem" id="menuitem_low">
|
||||||
<property name="label" translatable="yes">_Low Priority</property>
|
<property name="label" translatable="yes">_Low</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
@ -114,7 +114,7 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="menuitem_normal">
|
<object class="GtkImageMenuItem" id="menuitem_normal">
|
||||||
<property name="label" translatable="yes">_Normal Priority</property>
|
<property name="label" translatable="yes">_Normal</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkImageMenuItem" id="menuitem_high">
|
<object class="GtkImageMenuItem" id="menuitem_high">
|
||||||
<property name="label" translatable="yes">_High Priority</property>
|
<property name="label" translatable="yes">_High</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
|
|
@ -151,12 +151,13 @@ Ext.apply(Deluge, {
|
||||||
deluge.plugins = {};
|
deluge.plugins = {};
|
||||||
|
|
||||||
// Hinting for gettext_gen.py
|
// Hinting for gettext_gen.py
|
||||||
// _('Ignore')
|
// _('Skip')
|
||||||
// _('Low')
|
// _('Low')
|
||||||
// _('Normal')
|
// _('Normal')
|
||||||
// _('High')
|
// _('High')
|
||||||
|
// _('Mixed')
|
||||||
FILE_PRIORITY = {
|
FILE_PRIORITY = {
|
||||||
0: 'Ignore',
|
0: 'Skip',
|
||||||
1: 'Low',
|
1: 'Low',
|
||||||
2: 'Low',
|
2: 'Low',
|
||||||
3: 'Low',
|
3: 'Low',
|
||||||
|
@ -165,7 +166,7 @@ FILE_PRIORITY = {
|
||||||
6: 'High',
|
6: 'High',
|
||||||
7: 'High',
|
7: 'High',
|
||||||
9: 'Mixed',
|
9: 'Mixed',
|
||||||
Ignore: 0,
|
Skip: 0,
|
||||||
Low: 1,
|
Low: 1,
|
||||||
Normal: 4,
|
Normal: 4,
|
||||||
High: 7,
|
High: 7,
|
||||||
|
|
|
@ -361,10 +361,10 @@ deluge.menus.filePriorities = new Ext.menu.Menu({
|
||||||
},
|
},
|
||||||
'-',
|
'-',
|
||||||
{
|
{
|
||||||
id: 'ignore',
|
id: 'skip',
|
||||||
text: _('Ignore'),
|
text: _('Skip'),
|
||||||
iconCls: 'icon-do-not-download',
|
iconCls: 'icon-do-not-download',
|
||||||
filePriority: FILE_PRIORITY['Ignore'],
|
filePriority: FILE_PRIORITY['Skip'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'low',
|
id: 'low',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue