| | 1 | # |
| | 2 | # config.py |
| | 3 | # |
| | 4 | # Copyright (C) 2008-2009 Ido Abramovich <ido.deluge@gmail.com> |
| | 5 | # Copyright (C) 2009 Andrew Resch <andrewresch@gmail.com> |
| | 6 | # |
| | 7 | # Deluge is free software. |
| | 8 | # |
| | 9 | # You may redistribute it and/or modify it under the terms of the |
| | 10 | # GNU General Public License, as published by the Free Software |
| | 11 | # Foundation; either version 3 of the License, or (at your option) |
| | 12 | # any later version. |
| | 13 | # |
| | 14 | # deluge 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 deluge. If not, write to: |
| | 21 | # The Free Software Foundation, Inc., |
| | 22 | # 51 Franklin Street, Fifth Floor |
| | 23 | # Boston, MA 02110-1301, USA. |
| | 24 | # |
| | 25 | # In addition, as a special exception, the copyright holders give |
| | 26 | # permission to link the code of portions of this program with the OpenSSL |
| | 27 | # library. |
| | 28 | # You must obey the GNU General Public License in all respects for all of |
| | 29 | # the code used other than OpenSSL. If you modify file(s) with this |
| | 30 | # exception, you may extend this exception to your version of the file(s), |
| | 31 | # but you are not obligated to do so. If you do not wish to do so, delete |
| | 32 | # this exception statement from your version. If you delete this exception |
| | 33 | # statement from all source files in the program, then also delete it here. |
| | 34 | # |
| | 35 | # |
| | 36 | |
| | 37 | from twisted.internet import defer |
| | 38 | |
| | 39 | from deluge.ui.console.main import BaseCommand |
| | 40 | import deluge.ui.console.colors as colors |
| | 41 | from deluge.ui.client import client |
| | 42 | import deluge.component as component |
| | 43 | from deluge.log import LOG as log |
| | 44 | |
| | 45 | from optparse import make_option |
| | 46 | |
| | 47 | torrent_options = { |
| | 48 | "max_download_speed": float, |
| | 49 | "max_upload_speed": float, |
| | 50 | "max_connections": int, |
| | 51 | "max_upload_slots": int, |
| | 52 | "private": bool, |
| | 53 | "prioritize_first_last": bool, |
| | 54 | "is_auto_managed": bool, |
| | 55 | "stop_at_ratio": bool, |
| | 56 | "stop_ratio": float, |
| | 57 | "remove_at_ratio": bool, |
| | 58 | "move_on_completed": bool, |
| | 59 | "move_on_completed_path": str |
| | 60 | } |
| | 61 | |
| | 62 | |
| | 63 | class Command(BaseCommand): |
| | 64 | """Show and set per-torrent options""" |
| | 65 | |
| | 66 | option_list = BaseCommand.option_list + ( |
| | 67 | make_option('-s', '--set', action='store', nargs=2, dest='set', |
| | 68 | help='set value for key'), |
| | 69 | ) |
| | 70 | usage = "Usage: torrent_option <torrent-id> [<key1> [<key2> ...]]\n"\ |
| | 71 | " torrent_option <torrent-id> --set <key> <value>" |
| | 72 | |
| | 73 | def handle(self, *args, **options): |
| | 74 | self.console = component.get("ConsoleUI") |
| | 75 | if options['set']: |
| | 76 | return self._set_option(*args, **options) |
| | 77 | else: |
| | 78 | return self._get_option(*args, **options) |
| | 79 | |
| | 80 | |
| | 81 | def _get_option(self, *args, **options): |
| | 82 | |
| | 83 | def on_torrents_status(status): |
| | 84 | for torrentid, data in status.items(): |
| | 85 | self.console.write('') |
| | 86 | if 'name' in data: |
| | 87 | self.console.write('{!info!}Name: {!input!}%s' % data.get('name')) |
| | 88 | self.console.write('{!info!}ID: {!input!}%s' % torrentid) |
| | 89 | for k, v in data.items(): |
| | 90 | if k != 'name': |
| | 91 | self.console.write('{!info!}%s: {!input!}%s' % (k, v)) |
| | 92 | |
| | 93 | def on_torrents_status_fail(reason): |
| | 94 | self.console.write('{!error!}Failed to get torrent data.') |
| | 95 | |
| | 96 | torrent_ids = [] |
| | 97 | torrent_ids.extend(self.console.match_torrent(args[0])) |
| | 98 | |
| | 99 | request_options = [] |
| | 100 | for opt in args[1:]: |
| | 101 | if opt not in torrent_options: |
| | 102 | self.console.write('{!error!}Unknown torrent option: %s' % opt) |
| | 103 | return |
| | 104 | request_options.append(opt) |
| | 105 | if not request_options: |
| | 106 | request_options = [ opt for opt in torrent_options.keys() ] |
| | 107 | request_options.append('name') |
| | 108 | |
| | 109 | d = client.core.get_torrents_status({"id": torrent_ids}, request_options) |
| | 110 | d.addCallback(on_torrents_status) |
| | 111 | d.addErrback(on_torrents_status_fail) |
| | 112 | return d |
| | 113 | |
| | 114 | |
| | 115 | def _set_option(self, *args, **options): |
| | 116 | deferred = defer.Deferred() |
| | 117 | torrent_ids = [] |
| | 118 | torrent_ids.extend(self.console.match_torrent(args[0])) |
| | 119 | key = options["set"][0] |
| | 120 | val = options["set"][1] + " " .join(args[1:]) |
| | 121 | |
| | 122 | if key not in torrent_options: |
| | 123 | self.console.write("{!error!}The key '%s' is invalid!" % key) |
| | 124 | return |
| | 125 | |
| | 126 | val = torrent_options[key](val) |
| | 127 | |
| | 128 | def on_set_config(result): |
| | 129 | self.console.write("{!success!}Torrent option successfully updated.") |
| | 130 | deferred.callback(True) |
| | 131 | |
| | 132 | self.console.write("Setting %s to %s for torrents %s.." % (key, val, torrent_ids)) |
| | 133 | client.core.set_torrent_options(torrent_ids, {key: val}).addCallback(on_set_config) |
| | 134 | return deferred |