1 //=============================================================================
2 //
3 //   File : libkvitorrent.cpp
4 //   Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
5 //
6 //   This file is part of the KVIrc IRC client distribution
7 //   Copyright (C) 2001-2008 Alexander Stillich (torque at pltn dot org)
8 //
9 //   This program is FREE software. You can redistribute it and/or
10 //   modify it under the terms of the GNU General Public License
11 //   as published by the Free Software Foundation; either version 2
12 //   of the License, or (at your option) any later version.
13 //
14 //   This program is distributed in the HOPE that it will be USEFUL,
15 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 //   See the GNU General Public License for more details.
18 //
19 //   You should have received a copy of the GNU General Public License
20 //   along with this program. If not, write to the Free Software Foundation,
21 //   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=============================================================================
24 
25 #include "TorrentInterface.h"
26 #include "KTorrentDbusInterface.h"
27 #include "StatusBarApplet.h"
28 
29 #include "KviModule.h"
30 #include "KviOptions.h"
31 #include "KviMainWindow.h"
32 #include "KviLocale.h"
33 #include "kvi_out.h"
34 
35 static KviPointerList<TorrentInterfaceDescriptor> * g_pDescriptorList = nullptr;
36 
auto_detect_torrent_client(KviWindow * pOut=nullptr)37 static TorrentInterface * auto_detect_torrent_client(KviWindow * pOut = nullptr)
38 {
39 	int iBest = 0;
40 	TorrentInterface * pBest = nullptr;
41 	TorrentInterfaceDescriptor * d;
42 	TorrentInterfaceDescriptor * pDBest = nullptr;
43 
44 	for(d = g_pDescriptorList->first(); d != nullptr; d = g_pDescriptorList->next())
45 	{
46 		// instance gets deleted by descriptor later
47 		TorrentInterface * i = d->instance();
48 		if(i)
49 		{
50 			int iScore = i->detect();
51 			if(iScore > iBest)
52 			{
53 				iBest = iScore;
54 				pBest = i;
55 				pDBest = d;
56 			}
57 
58 			if(pOut)
59 			{
60 				pOut->output(KVI_OUT_TORRENT,
61 				    __tr2qs_ctx("Trying torrent client interface \"%Q\": score %d", "torrent"),
62 				    &d->name(),
63 				    iScore);
64 			}
65 		}
66 	}
67 
68 	if(pDBest)
69 	{
70 		KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient) = pDBest->name();
71 		if(pOut)
72 			pOut->output(KVI_OUT_TORRENT,
73 			    __tr2qs_ctx("Choosing torrent client interface \"%Q\"", "torrent"),
74 			    &pDBest->name());
75 	}
76 	else
77 	{
78 		if(pOut)
79 			pOut->outputNoFmt(KVI_OUT_TORRENT,
80 			    __tr2qs_ctx("Seems that there is no usable torrent client on this machine", "torrent"));
81 	}
82 
83 	return pBest;
84 }
85 
86 #define TC_KVS_FAIL_ON_NO_INTERFACE                                                                      \
87 	if(!TorrentInterface::selected())                                                                    \
88 	{                                                                                                    \
89 		c->warning(__tr2qs_ctx("No torrent client interface selected. Try /torrent.detect", "torrent")); \
90 		return true;                                                                                     \
91 	}
92 
93 #define TC_KVS_COMMAND(__name) static bool torrent_kvs_cmd_##__name(KviKvsModuleCommandCall * c)
94 #define TC_KVS_FUNCTION(__name) static bool torrent_kvs_fnc_##__name(KviKvsModuleFunctionCall * c)
95 
96 #define TC_KVS_COMMAND_ERROR                                                                                                  \
97 	if(!c->hasSwitch('q', "quiet"))                                                                                           \
98 	{                                                                                                                         \
99 		c->warning(__tr2qs_ctx("The selected torrent client interface failed to execute the requested function", "torrent")); \
100 		QString tmp = __tr2qs_ctx("Last interface error: ", "torrent");                                                       \
101 		tmp += TorrentInterface::selected()->lastError();                                                                     \
102 		c->warning(tmp);                                                                                                      \
103 	}
104 
105 #define TC_KVS_SIMPLE_COMMAND(__name, __ifacecommand)       \
106 	TC_KVS_COMMAND(__name)                                  \
107 	{                                                       \
108 		KVSM_PARAMETERS_BEGIN(c)                            \
109 		KVSM_PARAMETERS_END(c)                              \
110                                                             \
111 		TC_KVS_FAIL_ON_NO_INTERFACE                         \
112                                                             \
113 		if(!TorrentInterface::selected()->__ifacecommand()) \
114 		{                                                   \
115 			TC_KVS_COMMAND_ERROR                            \
116 		}                                                   \
117 		return true;                                        \
118 	}
119 
120 #define TC_KVS_INT_COMMAND(__name, __ifacecommand, __argname)  \
121 	TC_KVS_COMMAND(__name)                                     \
122 	{                                                          \
123 		kvs_int_t arg;                                         \
124 		KVSM_PARAMETERS_BEGIN(c)                               \
125 		KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg)          \
126 		KVSM_PARAMETERS_END(c)                                 \
127                                                                \
128 		TC_KVS_FAIL_ON_NO_INTERFACE                            \
129                                                                \
130 		if(!TorrentInterface::selected()->__ifacecommand(arg)) \
131 		{                                                      \
132 			TC_KVS_COMMAND_ERROR                               \
133 		}                                                      \
134 		return true;                                           \
135 	}
136 
137 #define TC_KVS_INT_INT_STRING_COMMAND(__name, __ifacecommand, __argname1, __argname2, __argname3) \
138 	TC_KVS_COMMAND(__name)                                                                        \
139 	{                                                                                             \
140 		kvs_int_t arg1;                                                                           \
141 		kvs_int_t arg2;                                                                           \
142 		QString arg3;                                                                             \
143 		KVSM_PARAMETERS_BEGIN(c)                                                                  \
144 		KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1)                                           \
145 		KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2)                                           \
146 		KVSM_PARAMETER(__argname3, KVS_PT_STRING, 0, arg3)                                        \
147 		KVSM_PARAMETERS_END(c)                                                                    \
148                                                                                                   \
149 		TC_KVS_FAIL_ON_NO_INTERFACE                                                               \
150                                                                                                   \
151 		if(!TorrentInterface::selected()->__ifacecommand(arg1, arg2, arg3))                       \
152 		{                                                                                         \
153 			TC_KVS_COMMAND_ERROR                                                                  \
154 		}                                                                                         \
155 		return true;                                                                              \
156 	}
157 
158 // TODO: error handling for functions
159 
160 #define TC_KVS_STRINGRET_FUNCTION(__name, __ifacecommand)               \
161 	TC_KVS_FUNCTION(__name)                                             \
162 	{                                                                   \
163 		TC_KVS_FAIL_ON_NO_INTERFACE                                     \
164 		QString szRet = TorrentInterface::selected()->__ifacecommand(); \
165 		c->returnValue()->setString(szRet);                             \
166 		return true;                                                    \
167 	}
168 
169 #define TC_KVS_INTRET_FUNCTION(__name, __ifacecommand)                  \
170 	TC_KVS_FUNCTION(__name)                                             \
171 	{                                                                   \
172 		TC_KVS_FAIL_ON_NO_INTERFACE                                     \
173 		kvs_int_t ret = TorrentInterface::selected()->__ifacecommand(); \
174 		c->returnValue()->setInteger(ret);                              \
175 		return true;                                                    \
176 	}
177 
178 #define TC_KVS_FLOATRET_FUNCTION(__name, __ifacecommand)                 \
179 	TC_KVS_FUNCTION(__name)                                              \
180 	{                                                                    \
181 		TC_KVS_FAIL_ON_NO_INTERFACE                                      \
182 		kvs_real_t ret = TorrentInterface::selected()->__ifacecommand(); \
183 		c->returnValue()->setReal(ret);                                  \
184 		return true;                                                     \
185 	}
186 
187 #define TC_KVS_INTRET_INT_FUNCTION(__name, __ifacecommand, __argname)      \
188 	TC_KVS_FUNCTION(__name)                                                \
189 	{                                                                      \
190 		kvs_int_t arg;                                                     \
191 		KVSM_PARAMETERS_BEGIN(c)                                           \
192 		KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg)                      \
193 		KVSM_PARAMETERS_END(c)                                             \
194 		TC_KVS_FAIL_ON_NO_INTERFACE                                        \
195 		kvs_int_t ret = TorrentInterface::selected()->__ifacecommand(arg); \
196 		c->returnValue()->setInteger(ret);                                 \
197 		return true;                                                       \
198 	}
199 
200 #define TC_KVS_STRINGRET_INT_FUNCTION(__name, __ifacecommand, __argname)   \
201 	TC_KVS_FUNCTION(__name)                                                \
202 	{                                                                      \
203 		kvs_int_t arg;                                                     \
204 		KVSM_PARAMETERS_BEGIN(c)                                           \
205 		KVSM_PARAMETER(__argname, KVS_PT_INT, 0, arg)                      \
206 		KVSM_PARAMETERS_END(c)                                             \
207 		TC_KVS_FAIL_ON_NO_INTERFACE                                        \
208 		QString szRet = TorrentInterface::selected()->__ifacecommand(arg); \
209 		c->returnValue()->setString(szRet);                                \
210 		return true;                                                       \
211 	}
212 
213 #define TC_KVS_STRINGRET_INT_INT_FUNCTION(__name, __ifacecommand, __argname1, __argname2) \
214 	TC_KVS_FUNCTION(__name)                                                               \
215 	{                                                                                     \
216 		kvs_int_t arg1;                                                                   \
217 		kvs_int_t arg2;                                                                   \
218 		KVSM_PARAMETERS_BEGIN(c)                                                          \
219 		KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1)                                   \
220 		KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2)                                   \
221 		KVSM_PARAMETERS_END(c)                                                            \
222 		TC_KVS_FAIL_ON_NO_INTERFACE                                                       \
223 		QString szRet = TorrentInterface::selected()->__ifacecommand(arg1, arg2);         \
224 		c->returnValue()->setString(szRet);                                               \
225 		return true;                                                                      \
226 	}
227 
228 #define TC_KVS_INTRET_INT_INT_FUNCTION(__name, __ifacecommand, __argname1, __argname2) \
229 	TC_KVS_FUNCTION(__name)                                                            \
230 	{                                                                                  \
231 		kvs_int_t arg1;                                                                \
232 		kvs_int_t arg2;                                                                \
233 		KVSM_PARAMETERS_BEGIN(c)                                                       \
234 		KVSM_PARAMETER(__argname1, KVS_PT_INT, 0, arg1)                                \
235 		KVSM_PARAMETER(__argname2, KVS_PT_INT, 0, arg2)                                \
236 		KVSM_PARAMETERS_END(c)                                                         \
237 		TC_KVS_FAIL_ON_NO_INTERFACE                                                    \
238 		kvs_int_t ret = TorrentInterface::selected()->__ifacecommand(arg1, arg2);      \
239 		c->returnValue()->setInteger(ret);                                             \
240 		return true;                                                                   \
241 	}
242 
243 /*
244 	@doc: torrent.detect
245 	@type:
246 		command
247 	@title:
248 		torrent.detect
249 	@short:
250 		Detects the torrent client interface to use
251 	@syntax:
252 		torrent.detect [-q]
253 	@description:
254 		Attempts to detect the best torrent client interface
255 		for the current system. The -q switch causes the detection
256 		algorithm to run quietly. This function may attempt to start
257 		the torrent clients in order to verify their presence on the system.
258 		You can guide the function by starting the torrent client you
259 		prefer before running it: if a running torrent client is found, it takes
260 		precedence over the others.[br]
261 		Take a look at the [module:torrent]torrent module documentation[/module]
262 		for more details about how it works.[br]
263 	@seealso:
264 		[module:torrent]torrent module documentation[/module],
265 		[cmd]torrent.setClient[/cmd],
266 		[fnc]$torrent.client[/fnc]
267 */
268 
TC_KVS_COMMAND(detect)269 TC_KVS_COMMAND(detect)
270 {
271 	TorrentInterface::select(auto_detect_torrent_client(c->hasSwitch('q', "quiet") ? nullptr : c->window()));
272 	return true;
273 }
274 
275 /*
276 	@doc: torrent.maxUploadSpeed
277 	@type:
278 		function
279 	@title:
280 		$torrent.maxUploadSpeed
281 	@short:
282 		Returns maximum upload speed set in client.
283 	@syntax:
284 		$torrent.maxUploadSpeed()
285 	@description:
286 		Returns maximum upload speed set in client.
287 		Take a look at the [module:torrent]torrent module documentation[/module]
288 		for more details about how it works.[br]
289 	@seealso:
290 		[module:torrent]torrent module documentation[/module]
291 */
292 
TC_KVS_INTRET_FUNCTION(maxUploadSpeed,maxUploadSpeed)293 TC_KVS_INTRET_FUNCTION(maxUploadSpeed, maxUploadSpeed)
294 
295 /*
296 	@doc: torrent.maxDownloadSpeed
297 	@type:
298 		function
299 	@title:
300 		$torrent.maxDownloadSpeed
301 	@short:
302 		Returns maximum download speed set in client.
303 	@syntax:
304 		$torrent.maxDownloadSpeed()
305 	@description:
306 		Returns maximum download speed set in client.
307 		Take a look at the [module:torrent]torrent module documentation[/module]
308 		for more details about how it works.[br]
309 	@seealso:
310 		[module:torrent]torrent module documentation[/module]
311 */
312 
313 TC_KVS_INTRET_FUNCTION(maxDownloadSpeed, maxDownloadSpeed)
314 
315 /*
316 	@doc: torrent.setMaxUploadSpeed
317 	@type:
318 		command
319 	@title:
320 		torrent.setMaxUploadSpeed
321 	@short:
322 		Sets maximum upload speed
323 	@syntax:
324 		torrent.setMaxUploadSpeed <kbytes_per_sec>
325 	@description:
326 		Sets maximum upload speed
327 		Take a look at the [module:torrent]torrent module documentation[/module]
328 		for more details about how it works.[br]
329 	@seealso:
330 		[module:torrent]torrent module documentation[/module]
331 */
332 
333 TC_KVS_INT_COMMAND(setMaxUploadSpeed, setMaxUploadSpeed, "kbytes_per_sec")
334 
335 /*
336 	@doc: torrent.setMaxDownloadSpeed
337 	@type:
338 		command
339 	@title:
340 		torrent.setMaxDownloadSpeed
341 	@short:
342 		Sets maximum download speed
343 	@syntax:
344 		torrent.setMaxDownloadSpeed <kbytes_per_sec>
345 	@description:
346 		Sets maximum download speed
347 		Take a look at the [module:torrent]torrent module documentation[/module]
348 		for more details about how it works.[br]
349 	@seealso:
350 		[module:torrent]torrent module documentation[/module]
351 */
352 
353 TC_KVS_INT_COMMAND(setMaxDownloadSpeed, setMaxDownloadSpeed, "kbytes_per_sec")
354 
355 /*
356 	@doc: torrent.speedUp
357 	@type:
358 		function
359 	@title:
360 		$torrent.speedUp
361 	@short:
362 		Returns current total upload speed
363 	@syntax:
364 		$torrent.speedUp()
365 	@description:
366 		Returns current total upload speed
367 		Take a look at the [module:torrent]torrent module documentation[/module]
368 		for more details about how it works.[br]
369 	@seealso:
370 		[module:torrent]torrent module documentation[/module]
371 */
372 
373 TC_KVS_FLOATRET_FUNCTION(speedUp, speedUp)
374 
375 /*
376 	@doc: torrent.speedDown
377 	@type:
378 		function
379 	@title:
380 		$torrent.speedDown
381 	@short:
382 		Returns current total download speed
383 	@syntax:
384 		$torrent.speedDown()
385 	@description:
386 		Returns current total download speed
387 		Take a look at the [module:torrent]torrent module documentation[/module]
388 		for more details about how it works.[br]
389 	@seealso:
390 		[module:torrent]torrent module documentation[/module]
391 */
392 
393 TC_KVS_FLOATRET_FUNCTION(speedDown, speedDown)
394 
395 /*
396 	@doc: torrent.trafficUp
397 	@type:
398 		function
399 	@title:
400 		$torrent.trafficUp
401 	@short:
402 		Returns the total number of bytes uploaded
403 	@syntax:
404 		$torrent.trafficUp()
405 	@description:
406 		Returns the total number of bytes uploaded
407 		Take a look at the [module:torrent]torrent module documentation[/module]
408 		for more details about how it works.[br]
409 	@seealso:
410 		[module:torrent]torrent module documentation[/module]
411 */
412 
413 TC_KVS_FLOATRET_FUNCTION(trafficUp, trafficUp)
414 
415 /*
416 	@doc: torrent.trafficDown
417 	@type:
418 		function
419 	@title:
420 		$torrent.trafficDown
421 	@short:
422 		Returns the total number of bytes downloaded
423 	@syntax:
424 		$torrent.trafficDown()
425 	@description:
426 		Returns the total number of bytes downloaded
427 		Take a look at the [module:torrent]torrent module documentation[/module]
428 		for more details about how it works.[br]
429 	@seealso:
430 		[module:torrent]torrent module documentation[/module]
431 */
432 
433 TC_KVS_FLOATRET_FUNCTION(trafficDown, trafficDown)
434 
435 /*
436 	@doc: torrent.count
437 	@type:
438 		function
439 	@title:
440 		$torrent.count
441 	@short:
442 		Returns number of torrents in client
443 	@syntax:
444 		$torrent.name()
445 	@description:
446 		Returns number of torrents in client
447 		Take a look at the [module:torrent]torrent module documentation[/module]
448 		for more details about how it works.[br]
449 	@seealso:
450 		[module:torrent]torrent module documentation[/module]
451 */
452 
453 TC_KVS_INTRET_FUNCTION(count, count)
454 
455 /*
456 	@doc: torrent.name
457 	@type:
458 		function
459 	@title:
460 		$torrent.name
461 	@short:
462 		Returns torrent name as displayed in client
463 	@syntax:
464 		$torrent.name(torrent_number)
465 	@description:
466 		Returns torrent name as displayed in client
467 		Take a look at the [module:torrent]torrent module documentation[/module]
468 		for more details about how it works.[br]
469 	@seealso:
470 		[module:torrent]torrent module documentation[/module]
471 */
472 
473 TC_KVS_STRINGRET_INT_FUNCTION(name, name, "torrent_number")
474 
475 /*
476 	@doc: torrent.start
477 	@type:
478 		command
479 	@title:
480 		torrent.start
481 	@short:
482 		Starts downloading of torrent <torrent_number>
483 	@syntax:
484 		torrent.start <torrent_number>
485 	@description:
486 		Starts downloading of torrent <torrent_number>
487 		Take a look at the [module:torrent]torrent module documentation[/module]
488 		for more details about how it works.[br]
489 	@seealso:
490 		[module:torrent]torrent module documentation[/module],
491 		[cmd]torrent.stop[/cmd], [cmd]torrent.stopAll[/cmd],
492 		[cmd]torrent.startAll[/cmd]
493 */
494 
495 TC_KVS_INT_COMMAND(start, start, "torrent_number")
496 
497 /*
498 	@doc: torrent.stop
499 	@type:
500 		command
501 	@title:
502 		torrent.stop
503 	@short:
504 		Stops downloading of torrent <torrent_number>
505 	@syntax:
506 		torrent.stop <torrent_number>
507 	@description:
508 		Stops downloading of torrent <torrent_number>
509 		Take a look at the [module:torrent]torrent module documentation[/module]
510 		for more details about how it works.[br]
511 	@seealso:
512 		[module:torrent]torrent module documentation[/module],
513 		[cmd]torrent.stopAll[/cmd], [cmd]torrent.startAll[/cmd],
514 		[cmd]torrent.start[/cmd]
515 */
516 
517 TC_KVS_INT_COMMAND(stop, stop, "torrent_number")
518 
519 /*
520 	@doc: torrent.announce
521 	@type:
522 		command
523 	@title:
524 		torrent.announce
525 	@short:
526 		Manually announces torrent to tracker
527 	@syntax:
528 		torrent.announce <torrent_number>
529 	@description:
530 		Manually announces torrent to tracker
531 		Take a look at the [module:torrent]torrent module documentation[/module]
532 		for more details about how it works.[br]
533 	@seealso:
534 		[module:torrent]torrent module documentation[/module]
535 */
536 
537 TC_KVS_INT_COMMAND(announce, announce, "torrent_number")
538 
539 /*
540 	@doc: torrent.fileCount
541 	@type:
542 		function
543 	@title:
544 		$torrent.fileCount
545 	@short:
546 		Returns the number of files in a torrent.
547 	@syntax:
548 		$torrent.fileCount <torrent_number>
549 	@description:
550 		Returns the number of files in a torrent.
551 		Take a look at the [module:torrent]torrent module documentation[/module]
552 		for more details about how it works.[br]
553 	@seealso:
554 		[module:torrent]torrent module documentation[/module]
555 */
556 
557 TC_KVS_INTRET_INT_FUNCTION(fileCount, fileCount, "torrent_number")
558 
559 /*
560 	@doc: torrent.fileName
561 	@type:
562 		function
563 	@title:
564 		$torrent.fileName
565 	@short:
566 		Returns the name of a file in a torrent.
567 	@syntax:
568 		$torrent.fileName <torrent_number> <file_number>
569 	@description:
570 		Returns the name of a file in a torrent.
571 		Take a look at the [module:torrent]torrent module documentation[/module]
572 		for more details about how it works.[br]
573 	@seealso:
574 		[module:torrent]torrent module documentation[/module]
575 */
576 
577 TC_KVS_STRINGRET_INT_INT_FUNCTION(fileName, fileName, "torrent_number", "file_number")
578 
579 /*
580 	@doc: torrent.filePriority
581 	@type:
582 		function
583 	@title:
584 		$torrent.filePriority
585 	@short:
586 		Returns the priority of a file in a torrent.
587 	@syntax:
588 		$torrent.filePriority <torrent_number> <file_number>
589 	@description:
590 		Returns the priority of a file in a torrent.
591 		Take a look at the [module:torrent]torrent module documentation[/module]
592 		for more details about how it works.[br]
593 	@seealso:
594 		[module:torrent]torrent module documentation[/module]
595 */
596 
597 TC_KVS_STRINGRET_INT_INT_FUNCTION(filePriority, filePriority, "torrent_number", "file_number")
598 
599 /*
600 	@doc: torrent.setFilePriority
601 	@type:
602 		command
603 	@title:
604 		torrent.setFilePriority
605 	@short:
606 		Sets the priority of a file in a torrent.
607 	@syntax:
608 		torrent.setFilePriority <torrent_number> <file_number>
609 	@description:
610 		Sets the priority of a file in a torrent.
611 		Take a look at the [module:torrent]torrent module documentation[/module]
612 		for more details about how it works.[br]
613 	@seealso:
614 		[module:torrent]torrent module documentation[/module]
615 */
616 
617 TC_KVS_INT_INT_STRING_COMMAND(setFilePriority, setFilePriority, "torrent_number", "file_number", "priority")
618 
619 /*
620 	@doc: torrent.startAll
621 	@type:
622 		command
623 	@title:
624 		torrent.startAll
625 	@short:
626 		Starts downloading of all torrents
627 	@syntax:
628 		torrent.startAll
629 	@description:
630 		Starts downloading of all torrents
631 		Take a look at the [module:torrent]torrent module documentation[/module]
632 		for more details about how it works.[br]
633 	@seealso:
634 		[module:torrent]torrent module documentation[/module],
635 		[cmd]torrent.stopAll[/cmd], [cmd]torrent.start[/cmd],
636 		[cmd]torrent.stop[/cmd]
637 */
638 
639 TC_KVS_SIMPLE_COMMAND(startAll, startAll)
640 
641 /*
642 	@doc: torrent.stopAll
643 	@type:
644 		command
645 	@title:
646 		torrent.stopAll
647 	@short:
648 		Stops downloading of all torrents
649 	@syntax:
650 		torrent.stopAll
651 	@description:
652 		Stops downloading of all torrents
653 		Take a look at the [module:torrent]torrent module documentation[/module]
654 		for more details about how it works.[br]
655 	@seealso:
656 		[module:torrent]torrent module documentation[/module],
657 		[cmd]torrent.startAll[/cmd], [cmd]torrent.start[/cmd],
658 		[cmd]torrent.stop[/cmd]
659 */
660 
661 TC_KVS_SIMPLE_COMMAND(stopAll, stopAll)
662 
663 /*
664 	@doc: torrent.setClient
665 	@type:
666 		command
667 	@title:
668 		torrent.setClient
669 	@short:
670 		Sets the torrent client interface
671 	@syntax:
672 		torrent.setClient <client_name>
673 	@description:
674 		Sets the torrent client interface to be used by the
675 		torrent interface module. <interface_name> must be one
676 		of the client names returned by [cmd]torrent.clientList[/cmd]
677 		Take a look at the [module:torrent]torrent module documentation[/module]
678 		for more details about how it works.[br]
679 	@seealso:
680 		[module:torrent]torrent module documentation[/module],
681 		[cmd]torrent.detect[/cmd], [fnc]$torrent.client[/fnc]
682 */
683 
684 TC_KVS_COMMAND(setClient)
685 {
686 	QString client;
687 
688 	KVSM_PARAMETERS_BEGIN(c)
689 	KVSM_PARAMETER("client", KVS_PT_STRING, 0, client)
690 	KVSM_PARAMETERS_END(c)
691 
692 	for(TorrentInterfaceDescriptor * d = g_pDescriptorList->first(); d; d = g_pDescriptorList->next())
693 	{
694 		if(d->name() == client)
695 		{
696 			TorrentInterface::select(d->instance());
697 			KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient) = client;
698 
699 			if(!c->hasSwitch('q', "quiet"))
700 				c->window()->output(KVI_OUT_TORRENT,
701 				    __tr2qs_ctx("Using client interface \"%Q\".", "torrent"),
702 				    &client);
703 			return true;
704 		}
705 	}
706 
707 	if(!c->hasSwitch('q', "quiet"))
708 		c->window()->output(KVI_OUT_TORRENT,
709 		    __tr2qs_ctx("Invalid client interface \"%Q\"!", "torrent"),
710 		    &client);
711 
712 	return false;
713 }
714 
715 /*
716 	@doc: torrent.client
717 	@type:
718 		function
719 	@title:
720 		$torrent.client
721 	@short:
722 		Returns the currently set torrent client interface
723 	@syntax:
724 		$torrent.client()
725 	@description:
726 		Returns the currently set torrent client interface.
727 		Take a look at the [module:torrent]torrent module documentation[/module]
728 		for more details about how it works.[br]
729 	@seealso:
730 		[module:torrent]torrent module documentation[/module],
731 		[cmd]torrent.detect[/cmd], [cmd]torrent.setClient[/cmd]
732 */
733 
TC_KVS_FUNCTION(client)734 TC_KVS_FUNCTION(client)
735 {
736 	c->returnValue()->setString(KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient));
737 	return true;
738 }
739 
740 /*
741 	@doc: torrent.clientList
742 	@type:
743 		function
744 	@title:
745 		$torrent.clientList
746 	@short:
747 		Returns a list of all supported clients.
748 	@syntax:
749 		$torrent.clientList()
750 	@description:
751 		Returns a list of all supported clients.
752 		Take a look at the [module:torrent]torrent module documentation[/module]
753 		for more details about how it works.[br]
754 	@seealso:
755 		[module:torrent]torrent module documentation[/module],
756 		[cmd]torrent.detect[/cmd], [cmd]torrent.setClient[/cmd],
757 		[cmd]torrent.client[/cmd]
758 */
759 
TC_KVS_FUNCTION(clientList)760 TC_KVS_FUNCTION(clientList)
761 {
762 	KviKvsArray * pArray = new KviKvsArray();
763 	int id = 0;
764 
765 	for(TorrentInterfaceDescriptor * d = g_pDescriptorList->first(); d; d = g_pDescriptorList->next())
766 		pArray->set(id++, new KviKvsVariant(d->name()));
767 
768 	c->returnValue()->setArray(pArray);
769 	return true;
770 }
771 
772 /*
773 	@doc: torrent.state
774 	@type:
775 		function
776 	@title:
777 		$torrent.state
778 	@short:
779 		Returns state of torrent (Stopped, Stalled, Seeding, Downloading)
780 	@syntax:
781 		$torrent.state <torrent_number>
782 	@description:
783 		Returns state of torrent (Stopped, Stalled, Seeding, Downloading)
784 		Take a look at the [module:torrent]torrent module documentation[/module]
785 		for more details about how it works.[br]
786 	@seealso:
787 		[module:torrent]torrent module documentation[/module]
788 */
789 
790 TC_KVS_STRINGRET_INT_FUNCTION(state, state, "torrent_number")
791 
792 /*
793 	@doc: torrent
794 	@type:
795 		module
796 	@short:
797 		Interface to the torrent clients
798 	@title:
799 		The torrent module
800 	@body:
801 		The torrent module is an interface to torrent clients. It currently supports KTorrent using D-Bus.[br]
802 		It provides the following set of commands:[br]
803 		[cmd]torrent.detect[/cmd]: Performs an auto-detection of installed torrent clients[br]
804 		[cmd]torrent.setClient[/cmd]: Sets the torrent client interface[br]
805 		[cmd]torrent.start[/cmd]: Starts downloading of a torrent[br]
806 		[cmd]torrent.stop[/cmd]: Stops downloading of a torrent[br]
807 		[cmd]torrent.announce[/cmd]: Manually announces torrent to tracker[br]
808 		[cmd]torrent.startAll[/cmd]: Starts downloading of all torrents[br]
809 		[cmd]torrent.stopAll[/cmd]: Stops downloading of all torrents[br]
810 		[cmd]torrent.setMaxUploadSpeed[/cmd]: Sets maximum upload speed[br]
811 		[cmd]torrent.setMaxDownloadSpeed[/cmd]: Sets maximum download speed[br]
812 		[cmd]torrent.setFilePriority[/cmd]: Sets the priority of a file in a torrent[br]
813 		[br]
814 		It provides the following set of functions:[br]
815 		[fnc]$torrent.client[/fnc]: Returns the currently set torrent client interface[br]
816 		[fnc]$torrent.clientList[/fnc]: Returns a list of all supported clients[br]
817 		[fnc]$torrent.maxUploadSpeed[/fnc]: Returns maximum upload speed set in client[br]
818 		[fnc]$torrent.maxDownloadSpeed[/fnc]: Returns maximum download speed set in client[br]
819 		[fnc]$torrent.speedUp[/fnc]: Returns current total upload speed[br]
820 		[fnc]$torrent.speedDown[/fnc]: Returns current total download speed[br]
821 		[fnc]$torrent.trafficUp[/fnc]: Returns the total number of bytes uploaded[br]
822 		[fnc]$torrent.trafficDown[/fnc]: Returns the total number of bytes downloaded[br]
823 		[fnc]$torrent.count[/fnc]: Returns number of torrents in client[br]
824 		[fnc]$torrent.name[/fnc]: Returns torrent name as displayed in client[br]
825 		[fnc]$torrent.state[/fnc]: Returns state of torrent[br]
826 		[fnc]$torrent.fileCount[/fnc]: Returns the number of files in a torrent[br]
827 		[fnc]$torrent.fileName[/fnc]: Returns the name of a file in a torrent[br]
828 		[fnc]$torrent.filePriority[/fnc]: Returns the priority of a file in a torrent[br]
829 */
830 
torrent_module_init(KviModule * m)831 static bool torrent_module_init(KviModule * m)
832 {
833 #define TC_KVS_REGCMD(__name, __stringname) KVSM_REGISTER_SIMPLE_COMMAND(m, __stringname, torrent_kvs_cmd_##__name)
834 #define TC_KVS_REGFNC(__name, __stringname) KVSM_REGISTER_FUNCTION(m, __stringname, torrent_kvs_fnc_##__name)
835 
836 	TC_KVS_REGCMD(detect, "detect");
837 	TC_KVS_REGCMD(setClient, "setClient");
838 	TC_KVS_REGCMD(start, "start")
839 	TC_KVS_REGCMD(stop, "stop")
840 	TC_KVS_REGCMD(announce, "announce")
841 	TC_KVS_REGCMD(startAll, "startAll")
842 	TC_KVS_REGCMD(stopAll, "stopAll")
843 	TC_KVS_REGCMD(setMaxUploadSpeed, "setMaxUploadSpeed")
844 	TC_KVS_REGCMD(setMaxDownloadSpeed, "setMaxDownloadSpeed")
845 	TC_KVS_REGCMD(setFilePriority, "setFilePriority")
846 	TC_KVS_REGFNC(client, "client")
847 	TC_KVS_REGFNC(clientList, "clientList")
848 	TC_KVS_REGFNC(maxUploadSpeed, "maxUploadSpeed")
849 	TC_KVS_REGFNC(maxDownloadSpeed, "maxDownloadSpeed")
850 	TC_KVS_REGFNC(speedUp, "speedUp")
851 	TC_KVS_REGFNC(speedDown, "speedDown")
852 	TC_KVS_REGFNC(trafficUp, "trafficUp")
853 	TC_KVS_REGFNC(trafficDown, "trafficDown")
854 	TC_KVS_REGFNC(count, "count")
855 	TC_KVS_REGFNC(name, "name")
856 	TC_KVS_REGFNC(state, "state")
857 	TC_KVS_REGFNC(fileCount, "fileCount")
858 	TC_KVS_REGFNC(fileName, "fileName")
859 	TC_KVS_REGFNC(filePriority, "filePriority")
860 
861 	g_pDescriptorList = new KviPointerList<TorrentInterfaceDescriptor>;
862 	g_pDescriptorList->setAutoDelete(true);
863 
864 #ifdef COMPILE_KDE_SUPPORT
865 	g_pDescriptorList->append(new KTorrentDbusInterfaceDescriptor);
866 #endif // COMPILE_KDE_SUPPORT
867 
868 	TorrentInterface::select(nullptr);
869 
870 	if(g_pMainWindow->mainStatusBar())
871 		StatusBarApplet::selfRegister(g_pMainWindow->mainStatusBar());
872 
873 	if(KVI_OPTION_STRING(KviOption_stringPreferredMediaPlayer) == "auto")
874 	{
875 		TorrentInterface::select(auto_detect_torrent_client());
876 	}
877 	else
878 	{
879 		for(TorrentInterfaceDescriptor * d = g_pDescriptorList->first(); d; d = g_pDescriptorList->next())
880 		{
881 			if(d->name() == KVI_OPTION_STRING(KviOption_stringPreferredTorrentClient))
882 				TorrentInterface::select(d->instance());
883 		}
884 	}
885 
886 	return true;
887 }
888 
torrent_module_cleanup(KviModule *)889 static bool torrent_module_cleanup(KviModule *)
890 {
891 	delete g_pDescriptorList;
892 	return true;
893 }
894 
torrent_module_can_unload(KviModule *)895 static bool torrent_module_can_unload(KviModule *)
896 {
897 	return true;
898 }
899 
torrent_module_ctrl(KviModule *,const char *,void *)900 static bool torrent_module_ctrl(KviModule *, const char *, void *) // KviModule * m,const char * operation,void * param)
901 {
902 	return false;
903 }
904 
905 KVIRC_MODULE(
906     "Torrent",
907     "4.0.0",
908     "Copyright (C) 2007 Alexander Stillich (torque at pltn dot org)"
909     "              2008 Fabio Bas (ctrlaltca at gmail dot com)",
910     "Interface to various torrent clients",
911     torrent_module_init,
912     torrent_module_can_unload,
913     torrent_module_ctrl,
914     torrent_module_cleanup,
915     "torrent")
916