summaryrefslogtreecommitdiffstats
path: root/deluge/ui/console/modes/torrentlist/torrentactions.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/console/modes/torrentlist/torrentactions.py')
-rw-r--r--deluge/ui/console/modes/torrentlist/torrentactions.py272
1 files changed, 272 insertions, 0 deletions
diff --git a/deluge/ui/console/modes/torrentlist/torrentactions.py b/deluge/ui/console/modes/torrentlist/torrentactions.py
new file mode 100644
index 0000000..a153e11
--- /dev/null
+++ b/deluge/ui/console/modes/torrentlist/torrentactions.py
@@ -0,0 +1,272 @@
+#
+# Copyright (C) 2011 Nick Lanham <nick@afternight.org>
+#
+# 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.
+#
+
+import logging
+import os
+
+from twisted.internet import defer
+
+import deluge.component as component
+from deluge.ui.client import client
+from deluge.ui.common import TORRENT_DATA_FIELD
+from deluge.ui.console.modes.torrentlist.queue_mode import QueueMode
+from deluge.ui.console.utils import colors
+from deluge.ui.console.utils.common import TORRENT_OPTIONS
+from deluge.ui.console.widgets.popup import InputPopup, MessagePopup, SelectablePopup
+
+from . import ACTION
+
+log = logging.getLogger(__name__)
+
+
+def action_error(error, mode):
+ mode.report_message('Error Occurred', error.getErrorMessage())
+ mode.refresh()
+
+
+def action_remove(mode=None, torrent_ids=None, **kwargs):
+ def do_remove(*args, **kwargs):
+ data = args[0] if args else None
+ if data is None or kwargs.get('close', False):
+ mode.pop_popup()
+ return True
+
+ mode.torrentview.clear_marked()
+ remove_data = data['remove_files']['value']
+
+ def on_removed_finished(errors):
+ if errors:
+ error_msgs = ''
+ for t_id, e_msg in errors:
+ error_msgs += f'Error removing torrent {t_id} : {e_msg}\n'
+ mode.report_message(
+ 'Error(s) occured when trying to delete torrent(s).', error_msgs
+ )
+ mode.refresh()
+
+ d = client.core.remove_torrents(torrent_ids, remove_data)
+ d.addCallback(on_removed_finished)
+ mode.pop_popup()
+
+ def got_status(status):
+ return (status['name'], status['state'])
+
+ callbacks = []
+ for tid in torrent_ids:
+ d = client.core.get_torrent_status(tid, ['name', 'state'])
+ callbacks.append(d.addCallback(got_status))
+
+ def remove_dialog(status):
+ status = [t_status[1] for t_status in status]
+
+ if len(torrent_ids) == 1:
+ rem_msg = '{!info!}Remove the following torrent?{!input!}'
+ else:
+ rem_msg = '{!info!}Remove the following %d torrents?{!input!}' % len(
+ torrent_ids
+ )
+
+ show_max = 6
+ for i, (name, state) in enumerate(status):
+ color = colors.state_color[state]
+ rem_msg += f'\n {color}* {{!input!}}{name}'
+ if i == show_max - 1:
+ if i < len(status) - 1:
+ rem_msg += '\n {!red!}And %i more' % (len(status) - show_max)
+ break
+
+ popup = InputPopup(
+ mode,
+ '(Esc to cancel, Enter to remove)',
+ close_cb=do_remove,
+ border_off_west=1,
+ border_off_north=1,
+ )
+ popup.add_text(rem_msg)
+ popup.add_spaces(1)
+ popup.add_select_input(
+ 'remove_files',
+ '{!info!}Torrent files:',
+ ['Keep', 'Remove'],
+ [False, True],
+ False,
+ )
+ mode.push_popup(popup)
+
+ defer.DeferredList(callbacks).addCallback(remove_dialog)
+
+
+def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
+ popup = MessagePopup(mode, 'Torrent options', 'Querying core, please wait...')
+ mode.push_popup(popup)
+ torrents = torrent_ids
+ options = {}
+
+ def _do_set_torrent_options(torrent_ids, result):
+ options = {}
+ for opt, val in result.items():
+ if val['value'] not in ['multiple', None]:
+ options[opt] = val['value']
+ client.core.set_torrent_options(torrent_ids, options)
+
+ def on_torrent_status(status):
+ for key in status:
+ if key not in options:
+ options[key] = status[key]
+ elif options[key] != status[key]:
+ options[key] = 'multiple'
+
+ def create_popup(status):
+ mode.pop_popup()
+
+ def cb(result, **kwargs):
+ if result is None:
+ return
+ _do_set_torrent_options(torrent_ids, result)
+ if kwargs.get('close', False):
+ mode.pop_popup()
+ return True
+
+ option_popup = InputPopup(
+ mode,
+ ' Set Torrent Options ',
+ close_cb=cb,
+ border_off_west=1,
+ border_off_north=1,
+ base_popup=kwargs.get('base_popup', None),
+ )
+ for field in TORRENT_OPTIONS:
+ caption = '{!info!}' + TORRENT_DATA_FIELD[field]['name']
+ value = options[field]
+ if isinstance(value, ''.__class__):
+ option_popup.add_text_input(field, caption, value)
+ elif isinstance(value, bool):
+ choices = (['Yes', 'No'], [True, False], [True, False].index(value))
+ option_popup.add_select_input(
+ field, caption, choices[0], choices[1], choices[2]
+ )
+ elif isinstance(value, float):
+ option_popup.add_float_spin_input(
+ field, caption, value=value, min_val=-1
+ )
+ elif isinstance(value, int):
+ option_popup.add_int_spin_input(field, caption, value=value, min_val=-1)
+
+ mode.push_popup(option_popup)
+
+ callbacks = []
+ for tid in torrents:
+ deferred = component.get('SessionProxy').get_torrent_status(
+ tid, list(TORRENT_OPTIONS)
+ )
+ callbacks.append(deferred.addCallback(on_torrent_status))
+
+ callbacks = defer.DeferredList(callbacks)
+ callbacks.addCallback(create_popup)
+
+
+def torrent_action(action, *args, **kwargs):
+ retval = False
+ torrent_ids = kwargs.get('torrent_ids', None)
+ mode = kwargs.get('mode', None)
+
+ if torrent_ids is None:
+ return
+
+ if action == ACTION.PAUSE:
+ log.debug('Pausing torrents: %s', torrent_ids)
+ client.core.pause_torrents(torrent_ids).addErrback(action_error, mode)
+ retval = True
+ elif action == ACTION.RESUME:
+ log.debug('Resuming torrents: %s', torrent_ids)
+ client.core.resume_torrents(torrent_ids).addErrback(action_error, mode)
+ retval = True
+ elif action == ACTION.QUEUE:
+ queue_mode = QueueMode(mode, torrent_ids)
+ queue_mode.popup(**kwargs)
+ elif action == ACTION.REMOVE:
+ action_remove(**kwargs)
+ retval = True
+ elif action == ACTION.MOVE_STORAGE:
+
+ def do_move(res, **kwargs):
+ if res is None or kwargs.get('close', False):
+ mode.pop_popup()
+ return True
+
+ if os.path.exists(res['path']['value']) and not os.path.isdir(
+ res['path']['value']
+ ):
+ mode.report_message(
+ 'Cannot Move Download Folder',
+ '{!error!}%s exists and is not a directory' % res['path']['value'],
+ )
+ else:
+ log.debug('Moving %s to: %s', torrent_ids, res['path']['value'])
+ client.core.move_storage(torrent_ids, res['path']['value']).addErrback(
+ action_error, mode
+ )
+
+ popup = InputPopup(
+ mode, 'Move Download Folder', close_cb=do_move, border_off_east=1
+ )
+ popup.add_text_input('path', 'Enter path to move to:', complete=True)
+ mode.push_popup(popup)
+ elif action == ACTION.RECHECK:
+ log.debug('Rechecking torrents: %s', torrent_ids)
+ client.core.force_recheck(torrent_ids).addErrback(action_error, mode)
+ retval = True
+ elif action == ACTION.REANNOUNCE:
+ log.debug('Reannouncing torrents: %s', torrent_ids)
+ client.core.force_reannounce(torrent_ids).addErrback(action_error, mode)
+ retval = True
+ elif action == ACTION.DETAILS:
+ log.debug('Torrent details')
+ tid = mode.torrentview.current_torrent_id()
+ if tid:
+ mode.show_torrent_details(tid)
+ else:
+ log.error('No current torrent in _torrentaction, this is a bug')
+ elif action == ACTION.TORRENT_OPTIONS:
+ action_torrent_info(**kwargs)
+
+ return retval
+
+
+# Creates the popup. mode is the calling mode, tids is a list of torrents to take action upon
+def torrent_actions_popup(mode, torrent_ids, details=False, action=None, close_cb=None):
+ if action is not None:
+ torrent_action(action, mode=mode, torrent_ids=torrent_ids)
+ return
+
+ popup = SelectablePopup(
+ mode,
+ 'Torrent Actions',
+ torrent_action,
+ cb_args={'mode': mode, 'torrent_ids': torrent_ids},
+ close_cb=close_cb,
+ border_off_north=1,
+ border_off_west=1,
+ border_off_east=1,
+ )
+ popup.add_line(ACTION.PAUSE, '_Pause')
+ popup.add_line(ACTION.RESUME, '_Resume')
+ if details:
+ popup.add_divider()
+ popup.add_line(ACTION.QUEUE, 'Queue')
+ popup.add_divider()
+ popup.add_line(ACTION.REANNOUNCE, '_Update Tracker')
+ popup.add_divider()
+ popup.add_line(ACTION.REMOVE, 'Remo_ve Torrent')
+ popup.add_line(ACTION.RECHECK, '_Force Recheck')
+ popup.add_line(ACTION.MOVE_STORAGE, '_Move Download Folder')
+ popup.add_divider()
+ if details:
+ popup.add_line(ACTION.DETAILS, 'Torrent _Details')
+ popup.add_line(ACTION.TORRENT_OPTIONS, 'Torrent _Options')
+ mode.push_popup(popup)