1 /*
  2 Script: deluge-connections.js
  3     Contains all objects and functions related to the connection manager.
  4 
  5 Copyright:
  6 	(C) Damien Churchill 2009 <damoxc@gmail.com>
  7 	This program is free software; you can redistribute it and/or modify
  8 	it under the terms of the GNU General Public License as published by
  9 	the Free Software Foundation; either version 3, or (at your option)
 10 	any later version.
 11 
 12 	This program is distributed in the hope that it will be useful,
 13 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15 	GNU General Public License for more details.
 16 
 17 	You should have received a copy of the GNU General Public License
 18 	along with this program.  If not, write to:
 19 		The Free Software Foundation, Inc.,
 20 		51 Franklin Street, Fifth Floor
 21 		Boston, MA  02110-1301, USA.
 22 
 23     In addition, as a special exception, the copyright holders give
 24     permission to link the code of portions of this program with the OpenSSL
 25     library.
 26     You must obey the GNU General Public License in all respects for all of
 27     the code used other than OpenSSL. If you modify file(s) with this
 28     exception, you may extend this exception to your version of the file(s),
 29     but you are not obligated to do so. If you do not wish to do so, delete
 30     this exception statement from your version. If you delete this exception
 31     statement from all source files in the program, then also delete it here.
 32 
 33 */
 34 
 35 (function() {
 36 	var hostRenderer = function(value, p, r) {
 37 		return value + ':' + r.data['port']
 38 	}
 39 	
 40 	Ext.deluge.AddConnectionWindow = Ext.extend(Ext.Window, {
 41 		
 42 		constructor: function(config) {
 43 			config = Ext.apply({
 44 				layout: 'fit',
 45 				width: 300,
 46 				height: 195,
 47 				bodyStyle: 'padding: 10px 5px;',
 48 				buttonAlign: 'right',
 49 				closeAction: 'hide',
 50 				closable: true,
 51 				plain: true,
 52 				title: _('Add Connection'),
 53 				iconCls: 'x-deluge-add-window-icon'
 54 			}, config);
 55 			Ext.deluge.AddConnectionWindow.superclass.constructor.call(this, config);
 56 		},
 57 		
 58 		initComponent: function() {
 59 			Ext.deluge.AddConnectionWindow.superclass.initComponent.call(this);
 60 			
 61 			this.addEvents('hostadded');
 62 			
 63 			this.addButton(_('Close'), this.hide, this);
 64 			this.addButton(_('Add'), this.onAdd, this);
 65 			
 66 			this.on('hide', this.onHide, this);
 67 			
 68 			this.form = this.add({
 69 				xtype: 'form',
 70 				defaultType: 'textfield',
 71 				id: 'connectionAddForm',
 72 				baseCls: 'x-plain',
 73 				labelWidth: 55
 74 			});
 75 			
 76 			this.hostField = this.form.add({
 77 				fieldLabel: _('Host'),
 78 				id: 'host',
 79 				name: 'host',
 80 				anchor: '100%',
 81 				value: ''
 82 			});
 83 			
 84 			this.portField = this.form.add({
 85 				fieldLabel: _('Port'),
 86 				id: 'port',
 87 				xtype: 'uxspinner',
 88 				ctCls: 'x-form-uxspinner',
 89 				name: 'port',
 90 				strategy: Ext.ux.form.Spinner.NumberStrategy(),
 91 				value: '58846',
 92 				anchor: '50%'
 93 			});
 94 			
 95 			this.usernameField = this.form.add({
 96 				fieldLabel: _('Username'),
 97 				id: 'username',
 98 				name: 'username',
 99 				anchor: '100%',
100 				value: ''
101 			});
102 			
103 			this.passwordField = this.form.add({
104 				fieldLabel: _('Password'),
105 				anchor: '100%',
106 				id: '_password',
107 				name: '_password',
108 				inputType: 'password',
109 				value: ''
110 			});
111 		},
112 		
113 		onAdd: function() {
114 			var host = this.hostField.getValue();
115 			var port = this.portField.getValue();
116 			var username = this.usernameField.getValue();
117 			var password = this.passwordField.getValue();
118 			
119 			Deluge.Client.web.add_host(host, port, username, password, {
120 				success: function(result) {
121 					if (!result[0]) {
122 						Ext.MessageBox.show({
123 							title: _('Error'),
124 							msg: "Unable to add host: " + result[1],
125 							buttons: Ext.MessageBox.OK,
126 							modal: false,
127 							icon: Ext.MessageBox.ERROR,
128 							iconCls: 'x-deluge-icon-error'
129 						});
130 					} else {
131 						this.fireEvent('hostadded');
132 					}
133 					this.hide();
134 				},
135 				scope: this
136 			});
137 		},
138 		
139 		onHide: function() {
140 			this.form.getForm().reset();
141 		}
142 	});
143 
144 	Ext.deluge.ConnectionManager = Ext.extend(Ext.Window, {
145 	
146 		layout: 'fit',
147 		width: 300,
148 		height: 220,
149 		bodyStyle: 'padding: 10px 5px;',
150 		buttonAlign: 'right',
151 		closeAction: 'hide',
152 		closable: true,
153 		plain: true,
154 		title: _('Connection Manager'),
155 		iconCls: 'x-deluge-connect-window-icon',
156 		
157 		initComponent: function() {
158 			Ext.deluge.ConnectionManager.superclass.initComponent.call(this);
159 			this.on({
160 				'hide': this.onHide,
161 				'show': this.onShow
162 			});
163 			Deluge.Events.on('login', this.onLogin, this);
164 			Deluge.Events.on('logout', this.onLogout, this);
165 			
166 			this.addButton(_('Close'), this.onClose, this);
167 			this.addButton(_('Connect'), this.onConnect, this);
168 			
169 			this.grid = this.add({
170 				xtype: 'grid',
171 				store: new Ext.data.SimpleStore({
172 					fields: [
173 						{name: 'status', mapping: 3},
174 						{name: 'host', mapping: 1},
175 						{name: 'port', mapping: 2},
176 						{name: 'version', mapping: 4}
177 					],
178 					id: 0
179 				}),
180 				columns: [{
181 					header: _('Status'),
182 					width: 65,
183 					sortable: true,
184 					renderer: fplain,
185 					dataIndex: 'status'
186 				}, {
187 					id:'host',
188 					header: _('Host'),
189 					width: 150,
190 					sortable: true,
191 					renderer: hostRenderer,
192 					dataIndex: 'host'
193 				}, {
194 					header: _('Version'),
195 					width: 75,
196 					sortable: true,
197 					renderer: fplain,
198 					dataIndex: 'version'
199 				}],
200 				stripeRows: true,
201 				selModel: new Ext.grid.RowSelectionModel({
202 					singleSelect: true,
203 					listeners: {
204 						'rowselect': {fn: this.onSelect, scope: this}
205 					}
206 				}),
207 				autoExpandColumn: 'host',
208 				deferredRender:false,
209 				autoScroll:true,
210 				margins: '0 0 0 0',
211 				bbar: new Ext.Toolbar({
212 					items: [
213 						{
214 							id: 'add',
215 							cls: 'x-btn-text-icon',
216 							text: _('Add'),
217 							icon: '/icons/add.png',
218 							handler: this.onAdd,
219 							scope: this
220 						}, {
221 							id: 'remove',
222 							cls: 'x-btn-text-icon',
223 							text: _('Remove'),
224 							icon: '/icons/remove.png',
225 							handler: this.onRemove,
226 							scope: this
227 						}, '->', {
228 							id: 'stop',
229 							cls: 'x-btn-text-icon',
230 							text: _('Stop Daemon'),
231 							icon: '/icons/error.png',
232 							handler: this.onStop,
233 							scope: this
234 						}
235 					]
236 				})
237 			});
238 		},
239 		
240 		disconnect: function() {
241 			Deluge.Events.fire('disconnect');
242 		},
243 		
244 		loadHosts: function() {
245 			Deluge.Client.web.get_hosts({
246 				success: this.onGetHosts,
247 				scope: this
248 			});
249 		},
250 		
251 		update: function(self) {
252 			self.grid.getStore().each(function(r) {
253 				Deluge.Client.web.get_host_status(r.id, {
254 					success: self.onGetHostStatus,
255 					scope: self
256 				});
257 			}, this);
258 		},
259 		
260 		onAdd: function(button, e) {
261 			if (!this.addWindow) {
262 				this.addWindow = new Ext.deluge.AddConnectionWindow();
263 				this.addWindow.on('hostadded', this.onHostAdded, this);
264 			}
265 			this.addWindow.show();
266 		},
267 		
268 		onHostAdded: function() {
269 			this.runCheck();
270 		},
271 		
272 		onClose: function(e) {
273 			if (this.running) window.clearInterval(this.running);
274 			this.hide();
275 		},
276 		
277 		onConnect: function(e) {
278 			var selected = this.grid.getSelectionModel().getSelected();
279 			if (!selected) return;
280 			
281 			if (selected.get('status') == _('Connected')) {
282 				Deluge.Client.web.disconnect({
283 					success: function(result) {
284 						this.update();
285 						Deluge.Events.fire('disconnect');
286 					},
287 					scope: this
288 				});
289 			} else {
290 				var id = selected.id;
291 				Deluge.Client.web.connect(id, {
292 					success: function(methods) {
293 						Deluge.Client.reloadMethods();
294 						Deluge.Client.on('connected', function(e) {
295 							Deluge.Events.fire('connect');
296 						}, this, {single: true});
297 					}
298 				});
299 				if (this.running) window.clearInterval(this.running);
300 				this.hide();
301 			}
302 		},
303 		
304 		onGetHosts: function(hosts) {
305 			var store = this.grid.getStore();
306 			Ext.each(hosts, function(host) {
307 				var record = store.getById(host[0]);
308 				if (!record) {
309 					store.loadData([host], true);
310 				}
311 				Deluge.Client.web.get_host_status(host[0], {
312 					success: this.onGetHostStatus,
313 					scope: this
314 				});
315 			}, this);
316 		},
317 		
318 		onGetHostStatus: function(host) {
319 			var record = this.grid.getStore().getById(host[0]);
320 			record.set('status', host[3])
321 			record.set('version', host[4])
322 			record.commit();
323 		},
324 		
325 		onLogin: function() {
326 			Deluge.Client.web.connected({
327 				success: function(connected) {
328 					if (connected) {
329 						Deluge.Events.fire('connect');
330 					} else {
331 						this.show();
332 					}
333 				},
334 				scope: this
335 			});
336 		},
337 		
338 		onLogout: function() {
339 			this.disconnect();
340 			if (!this.hidden && this.rendered) {
341 				this.hide();
342 			}
343 		},
344 		
345 		onRemove: function(button) {
346 			var connection = this.grid.getSelectionModel().getSelected();
347 			Deluge.Client.web.remove_host(connection.id, {
348 				success: function(result) {
349 					if (!result) {
350 						Ext.MessageBox.show({
351 							title: _('Error'),
352 							msg: result[1],
353 							buttons: Ext.MessageBox.OK,
354 							modal: false,
355 							icon: Ext.MessageBox.ERROR,
356 							iconCls: 'x-deluge-icon-error'
357 						});
358 					} else {
359 						this.grid.getStore().remove(connection);
360 					}
361 				},
362 				scope: this
363 			});
364 		},
365 		
366 		onSelect: function(selModel, rowIndex, record) {
367 			this.selectedRow = rowIndex;
368 			var button = this.buttons[1];
369 			if (record.get('status') == _('Connected')) {
370 				button.setText(_('Disconnect'));
371 			} else {
372 				button.setText(_('Connect'));
373 			}
374 		},
375 		
376 		onShow: function() {
377 			this.loadHosts();
378 			this.running = window.setInterval(this.update, 2000, this);
379 		},
380 		
381 		onStop: function(button, e) {
382 			var connection = this.grid.getSelectionModel().getSelected();
383 			Deluge.Client.web.stop_daemon(connection.id, {
384 				success: function(result) {
385 					if (!result[0]) {
386 						Ext.MessageBox.show({
387 							title: _('Error'),
388 							msg: result[1],
389 							buttons: Ext.MessageBox.OK,
390 							modal: false,
391 							icon: Ext.MessageBox.ERROR,
392 							iconCls: 'x-deluge-icon-error'
393 						});
394 					}
395 				}
396 			});
397 		}
398 	});
399 	Deluge.ConnectionManager = new Ext.deluge.ConnectionManager();
400 })();
401