Setup
This commit is contained in:
Executable
+226
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* Script: autoadd.js
|
||||
* The client-side javascript code for the AutoAdd plugin.
|
||||
*
|
||||
* Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.AutoAdd');
|
||||
Deluge.ux.AutoAdd.onClickFunctions = {};
|
||||
|
||||
Ext.ns('Deluge.ux.preferences');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.preferences.AutoAddPage
|
||||
* @extends Ext.Panel
|
||||
*/
|
||||
Deluge.ux.preferences.AutoAddPage = Ext.extend(Ext.Panel, {
|
||||
title: _('AutoAdd'),
|
||||
header: false,
|
||||
layout: 'fit',
|
||||
border: false,
|
||||
watchdirs: {},
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.preferences.AutoAddPage.superclass.initComponent.call(this);
|
||||
|
||||
var autoAdd = this;
|
||||
|
||||
this.list = new Ext.list.ListView({
|
||||
store: new Ext.data.JsonStore({
|
||||
fields: ['id', 'enabled', 'owner', 'path'],
|
||||
}),
|
||||
columns: [
|
||||
{
|
||||
id: 'enabled',
|
||||
header: _('Active'),
|
||||
sortable: true,
|
||||
dataIndex: 'enabled',
|
||||
tpl: new Ext.XTemplate('{enabled:this.getCheckbox}', {
|
||||
getCheckbox: function (checked, selected) {
|
||||
Deluge.ux.AutoAdd.onClickFunctions[selected.id] =
|
||||
function () {
|
||||
if (selected.enabled) {
|
||||
deluge.client.autoadd.disable_watchdir(
|
||||
selected.id
|
||||
);
|
||||
checked = false;
|
||||
} else {
|
||||
deluge.client.autoadd.enable_watchdir(
|
||||
selected.id
|
||||
);
|
||||
checked = true;
|
||||
}
|
||||
autoAdd.updateWatchDirs();
|
||||
};
|
||||
return (
|
||||
'<input id="enabled-' +
|
||||
selected.id +
|
||||
'" type="checkbox"' +
|
||||
(checked ? ' checked' : '') +
|
||||
' onclick="Deluge.ux.AutoAdd.onClickFunctions[' +
|
||||
selected.id +
|
||||
']()" />'
|
||||
);
|
||||
},
|
||||
}),
|
||||
width: 0.15,
|
||||
},
|
||||
{
|
||||
id: 'owner',
|
||||
header: _('Owner'),
|
||||
sortable: true,
|
||||
dataIndex: 'owner',
|
||||
width: 0.2,
|
||||
},
|
||||
{
|
||||
id: 'path',
|
||||
header: _('Path'),
|
||||
sortable: true,
|
||||
dataIndex: 'path',
|
||||
},
|
||||
],
|
||||
singleSelect: true,
|
||||
autoExpandColumn: 'path',
|
||||
});
|
||||
this.list.on('selectionchange', this.onSelectionChange, this);
|
||||
|
||||
this.panel = this.add({
|
||||
items: [this.list],
|
||||
bbar: {
|
||||
items: [
|
||||
{
|
||||
text: _('Add'),
|
||||
iconCls: 'icon-add',
|
||||
handler: this.onAddClick,
|
||||
scope: this,
|
||||
},
|
||||
{
|
||||
text: _('Edit'),
|
||||
iconCls: 'icon-edit',
|
||||
handler: this.onEditClick,
|
||||
scope: this,
|
||||
disabled: true,
|
||||
},
|
||||
'->',
|
||||
{
|
||||
text: _('Remove'),
|
||||
iconCls: 'icon-remove',
|
||||
handler: this.onRemoveClick,
|
||||
scope: this,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
this.on('show', this.onPreferencesShow, this);
|
||||
},
|
||||
|
||||
updateWatchDirs: function () {
|
||||
deluge.client.autoadd.get_watchdirs({
|
||||
success: function (watchdirs) {
|
||||
this.watchdirs = watchdirs;
|
||||
var watchdirsArray = [];
|
||||
for (var id in watchdirs) {
|
||||
if (watchdirs.hasOwnProperty(id)) {
|
||||
var watchdir = {};
|
||||
watchdir['id'] = id;
|
||||
watchdir['enabled'] = watchdirs[id].enabled;
|
||||
watchdir['owner'] =
|
||||
watchdirs[id].owner || 'localclient';
|
||||
watchdir['path'] = watchdirs[id].path;
|
||||
|
||||
watchdirsArray.push(watchdir);
|
||||
}
|
||||
}
|
||||
this.list.getStore().loadData(watchdirsArray);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
|
||||
onAddClick: function () {
|
||||
if (!this.addWin) {
|
||||
this.addWin = new Deluge.ux.AutoAdd.AddAutoAddCommandWindow();
|
||||
this.addWin.on(
|
||||
'watchdiradd',
|
||||
function () {
|
||||
this.updateWatchDirs();
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
this.addWin.show();
|
||||
},
|
||||
|
||||
onEditClick: function () {
|
||||
if (!this.editWin) {
|
||||
this.editWin = new Deluge.ux.AutoAdd.EditAutoAddCommandWindow();
|
||||
this.editWin.on(
|
||||
'watchdiredit',
|
||||
function () {
|
||||
this.updateWatchDirs();
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
var id = this.list.getSelectedRecords()[0].id;
|
||||
this.editWin.show(id, this.watchdirs[id]);
|
||||
},
|
||||
|
||||
onPreferencesShow: function () {
|
||||
this.updateWatchDirs();
|
||||
},
|
||||
|
||||
onRemoveClick: function () {
|
||||
var record = this.list.getSelectedRecords()[0];
|
||||
deluge.client.autoadd.remove(record.id, {
|
||||
success: function () {
|
||||
this.updateWatchDirs();
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
|
||||
onSelectionChange: function (dv, selections) {
|
||||
if (selections.length) {
|
||||
this.panel.getBottomToolbar().items.get(1).enable();
|
||||
this.panel.getBottomToolbar().items.get(3).enable();
|
||||
} else {
|
||||
this.panel.getBottomToolbar().items.get(1).disable();
|
||||
this.panel.getBottomToolbar().items.get(3).disable();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Deluge.plugins.AutoAddPlugin = Ext.extend(Deluge.Plugin, {
|
||||
name: 'AutoAdd',
|
||||
|
||||
static: {
|
||||
prefsPage: null,
|
||||
},
|
||||
|
||||
onDisable: function () {
|
||||
deluge.preferences.removePage(Deluge.plugins.AutoAddPlugin.prefsPage);
|
||||
Deluge.plugins.AutoAddPlugin.prefsPage = null;
|
||||
},
|
||||
|
||||
onEnable: function () {
|
||||
/*
|
||||
* Called for each of the JavaScript files.
|
||||
* This will prevent adding unnecessary tabs to the preferences window.
|
||||
*/
|
||||
if (!Deluge.plugins.AutoAddPlugin.prefsPage) {
|
||||
Deluge.plugins.AutoAddPlugin.prefsPage = deluge.preferences.addPage(
|
||||
new Deluge.ux.preferences.AutoAddPage()
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Deluge.registerPlugin('AutoAdd', Deluge.plugins.AutoAddPlugin);
|
||||
deluge/config/plugins/.python-eggs/AutoAdd-1.8-py3.12.egg-tmp/deluge_autoadd/data/autoadd_options.js
Executable
+472
@@ -0,0 +1,472 @@
|
||||
/**
|
||||
* Script: autoadd.js
|
||||
* The client-side javascript code for the AutoAdd plugin.
|
||||
*
|
||||
* Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.AutoAdd');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AutoAdd.AutoAddWindowBase
|
||||
* @extends Ext.Window
|
||||
*/
|
||||
Deluge.ux.AutoAdd.AutoAddWindowBase = Ext.extend(Ext.Window, {
|
||||
width: 350,
|
||||
height: 500,
|
||||
layout: 'fit',
|
||||
closeAction: 'hide',
|
||||
|
||||
spin_ids: ['max_download_speed', 'max_upload_speed', 'stop_ratio'],
|
||||
spin_int_ids: ['max_upload_slots', 'max_connections'],
|
||||
chk_ids: [
|
||||
'stop_at_ratio',
|
||||
'remove_at_ratio',
|
||||
'move_completed',
|
||||
'add_paused',
|
||||
'auto_managed',
|
||||
'queue_to_top',
|
||||
],
|
||||
toggle_ids: [
|
||||
'append_extension_toggle',
|
||||
'download_location_toggle',
|
||||
'label_toggle',
|
||||
'copy_torrent_toggle',
|
||||
'delete_copy_torrent_toggle',
|
||||
'seed_mode',
|
||||
],
|
||||
|
||||
accounts: new Ext.data.ArrayStore({
|
||||
storeId: 'accountStore',
|
||||
id: 0,
|
||||
fields: [
|
||||
{
|
||||
name: 'displayText',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
}),
|
||||
labels: new Ext.data.ArrayStore({
|
||||
storeId: 'labelStore',
|
||||
id: 0,
|
||||
fields: [
|
||||
{
|
||||
name: 'displayText',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AutoAdd.AutoAddWindowBase.superclass.initComponent.call(this);
|
||||
this.addButton(_('Cancel'), this.onCancelClick, this);
|
||||
|
||||
this.MainTab = new Deluge.ux.AutoAdd.AutoAddMainPanel();
|
||||
this.OptionsTab = new Deluge.ux.AutoAdd.AutoAddOptionsPanel();
|
||||
|
||||
this.form = this.add({
|
||||
xtype: 'form',
|
||||
layout: 'fit',
|
||||
baseCls: 'x-plain',
|
||||
bodyStyle: 'padding: 5px',
|
||||
items: [
|
||||
{
|
||||
xtype: 'tabpanel',
|
||||
activeTab: 0,
|
||||
items: [this.MainTab, this.OptionsTab],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
onCancelClick: function () {
|
||||
this.hide();
|
||||
},
|
||||
|
||||
getOptions: function () {
|
||||
var options = {};
|
||||
|
||||
options['enabled'] = Ext.getCmp('enabled').getValue();
|
||||
options['path'] = Ext.getCmp('path').getValue();
|
||||
options['download_location'] =
|
||||
Ext.getCmp('download_location').getValue();
|
||||
options['move_completed_path'] = Ext.getCmp(
|
||||
'move_completed_path'
|
||||
).getValue();
|
||||
options['copy_torrent'] = Ext.getCmp('copy_torrent').getValue();
|
||||
|
||||
options['label'] = Ext.getCmp('label').getValue();
|
||||
options['append_extension'] = Ext.getCmp('append_extension').getValue();
|
||||
options['owner'] = Ext.getCmp('owner').getValue();
|
||||
|
||||
this.toggle_ids.forEach(function (toggle_id) {
|
||||
options[toggle_id] = Ext.getCmp(toggle_id).getValue();
|
||||
});
|
||||
this.spin_ids.forEach(function (spin_id) {
|
||||
options[spin_id] = Ext.getCmp(spin_id).getValue();
|
||||
options[spin_id + '_toggle'] = Ext.getCmp(
|
||||
spin_id + '_toggle'
|
||||
).getValue();
|
||||
});
|
||||
this.spin_int_ids.forEach(function (spin_int_id) {
|
||||
options[spin_int_id] = Ext.getCmp(spin_int_id).getValue();
|
||||
options[spin_int_id + '_toggle'] = Ext.getCmp(
|
||||
spin_int_id + '_toggle'
|
||||
).getValue();
|
||||
});
|
||||
this.chk_ids.forEach(function (chk_id) {
|
||||
options[chk_id] = Ext.getCmp(chk_id).getValue();
|
||||
options[chk_id + '_toggle'] = Ext.getCmp(
|
||||
chk_id + '_toggle'
|
||||
).getValue();
|
||||
});
|
||||
|
||||
if (
|
||||
options['copy_torrent_toggle'] &&
|
||||
options['path'] === options['copy_torrent']
|
||||
) {
|
||||
throw _(
|
||||
'"Watch Folder" directory and "Copy of .torrent' +
|
||||
' files to" directory cannot be the same!'
|
||||
);
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
loadOptions: function (options) {
|
||||
/*
|
||||
* Populate all available options data to the UI
|
||||
*/
|
||||
var value;
|
||||
|
||||
if (options === undefined) {
|
||||
options = {};
|
||||
}
|
||||
Ext.getCmp('enabled').setValue(
|
||||
options['enabled'] !== undefined ? options['enabled'] : true
|
||||
);
|
||||
Ext.getCmp('isnt_append_extension').setValue(true);
|
||||
Ext.getCmp('append_extension_toggle').setValue(
|
||||
options['append_extension_toggle'] !== undefined
|
||||
? options['append_extension_toggle']
|
||||
: false
|
||||
);
|
||||
Ext.getCmp('append_extension').setValue(
|
||||
options['append_extension'] !== undefined
|
||||
? options['append_extension']
|
||||
: '.added'
|
||||
);
|
||||
Ext.getCmp('download_location_toggle').setValue(
|
||||
options['download_location_toggle'] !== undefined
|
||||
? options['download_location_toggle']
|
||||
: false
|
||||
);
|
||||
Ext.getCmp('copy_torrent_toggle').setValue(
|
||||
options['copy_torrent_toggle'] !== undefined
|
||||
? options['copy_torrent_toggle']
|
||||
: false
|
||||
);
|
||||
Ext.getCmp('delete_copy_torrent_toggle').setValue(
|
||||
options['delete_copy_torrent_toggle'] !== undefined
|
||||
? options['delete_copy_torrent_toggle']
|
||||
: false
|
||||
);
|
||||
|
||||
value =
|
||||
options['seed_mode'] !== undefined ? options['seed_mode'] : false;
|
||||
Ext.getCmp('seed_mode').setValue(value);
|
||||
|
||||
this.accounts.removeAll(true);
|
||||
this.labels.removeAll(true);
|
||||
Ext.getCmp('owner').store = this.accounts;
|
||||
Ext.getCmp('label').store = this.labels;
|
||||
Ext.getCmp('label').setValue(
|
||||
options['label'] !== undefined ? options['label'] : ''
|
||||
);
|
||||
Ext.getCmp('label_toggle').setValue(
|
||||
options['label_toggle'] !== undefined
|
||||
? options['label_toggle']
|
||||
: false
|
||||
);
|
||||
|
||||
this.spin_ids.forEach(function (spin_id) {
|
||||
Ext.getCmp(spin_id).setValue(
|
||||
options[spin_id] !== undefined ? options[spin_id] : 0
|
||||
);
|
||||
Ext.getCmp(spin_id + '_toggle').setValue(
|
||||
options[spin_id + '_toggle'] !== undefined
|
||||
? options[spin_id + '_toggle']
|
||||
: false
|
||||
);
|
||||
});
|
||||
this.chk_ids.forEach(function (chk_id) {
|
||||
Ext.getCmp(chk_id).setValue(
|
||||
options[chk_id] !== undefined ? options[chk_id] : true
|
||||
);
|
||||
Ext.getCmp(chk_id + '_toggle').setValue(
|
||||
options[chk_id + '_toggle'] !== undefined
|
||||
? options[chk_id + '_toggle']
|
||||
: false
|
||||
);
|
||||
});
|
||||
value =
|
||||
options['add_paused'] !== undefined ? options['add_paused'] : true;
|
||||
if (!value) {
|
||||
Ext.getCmp('not_add_paused').setValue(true);
|
||||
}
|
||||
value =
|
||||
options['queue_to_top'] !== undefined
|
||||
? options['queue_to_top']
|
||||
: true;
|
||||
if (!value) {
|
||||
Ext.getCmp('not_queue_to_top').setValue(true);
|
||||
}
|
||||
value =
|
||||
options['auto_managed'] !== undefined
|
||||
? options['auto_managed']
|
||||
: true;
|
||||
if (!value) {
|
||||
Ext.getCmp('not_auto_managed').setValue(true);
|
||||
}
|
||||
[
|
||||
'move_completed_path',
|
||||
'path',
|
||||
'download_location',
|
||||
'copy_torrent',
|
||||
].forEach(function (field) {
|
||||
value = options[field] !== undefined ? options[field] : '';
|
||||
Ext.getCmp(field).setValue(value);
|
||||
});
|
||||
|
||||
if (Object.keys(options).length === 0) {
|
||||
deluge.client.core.get_config({
|
||||
success: function (config) {
|
||||
var value;
|
||||
Ext.getCmp('download_location').setValue(
|
||||
options['download_location'] !== undefined
|
||||
? options['download_location']
|
||||
: config['download_location']
|
||||
);
|
||||
value =
|
||||
options['move_completed_toggle'] !== undefined
|
||||
? options['move_completed_toggle']
|
||||
: config['move_completed'];
|
||||
if (value) {
|
||||
Ext.getCmp('move_completed_toggle').setValue(
|
||||
options['move_completed_toggle'] !== undefined
|
||||
? options['move_completed_toggle']
|
||||
: false
|
||||
);
|
||||
Ext.getCmp('move_completed_path').setValue(
|
||||
options['move_completed_path'] !== undefined
|
||||
? options['move_completed_path']
|
||||
: config['move_completed_path']
|
||||
);
|
||||
}
|
||||
value =
|
||||
options['copy_torrent_toggle'] !== undefined
|
||||
? options['copy_torrent_toggle']
|
||||
: config['copy_torrent_file'];
|
||||
if (value) {
|
||||
Ext.getCmp('copy_torrent_toggle').setValue(true);
|
||||
Ext.getCmp('copy_torrent').setValue(
|
||||
options['copy_torrent'] !== undefined
|
||||
? options['copy_torrent']
|
||||
: config['torrentfiles_location']
|
||||
);
|
||||
}
|
||||
value =
|
||||
options['delete_copy_torrent_toggle'] !== undefined
|
||||
? options['copy_torrent_toggle']
|
||||
: config['del_copy_torrent_file'];
|
||||
if (value) {
|
||||
Ext.getCmp('delete_copy_torrent_toggle').setValue(true);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
deluge.client.core.get_enabled_plugins({
|
||||
success: function (plugins) {
|
||||
if (plugins !== undefined && plugins.indexOf('Label') > -1) {
|
||||
this.MainTab.LabelFset.setVisible(true);
|
||||
deluge.client.label.get_labels({
|
||||
success: function (labels) {
|
||||
for (
|
||||
var index = 0;
|
||||
index < labels.length;
|
||||
index++
|
||||
) {
|
||||
labels[index] = [labels[index]];
|
||||
}
|
||||
this.labels.loadData(labels, false);
|
||||
},
|
||||
failure: function (failure) {
|
||||
console.error(failure);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
} else {
|
||||
this.MainTab.LabelFset.setVisible(false);
|
||||
}
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
|
||||
var me = this;
|
||||
|
||||
function on_accounts(accounts, owner) {
|
||||
for (var index = 0; index < accounts.length; index++) {
|
||||
accounts[index] = [accounts[index]['username']];
|
||||
}
|
||||
me.accounts.loadData(accounts, false);
|
||||
Ext.getCmp('owner').setValue(owner).enable();
|
||||
}
|
||||
|
||||
function on_accounts_failure(failure) {
|
||||
deluge.client.autoadd.get_auth_user({
|
||||
success: function (user) {
|
||||
me.accounts.loadData([[user]], false);
|
||||
Ext.getCmp('owner').setValue(user).disable(true);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
}
|
||||
|
||||
deluge.client.autoadd.is_admin_level({
|
||||
success: function (is_admin) {
|
||||
if (is_admin) {
|
||||
deluge.client.core.get_known_accounts({
|
||||
success: function (accounts) {
|
||||
deluge.client.autoadd.get_auth_user({
|
||||
success: function (user) {
|
||||
on_accounts(
|
||||
accounts,
|
||||
options['owner'] !== undefined
|
||||
? options['owner']
|
||||
: user
|
||||
);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
failure: on_accounts_failure,
|
||||
scope: this,
|
||||
});
|
||||
} else {
|
||||
on_accounts_failure(null);
|
||||
}
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AutoAdd.EditAutoAddCommandWindow
|
||||
* @extends Deluge.ux.AutoAdd.AutoAddWindowBase
|
||||
*/
|
||||
Deluge.ux.AutoAdd.EditAutoAddCommandWindow = Ext.extend(
|
||||
Deluge.ux.AutoAdd.AutoAddWindowBase,
|
||||
{
|
||||
title: _('Edit Watch Folder'),
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AutoAdd.EditAutoAddCommandWindow.superclass.initComponent.call(
|
||||
this
|
||||
);
|
||||
this.addButton(_('Save'), this.onSaveClick, this);
|
||||
this.addEvents({
|
||||
watchdiredit: true,
|
||||
});
|
||||
},
|
||||
|
||||
show: function (watchdir_id, options) {
|
||||
Deluge.ux.AutoAdd.EditAutoAddCommandWindow.superclass.show.call(
|
||||
this
|
||||
);
|
||||
this.watchdir_id = watchdir_id;
|
||||
this.loadOptions(options);
|
||||
},
|
||||
|
||||
onSaveClick: function () {
|
||||
try {
|
||||
var options = this.getOptions();
|
||||
deluge.client.autoadd.set_options(this.watchdir_id, options, {
|
||||
success: function () {
|
||||
this.fireEvent('watchdiredit', this, options);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
} catch (err) {
|
||||
Ext.Msg.show({
|
||||
title: _('Incompatible Option'),
|
||||
msg: err,
|
||||
buttons: Ext.Msg.OK,
|
||||
scope: this,
|
||||
});
|
||||
}
|
||||
|
||||
this.hide();
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AutoAdd.AddAutoAddCommandWindow
|
||||
* @extends Deluge.ux.AutoAdd.AutoAddWindowBase
|
||||
*/
|
||||
Deluge.ux.AutoAdd.AddAutoAddCommandWindow = Ext.extend(
|
||||
Deluge.ux.AutoAdd.AutoAddWindowBase,
|
||||
{
|
||||
title: _('Add Watch Folder'),
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AutoAdd.AddAutoAddCommandWindow.superclass.initComponent.call(
|
||||
this
|
||||
);
|
||||
this.addButton(_('Add'), this.onAddClick, this);
|
||||
this.addEvents({
|
||||
watchdiradd: true,
|
||||
});
|
||||
},
|
||||
|
||||
show: function () {
|
||||
Deluge.ux.AutoAdd.AddAutoAddCommandWindow.superclass.show.call(
|
||||
this
|
||||
);
|
||||
this.loadOptions();
|
||||
},
|
||||
|
||||
onAddClick: function () {
|
||||
var options = this.getOptions();
|
||||
deluge.client.autoadd.add(options, {
|
||||
success: function () {
|
||||
this.fireEvent('watchdiradd', this, options);
|
||||
this.hide();
|
||||
},
|
||||
failure: function (err) {
|
||||
const regex = /: (.*\n)\n?\]/m;
|
||||
var error;
|
||||
if ((error = regex.exec(err.error.message)) !== null) {
|
||||
error = error[1];
|
||||
} else {
|
||||
error = err.error.message;
|
||||
}
|
||||
Ext.Msg.show({
|
||||
title: _('Incompatible Option'),
|
||||
msg: error,
|
||||
buttons: Ext.Msg.OK,
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
/**
|
||||
* Script: main_tab.js
|
||||
* The client-side javascript code for the AutoAdd plugin.
|
||||
*
|
||||
* Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.AutoAdd');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AutoAdd.AutoAddMainPanel
|
||||
* @extends Ext.Panel
|
||||
*/
|
||||
Deluge.ux.AutoAdd.AutoAddMainPanel = Ext.extend(Ext.Panel, {
|
||||
id: 'main_tab_panel',
|
||||
title: _('Main'),
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AutoAdd.AutoAddMainPanel.superclass.initComponent.call(this);
|
||||
this.watchFolderFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Watch Folder'),
|
||||
defaultType: 'textfield',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
width: '85%',
|
||||
labelWidth: 1,
|
||||
items: [
|
||||
{
|
||||
xtype: 'textfield',
|
||||
id: 'path',
|
||||
hideLabel: true,
|
||||
width: 304,
|
||||
},
|
||||
{
|
||||
hideLabel: true,
|
||||
id: 'enabled',
|
||||
xtype: 'checkbox',
|
||||
boxLabel: _('Enable this watch folder'),
|
||||
checked: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.torrentActionFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Torrent File Action'),
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
width: '85%',
|
||||
labelWidth: 1,
|
||||
defaults: {
|
||||
style: 'margin-bottom: 2px',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
xtype: 'radiogroup',
|
||||
columns: 1,
|
||||
items: [
|
||||
{
|
||||
xtype: 'radio',
|
||||
name: 'torrent_action',
|
||||
id: 'isnt_append_extension',
|
||||
boxLabel: _('Delete .torrent after adding'),
|
||||
checked: true,
|
||||
hideLabel: true,
|
||||
listeners: {
|
||||
check: function (cb, newValue) {
|
||||
if (newValue) {
|
||||
Ext.getCmp(
|
||||
'append_extension'
|
||||
).setDisabled(newValue);
|
||||
Ext.getCmp('copy_torrent').setDisabled(
|
||||
newValue
|
||||
);
|
||||
Ext.getCmp(
|
||||
'delete_copy_torrent_toggle'
|
||||
).setDisabled(newValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'radio',
|
||||
name: 'torrent_action',
|
||||
id: 'append_extension_toggle',
|
||||
boxLabel: _(
|
||||
'Append extension after adding:'
|
||||
),
|
||||
hideLabel: true,
|
||||
listeners: {
|
||||
check: function (cb, newValue) {
|
||||
if (newValue) {
|
||||
Ext.getCmp(
|
||||
'append_extension'
|
||||
).setDisabled(!newValue);
|
||||
Ext.getCmp(
|
||||
'copy_torrent'
|
||||
).setDisabled(newValue);
|
||||
Ext.getCmp(
|
||||
'delete_copy_torrent_toggle'
|
||||
).setDisabled(newValue);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
id: 'append_extension',
|
||||
hideLabel: true,
|
||||
disabled: true,
|
||||
style: 'margin-left: 2px',
|
||||
width: 112,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'container',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'radio',
|
||||
name: 'torrent_action',
|
||||
id: 'copy_torrent_toggle',
|
||||
boxLabel: _(
|
||||
'Copy of .torrent files to:'
|
||||
),
|
||||
hideLabel: true,
|
||||
listeners: {
|
||||
check: function (cb, newValue) {
|
||||
if (newValue) {
|
||||
Ext.getCmp(
|
||||
'append_extension'
|
||||
).setDisabled(newValue);
|
||||
Ext.getCmp(
|
||||
'copy_torrent'
|
||||
).setDisabled(
|
||||
!newValue
|
||||
);
|
||||
Ext.getCmp(
|
||||
'delete_copy_torrent_toggle'
|
||||
).setDisabled(
|
||||
!newValue
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
id: 'copy_torrent',
|
||||
hideLabel: true,
|
||||
disabled: true,
|
||||
style: 'margin-left: 2px',
|
||||
width: 152,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'delete_copy_torrent_toggle',
|
||||
boxLabel: _(
|
||||
'Delete copy of torrent file on remove'
|
||||
),
|
||||
style: 'margin-left: 10px',
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.downloadFolderFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Download Folder'),
|
||||
defaultType: 'textfield',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
width: '85%',
|
||||
labelWidth: 1,
|
||||
items: [
|
||||
{
|
||||
hideLabel: true,
|
||||
id: 'download_location_toggle',
|
||||
xtype: 'checkbox',
|
||||
boxLabel: _('Set download folder'),
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp('download_location').setDisabled(
|
||||
!checked
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
id: 'download_location',
|
||||
hideLabel: true,
|
||||
width: 304,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.moveCompletedFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Move Completed'),
|
||||
defaultType: 'textfield',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
width: '85%',
|
||||
labelWidth: 1,
|
||||
items: [
|
||||
{
|
||||
hideLabel: true,
|
||||
id: 'move_completed_toggle',
|
||||
xtype: 'checkbox',
|
||||
boxLabel: _('Set move completed folder'),
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp('move_completed_path').setDisabled(
|
||||
!checked
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
id: 'move_completed_path',
|
||||
hideLabel: true,
|
||||
width: 304,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.LabelFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Label'),
|
||||
defaultType: 'textfield',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 3px;',
|
||||
//width: '85%',
|
||||
labelWidth: 1,
|
||||
//hidden: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
hashLabel: false,
|
||||
id: 'label_toggle',
|
||||
xtype: 'checkbox',
|
||||
boxLabel: _('Label:'),
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp('label').setDisabled(!checked);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'combo',
|
||||
id: 'label',
|
||||
hideLabel: true,
|
||||
//width: 220,
|
||||
width: 254,
|
||||
disabled: true,
|
||||
style: 'margin-left: 2px',
|
||||
mode: 'local',
|
||||
valueField: 'displayText',
|
||||
displayField: 'displayText',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.add([
|
||||
this.watchFolderFset,
|
||||
this.torrentActionFset,
|
||||
this.downloadFolderFset,
|
||||
this.moveCompletedFset,
|
||||
this.LabelFset,
|
||||
]);
|
||||
},
|
||||
});
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* Script: options_tab.js
|
||||
* The client-side javascript code for the AutoAdd plugin.
|
||||
*
|
||||
* Copyright (C) 2009 GazpachoKing <chase.sterling@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.AutoAdd');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AutoAdd.AutoAddOptionsPanel
|
||||
* @extends Ext.Panel
|
||||
*/
|
||||
Deluge.ux.AutoAdd.AutoAddOptionsPanel = Ext.extend(Ext.Panel, {
|
||||
id: 'options_tab_panel',
|
||||
title: _('Options'),
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AutoAdd.AutoAddOptionsPanel.superclass.initComponent.call(
|
||||
this
|
||||
);
|
||||
var maxDownload = {
|
||||
idCheckbox: 'max_download_speed_toggle',
|
||||
labelCheckbox: 'Max Download Speed (KiB/s):',
|
||||
idSpinner: 'max_download_speed',
|
||||
decimalPrecision: 1,
|
||||
};
|
||||
var maxUploadSpeed = {
|
||||
idCheckbox: 'max_upload_speed_toggle',
|
||||
labelCheckbox: 'Max upload Speed (KiB/s):',
|
||||
idSpinner: 'max_upload_speed',
|
||||
decimalPrecision: 1,
|
||||
};
|
||||
var maxConnections = {
|
||||
idCheckbox: 'max_connections_toggle',
|
||||
labelCheckbox: 'Max Connections::',
|
||||
idSpinner: 'max_connections',
|
||||
decimalPrecision: 0,
|
||||
};
|
||||
var maxUploadSlots = {
|
||||
idCheckbox: 'max_upload_slots_toggle',
|
||||
labelCheckbox: 'Max Upload Slots:',
|
||||
idSpinner: 'max_upload_slots',
|
||||
decimalPrecision: 0,
|
||||
};
|
||||
// queue data
|
||||
var addPause = {
|
||||
idCheckbox: 'add_paused_toggle',
|
||||
labelCheckbox: 'Add Pause:',
|
||||
nameRadio: 'add_paused',
|
||||
labelRadio: {
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
},
|
||||
};
|
||||
var queueTo = {
|
||||
idCheckbox: 'queue_to_top_toggle',
|
||||
labelCheckbox: 'Queue To:',
|
||||
nameRadio: 'queue_to_top',
|
||||
labelRadio: {
|
||||
yes: 'Top',
|
||||
no: 'Bottom',
|
||||
},
|
||||
};
|
||||
var autoManaged = {
|
||||
idCheckbox: 'auto_managed_toggle',
|
||||
labelCheckbox: 'Auto Managed:',
|
||||
nameRadio: 'auto_managed',
|
||||
labelRadio: {
|
||||
yes: 'Yes',
|
||||
no: 'No',
|
||||
},
|
||||
};
|
||||
|
||||
this.ownerFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Owner'),
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
//width: '85%',
|
||||
labelWidth: 1,
|
||||
items: [
|
||||
{
|
||||
xtype: 'combo',
|
||||
id: 'owner',
|
||||
hideLabel: true,
|
||||
width: 312,
|
||||
mode: 'local',
|
||||
valueField: 'displayText',
|
||||
displayField: 'displayText',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.bandwidthFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Bandwidth'),
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
//width: '85%',
|
||||
labelWidth: 1,
|
||||
defaults: {
|
||||
style: 'margin-bottom: 5px',
|
||||
},
|
||||
});
|
||||
this.bandwidthFset.add(this._getBandwidthContainer(maxDownload));
|
||||
this.bandwidthFset.add(this._getBandwidthContainer(maxUploadSpeed));
|
||||
this.bandwidthFset.add(this._getBandwidthContainer(maxConnections));
|
||||
this.bandwidthFset.add(this._getBandwidthContainer(maxUploadSlots));
|
||||
|
||||
this.queueFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Queue'),
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
//width: '85%',
|
||||
labelWidth: 1,
|
||||
defaults: {
|
||||
style: 'margin-bottom: 5px',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
this.queueFset.add(this._getQueueContainer(addPause));
|
||||
this.queueFset.add(this._getQueueContainer(queueTo));
|
||||
this.queueFset.add(this._getQueueContainer(autoManaged));
|
||||
this.queueFset.add({
|
||||
xtype: 'container',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'stop_at_ratio_toggle',
|
||||
boxLabel: _('Stop seed at ratio:'),
|
||||
hideLabel: true,
|
||||
width: 175,
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp('stop_ratio').setDisabled(
|
||||
!checked
|
||||
);
|
||||
Ext.getCmp('remove_at_ratio').setDisabled(
|
||||
!checked
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'spinnerfield',
|
||||
id: 'stop_ratio',
|
||||
hideLabel: true,
|
||||
disabled: true,
|
||||
value: 0.0,
|
||||
minValue: 0.0,
|
||||
maxValue: 100.0,
|
||||
decimalPrecision: 1,
|
||||
incrementValue: 0.1,
|
||||
style: 'margin-left: 2px',
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
style: 'margin-left: 10px',
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'remove_at_ratio',
|
||||
boxLabel: _('Remove at ratio'),
|
||||
disabled: true,
|
||||
checked: true,
|
||||
},
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'remove_at_ratio_toggle',
|
||||
disabled: true,
|
||||
checked: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'stop_ratio_toggle',
|
||||
disabled: true,
|
||||
checked: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
id: 'stop_ratio_toggle',
|
||||
disabled: true,
|
||||
checked: true,
|
||||
hidden: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
this.queueFset.add({
|
||||
xtype: 'checkbox',
|
||||
id: 'seed_mode',
|
||||
boxLabel: _('Skip File Hash Check'),
|
||||
hideLabel: true,
|
||||
width: 175,
|
||||
});
|
||||
|
||||
this.add([this.ownerFset, this.bandwidthFset, this.queueFset]);
|
||||
},
|
||||
|
||||
_getBandwidthContainer: function (values) {
|
||||
return new Ext.Container({
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
hideLabel: true,
|
||||
id: values.idCheckbox,
|
||||
boxLabel: _(values.labelCheckbox),
|
||||
width: 175,
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp(values.idSpinner).setDisabled(!checked);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'spinnerfield',
|
||||
id: values.idSpinner,
|
||||
hideLabel: true,
|
||||
disabled: true,
|
||||
minValue: -1,
|
||||
maxValue: 10000,
|
||||
value: 0.0,
|
||||
decimalPrecision: values.decimalPrecision,
|
||||
style: 'margin-left: 2px',
|
||||
width: 100,
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
_getQueueContainer: function (values) {
|
||||
return new Ext.Container({
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
hideLabel: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
hideLabel: true,
|
||||
id: values.idCheckbox,
|
||||
boxLabel: _(values.labelCheckbox),
|
||||
width: 175,
|
||||
listeners: {
|
||||
check: function (cb, checked) {
|
||||
Ext.getCmp(values.nameRadio).setDisabled(!checked);
|
||||
Ext.getCmp('not_' + values.nameRadio).setDisabled(
|
||||
!checked
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
xtype: 'radio',
|
||||
name: values.nameRadio,
|
||||
id: values.nameRadio,
|
||||
boxLabel: _(values.labelRadio.yes),
|
||||
hideLabel: true,
|
||||
checked: true,
|
||||
disabled: true,
|
||||
width: 50,
|
||||
},
|
||||
{
|
||||
xtype: 'radio',
|
||||
name: values.nameRadio,
|
||||
id: 'not_' + values.nameRadio,
|
||||
boxLabel: _(values.labelRadio.no),
|
||||
hideLabel: true,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
+635
@@ -0,0 +1,635 @@
|
||||
/**
|
||||
* label.js
|
||||
*
|
||||
* Copyright (C) Damien Churchill 2010 <damoxc@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.preferences');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.preferences.LabelPage
|
||||
* @extends Ext.Panel
|
||||
*/
|
||||
Deluge.ux.preferences.LabelPage = Ext.extend(Ext.Panel, {
|
||||
title: _('Label'),
|
||||
layout: 'fit',
|
||||
border: false,
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.preferences.LabelPage.superclass.initComponent.call(this);
|
||||
fieldset = this.add({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Label Preferences'),
|
||||
autoHeight: true,
|
||||
labelWidth: 1,
|
||||
defaultType: 'panel',
|
||||
});
|
||||
fieldset.add({
|
||||
border: false,
|
||||
bodyCfg: {
|
||||
html: _(
|
||||
'<p>The Label plugin is enabled.</p><br>' +
|
||||
'<p>To add, remove or edit labels right-click on the Label filter ' +
|
||||
'entry in the sidebar.</p><br>' +
|
||||
'<p>To apply a label right-click on torrent(s).<p>'
|
||||
),
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Ext.ns('Deluge.ux');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.AddLabelWindow
|
||||
* @extends Ext.Window
|
||||
*/
|
||||
Deluge.ux.AddLabelWindow = Ext.extend(Ext.Window, {
|
||||
title: _('Add Label'),
|
||||
width: 300,
|
||||
height: 100,
|
||||
closeAction: 'hide',
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.AddLabelWindow.superclass.initComponent.call(this);
|
||||
this.addButton(_('Cancel'), this.onCancelClick, this);
|
||||
this.addButton(_('Ok'), this.onOkClick, this);
|
||||
|
||||
this.form = this.add({
|
||||
xtype: 'form',
|
||||
height: 35,
|
||||
baseCls: 'x-plain',
|
||||
bodyStyle: 'padding:5px 5px 0',
|
||||
defaultType: 'textfield',
|
||||
labelWidth: 50,
|
||||
items: [
|
||||
{
|
||||
fieldLabel: _('Name'),
|
||||
name: 'name',
|
||||
allowBlank: false,
|
||||
width: 220,
|
||||
listeners: {
|
||||
specialkey: {
|
||||
fn: function (field, e) {
|
||||
if (e.getKey() == 13) this.onOkClick();
|
||||
},
|
||||
scope: this,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
onCancelClick: function () {
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onOkClick: function () {
|
||||
var label = this.form.getForm().getValues().name;
|
||||
deluge.client.label.add(label, {
|
||||
success: function () {
|
||||
deluge.ui.update();
|
||||
this.fireEvent('labeladded', label);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onHide: function (comp) {
|
||||
Deluge.ux.AddLabelWindow.superclass.onHide.call(this, comp);
|
||||
this.form.getForm().reset();
|
||||
},
|
||||
|
||||
onShow: function (comp) {
|
||||
Deluge.ux.AddLabelWindow.superclass.onShow.call(this, comp);
|
||||
this.form.getForm().findField('name').focus(false, 150);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.LabelOptionsWindow
|
||||
* @extends Ext.Window
|
||||
*/
|
||||
Deluge.ux.LabelOptionsWindow = Ext.extend(Ext.Window, {
|
||||
title: _('Label Options'),
|
||||
width: 325,
|
||||
height: 240,
|
||||
closeAction: 'hide',
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.LabelOptionsWindow.superclass.initComponent.call(this);
|
||||
this.addButton(_('Cancel'), this.onCancelClick, this);
|
||||
this.addButton(_('Ok'), this.onOkClick, this);
|
||||
|
||||
this.form = this.add({
|
||||
xtype: 'form',
|
||||
});
|
||||
|
||||
this.tabs = this.form.add({
|
||||
xtype: 'tabpanel',
|
||||
height: 175,
|
||||
border: false,
|
||||
items: [
|
||||
{
|
||||
title: _('Maximum'),
|
||||
items: [
|
||||
{
|
||||
border: false,
|
||||
items: [
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
name: 'apply_max',
|
||||
fieldLabel: '',
|
||||
boxLabel: _(
|
||||
'Apply per torrent max settings:'
|
||||
),
|
||||
listeners: {
|
||||
check: this.onFieldChecked,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
defaultType: 'spinnerfield',
|
||||
style: 'margin-top: 0px; padding-top: 0px;',
|
||||
items: [
|
||||
{
|
||||
fieldLabel: _('Download Speed'),
|
||||
name: 'max_download_speed',
|
||||
width: 80,
|
||||
disabled: true,
|
||||
value: -1,
|
||||
minValue: -1,
|
||||
},
|
||||
{
|
||||
fieldLabel: _('Upload Speed'),
|
||||
name: 'max_upload_speed',
|
||||
width: 80,
|
||||
disabled: true,
|
||||
value: -1,
|
||||
minValue: -1,
|
||||
},
|
||||
{
|
||||
fieldLabel: _('Upload Slots'),
|
||||
name: 'max_upload_slots',
|
||||
width: 80,
|
||||
disabled: true,
|
||||
value: -1,
|
||||
minValue: -1,
|
||||
},
|
||||
{
|
||||
fieldLabel: _('Connections'),
|
||||
name: 'max_connections',
|
||||
width: 80,
|
||||
disabled: true,
|
||||
value: -1,
|
||||
minValue: -1,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: _('Queue'),
|
||||
items: [
|
||||
{
|
||||
border: false,
|
||||
items: [
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
name: 'apply_queue',
|
||||
fieldLabel: '',
|
||||
boxLabel: _(
|
||||
'Apply queue settings:'
|
||||
),
|
||||
listeners: {
|
||||
check: this.onFieldChecked,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
defaultType: 'checkbox',
|
||||
style: 'margin-top: 0px; padding-top: 0px;',
|
||||
defaults: {
|
||||
style: 'margin-left: 20px',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
boxLabel: _('Auto Managed'),
|
||||
name: 'is_auto_managed',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
boxLabel: _('Stop seed at ratio:'),
|
||||
name: 'stop_at_ratio',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
xtype: 'spinnerfield',
|
||||
name: 'stop_ratio',
|
||||
width: 60,
|
||||
decimalPrecision: 2,
|
||||
incrementValue: 0.1,
|
||||
style: 'position: relative; left: 100px',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
boxLabel: _('Remove at ratio'),
|
||||
name: 'remove_at_ratio',
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: _('Folders'),
|
||||
items: [
|
||||
{
|
||||
border: false,
|
||||
items: [
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
name: 'apply_move_completed',
|
||||
fieldLabel: '',
|
||||
boxLabel: _(
|
||||
'Apply folder settings:'
|
||||
),
|
||||
listeners: {
|
||||
check: this.onFieldChecked,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
defaultType: 'checkbox',
|
||||
labelWidth: 1,
|
||||
style: 'margin-top: 0px; padding-top: 0px;',
|
||||
defaults: {
|
||||
style: 'margin-left: 20px',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
boxLabel: _('Move completed to:'),
|
||||
name: 'move_completed',
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
name: 'move_completed_path',
|
||||
width: 250,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: _('Trackers'),
|
||||
items: [
|
||||
{
|
||||
border: false,
|
||||
items: [
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||
items: [
|
||||
{
|
||||
xtype: 'checkbox',
|
||||
name: 'auto_add',
|
||||
fieldLabel: '',
|
||||
boxLabel: _(
|
||||
'Automatically apply label:'
|
||||
),
|
||||
listeners: {
|
||||
check: this.onFieldChecked,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
labelWidth: 1,
|
||||
style: 'margin-top: 0px; padding-top: 0px;',
|
||||
defaults: {
|
||||
style: 'margin-left: 20px',
|
||||
},
|
||||
defaultType: 'textarea',
|
||||
items: [
|
||||
{
|
||||
boxLabel: _('Move completed to:'),
|
||||
name: 'auto_add_trackers',
|
||||
width: 250,
|
||||
height: 100,
|
||||
disabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
getLabelOptions: function () {
|
||||
deluge.client.label.get_options(this.label, {
|
||||
success: this.gotOptions,
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
|
||||
gotOptions: function (options) {
|
||||
this.form.getForm().setValues(options);
|
||||
},
|
||||
|
||||
show: function (label) {
|
||||
Deluge.ux.LabelOptionsWindow.superclass.show.call(this);
|
||||
this.label = label;
|
||||
this.setTitle(_('Label Options') + ': ' + this.label);
|
||||
this.tabs.setActiveTab(0);
|
||||
this.getLabelOptions();
|
||||
},
|
||||
|
||||
onCancelClick: function () {
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onOkClick: function () {
|
||||
var values = this.form.getForm().getFieldValues();
|
||||
if (values['auto_add_trackers']) {
|
||||
values['auto_add_trackers'] =
|
||||
values['auto_add_trackers'].split('\n');
|
||||
}
|
||||
deluge.client.label.set_options(this.label, values);
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onFieldChecked: function (field, checked) {
|
||||
var fs = field.ownerCt.nextSibling();
|
||||
fs.items.each(function (field) {
|
||||
field.setDisabled(!checked);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Ext.ns('Deluge.plugins');
|
||||
|
||||
/**
|
||||
* @class Deluge.plugins.LabelPlugin
|
||||
* @extends Deluge.Plugin
|
||||
*/
|
||||
Deluge.plugins.LabelPlugin = Ext.extend(Deluge.Plugin, {
|
||||
name: 'Label',
|
||||
|
||||
createMenu: function () {
|
||||
this.labelMenu = new Ext.menu.Menu({
|
||||
items: [
|
||||
{
|
||||
text: _('Add Label'),
|
||||
iconCls: 'icon-add',
|
||||
handler: this.onLabelAddClick,
|
||||
scope: this,
|
||||
},
|
||||
{
|
||||
text: _('Remove Label'),
|
||||
disabled: true,
|
||||
iconCls: 'icon-remove',
|
||||
handler: this.onLabelRemoveClick,
|
||||
scope: this,
|
||||
},
|
||||
{
|
||||
text: _('Label Options'),
|
||||
disabled: true,
|
||||
handler: this.onLabelOptionsClick,
|
||||
scope: this,
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
|
||||
setFilter: function (filter) {
|
||||
filter.show_zero = true;
|
||||
|
||||
filter.list.on('contextmenu', this.onLabelContextMenu, this);
|
||||
filter.header.on('contextmenu', this.onLabelHeaderContextMenu, this);
|
||||
this.filter = filter;
|
||||
},
|
||||
|
||||
updateTorrentMenu: function (states) {
|
||||
this.torrentMenu.removeAll(true);
|
||||
this.torrentMenu.addMenuItem({
|
||||
text: _('No Label'),
|
||||
label: '',
|
||||
handler: this.onTorrentMenuClick,
|
||||
scope: this,
|
||||
});
|
||||
for (var state in states) {
|
||||
if (!state || state == 'All') continue;
|
||||
this.torrentMenu.addMenuItem({
|
||||
text: state,
|
||||
label: state,
|
||||
handler: this.onTorrentMenuClick,
|
||||
scope: this,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onDisable: function () {
|
||||
deluge.sidebar.un('filtercreate', this.onFilterCreate);
|
||||
deluge.sidebar.un('afterfiltercreate', this.onAfterFilterCreate);
|
||||
delete Deluge.FilterPanel.templates.label;
|
||||
this.deregisterTorrentStatus('label');
|
||||
deluge.menus.torrent.remove(this.tmSep);
|
||||
deluge.menus.torrent.remove(this.tm);
|
||||
deluge.preferences.removePage(this.prefsPage);
|
||||
},
|
||||
|
||||
onEnable: function () {
|
||||
this.prefsPage = deluge.preferences.addPage(
|
||||
new Deluge.ux.preferences.LabelPage()
|
||||
);
|
||||
this.torrentMenu = new Ext.menu.Menu();
|
||||
|
||||
this.tmSep = deluge.menus.torrent.add({
|
||||
xtype: 'menuseparator',
|
||||
});
|
||||
|
||||
this.tm = deluge.menus.torrent.add({
|
||||
text: _('Label'),
|
||||
menu: this.torrentMenu,
|
||||
});
|
||||
|
||||
var lbltpl =
|
||||
'<div class="x-deluge-filter">' +
|
||||
'<tpl if="filter">{filter}</tpl>' +
|
||||
'<tpl if="!filter">No Label</tpl>' +
|
||||
' ({count})' +
|
||||
'</div>';
|
||||
|
||||
if (deluge.sidebar.hasFilter('label')) {
|
||||
var filter = deluge.sidebar.getFilter('label');
|
||||
filter.list.columns[0].tpl = new Ext.XTemplate(lbltpl);
|
||||
this.setFilter(filter);
|
||||
this.updateTorrentMenu(filter.getStates());
|
||||
filter.list.refresh();
|
||||
} else {
|
||||
deluge.sidebar.on('filtercreate', this.onFilterCreate, this);
|
||||
deluge.sidebar.on(
|
||||
'afterfiltercreate',
|
||||
this.onAfterFilterCreate,
|
||||
this
|
||||
);
|
||||
Deluge.FilterPanel.templates.label = lbltpl;
|
||||
}
|
||||
this.registerTorrentStatus('label', _('Label'));
|
||||
},
|
||||
|
||||
onAfterFilterCreate: function (sidebar, filter) {
|
||||
if (filter.filter != 'label') return;
|
||||
this.updateTorrentMenu(filter.getStates());
|
||||
},
|
||||
|
||||
onFilterCreate: function (sidebar, filter) {
|
||||
if (filter.filter != 'label') return;
|
||||
this.setFilter(filter);
|
||||
},
|
||||
|
||||
onLabelAddClick: function () {
|
||||
if (!this.addWindow) {
|
||||
this.addWindow = new Deluge.ux.AddLabelWindow();
|
||||
this.addWindow.on('labeladded', this.onLabelAdded, this);
|
||||
}
|
||||
this.addWindow.show();
|
||||
},
|
||||
|
||||
onLabelAdded: function (label) {
|
||||
var filter = deluge.sidebar.getFilter('label');
|
||||
var states = filter.getStates();
|
||||
var statesArray = [];
|
||||
|
||||
for (state in states) {
|
||||
if (!state || state == 'All') continue;
|
||||
statesArray.push(state);
|
||||
}
|
||||
|
||||
statesArray.push(label.toLowerCase());
|
||||
statesArray.sort();
|
||||
|
||||
//console.log(states);
|
||||
//console.log(statesArray);
|
||||
|
||||
states = {};
|
||||
|
||||
for (i = 0; i < statesArray.length; ++i) {
|
||||
states[statesArray[i]] = 0;
|
||||
}
|
||||
|
||||
this.updateTorrentMenu(states);
|
||||
},
|
||||
|
||||
onLabelContextMenu: function (dv, i, node, e) {
|
||||
e.preventDefault();
|
||||
if (!this.labelMenu) this.createMenu();
|
||||
var r = dv.getRecord(node).get('filter');
|
||||
if (!r || r == 'All') {
|
||||
this.labelMenu.items.get(1).setDisabled(true);
|
||||
this.labelMenu.items.get(2).setDisabled(true);
|
||||
} else {
|
||||
this.labelMenu.items.get(1).setDisabled(false);
|
||||
this.labelMenu.items.get(2).setDisabled(false);
|
||||
}
|
||||
dv.select(i);
|
||||
this.labelMenu.showAt(e.getXY());
|
||||
},
|
||||
|
||||
onLabelHeaderContextMenu: function (e, t) {
|
||||
e.preventDefault();
|
||||
if (!this.labelMenu) this.createMenu();
|
||||
this.labelMenu.items.get(1).setDisabled(true);
|
||||
this.labelMenu.items.get(2).setDisabled(true);
|
||||
this.labelMenu.showAt(e.getXY());
|
||||
},
|
||||
|
||||
onLabelOptionsClick: function () {
|
||||
if (!this.labelOpts)
|
||||
this.labelOpts = new Deluge.ux.LabelOptionsWindow();
|
||||
this.labelOpts.show(this.filter.getState());
|
||||
},
|
||||
|
||||
onLabelRemoveClick: function () {
|
||||
var state = this.filter.getState();
|
||||
deluge.client.label.remove(state, {
|
||||
success: function () {
|
||||
deluge.ui.update();
|
||||
this.torrentMenu.items.each(function (item) {
|
||||
if (item.text != state) return;
|
||||
this.torrentMenu.remove(item);
|
||||
var i = item;
|
||||
}, this);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
|
||||
onTorrentMenuClick: function (item, e) {
|
||||
var ids = deluge.torrents.getSelectedIds();
|
||||
Ext.each(ids, function (id, i) {
|
||||
if (ids.length == i + 1) {
|
||||
deluge.client.label.set_torrent(id, item.label, {
|
||||
success: function () {
|
||||
deluge.ui.update();
|
||||
},
|
||||
});
|
||||
} else {
|
||||
deluge.client.label.set_torrent(id, item.label);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
Deluge.registerPlugin('Label', Deluge.plugins.LabelPlugin);
|
||||
+522
@@ -0,0 +1,522 @@
|
||||
/**
|
||||
* notifications.js
|
||||
*
|
||||
* Copyright (c) Omar Alvarez 2014 <omar.alvarez@udc.es>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux.preferences');
|
||||
|
||||
/**
|
||||
* @class Deluge.ux.preferences.NotificationsPage
|
||||
* @extends Ext.Panel
|
||||
*/
|
||||
Deluge.ux.preferences.NotificationsPage = Ext.extend(Ext.Panel, {
|
||||
title: _('Notifications'),
|
||||
header: false,
|
||||
layout: 'fit',
|
||||
border: false,
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.preferences.NotificationsPage.superclass.initComponent.call(
|
||||
this
|
||||
);
|
||||
|
||||
this.emailNotiFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Email Notifications'),
|
||||
autoHeight: true,
|
||||
defaultType: 'textfield',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
width: '85%',
|
||||
labelWidth: 1,
|
||||
});
|
||||
|
||||
this.chkEnableEmail = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'enable_email',
|
||||
xtype: 'checkbox',
|
||||
boxLabel: _('Enabled'),
|
||||
listeners: {
|
||||
check: function (object, checked) {
|
||||
this.setSmtpDisabled(!checked);
|
||||
},
|
||||
scope: this,
|
||||
},
|
||||
});
|
||||
|
||||
this.hBoxHost = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'host',
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
disabled: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'label',
|
||||
text: _('Hostname:'),
|
||||
margins: '6 0 0 6',
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
margins: '2 0 0 4',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.hBoxPort = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'port',
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
disabled: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'label',
|
||||
text: _('Port:'),
|
||||
margins: '6 0 0 6',
|
||||
},
|
||||
{
|
||||
xtype: 'spinnerfield',
|
||||
margins: '2 0 0 34',
|
||||
width: 64,
|
||||
decimalPrecision: 0,
|
||||
minValue: 0,
|
||||
maxValue: 65535,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.hBoxUser = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'username',
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
disabled: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'label',
|
||||
text: _('Username:'),
|
||||
margins: '6 0 0 6',
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
margins: '2 0 0 3',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.hBoxPassword = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'password',
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
disabled: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'label',
|
||||
text: _('Password:'),
|
||||
margins: '6 0 0 6',
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
inputType: 'password',
|
||||
margins: '2 0 0 5',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.hBoxFrom = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'from',
|
||||
xtype: 'container',
|
||||
layout: 'hbox',
|
||||
disabled: true,
|
||||
items: [
|
||||
{
|
||||
xtype: 'label',
|
||||
text: _('From:'),
|
||||
margins: '6 0 0 6',
|
||||
},
|
||||
{
|
||||
xtype: 'textfield',
|
||||
margins: '2 0 0 28',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.chkTLS = this.emailNotiFset.add({
|
||||
fieldLabel: '',
|
||||
labelSeparator: '',
|
||||
name: 'enable_tls_ssl',
|
||||
xtype: 'checkbox',
|
||||
disabled: true,
|
||||
boxLabel: _('Server requires TLS/SSL'),
|
||||
});
|
||||
|
||||
this.recipientsFset = new Ext.form.FieldSet({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Recipients'),
|
||||
autoHeight: true,
|
||||
defaultType: 'editorgrid',
|
||||
style: 'margin-top: 3px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
autoWidth: true,
|
||||
items: [
|
||||
{
|
||||
fieldLabel: '',
|
||||
name: 'recipients',
|
||||
margins: '2 0 5 5',
|
||||
height: 130,
|
||||
hideHeaders: true,
|
||||
width: 260,
|
||||
disabled: true,
|
||||
autoExpandColumn: 'recipient',
|
||||
bbar: {
|
||||
items: [
|
||||
{
|
||||
text: _('Add'),
|
||||
iconCls: 'icon-add',
|
||||
handler: this.onAddClick,
|
||||
scope: this,
|
||||
},
|
||||
{
|
||||
text: _('Remove'),
|
||||
iconCls: 'icon-remove',
|
||||
handler: this.onRemoveClick,
|
||||
scope: this,
|
||||
},
|
||||
],
|
||||
},
|
||||
viewConfig: {
|
||||
emptyText: _('Add an recipient...'),
|
||||
deferEmptyText: false,
|
||||
},
|
||||
colModel: new Ext.grid.ColumnModel({
|
||||
columns: [
|
||||
{
|
||||
id: 'recipient',
|
||||
header: _('Recipient'),
|
||||
dataIndex: 'recipient',
|
||||
sortable: true,
|
||||
hideable: false,
|
||||
editable: true,
|
||||
editor: {
|
||||
xtype: 'textfield',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
selModel: new Ext.grid.RowSelectionModel({
|
||||
singleSelect: false,
|
||||
moveEditorOnEnter: false,
|
||||
}),
|
||||
store: new Ext.data.ArrayStore({
|
||||
autoDestroy: true,
|
||||
fields: [{ name: 'recipient' }],
|
||||
}),
|
||||
listeners: {
|
||||
afteredit: function (e) {
|
||||
e.record.commit();
|
||||
},
|
||||
},
|
||||
setEmptyText: function (text) {
|
||||
if (this.viewReady) {
|
||||
this.getView().emptyText = text;
|
||||
this.getView().refresh();
|
||||
} else {
|
||||
Ext.apply(this.viewConfig, { emptyText: text });
|
||||
}
|
||||
},
|
||||
loadData: function (data) {
|
||||
this.getStore().loadData(data);
|
||||
if (this.viewReady) {
|
||||
this.getView().updateHeaders();
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.edGridSubs = new Ext.grid.EditorGridPanel({
|
||||
xtype: 'editorgrid',
|
||||
autoHeight: true,
|
||||
autoExpandColumn: 'event',
|
||||
viewConfig: {
|
||||
emptyText: _('Loading events...'),
|
||||
deferEmptyText: false,
|
||||
},
|
||||
colModel: new Ext.grid.ColumnModel({
|
||||
defaults: {
|
||||
renderer: function (
|
||||
value,
|
||||
meta,
|
||||
record,
|
||||
rowIndex,
|
||||
colIndex,
|
||||
store
|
||||
) {
|
||||
if (Ext.isNumber(value) && parseInt(value) !== value) {
|
||||
return value.toFixed(6);
|
||||
} else if (Ext.isBoolean(value)) {
|
||||
return (
|
||||
'<div class="x-grid3-check-col' +
|
||||
(value ? '-on' : '') +
|
||||
'" style="width: 20px;"> </div>'
|
||||
);
|
||||
}
|
||||
return value;
|
||||
},
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
id: 'event',
|
||||
header: 'Event',
|
||||
dataIndex: 'event',
|
||||
sortable: true,
|
||||
hideable: false,
|
||||
},
|
||||
{
|
||||
id: 'email',
|
||||
header: _('Email'),
|
||||
dataIndex: 'email',
|
||||
sortable: true,
|
||||
hideable: false,
|
||||
menuDisabled: true,
|
||||
width: 40,
|
||||
},
|
||||
],
|
||||
}),
|
||||
store: new Ext.data.ArrayStore({
|
||||
autoDestroy: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'event',
|
||||
},
|
||||
{
|
||||
name: 'email',
|
||||
},
|
||||
],
|
||||
}),
|
||||
listeners: {
|
||||
cellclick: function (grid, rowIndex, colIndex, e) {
|
||||
var record = grid.getStore().getAt(rowIndex);
|
||||
var field = grid.getColumnModel().getDataIndex(colIndex);
|
||||
var value = record.get(field);
|
||||
|
||||
if (colIndex == 1) {
|
||||
if (Ext.isBoolean(value)) {
|
||||
record.set(field, !value);
|
||||
record.commit();
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeedit: function (e) {
|
||||
if (Ext.isBoolean(e.value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return e.record.get('enabled');
|
||||
},
|
||||
afteredit: function (e) {
|
||||
e.record.commit();
|
||||
},
|
||||
},
|
||||
setEmptyText: function (text) {
|
||||
if (this.viewReady) {
|
||||
this.getView().emptyText = text;
|
||||
this.getView().refresh();
|
||||
} else {
|
||||
Ext.apply(this.viewConfig, { emptyText: text });
|
||||
}
|
||||
},
|
||||
setSub: function (eventName) {
|
||||
var store = this.getStore();
|
||||
var index = store.find('event', eventName);
|
||||
store.getAt(index).set('email', true);
|
||||
store.getAt(index).commit();
|
||||
},
|
||||
loadData: function (data) {
|
||||
this.getStore().loadData(data);
|
||||
if (this.viewReady) {
|
||||
this.getView().updateHeaders();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
this.tabPanSettings = this.add({
|
||||
xtype: 'tabpanel',
|
||||
activeTab: 0,
|
||||
items: [
|
||||
{
|
||||
title: _('Settings'),
|
||||
items: [this.emailNotiFset, this.recipientsFset],
|
||||
autoScroll: true,
|
||||
},
|
||||
{
|
||||
title: _('Subscriptions'),
|
||||
items: this.edGridSubs,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.on('show', this.updateConfig, this);
|
||||
},
|
||||
|
||||
updateConfig: function () {
|
||||
deluge.client.notifications.get_handled_events({
|
||||
success: function (events) {
|
||||
var data = [];
|
||||
var keys = Ext.keys(events);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
data.push([events[key][0], false]);
|
||||
}
|
||||
this.edGridSubs.loadData(data);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
deluge.client.notifications.get_config({
|
||||
success: function (config) {
|
||||
this.chkEnableEmail.setValue(config['smtp_enabled']);
|
||||
this.setSmtpDisabled(!config['smtp_enabled']);
|
||||
|
||||
this.hBoxHost.getComponent(1).setValue(config['smtp_host']);
|
||||
this.hBoxPort.getComponent(1).setValue(config['smtp_port']);
|
||||
this.hBoxUser.getComponent(1).setValue(config['smtp_user']);
|
||||
this.hBoxPassword.getComponent(1).setValue(config['smtp_pass']);
|
||||
this.hBoxFrom.getComponent(1).setValue(config['smtp_from']);
|
||||
this.chkTLS.setValue(config['smtp_tls']);
|
||||
|
||||
var data = [];
|
||||
var keys = Ext.keys(config['smtp_recipients']);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
data.push([config['smtp_recipients'][key]]);
|
||||
}
|
||||
this.recipientsFset.getComponent(0).loadData(data);
|
||||
|
||||
data = [];
|
||||
keys = Ext.keys(config['subscriptions']['email']);
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
this.edGridSubs.setSub(
|
||||
config['subscriptions']['email'][key]
|
||||
);
|
||||
}
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
|
||||
onApply: function () {
|
||||
var config = {};
|
||||
|
||||
config['smtp_enabled'] = this.chkEnableEmail.getValue();
|
||||
config['smtp_host'] = this.hBoxHost.getComponent(1).getValue();
|
||||
config['smtp_port'] = Number(this.hBoxPort.getComponent(1).getValue());
|
||||
config['smtp_user'] = this.hBoxUser.getComponent(1).getValue();
|
||||
config['smtp_pass'] = this.hBoxPassword.getComponent(1).getValue();
|
||||
config['smtp_from'] = this.hBoxFrom.getComponent(1).getValue();
|
||||
config['smtp_tls'] = this.chkTLS.getValue();
|
||||
|
||||
var recipientsList = [];
|
||||
var store = this.recipientsFset.getComponent(0).getStore();
|
||||
|
||||
for (var i = 0; i < store.getCount(); i++) {
|
||||
var record = store.getAt(i);
|
||||
var recipient = record.get('recipient');
|
||||
recipientsList.push(recipient);
|
||||
}
|
||||
|
||||
config['smtp_recipients'] = recipientsList;
|
||||
|
||||
var subscriptions = {};
|
||||
var eventList = [];
|
||||
store = this.edGridSubs.getStore();
|
||||
|
||||
for (var i = 0; i < store.getCount(); i++) {
|
||||
var record = store.getAt(i);
|
||||
var ev = record.get('event');
|
||||
var email = record.get('email');
|
||||
if (email) {
|
||||
eventList.push(ev);
|
||||
}
|
||||
}
|
||||
|
||||
subscriptions['email'] = eventList;
|
||||
config['subscriptions'] = subscriptions;
|
||||
|
||||
deluge.client.notifications.set_config(config);
|
||||
},
|
||||
|
||||
onOk: function () {
|
||||
this.onApply();
|
||||
},
|
||||
|
||||
onAddClick: function () {
|
||||
var store = this.recipientsFset.getComponent(0).getStore();
|
||||
var Recipient = store.recordType;
|
||||
var i = new Recipient({
|
||||
recipient: '',
|
||||
});
|
||||
this.recipientsFset.getComponent(0).stopEditing();
|
||||
store.insert(0, i);
|
||||
this.recipientsFset.getComponent(0).startEditing(0, 0);
|
||||
},
|
||||
|
||||
onRemoveClick: function () {
|
||||
var selections = this.recipientsFset
|
||||
.getComponent(0)
|
||||
.getSelectionModel()
|
||||
.getSelections();
|
||||
var store = this.recipientsFset.getComponent(0).getStore();
|
||||
|
||||
this.recipientsFset.getComponent(0).stopEditing();
|
||||
for (var i = 0; i < selections.length; i++) store.remove(selections[i]);
|
||||
store.commitChanges();
|
||||
},
|
||||
|
||||
setSmtpDisabled: function (disable) {
|
||||
this.hBoxHost.setDisabled(disable);
|
||||
this.hBoxPort.setDisabled(disable);
|
||||
this.hBoxUser.setDisabled(disable);
|
||||
this.hBoxPassword.setDisabled(disable);
|
||||
this.hBoxFrom.setDisabled(disable);
|
||||
this.chkTLS.setDisabled(disable);
|
||||
this.recipientsFset.getComponent(0).setDisabled(disable);
|
||||
},
|
||||
|
||||
onDestroy: function () {
|
||||
deluge.preferences.un('show', this.updateConfig, this);
|
||||
|
||||
Deluge.ux.preferences.NotificationsPage.superclass.onDestroy.call(this);
|
||||
},
|
||||
});
|
||||
|
||||
Deluge.plugins.NotificationsPlugin = Ext.extend(Deluge.Plugin, {
|
||||
name: 'Notifications',
|
||||
|
||||
onDisable: function () {
|
||||
deluge.preferences.removePage(this.prefsPage);
|
||||
},
|
||||
|
||||
onEnable: function () {
|
||||
this.prefsPage = deluge.preferences.addPage(
|
||||
new Deluge.ux.preferences.NotificationsPage()
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
Deluge.registerPlugin('Notifications', Deluge.plugins.NotificationsPlugin);
|
||||
Executable
+621
@@ -0,0 +1,621 @@
|
||||
/**
|
||||
* scheduler.js
|
||||
* The client-side javascript code for the Scheduler plugin.
|
||||
*
|
||||
* Copyright (C) samuel337 2011
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
Ext.ns('Deluge.ux');
|
||||
|
||||
Deluge.ux.ScheduleSelector = Ext.extend(Ext.form.FieldSet, {
|
||||
title: _('Schedule'),
|
||||
autoHeight: true,
|
||||
style: 'margin-bottom: 0px; padding-bottom: 0px;',
|
||||
border: false,
|
||||
|
||||
states: [
|
||||
{
|
||||
name: 'Normal',
|
||||
backgroundColor: 'LightGreen',
|
||||
borderColor: 'DarkGreen',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: 'Throttled',
|
||||
backgroundColor: 'Yellow',
|
||||
borderColor: 'Gold',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
name: 'Paused',
|
||||
backgroundColor: 'OrangeRed',
|
||||
borderColor: 'FireBrick',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
daysOfWeek: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.ScheduleSelector.superclass.initComponent.call(this);
|
||||
|
||||
// ExtJS' radiogroup implementation is very broken for styling.
|
||||
/*this.stateBrush = this.add({
|
||||
xtype: 'radiogroup',
|
||||
fieldLabel: _('State Brush'),
|
||||
name: 'current_state_brush',
|
||||
submitValue: false,
|
||||
items: [
|
||||
{ boxLabel: 'Normal', name: 'current_state_brush', inputValue: 0 },
|
||||
{ boxLabel: 'Throttled', name: 'current_state_brush', inputValue: 1, checked: true },
|
||||
{ boxLabel: 'Paused', name: 'current_state_brush', inputValue: 2 },
|
||||
]
|
||||
});*/
|
||||
},
|
||||
|
||||
onRender: function (ct, position) {
|
||||
Deluge.ux.ScheduleSelector.superclass.onRender.call(this, ct, position);
|
||||
|
||||
var dom = this.body.dom;
|
||||
|
||||
function createEl(parent, type) {
|
||||
var el = document.createElement(type);
|
||||
parent.appendChild(el);
|
||||
return el;
|
||||
}
|
||||
|
||||
// create state brushes
|
||||
// tack a random number to the end to avoid clashes
|
||||
this.stateBrushName =
|
||||
'schedule-state-brush-' + Math.round(Math.random() * 10000);
|
||||
|
||||
var el1 = createEl(dom, 'div');
|
||||
|
||||
var el2 = createEl(el1, 'div');
|
||||
this.stateBrush = el2;
|
||||
el2.id = this.stateBrushName;
|
||||
|
||||
// for webkit
|
||||
var floatAttr = 'float';
|
||||
if (el2.style.float == undefined) {
|
||||
// for firefox
|
||||
if (el2.style.cssFloat != undefined) floatAttr = 'cssFloat';
|
||||
// for IE
|
||||
if (el2.style.styleFloat != undefined) floatAttr = 'styleFloat';
|
||||
}
|
||||
el2.style[floatAttr] = 'right';
|
||||
|
||||
for (var i = 0; i < this.states.length; i++) {
|
||||
var el3 = createEl(el2, 'input');
|
||||
el3.type = 'radio';
|
||||
el3.value = this.states[i].value;
|
||||
el3.name = this.stateBrushName;
|
||||
el3.id = this.stateBrushName + '-' + this.states[i].name;
|
||||
|
||||
// isn't the first one
|
||||
if (i > 0) el3.style.marginLeft = '7px';
|
||||
|
||||
// assume the first is the default state, so make the 2nd one the default brush
|
||||
if (i == 1) el3.checked = true;
|
||||
|
||||
var el4 = createEl(el2, 'label');
|
||||
el4.appendChild(document.createTextNode(this.states[i].name));
|
||||
el4.htmlFor = el3.id;
|
||||
el4.style.backgroundColor = this.states[i].backgroundColor;
|
||||
el4.style.borderBottom = '2px solid ' + this.states[i].borderColor;
|
||||
el4.style.padding = '2px 3px';
|
||||
el4.style.marginLeft = '3px';
|
||||
}
|
||||
|
||||
el1.appendChild(document.createTextNode('Select a state brush:'));
|
||||
|
||||
el1.style.marginBottom = '10px';
|
||||
|
||||
// keep the radio buttons separate from the time bars
|
||||
createEl(dom, 'div').style.clear = 'both';
|
||||
|
||||
var table = createEl(dom, 'table');
|
||||
table.cellSpacing = 0;
|
||||
|
||||
// cache access to cells for easier access later
|
||||
this.scheduleCells = {};
|
||||
|
||||
Ext.each(
|
||||
this.daysOfWeek,
|
||||
function (day) {
|
||||
var cells = [];
|
||||
var row = createEl(table, 'tr');
|
||||
var label = createEl(row, 'th');
|
||||
label.setAttribute(
|
||||
'style',
|
||||
'font-weight: bold; padding-right: 5px;'
|
||||
);
|
||||
label.appendChild(document.createTextNode(day));
|
||||
for (var hour = 0; hour < 24; hour++) {
|
||||
var cell = createEl(row, 'td');
|
||||
|
||||
// assume the first state is the default state
|
||||
cell.currentValue = cell.oldValue = this.states[0].value;
|
||||
cell.day = day;
|
||||
cell.hour = hour;
|
||||
|
||||
cell.width = '16px';
|
||||
cell.height = '20px';
|
||||
|
||||
cell.style.border = '1px solid #999999';
|
||||
// don't repeat borders in between cells
|
||||
if (hour != 23)
|
||||
// not the last cell
|
||||
cell.style.borderRight = 'none';
|
||||
|
||||
this.updateCell(cell);
|
||||
|
||||
cells.push(cell);
|
||||
|
||||
cell = Ext.get(cell);
|
||||
cell.on('click', this.onCellClick, this);
|
||||
cell.on('mouseover', this.onCellMouseOver, this);
|
||||
cell.on('mouseout', this.onCellMouseOut, this);
|
||||
cell.on('mousedown', this.onCellMouseDown, this);
|
||||
cell.on('mouseup', this.onCellMouseUp, this);
|
||||
}
|
||||
|
||||
// insert gap row to provide visual separation
|
||||
row = createEl(table, 'tr');
|
||||
// blank cell to create gap
|
||||
createEl(row, 'td').height = '3px';
|
||||
|
||||
this.scheduleCells[day] = cells;
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
updateCell: function (cell) {
|
||||
// sanity check
|
||||
if (cell.currentValue == undefined) return;
|
||||
|
||||
for (var i in this.states) {
|
||||
var curState = this.states[i];
|
||||
if (curState.value == cell.currentValue) {
|
||||
cell.style.background = curState.backgroundColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getCurrentBrushValue: function () {
|
||||
var v = null;
|
||||
var brushes = Ext.get(this.body.dom).findParent('form').elements[
|
||||
this.stateBrushName
|
||||
];
|
||||
Ext.each(brushes, function (b) {
|
||||
if (b.checked) v = b.value;
|
||||
});
|
||||
|
||||
return v;
|
||||
},
|
||||
|
||||
onCellClick: function (event, cell) {
|
||||
cell.oldValue = cell.currentValue;
|
||||
|
||||
this.dragAnchor = null;
|
||||
},
|
||||
|
||||
onCellMouseDown: function (event, cell) {
|
||||
this.dragAnchor = cell;
|
||||
},
|
||||
|
||||
onCellMouseUp: function (event, cell) {
|
||||
// if we're dragging...
|
||||
if (this.dragAnchor) {
|
||||
// set all those between here and the anchor to the new values
|
||||
if (cell.hour > this.dragAnchor.hour)
|
||||
this.confirmCells(cell.day, this.dragAnchor.hour, cell.hour);
|
||||
else if (cell.hour < this.dragAnchor.hour)
|
||||
this.confirmCells(cell.day, cell.hour, this.dragAnchor.hour);
|
||||
else this.confirmCells(cell.day, cell.hour, cell.hour);
|
||||
|
||||
this.hideCellLeftTooltip();
|
||||
this.hideCellRightTooltip();
|
||||
this.dragAnchor = null;
|
||||
}
|
||||
},
|
||||
|
||||
onCellMouseOver: function (event, cell) {
|
||||
// LEFT TOOL TIP
|
||||
// if it isn't showing and we're dragging, show it.
|
||||
// otherwise if dragging, leave it alone unless we're dragging to the left.
|
||||
// if we're not dragging, show it.
|
||||
var leftTooltipCell = null;
|
||||
if (!this.dragAnchor) leftTooltipCell = cell;
|
||||
else if (
|
||||
(this.dragAnchor && this.isCellLeftTooltipHidden()) ||
|
||||
(this.dragAnchor && this.dragAnchor.hour > cell.hour)
|
||||
)
|
||||
leftTooltipCell = this.dragAnchor;
|
||||
|
||||
if (leftTooltipCell) {
|
||||
var hour = leftTooltipCell.hour;
|
||||
var pm = false;
|
||||
|
||||
// convert to 12-hour time
|
||||
if (hour >= 12) {
|
||||
pm = true;
|
||||
if (hour > 12) hour -= 12;
|
||||
} else if (hour == 0) {
|
||||
// change 0 hour to 12am
|
||||
hour = 12;
|
||||
}
|
||||
this.showCellLeftTooltip(
|
||||
hour + ' ' + (pm ? 'pm' : 'am'),
|
||||
leftTooltipCell
|
||||
);
|
||||
}
|
||||
|
||||
// RIGHT TOOL TIP
|
||||
var rightTooltipCell = null;
|
||||
if (this.dragAnchor) {
|
||||
if (this.dragAnchor.hour == cell.hour) this.hideCellRightTooltip();
|
||||
else if (
|
||||
this.dragAnchor.hour > cell.hour &&
|
||||
this.isCellRightTooltipHidden()
|
||||
)
|
||||
rightTooltipCell = this.dragAnchor;
|
||||
// cell.hour > this.dragAnchor.hour
|
||||
else rightTooltipCell = cell;
|
||||
}
|
||||
|
||||
if (rightTooltipCell) {
|
||||
var hour = rightTooltipCell.hour;
|
||||
var pm = false;
|
||||
|
||||
// convert to 12-hour time
|
||||
if (hour >= 12) {
|
||||
pm = true;
|
||||
if (hour > 12) hour -= 12;
|
||||
} else if (hour == 0) {
|
||||
// change 0 hour to 12am
|
||||
hour = 12;
|
||||
}
|
||||
this.showCellRightTooltip(
|
||||
hour + ' ' + (pm ? 'pm' : 'am'),
|
||||
rightTooltipCell
|
||||
);
|
||||
}
|
||||
|
||||
// preview colour change and
|
||||
// revert state for all those on the outer side of the drag if dragging
|
||||
if (this.dragAnchor) {
|
||||
if (cell.day != this.dragAnchor.day) {
|
||||
// dragged into another day. Abort! Abort!
|
||||
Ext.each(
|
||||
this.daysOfWeek,
|
||||
function (day) {
|
||||
this.revertCells(day, 0, 23);
|
||||
},
|
||||
this
|
||||
);
|
||||
this.dragAnchor = null;
|
||||
this.hideCellLeftTooltip();
|
||||
this.hideCellRightTooltip();
|
||||
} else if (cell.hour > this.dragAnchor.hour) {
|
||||
// dragging right
|
||||
this.revertCells(cell.day, cell.hour + 1, 23);
|
||||
this.previewCells(cell.day, this.dragAnchor.hour, cell.hour);
|
||||
} else if (cell.hour < this.dragAnchor.hour) {
|
||||
// dragging left
|
||||
this.revertCells(cell.day, 0, cell.hour - 1);
|
||||
this.previewCells(cell.day, cell.hour, this.dragAnchor.hour);
|
||||
} else {
|
||||
// back to anchor cell
|
||||
// don't know if it is from right or left, so revert all except this
|
||||
this.revertCells(cell.day, cell.hour + 1, 23);
|
||||
this.revertCells(cell.day, 0, cell.hour - 1);
|
||||
}
|
||||
} else {
|
||||
// not dragging, just preview this cell
|
||||
this.previewCells(cell.day, cell.hour, cell.hour);
|
||||
}
|
||||
},
|
||||
|
||||
onCellMouseOut: function (event, cell) {
|
||||
if (!this.dragAnchor) this.hideCellLeftTooltip();
|
||||
|
||||
// revert state. If new state has been set, old and new will be equal.
|
||||
// if dragging, this will be handled by the next mouse over
|
||||
if (this.dragAnchor == null && cell.oldValue != cell.currentValue) {
|
||||
this.revertCells(cell.day, cell.hour, cell.hour);
|
||||
}
|
||||
},
|
||||
|
||||
previewCells: function (day, fromHour, toHour) {
|
||||
var cells = this.scheduleCells[day];
|
||||
var curBrushValue = this.getCurrentBrushValue();
|
||||
|
||||
if (toHour > cells.length) toHour = cells.length;
|
||||
|
||||
for (var i = fromHour; i <= toHour; i++) {
|
||||
if (cells[i].currentValue != curBrushValue) {
|
||||
cells[i].oldValue = cells[i].currentValue;
|
||||
cells[i].currentValue = curBrushValue;
|
||||
this.updateCell(cells[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
revertCells: function (day, fromHour, toHour) {
|
||||
var cells = this.scheduleCells[day];
|
||||
|
||||
if (toHour > cells.length) toHour = cells.length;
|
||||
|
||||
for (var i = fromHour; i <= toHour; i++) {
|
||||
cells[i].currentValue = cells[i].oldValue;
|
||||
this.updateCell(cells[i]);
|
||||
}
|
||||
},
|
||||
|
||||
confirmCells: function (day, fromHour, toHour) {
|
||||
var cells = this.scheduleCells[day];
|
||||
|
||||
if (toHour > cells.length) toHour = cells.length;
|
||||
|
||||
for (var i = fromHour; i <= toHour; i++) {
|
||||
if (cells[i].currentValue != cells[i].oldValue) {
|
||||
cells[i].oldValue = cells[i].currentValue;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
showCellLeftTooltip: function (text, cell) {
|
||||
var tooltip = this.cellLeftTooltip;
|
||||
|
||||
if (!tooltip) {
|
||||
// no cached left tooltip exists, create one
|
||||
tooltip = document.createElement('div');
|
||||
this.cellLeftTooltip = tooltip;
|
||||
this.body.dom.appendChild(tooltip);
|
||||
tooltip.style.position = 'absolute';
|
||||
tooltip.style.backgroundColor = '#F2F2F2';
|
||||
tooltip.style.border = '1px solid #333333';
|
||||
tooltip.style.padding = '1px 3px';
|
||||
tooltip.style.opacity = 0.8;
|
||||
}
|
||||
|
||||
// remove all existing children
|
||||
while (tooltip.childNodes.length > 0) {
|
||||
tooltip.removeChild(tooltip.firstChild);
|
||||
}
|
||||
// add the requested text
|
||||
tooltip.appendChild(document.createTextNode(text));
|
||||
|
||||
// place the tooltip
|
||||
Ext.get(tooltip).alignTo(cell, 'br-tr');
|
||||
|
||||
// make it visible
|
||||
tooltip.style.visibility = 'visible';
|
||||
},
|
||||
|
||||
hideCellLeftTooltip: function () {
|
||||
if (this.cellLeftTooltip) {
|
||||
this.cellLeftTooltip.style.visibility = 'hidden';
|
||||
}
|
||||
},
|
||||
|
||||
isCellLeftTooltipHidden: function () {
|
||||
if (this.cellLeftTooltip)
|
||||
return this.cellLeftTooltip.style.visibility == 'hidden';
|
||||
else return true;
|
||||
},
|
||||
|
||||
showCellRightTooltip: function (text, cell) {
|
||||
var tooltip = this.cellRightTooltip;
|
||||
|
||||
if (!tooltip) {
|
||||
// no cached left tooltip exists, create one
|
||||
tooltip = document.createElement('div');
|
||||
this.cellRightTooltip = tooltip;
|
||||
this.body.dom.appendChild(tooltip);
|
||||
tooltip.style.position = 'absolute';
|
||||
tooltip.style.backgroundColor = '#F2F2F2';
|
||||
tooltip.style.border = '1px solid #333333';
|
||||
tooltip.style.padding = '1px 3px';
|
||||
tooltip.style.opacity = 0.8;
|
||||
}
|
||||
|
||||
// remove all existing children
|
||||
while (tooltip.childNodes.length > 0) {
|
||||
tooltip.removeChild(tooltip.firstChild);
|
||||
}
|
||||
// add the requested text
|
||||
tooltip.appendChild(document.createTextNode(text));
|
||||
|
||||
// place the tooltip
|
||||
Ext.get(tooltip).alignTo(cell, 'bl-tl');
|
||||
|
||||
// make it visible
|
||||
tooltip.style.visibility = 'visible';
|
||||
},
|
||||
|
||||
hideCellRightTooltip: function () {
|
||||
if (this.cellRightTooltip) {
|
||||
this.cellRightTooltip.style.visibility = 'hidden';
|
||||
}
|
||||
},
|
||||
|
||||
isCellRightTooltipHidden: function () {
|
||||
if (this.cellRightTooltip)
|
||||
return this.cellRightTooltip.style.visibility == 'hidden';
|
||||
else return true;
|
||||
},
|
||||
|
||||
getConfig: function () {
|
||||
var config = [];
|
||||
|
||||
for (var i = 0; i < 24; i++) {
|
||||
var hourConfig = [0, 0, 0, 0, 0, 0, 0];
|
||||
|
||||
for (var j = 0; j < this.daysOfWeek.length; j++) {
|
||||
hourConfig[j] = parseInt(
|
||||
this.scheduleCells[this.daysOfWeek[j]][i].currentValue
|
||||
);
|
||||
}
|
||||
|
||||
config.push(hourConfig);
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
|
||||
setConfig: function (config) {
|
||||
for (var i = 0; i < 24; i++) {
|
||||
var hourConfig = config[i];
|
||||
|
||||
for (var j = 0; j < this.daysOfWeek.length; j++) {
|
||||
if (this.scheduleCells == undefined) {
|
||||
var cell = hourConfig[j];
|
||||
} else {
|
||||
var cell = this.scheduleCells[this.daysOfWeek[j]][i];
|
||||
}
|
||||
cell.currentValue = cell.oldValue = hourConfig[j];
|
||||
this.updateCell(cell);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Ext.ns('Deluge.ux.preferences');
|
||||
|
||||
Deluge.ux.preferences.SchedulerPage = Ext.extend(Ext.Panel, {
|
||||
border: false,
|
||||
title: _('Scheduler'),
|
||||
header: false,
|
||||
layout: 'fit',
|
||||
|
||||
initComponent: function () {
|
||||
Deluge.ux.preferences.SchedulerPage.superclass.initComponent.call(this);
|
||||
|
||||
this.form = this.add({
|
||||
xtype: 'form',
|
||||
layout: 'form',
|
||||
border: false,
|
||||
autoHeight: true,
|
||||
});
|
||||
|
||||
this.schedule = this.form.add(new Deluge.ux.ScheduleSelector());
|
||||
|
||||
this.slowSettings = this.form.add({
|
||||
xtype: 'fieldset',
|
||||
border: false,
|
||||
title: _('Throttled Settings'),
|
||||
autoHeight: true,
|
||||
defaultType: 'spinnerfield',
|
||||
defaults: {
|
||||
minValue: -1,
|
||||
maxValue: 99999,
|
||||
},
|
||||
style: 'margin-top: 5px; margin-bottom: 0px; padding-bottom: 0px;',
|
||||
labelWidth: 200,
|
||||
});
|
||||
|
||||
this.downloadLimit = this.slowSettings.add({
|
||||
fieldLabel: _('Maximum Download Speed (KiB/s)'),
|
||||
name: 'download_limit',
|
||||
width: 80,
|
||||
value: -1,
|
||||
decimalPrecision: 0,
|
||||
});
|
||||
this.uploadLimit = this.slowSettings.add({
|
||||
fieldLabel: _('Maximum Upload Speed (KiB/s)'),
|
||||
name: 'upload_limit',
|
||||
width: 80,
|
||||
value: -1,
|
||||
decimalPrecision: 0,
|
||||
});
|
||||
this.activeTorrents = this.slowSettings.add({
|
||||
fieldLabel: _('Active Torrents'),
|
||||
name: 'active_torrents',
|
||||
width: 80,
|
||||
value: -1,
|
||||
decimalPrecision: 0,
|
||||
});
|
||||
this.activeDownloading = this.slowSettings.add({
|
||||
fieldLabel: _('Active Downloading'),
|
||||
name: 'active_downloading',
|
||||
width: 80,
|
||||
value: -1,
|
||||
decimalPrecision: 0,
|
||||
});
|
||||
this.activeSeeding = this.slowSettings.add({
|
||||
fieldLabel: _('Active Seeding'),
|
||||
name: 'active_seeding',
|
||||
width: 80,
|
||||
value: -1,
|
||||
decimalPrecision: 0,
|
||||
});
|
||||
|
||||
this.on('show', this.updateConfig, this);
|
||||
},
|
||||
|
||||
onRender: function (ct, position) {
|
||||
Deluge.ux.preferences.SchedulerPage.superclass.onRender.call(
|
||||
this,
|
||||
ct,
|
||||
position
|
||||
);
|
||||
this.form.layout = new Ext.layout.FormLayout();
|
||||
this.form.layout.setContainer(this);
|
||||
this.form.doLayout();
|
||||
},
|
||||
|
||||
onApply: function () {
|
||||
// build settings object
|
||||
var config = {};
|
||||
|
||||
config['button_state'] = this.schedule.getConfig();
|
||||
config['low_down'] = this.downloadLimit.getValue();
|
||||
config['low_up'] = this.uploadLimit.getValue();
|
||||
config['low_active'] = this.activeTorrents.getValue();
|
||||
config['low_active_down'] = this.activeDownloading.getValue();
|
||||
config['low_active_up'] = this.activeSeeding.getValue();
|
||||
|
||||
deluge.client.scheduler.set_config(config);
|
||||
},
|
||||
|
||||
onOk: function () {
|
||||
this.onApply();
|
||||
},
|
||||
|
||||
updateConfig: function () {
|
||||
deluge.client.scheduler.get_config({
|
||||
success: function (config) {
|
||||
this.schedule.setConfig(config['button_state']);
|
||||
this.downloadLimit.setValue(config['low_down']);
|
||||
this.uploadLimit.setValue(config['low_up']);
|
||||
this.activeTorrents.setValue(config['low_active']);
|
||||
this.activeDownloading.setValue(config['low_active_down']);
|
||||
this.activeSeeding.setValue(config['low_active_up']);
|
||||
},
|
||||
scope: this,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Deluge.plugins.SchedulerPlugin = Ext.extend(Deluge.Plugin, {
|
||||
name: 'Scheduler',
|
||||
|
||||
onDisable: function () {
|
||||
deluge.preferences.removePage(this.prefsPage);
|
||||
},
|
||||
|
||||
onEnable: function () {
|
||||
this.prefsPage = deluge.preferences.addPage(
|
||||
new Deluge.ux.preferences.SchedulerPage()
|
||||
);
|
||||
},
|
||||
});
|
||||
Deluge.registerPlugin('Scheduler', Deluge.plugins.SchedulerPlugin);
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Script: stats.js
|
||||
* The javascript client-side code for the Stats plugin.
|
||||
*
|
||||
* Copyright (c) Damien Churchill 2009-2010 <damoxc@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
StatsPlugin = Ext.extend(Deluge.Plugin, {
|
||||
constructor: function (config) {
|
||||
config = Ext.apply(
|
||||
{
|
||||
name: 'Stats',
|
||||
},
|
||||
config
|
||||
);
|
||||
StatsPlugin.superclass.constructor.call(this, config);
|
||||
},
|
||||
|
||||
onDisable: function () {},
|
||||
|
||||
onEnable: function () {},
|
||||
});
|
||||
new StatsPlugin();
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Script: toggle.js
|
||||
* The client-side javascript code for the Toggle plugin.
|
||||
*
|
||||
* Copyright (C) John Garland 2010 <johnnybg+deluge@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
TogglePlugin = Ext.extend(Deluge.Plugin, {
|
||||
constructor: function (config) {
|
||||
config = Ext.apply(
|
||||
{
|
||||
name: 'Toggle',
|
||||
},
|
||||
config
|
||||
);
|
||||
TogglePlugin.superclass.constructor.call(this, config);
|
||||
},
|
||||
|
||||
onDisable: function () {},
|
||||
|
||||
onEnable: function () {},
|
||||
});
|
||||
new TogglePlugin();
|
||||
Reference in New Issue
Block a user