This commit is contained in:
Damien Churchill 2011-05-06 22:00:47 +01:00
parent 871d9ac4b0
commit 6a131f021e
3 changed files with 80 additions and 56 deletions

View File

@ -82,7 +82,7 @@ class Torrent(object):
self.config = ConfigManager("core.conf") self.config = ConfigManager("core.conf")
self.rpcserver = component.get("RPCServer") self.rpcserver = component.get("RPCServer")
# This dict holds previous status dicts returned for this torrent # This dict holds previous status dicts returned for this torrent
# We use this to return dicts that only contain changes from the previous # We use this to return dicts that only contain changes from the previous
# {session_id: status_dict, ...} # {session_id: status_dict, ...}
@ -90,7 +90,7 @@ class Torrent(object):
from twisted.internet.task import LoopingCall from twisted.internet.task import LoopingCall
self.prev_status_cleanup_loop = LoopingCall(self.cleanup_prev_status) self.prev_status_cleanup_loop = LoopingCall(self.cleanup_prev_status)
self.prev_status_cleanup_loop.start(10) self.prev_status_cleanup_loop.start(10)
# Set the libtorrent handle # Set the libtorrent handle
self.handle = handle self.handle = handle
# Set the torrent_id for this torrent # Set the torrent_id for this torrent
@ -183,7 +183,7 @@ class Torrent(object):
# repause it after its done if necessary # repause it after its done if necessary
self.forcing_recheck = False self.forcing_recheck = False
self.forcing_recheck_paused = False self.forcing_recheck_paused = False
log.debug("Torrent object created.") log.debug("Torrent object created.")
## Options methods ## ## Options methods ##
@ -547,18 +547,18 @@ class Torrent(object):
def get_status(self, keys, diff=False): def get_status(self, keys, diff=False):
""" """
Returns the status of the torrent based on the keys provided Returns the status of the torrent based on the keys provided
:param keys: the keys to get the status on :param keys: the keys to get the status on
:type keys: list of str :type keys: list of str
:param diff: if True, will return a diff of the changes since the last :param diff: if True, will return a diff of the changes since the last
call to get_status based on the session_id call to get_status based on the session_id
:type diff: bool :type diff: bool
:returns: a dictionary of the status keys and their values :returns: a dictionary of the status keys and their values
:rtype: dict :rtype: dict
""" """
# Create the full dictionary # Create the full dictionary
self.status = self.handle.status() self.status = self.handle.status()
if self.handle.has_metadata(): if self.handle.has_metadata():
@ -590,6 +590,8 @@ class Torrent(object):
"message": self.statusmsg, "message": self.statusmsg,
"move_on_completed_path": self.options["move_completed_path"], "move_on_completed_path": self.options["move_completed_path"],
"move_on_completed": self.options["move_completed"], "move_on_completed": self.options["move_completed"],
"move_completed_path": self.options["move_completed_path"],
"move_completed": self.options["move_completed"],
"next_announce": self.status.next_announce.seconds, "next_announce": self.status.next_announce.seconds,
"num_peers": self.status.num_peers - self.status.num_seeds, "num_peers": self.status.num_peers - self.status.num_seeds,
"num_seeds": self.status.num_seeds, "num_seeds": self.status.num_seeds,
@ -703,7 +705,7 @@ class Torrent(object):
status_dict[key] = full_status[key] status_dict[key] = full_status[key]
elif key in fns: elif key in fns:
status_dict[key] = fns[key]() status_dict[key] = fns[key]()
session_id = self.rpcserver.get_session_id() session_id = self.rpcserver.get_session_id()
if diff: if diff:
if session_id in self.prev_status: if session_id in self.prev_status:
@ -715,7 +717,7 @@ class Torrent(object):
status_diff[key] = value status_diff[key] = value
else: else:
status_diff[key] = value status_diff[key] = value
self.prev_status[session_id] = status_dict self.prev_status[session_id] = status_dict
return status_diff return status_diff
@ -908,12 +910,12 @@ class Torrent(object):
wait_on_folder[2].append(f["index"]) wait_on_folder[2].append(f["index"])
self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8")) self.handle.rename_file(f["index"], f["path"].replace(folder, new_folder, 1).encode("utf-8"))
self.waiting_on_folder_rename.append(wait_on_folder) self.waiting_on_folder_rename.append(wait_on_folder)
def cleanup_prev_status(self): def cleanup_prev_status(self):
""" """
This method gets called to check the validity of the keys in the prev_status This method gets called to check the validity of the keys in the prev_status
dict. If the key is no longer valid, the dict will be deleted. dict. If the key is no longer valid, the dict will be deleted.
""" """
for key in self.prev_status.keys(): for key in self.prev_status.keys():
if not self.rpcserver.is_session_valid(key): if not self.rpcserver.is_session_valid(key):

View File

@ -1,6 +1,6 @@
/*! /*!
* Deluge.Keys.js * Deluge.Keys.js
* *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com> * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -50,7 +50,7 @@ Deluge.Keys = {
'upload_payload_rate', 'eta', 'ratio', 'distributed_copies', 'upload_payload_rate', 'eta', 'ratio', 'distributed_copies',
'is_auto_managed', 'time_added', 'tracker_host', 'save_path' 'is_auto_managed', 'time_added', 'tracker_host', 'save_path'
], ],
/** /**
* Keys used in the status tab of the statistics panel. * Keys used in the status tab of the statistics panel.
* These get updated to include the keys in {@link #Grid}. * These get updated to include the keys in {@link #Grid}.
@ -65,7 +65,7 @@ Deluge.Keys = {
'piece_length', 'is_auto_managed', 'active_time', 'seeding_time', 'piece_length', 'is_auto_managed', 'active_time', 'seeding_time',
'seed_rank' 'seed_rank'
], ],
/** /**
* Keys used in the files tab of the statistics panel. * Keys used in the files tab of the statistics panel.
* <pre>['files', 'file_progress', 'file_priorities']</pre> * <pre>['files', 'file_progress', 'file_priorities']</pre>
@ -73,7 +73,7 @@ Deluge.Keys = {
Files: [ Files: [
'files', 'file_progress', 'file_priorities' 'files', 'file_progress', 'file_priorities'
], ],
/** /**
* Keys used in the peers tab of the statistics panel. * Keys used in the peers tab of the statistics panel.
* <pre>['peers']</pre> * <pre>['peers']</pre>
@ -81,7 +81,7 @@ Deluge.Keys = {
Peers: [ Peers: [
'peers' 'peers'
], ],
/** /**
* Keys used in the details tab of the statistics panel. * Keys used in the details tab of the statistics panel.
*/ */
@ -89,7 +89,7 @@ Deluge.Keys = {
'name', 'save_path', 'total_size', 'num_files', 'tracker_status', 'name', 'save_path', 'total_size', 'num_files', 'tracker_status',
'tracker', 'comment' 'tracker', 'comment'
], ],
/** /**
* Keys used in the options tab of the statistics panel. * Keys used in the options tab of the statistics panel.
* <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots', * <pre>['max_download_speed', 'max_upload_speed', 'max_connections', 'max_upload_slots',
@ -99,7 +99,8 @@ Deluge.Keys = {
Options: [ Options: [
'max_download_speed', 'max_upload_speed', 'max_connections', 'max_download_speed', 'max_upload_speed', 'max_connections',
'max_upload_slots','is_auto_managed', 'stop_at_ratio', 'stop_ratio', 'max_upload_slots','is_auto_managed', 'stop_at_ratio', 'stop_ratio',
'remove_at_ratio', 'private', 'prioritize_first_last' 'remove_at_ratio', 'private', 'prioritize_first_last',
'move_completed', 'move_completed_path'
] ]
}; };

View File

@ -1,6 +1,6 @@
/*! /*!
* Deluge.details.OptionsTab.js * Deluge.details.OptionsTab.js
* *
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com> * Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -53,7 +53,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
initComponent: function() { initComponent: function() {
Deluge.details.OptionsTab.superclass.initComponent.call(this); Deluge.details.OptionsTab.superclass.initComponent.call(this);
this.fieldsets = {}, this.fields = {}; this.fieldsets = {}, this.fields = {};
this.optionsManager = new Deluge.MultiOptionsManager({ this.optionsManager = new Deluge.MultiOptionsManager({
options: { options: {
@ -65,12 +65,13 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
'stop_at_ratio': false, 'stop_at_ratio': false,
'stop_ratio': 2.0, 'stop_ratio': 2.0,
'remove_at_ratio': false, 'remove_at_ratio': false,
'move_completed': null, 'move_completed': false,
'move_completed_path': '',
'private': false, 'private': false,
'prioritize_first_last': false 'prioritize_first_last': false
} }
}); });
/* /*
* Bandwidth Options * Bandwidth Options
*/ */
@ -78,16 +79,16 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
xtype: 'fieldset', xtype: 'fieldset',
defaultType: 'spinnerfield', defaultType: 'spinnerfield',
bodyStyle: 'padding: 5px', bodyStyle: 'padding: 5px',
layout: 'table', layout: 'table',
layoutConfig: {columns: 3}, layoutConfig: {columns: 3},
labelWidth: 150, labelWidth: 150,
style: 'margin-left: 10px; margin-right: 5px; padding: 5px', style: 'margin-left: 10px; margin-right: 5px; padding: 5px',
title: _('Bandwidth'), title: _('Bandwidth'),
width: 250 width: 250
}); });
/* /*
* Max Download Speed * Max Download Speed
*/ */
@ -113,7 +114,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
text: _('KiB/s'), text: _('KiB/s'),
style: 'margin-left: 10px' style: 'margin-left: 10px'
}); });
/* /*
* Max Upload Speed * Max Upload Speed
*/ */
@ -140,7 +141,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
text: _('KiB/s'), text: _('KiB/s'),
style: 'margin-left: 10px' style: 'margin-left: 10px'
}); });
/* /*
* Max Connections * Max Connections
*/ */
@ -163,7 +164,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
}, },
colspan: 2 colspan: 2
}); });
/* /*
* Max Upload Slots * Max Upload Slots
*/ */
@ -195,17 +196,17 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('Queue'), title: _('Queue'),
style: 'margin-left: 5px; margin-right: 5px; padding: 5px', style: 'margin-left: 5px; margin-right: 5px; padding: 5px',
width: 210, width: 210,
layout: 'table', layout: 'table',
layoutConfig: {columns: 2}, layoutConfig: {columns: 2},
labelWidth: 0, labelWidth: 0,
defaults: { defaults: {
fieldLabel: '', fieldLabel: '',
labelSeparator: '' labelSeparator: ''
} }
}); });
this.fields.auto_managed = this.fieldsets.queue.add({ this.fields.auto_managed = this.fieldsets.queue.add({
xtype: 'checkbox', xtype: 'checkbox',
fieldLabel: '', fieldLabel: '',
@ -215,7 +216,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
width: 200, width: 200,
colspan: 2 colspan: 2
}); });
this.fields.stop_at_ratio = this.fieldsets.queue.add({ this.fields.stop_at_ratio = this.fieldsets.queue.add({
fieldLabel: '', fieldLabel: '',
labelSeparator: '', labelSeparator: '',
@ -225,7 +226,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
handler: this.onStopRatioChecked, handler: this.onStopRatioChecked,
scope: this scope: this
}); });
this.fields.stop_ratio = this.fieldsets.queue.add({ this.fields.stop_ratio = this.fieldsets.queue.add({
xtype: 'spinnerfield', xtype: 'spinnerfield',
id: 'stop_ratio', id: 'stop_ratio',
@ -242,7 +243,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
decimalPrecision: 1 decimalPrecision: 1
} }
}); });
this.fields.remove_at_ratio = this.fieldsets.queue.add({ this.fields.remove_at_ratio = this.fieldsets.queue.add({
fieldLabel: '', fieldLabel: '',
labelSeparator: '', labelSeparator: '',
@ -253,16 +254,28 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
disabled: true, disabled: true,
colspan: 2 colspan: 2
}); });
this.fields.move_completed = this.fieldsets.queue.add({ this.fields.move_completed = this.fieldsets.queue.add({
fieldLabel: '', fieldLabel: '',
labelSeparator: '', labelSeparator: '',
id: 'move_completed', id: 'move_completed',
boxLabel: _('Move Completed'), boxLabel: _('Move Completed'),
colspan: 2 colspan: 2,
handler: this.onMoveCompletedChecked,
scope: this
}); });
this.fields.move_completed_path = this.fieldsets.queue.add({
xtype: 'textfield',
fieldLabel: '',
id: 'move_completed_path',
colspan: 3,
bodyStyle: 'margin-left: 20px',
width: 180,
disabled: true
});
/* /*
* General Options * General Options
*/ */
@ -272,7 +285,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
style: 'margin-left: 5px', style: 'margin-left: 5px',
width: 210 width: 210
}); });
this.fieldsets.general = this.rightColumn.add({ this.fieldsets.general = this.rightColumn.add({
xtype: 'fieldset', xtype: 'fieldset',
autoHeight: true, autoHeight: true,
@ -280,7 +293,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
title: _('General'), title: _('General'),
layout: 'form' layout: 'form'
}); });
this.fields['private'] = this.fieldsets.general.add({ this.fields['private'] = this.fieldsets.general.add({
fieldLabel: '', fieldLabel: '',
labelSeparator: '', labelSeparator: '',
@ -288,19 +301,19 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
id: 'private', id: 'private',
disabled: true disabled: true
}); });
this.fields.prioritize_first_last = this.fieldsets.general.add({ this.fields.prioritize_first_last = this.fieldsets.general.add({
fieldLabel: '', fieldLabel: '',
labelSeparator: '', labelSeparator: '',
boxLabel: _('Prioritize First/Last'), boxLabel: _('Prioritize First/Last'),
id: 'prioritize_first_last' id: 'prioritize_first_last'
}); });
// Bind the fields so the options manager can manage them. // Bind the fields so the options manager can manage them.
for (var id in this.fields) { for (var id in this.fields) {
this.optionsManager.bind(id, this.fields[id]); this.optionsManager.bind(id, this.fields[id]);
} }
/* /*
* Buttons * Buttons
*/ */
@ -309,7 +322,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
xtype: 'panel', xtype: 'panel',
border: false border: false
}); });
/* /*
* Edit Trackers button * Edit Trackers button
*/ */
@ -324,7 +337,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
handler: this.onEditTrackers, handler: this.onEditTrackers,
scope: this scope: this
}); });
/* /*
* Apply button * Apply button
*/ */
@ -339,31 +352,31 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
scope: this scope: this
}); });
}, },
onRender: function(ct, position) { onRender: function(ct, position) {
Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position); Deluge.details.OptionsTab.superclass.onRender.call(this, ct, position);
// This is another hack I think, so keep an eye out here when upgrading. // This is another hack I think, so keep an eye out here when upgrading.
this.layout = new Ext.layout.ColumnLayout(); this.layout = new Ext.layout.ColumnLayout();
this.layout.setContainer(this); this.layout.setContainer(this);
this.doLayout(); this.doLayout();
}, },
clear: function() { clear: function() {
if (this.torrentId == null) return; if (this.torrentId == null) return;
this.torrentId = null; this.torrentId = null;
this.optionsManager.changeId(null); this.optionsManager.changeId(null);
}, },
reset: function() { reset: function() {
if (this.torrentId) this.optionsManager.reset(); if (this.torrentId) this.optionsManager.reset();
}, },
update: function(torrentId) { update: function(torrentId) {
if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds if (this.torrentId && !torrentId) this.clear(); // we want to clear the pane if we get a null torrent torrentIds
if (!torrentId) return; // we don't care about null torrentIds if (!torrentId) return; // we don't care about null torrentIds
if (this.torrentId != torrentId) { if (this.torrentId != torrentId) {
this.torrentId = torrentId; this.torrentId = torrentId;
this.optionsManager.changeId(torrentId); this.optionsManager.changeId(torrentId);
@ -373,7 +386,7 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
scope: this scope: this
}); });
}, },
onApply: function() { onApply: function() {
var changed = this.optionsManager.getDirty(); var changed = this.optionsManager.getDirty();
if (!Ext.isEmpty(changed['prioritize_first_last'])) { if (!Ext.isEmpty(changed['prioritize_first_last'])) {
@ -392,16 +405,23 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
scope: this scope: this
}); });
}, },
onEditTrackers: function() { onEditTrackers: function() {
deluge.editTrackers.show(); deluge.editTrackers.show();
}, },
onMoveCompletedChecked: function(checkbox, checked) {
this.fields.move_completed_path.setDisabled(!checked);
if (!checked) return;
this.fields.move_completed_path.focus();
},
onStopRatioChecked: function(checkbox, checked) { onStopRatioChecked: function(checkbox, checked) {
this.fields.remove_at_ratio.setDisabled(!checked); this.fields.remove_at_ratio.setDisabled(!checked);
this.fields.stop_ratio.setDisabled(!checked); this.fields.stop_ratio.setDisabled(!checked);
}, },
onRequestComplete: function(torrent, options) { onRequestComplete: function(torrent, options) {
this.fields['private'].setValue(torrent['private']); this.fields['private'].setValue(torrent['private']);
this.fields['private'].setDisabled(true); this.fields['private'].setDisabled(true);
@ -411,5 +431,6 @@ Deluge.details.OptionsTab = Ext.extend(Ext.form.FormPanel, {
var stop_at_ratio = this.optionsManager.get('stop_at_ratio'); var stop_at_ratio = this.optionsManager.get('stop_at_ratio');
this.fields.remove_at_ratio.setDisabled(!stop_at_ratio); this.fields.remove_at_ratio.setDisabled(!stop_at_ratio);
this.fields.stop_ratio.setDisabled(!stop_at_ratio); this.fields.stop_ratio.setDisabled(!stop_at_ratio);
this.fields.move_completed_path.setDisabled(!this.optionsManager.get('move_completed'));
} }
}); });