def torrent_action(idx, data, mode, ids): if ids: if data==ACTION.PAUSE: log.debug("Pausing torrents: %s",ids) client.core.pause_torrent(ids).addErrback(action_error,mode) elif data==ACTION.RESUME: log.debug("Resuming torrents: %s", ids) client.core.resume_torrent(ids).addErrback(action_error,mode) elif data==ACTION.QUEUE: def do_queue(idx,qact,mode,ids): def move_selection(r): if mode.config["move_selection"]: queue_length = 0 selected_num = 0 for tid in mode.curstate: tq = mode.curstate.get(tid)["queue"] if tq != -1: queue_length += 1 if tq in mode.marked: selected_num += 1 if qact == ACTION.QUEUE_TOP: if mode.marked: mode.cursel = 1 + sorted(mode.marked).index(mode.cursel) else: mode.cursel = 1 mode.marked = range(1, selected_num + 1) elif qact == ACTION.QUEUE_UP: mode.cursel = max(1, mode.cursel - 1) mode.marked = map(lambda v: v-1, mode.marked) mode.marked = filter(lambda v: v>0, mode.marked) elif qact == ACTION.QUEUE_DOWN: mode.cursel = min(queue_length, mode.cursel + 1) mode.marked = map(lambda v: v+1, mode.marked) mode.marked = filter(lambda v: v<=queue_length, mode.marked) elif qact == ACTION.QUEUE_BOTTOM: if mode.marked: mode.cursel = queue_length - selected_num + 1 + sorted(mode.marked).index(mode.cursel) else: mode.cursel = queue_length mode.marked = range(queue_length - selected_num + 1, queue_length+1) if qact == ACTION.QUEUE_TOP: log.debug("Queuing torrents top") client.core.queue_top(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_UP: log.debug("Queuing torrents up") client.core.queue_up(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_DOWN: log.debug("Queuing torrents down") client.core.queue_down(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_BOTTOM: log.debug("Queuing torrents bottom") client.core.queue_bottom(ids).addCallback(move_selection) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode,"Queue Action", do_queue, (mode, ids)) popup.add_line("_Top",data=ACTION.QUEUE_TOP) popup.add_line("_Up",data=ACTION.QUEUE_UP) popup.add_line("_Down",data=ACTION.QUEUE_DOWN) popup.add_line("_Bottom",data=ACTION.QUEUE_BOTTOM) mode.set_popup(popup) return False elif data==ACTION.REMOVE: def do_remove(data): if not data: return mode.clear_marks() wd = data["remove_files"] for tid in ids: log.debug("Removing torrent: %s, %d", tid, wd) client.core.remove_torrent(tid,wd).addErrback(action_error,mode) rem_msg = "" def got_status(status): return (status["name"], status["state"]) callbacks = [] for tid in ids: d = client.core.get_torrent_status(tid, ["name", "state"]) callbacks.append( d.addCallback(got_status) ) def finish_up(status): status = map(lambda x: x[1], status) if len(ids) == 1: rem_msg = "{!info!}Removing the following torrent:{!input!}" else: rem_msg = "{!info!}Removing the following torrents:{!input!}" for i, (name, state) in enumerate(status): color = colors.state_color[state] rem_msg += "\n %s* {!input!}%s" % (color, name) if i == 5: if i < len(status): rem_msg += "\n {!red!}And %i more" % (len(status) - 5) break popup = InputPopup(mode, "(Esc to cancel, Enter to remove)", close_cb=do_remove) popup.add_text(rem_msg) popup.add_spaces(1) popup.add_select_input("{!info!}Torrent files:", 'remove_files', ["Keep", "Remove"], [False, True], False) mode.set_popup(popup) defer.DeferredList(callbacks).addCallback(finish_up) return False elif data==ACTION.MOVE_STORAGE: def do_move(res): import os.path if os.path.exists(res["path"]) and not os.path.isdir(res["path"]): mode.report_message("Cannot Move Storage","{!error!}%s exists and is not a directory"%res["path"]) else: log.debug("Moving %s to: %s",ids,res["path"]) client.core.move_storage(ids,res["path"]).addErrback(action_error,mode) if len(ids) == 1: mode.clear_marks() return True popup = InputPopup(mode,"Move Storage (Esc to cancel)",close_cb=do_move) popup.add_text_input("Enter path to move to:","path") mode.set_popup(popup) return False elif data==ACTION.RECHECK: log.debug("Rechecking torrents: %s", ids) client.core.force_recheck(ids).addErrback(action_error,mode) elif data==ACTION.REANNOUNCE: log.debug("Reannouncing torrents: %s",ids) client.core.force_reannounce(ids).addErrback(action_error,mode) elif data==ACTION.DETAILS: log.debug("Torrent details") tid = mode.current_torrent_id() if tid: mode.show_torrent_details(tid) else: log.error("No current torrent in _torrent_action, this is a bug") elif data==ACTION.TORRENT_OPTIONS: mode.popup = Popup(mode, "Torrent options") mode.popup.add_line("Querying core, please wait...") torrents = ids options = {} def _do_set_torrent_options(ids, result): options = {} for opt in result: if result[opt] not in ["multiple", None]: options[opt] = result[opt] client.core.set_torrent_options( ids, options ) for tid in ids: if "move_on_completed_path" in options: client.core.set_torrent_move_completed_path(tid, options["move_on_completed_path"]) if "move_on_completed" in options: client.core.set_torrent_move_completed(tid, options["move_on_completed"]) if "is_auto_managed" in options: client.core.set_torrent_auto_managed(tid, options["is_auto_managed"]) if "remove_at_ratio" in options: client.core.set_torrent_remove_at_ratio(tid, options["remove_at_ratio"]) if "prioritize_first_last" in options: client.core.set_torrent_prioritize_first_last(tid, options["prioritize_first_last"]) 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): cb = lambda result, ids=ids: _do_set_torrent_options(ids, result) option_popup = InputPopup(mode,"Set torrent options (Esc to cancel)",close_cb=cb, height_req=22) for (field, field_type) in torrent_options: caption = "{!info!}" + torrent_options_to_names[field] value = options[field] if field_type == str: if not isinstance(value, basestring): value = str(value) option_popup.add_text_input(caption, field, value) elif field_type == bool: if options[field] == "multiple": choices = ( ["Yes", "No", "Mixed"], [True, False, None], 2 ) else: choices = ( ["Yes", "No"], [True, False], [True, False].index(options[field]) ) option_popup.add_select_input(caption, field, choices[0], choices[1], choices[2]) elif field_type == float: option_popup.add_float_spin_input(caption, field, value, min_val = -1) elif field_type == int: option_popup.add_int_spin_input(caption, field, value, min_val = -1) mode.set_popup(option_popup) mode.refresh() callbacks = [] field_list = map(lambda t: t[0], torrent_options) for tid in torrents: deferred = component.get("SessionProxy").get_torrent_status(tid, field_list) callbacks.append( deferred.addCallback(on_torrent_status) ) callbacks = defer.DeferredList(callbacks) callbacks.addCallback(create_popup) if len(ids) == 1: mode.clear_marks() return True
def torrent_actions_popup(mode,tids,details=False, action = None): if action != None: torrent_action(-1, action, mode, tids) return popup = SelectablePopup(mode,"Torrent Actions",torrent_action, (mode, tids)) popup.add_line("_Pause",data=ACTION.PAUSE) popup.add_line("_Resume",data=ACTION.RESUME) if details: popup.add_divider() popup.add_line("Queue",data=ACTION.QUEUE) popup.add_divider() popup.add_line("_Update Tracker",data=ACTION.REANNOUNCE) popup.add_divider() popup.add_line("Remo_ve Torrent",data=ACTION.REMOVE) popup.add_line("_Force Recheck",data=ACTION.RECHECK) popup.add_line("_Move Storage",data=ACTION.MOVE_STORAGE) popup.add_divider() if details: popup.add_line("Torrent _Details",data=ACTION.DETAILS) popup.add_line("Torrent _Options",data=ACTION.TORRENT_OPTIONS) mode.set_popup(popup)
def torrent_action(idx, data, mode, ids): if ids: if data == ACTION.PAUSE: log.debug("Pausing torrents: %s", ids) client.core.pause_torrent(ids).addErrback(action_error, mode) elif data == ACTION.RESUME: log.debug("Resuming torrents: %s", ids) client.core.resume_torrent(ids).addErrback(action_error, mode) elif data == ACTION.QUEUE: def do_queue(idx, qact, mode, ids): def move_selection(r): if mode.config["move_selection"]: queue_length = 0 selected_num = 0 for tid in mode.curstate: tq = mode.curstate.get(tid)["queue"] if tq != -1: queue_length += 1 if tq in mode.marked: selected_num += 1 if qact == ACTION.QUEUE_TOP: if mode.marked: mode.cursel = 1 + sorted(mode.marked).index( mode.cursel) else: mode.cursel = 1 mode.marked = range(1, selected_num + 1) elif qact == ACTION.QUEUE_UP: mode.cursel = max(1, mode.cursel - 1) mode.marked = map(lambda v: v - 1, mode.marked) mode.marked = filter(lambda v: v > 0, mode.marked) elif qact == ACTION.QUEUE_DOWN: mode.cursel = min(queue_length, mode.cursel + 1) mode.marked = map(lambda v: v + 1, mode.marked) mode.marked = filter(lambda v: v <= queue_length, mode.marked) elif qact == ACTION.QUEUE_BOTTOM: if mode.marked: mode.cursel = queue_length - selected_num + 1 + sorted( mode.marked).index(mode.cursel) else: mode.cursel = queue_length mode.marked = range( queue_length - selected_num + 1, queue_length + 1) if qact == ACTION.QUEUE_TOP: log.debug("Queuing torrents top") client.core.queue_top(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_UP: log.debug("Queuing torrents up") client.core.queue_up(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_DOWN: log.debug("Queuing torrents down") client.core.queue_down(ids).addCallback(move_selection) elif qact == ACTION.QUEUE_BOTTOM: log.debug("Queuing torrents bottom") client.core.queue_bottom(ids).addCallback(move_selection) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode, "Queue Action", do_queue, (mode, ids)) popup.add_line("_Top", data=ACTION.QUEUE_TOP) popup.add_line("_Up", data=ACTION.QUEUE_UP) popup.add_line("_Down", data=ACTION.QUEUE_DOWN) popup.add_line("_Bottom", data=ACTION.QUEUE_BOTTOM) mode.set_popup(popup) return False elif data == ACTION.REMOVE: def do_remove(data): if not data: return mode.clear_marks() wd = data["remove_files"] for tid in ids: log.debug("Removing torrent: %s, %d", tid, wd) client.core.remove_torrent(tid, wd).addErrback( action_error, mode) rem_msg = "" def got_status(status): return (status["name"], status["state"]) callbacks = [] for tid in ids: d = client.core.get_torrent_status(tid, ["name", "state"]) callbacks.append(d.addCallback(got_status)) def finish_up(status): status = map(lambda x: x[1], status) if len(ids) == 1: rem_msg = "{!info!}Removing the following torrent:{!input!}" else: rem_msg = "{!info!}Removing the following torrents:{!input!}" for i, (name, state) in enumerate(status): color = colors.state_color[state] rem_msg += "\n %s* {!input!}%s" % (color, name) if i == 5: if i < len(status): rem_msg += "\n {!red!}And %i more" % ( len(status) - 5) break popup = InputPopup(mode, "(Esc to cancel, Enter to remove)", close_cb=do_remove) popup.add_text(rem_msg) popup.add_spaces(1) popup.add_select_input("{!info!}Torrent files:", 'remove_files', ["Keep", "Remove"], [False, True], False) mode.set_popup(popup) defer.DeferredList(callbacks).addCallback(finish_up) return False elif data == ACTION.MOVE_STORAGE: def do_move(res): import os.path if os.path.exists( res["path"]) and not os.path.isdir(res["path"]): mode.report_message( "Cannot Move Storage", "{!error!}%s exists and is not a directory" % res["path"]) else: log.debug("Moving %s to: %s", ids, res["path"]) client.core.move_storage(ids, res["path"]).addErrback( action_error, mode) if len(ids) == 1: mode.clear_marks() return True popup = InputPopup(mode, "Move Storage (Esc to cancel)", close_cb=do_move) popup.add_text_input("Enter path to move to:", "path") mode.set_popup(popup) return False elif data == ACTION.RECHECK: log.debug("Rechecking torrents: %s", ids) client.core.force_recheck(ids).addErrback(action_error, mode) elif data == ACTION.REANNOUNCE: log.debug("Reannouncing torrents: %s", ids) client.core.force_reannounce(ids).addErrback(action_error, mode) elif data == ACTION.DETAILS: log.debug("Torrent details") tid = mode.current_torrent_id() if tid: mode.show_torrent_details(tid) else: log.error( "No current torrent in _torrent_action, this is a bug") elif data == ACTION.TORRENT_OPTIONS: mode.popup = Popup(mode, "Torrent options") mode.popup.add_line("Querying core, please wait...") torrents = ids options = {} def _do_set_torrent_options(ids, result): options = {} for opt in result: if result[opt] not in ["multiple", None]: options[opt] = result[opt] client.core.set_torrent_options(ids, options) for tid in ids: if "move_on_completed_path" in options: client.core.set_torrent_move_completed_path( tid, options["move_on_completed_path"]) if "move_on_completed" in options: client.core.set_torrent_move_completed( tid, options["move_on_completed"]) if "is_auto_managed" in options: client.core.set_torrent_auto_managed( tid, options["is_auto_managed"]) if "remove_at_ratio" in options: client.core.set_torrent_remove_at_ratio( tid, options["remove_at_ratio"]) if "prioritize_first_last" in options: client.core.set_torrent_prioritize_first_last( tid, options["prioritize_first_last"]) 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): cb = lambda result, ids=ids: _do_set_torrent_options( ids, result) option_popup = InputPopup( mode, "Set torrent options (Esc to cancel)", close_cb=cb, height_req=22) for (field, field_type) in torrent_options: caption = "{!info!}" + torrent_options_to_names[field] value = options[field] if field_type == str: if not isinstance(value, basestring): value = str(value) option_popup.add_text_input(caption, field, value) elif field_type == bool: if options[field] == "multiple": choices = (["Yes", "No", "Mixed"], [True, False, None], 2) else: choices = (["Yes", "No"], [True, False], [True, False].index(options[field])) option_popup.add_select_input(caption, field, choices[0], choices[1], choices[2]) elif field_type == float: option_popup.add_float_spin_input(caption, field, value, min_val=-1) elif field_type == int: option_popup.add_int_spin_input(caption, field, value, min_val=-1) mode.set_popup(option_popup) mode.refresh() callbacks = [] field_list = map(lambda t: t[0], torrent_options) for tid in torrents: deferred = component.get("SessionProxy").get_torrent_status( tid, field_list) callbacks.append(deferred.addCallback(on_torrent_status)) callbacks = defer.DeferredList(callbacks) callbacks.addCallback(create_popup) if len(ids) == 1: mode.clear_marks() return True
def torrent_actions_popup(mode, tids, details=False, action=None): if action != None: torrent_action(-1, action, mode, tids) return popup = SelectablePopup(mode, "Torrent Actions", torrent_action, (mode, tids)) popup.add_line("_Pause", data=ACTION.PAUSE) popup.add_line("_Resume", data=ACTION.RESUME) if details: popup.add_divider() popup.add_line("Queue", data=ACTION.QUEUE) popup.add_divider() popup.add_line("_Update Tracker", data=ACTION.REANNOUNCE) popup.add_divider() popup.add_line("Remo_ve Torrent", data=ACTION.REMOVE) popup.add_line("_Force Recheck", data=ACTION.RECHECK) popup.add_line("_Move Storage", data=ACTION.MOVE_STORAGE) popup.add_divider() if details: popup.add_line("Torrent _Details", data=ACTION.DETAILS) popup.add_line("Torrent _Options", data=ACTION.TORRENT_OPTIONS) mode.set_popup(popup)
def torrent_action(idx, data, mode, ids): if ids: if data == ACTION.PAUSE: log.debug("Pausing torrents: %s", ids) client.core.pause_torrent(ids).addErrback(action_error, mode) elif data == ACTION.RESUME: log.debug("Resuming torrents: %s", ids) client.core.resume_torrent(ids).addErrback(action_error, mode) elif data == ACTION.QUEUE: def do_queue(idx, qact, mode, ids): if qact == ACTION.QUEUE_TOP: log.debug("Queuing torrents top") client.core.queue_top(ids) elif qact == ACTION.QUEUE_UP: log.debug("Queuing torrents up") client.core.queue_up(ids) elif qact == ACTION.QUEUE_DOWN: log.debug("Queuing torrents down") client.core.queue_down(ids) elif qact == ACTION.QUEUE_BOTTOM: log.debug("Queuing torrents bottom") client.core.queue_bottom(ids) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode, "Queue Action", do_queue, mode, ids) popup.add_line("_Top", data=ACTION.QUEUE_TOP) popup.add_line("_Up", data=ACTION.QUEUE_UP) popup.add_line("_Down", data=ACTION.QUEUE_DOWN) popup.add_line("_Bottom", data=ACTION.QUEUE_BOTTOM) mode.set_popup(popup) return False elif data == ACTION.REMOVE: def do_remove(idx, data, mode, ids): if data: wd = data == ACTION.REMOVE_DATA for tid in ids: log.debug("Removing torrent: %s,%d", tid, wd) client.core.remove_torrent(tid, wd).addErrback(action_error, mode) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode, "Confirm Remove", do_remove, mode, ids) popup.add_line("Are you sure you want to remove the marked torrents?", selectable=False) popup.add_line("Remove with _data", data=ACTION.REMOVE_DATA) popup.add_line("Remove _torrent", data=ACTION.REMOVE_NODATA) popup.add_line("_Cancel", data=0) mode.set_popup(popup) return False elif data == ACTION.MOVE_STORAGE: def do_move(res): import os.path if os.path.exists(res["path"]) and not os.path.isdir(res["path"]): mode.report_message( "Cannot Move Storage", "{!error!}%s exists and is not a directory" % res["path"] ) else: log.debug("Moving %s to: %s", ids, res["path"]) client.core.move_storage(ids, res["path"]).addErrback(action_error, mode) if len(ids) == 1: mode.clear_marks() return True popup = InputPopup(mode, "Move Storage (Esc to cancel)", close_cb=do_move) popup.add_text_input("Enter path to move to:", "path") mode.set_popup(popup) return False elif data == ACTION.RECHECK: log.debug("Rechecking torrents: %s", ids) client.core.force_recheck(ids).addErrback(action_error, mode) elif data == ACTION.REANNOUNCE: log.debug("Reannouncing torrents: %s", ids) client.core.force_reannounce(ids).addErrback(action_error, mode) elif data == ACTION.DETAILS: log.debug("Torrent details") tid = mode.current_torrent_id() if tid: mode.show_torrent_details(tid) else: log.error("No current torrent in _torrent_action, this is a bug") if len(ids) == 1: mode.clear_marks() return True
def torrent_action(idx, data, mode, ids): if ids: if data == ACTION.PAUSE: log.debug("Pausing torrents: %s", ids) client.core.pause_torrent(ids).addErrback(action_error, mode) elif data == ACTION.RESUME: log.debug("Resuming torrents: %s", ids) client.core.resume_torrent(ids).addErrback(action_error, mode) elif data == ACTION.QUEUE: def do_queue(idx, qact, mode, ids): if qact == ACTION.QUEUE_TOP: log.debug("Queuing torrents top") client.core.queue_top(ids) elif qact == ACTION.QUEUE_UP: log.debug("Queuing torrents up") client.core.queue_up(ids) elif qact == ACTION.QUEUE_DOWN: log.debug("Queuing torrents down") client.core.queue_down(ids) elif qact == ACTION.QUEUE_BOTTOM: log.debug("Queuing torrents bottom") client.core.queue_bottom(ids) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode, "Queue Action", do_queue, mode, ids) popup.add_line("_Top", data=ACTION.QUEUE_TOP) popup.add_line("_Up", data=ACTION.QUEUE_UP) popup.add_line("_Down", data=ACTION.QUEUE_DOWN) popup.add_line("_Bottom", data=ACTION.QUEUE_BOTTOM) mode.set_popup(popup) return False elif data == ACTION.REMOVE: def do_remove(idx, data, mode, ids): if data: wd = data == ACTION.REMOVE_DATA for tid in ids: log.debug("Removing torrent: %s,%d", tid, wd) client.core.remove_torrent(tid, wd).addErrback( action_error, mode) if len(ids) == 1: mode.clear_marks() return True popup = SelectablePopup(mode, "Confirm Remove", do_remove, mode, ids) popup.add_line( "Are you sure you want to remove the marked torrents?", selectable=False) popup.add_line("Remove with _data", data=ACTION.REMOVE_DATA) popup.add_line("Remove _torrent", data=ACTION.REMOVE_NODATA) popup.add_line("_Cancel", data=0) mode.set_popup(popup) return False elif data == ACTION.MOVE_STORAGE: def do_move(res): import os.path if os.path.exists( res["path"]) and not os.path.isdir(res["path"]): mode.report_message( "Cannot Move Storage", "{!error!}%s exists and is not a directory" % res["path"]) else: log.debug("Moving %s to: %s", ids, res["path"]) client.core.move_storage(ids, res["path"]).addErrback( action_error, mode) if len(ids) == 1: mode.clear_marks() return True popup = InputPopup(mode, "Move Storage (Esc to cancel)", close_cb=do_move) popup.add_text_input("Enter path to move to:", "path") mode.set_popup(popup) return False elif data == ACTION.RECHECK: log.debug("Rechecking torrents: %s", ids) client.core.force_recheck(ids).addErrback(action_error, mode) elif data == ACTION.REANNOUNCE: log.debug("Reannouncing torrents: %s", ids) client.core.force_reannounce(ids).addErrback(action_error, mode) elif data == ACTION.DETAILS: log.debug("Torrent details") tid = mode.current_torrent_id() if tid: mode.show_torrent_details(tid) else: log.error( "No current torrent in _torrent_action, this is a bug") if len(ids) == 1: mode.clear_marks() return True