mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-20 03:24:54 +00:00
[Py2to3] Large set of changes for Python 3 compat
- Preparation work for using six or future module for Py2/3 compat. The code will be written in Python 3 with Python 2 fallbacks. - Added some Py3 imports with Py2 fallbacks to make it easier to remove Py2 code in future. - Replace xrange with range (sort out import as top of files in future). - Workaround Py2to3 basestring issue with inline if in instances. This means every usage of basestring is more considered. - Replace iteritems and itervalues for items and values. There might be a performance penalty on Py2 so might need to revisit this change.
This commit is contained in:
parent
321677e05a
commit
eb38e0ffff
64 changed files with 230 additions and 198 deletions
|
@ -21,14 +21,20 @@ import re
|
|||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
import chardet
|
||||
import pkg_resources
|
||||
|
||||
from deluge.error import InvalidPathError
|
||||
|
||||
try:
|
||||
from urllib.parse import unquote_plus, urljoin
|
||||
from urllib.request import pathname2url
|
||||
except ImportError:
|
||||
# PY2 fallback
|
||||
from urlparse import urljoin # pylint: disable=ungrouped-imports
|
||||
from urllib import pathname2url, unquote_plus # pylint: disable=ungrouped-imports
|
||||
|
||||
DBUS_FILEMAN = None
|
||||
# gi makes dbus available on Window but don't import it as unused.
|
||||
if platform.system() not in ('Windows', 'Microsoft', 'Darwin'):
|
||||
|
@ -56,6 +62,8 @@ TORRENT_STATE = [
|
|||
'Moving'
|
||||
]
|
||||
|
||||
PY2 = sys.version_info.major == 2
|
||||
|
||||
|
||||
def get_version():
|
||||
"""
|
||||
|
@ -82,12 +90,16 @@ def get_default_config_dir(filename=None):
|
|||
def save_config_path(resource):
|
||||
app_data_path = os.environ.get('APPDATA')
|
||||
if not app_data_path:
|
||||
import _winreg
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
|
||||
'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders')
|
||||
app_data_reg = _winreg.QueryValueEx(hkey, 'AppData')
|
||||
try:
|
||||
import winreg
|
||||
except ImportError:
|
||||
import _winreg as winreg # For Python 2.
|
||||
hkey = winreg.OpenKey(
|
||||
winreg.HKEY_CURRENT_USER,
|
||||
'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders')
|
||||
app_data_reg = winreg.QueryValueEx(hkey, 'AppData')
|
||||
app_data_path = app_data_reg[0]
|
||||
_winreg.CloseKey(hkey)
|
||||
winreg.CloseKey(hkey)
|
||||
return os.path.join(app_data_path, resource)
|
||||
else:
|
||||
from xdg.BaseDirectory import save_config_path
|
||||
|
@ -241,7 +253,7 @@ def show_file(path, timestamp=None):
|
|||
timestamp = int(time.time())
|
||||
startup_id = '%s_%u_%s-dbus_TIME%d' % (os.path.basename(sys.argv[0]), os.getpid(), os.uname()[1], timestamp)
|
||||
if DBUS_FILEMAN:
|
||||
paths = [urlparse.urljoin('file:', urllib.pathname2url(path))]
|
||||
paths = [urljoin('file:', pathname2url(path))]
|
||||
DBUS_FILEMAN.ShowItems(paths, startup_id, dbus_interface='org.freedesktop.FileManager1')
|
||||
else:
|
||||
env = os.environ.copy()
|
||||
|
@ -626,7 +638,7 @@ def get_magnet_info(uri):
|
|||
else:
|
||||
break
|
||||
elif param.startswith(dn_param):
|
||||
name = urllib.unquote_plus(param[len(dn_param):])
|
||||
name = unquote_plus(param[len(dn_param):])
|
||||
|
||||
if info_hash:
|
||||
if not name:
|
||||
|
@ -837,9 +849,9 @@ def utf8_encode_structure(data):
|
|||
|
||||
"""
|
||||
if isinstance(data, (list, tuple)):
|
||||
return type(data)(map(utf8_encode_structure, data))
|
||||
return type(data)([utf8_encode_structure(d) for d in data])
|
||||
elif isinstance(data, dict):
|
||||
return dict(map(utf8_encode_structure, data.items()))
|
||||
return dict([utf8_encode_structure(d) for d in data.items()])
|
||||
elif not isinstance(data, bytes):
|
||||
try:
|
||||
return data.encode('utf8')
|
||||
|
@ -1048,7 +1060,7 @@ def unicode_argv():
|
|||
# Remove Python executable and commands if present
|
||||
start = argc.value - len(sys.argv)
|
||||
return [argv[i] for i in
|
||||
xrange(start, argc.value)]
|
||||
range(start, argc.value)]
|
||||
else:
|
||||
# On other platforms, we have to find the likely encoding of the args and decode
|
||||
# First check if sys.stdout or stdin have encoding set
|
||||
|
|
|
@ -17,6 +17,8 @@ from twisted.internet import reactor
|
|||
from twisted.internet.defer import DeferredList, fail, maybeDeferred, succeed
|
||||
from twisted.internet.task import LoopingCall, deferLater
|
||||
|
||||
from deluge.common import PY2
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -307,7 +309,7 @@ class ComponentRegistry(object):
|
|||
# Start all the components if names is empty
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
elif isinstance(names, str if not PY2 else basestring):
|
||||
names = [names]
|
||||
|
||||
def on_depends_started(result, name):
|
||||
|
@ -341,7 +343,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
elif isinstance(names, str if not PY2 else basestring):
|
||||
names = [names]
|
||||
|
||||
def on_dependents_stopped(result, name):
|
||||
|
@ -379,7 +381,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
elif isinstance(names, str if not PY2 else basestring):
|
||||
names = [names]
|
||||
|
||||
deferreds = []
|
||||
|
@ -405,7 +407,7 @@ class ComponentRegistry(object):
|
|||
"""
|
||||
if not names:
|
||||
names = self.components.keys()
|
||||
elif not isinstance(names, (list, tuple)):
|
||||
elif isinstance(names, str if not PY2 else basestring):
|
||||
names = [names]
|
||||
|
||||
deferreds = []
|
||||
|
@ -429,7 +431,7 @@ class ComponentRegistry(object):
|
|||
def on_stopped(result):
|
||||
return DeferredList([comp._component_shutdown() for comp in self.components.values()])
|
||||
|
||||
return self.stop(self.components.keys()).addCallback(on_stopped)
|
||||
return self.stop(list(self.components.keys())).addCallback(on_stopped)
|
||||
|
||||
def update(self):
|
||||
"""Update all Components that are in a Started state."""
|
||||
|
|
|
@ -129,7 +129,7 @@ class Config(object):
|
|||
self._save_timer = None
|
||||
|
||||
if defaults:
|
||||
for key, value in defaults.iteritems():
|
||||
for key, value in defaults.items():
|
||||
self.set_item(key, value)
|
||||
|
||||
# Load the config from file in the config_dir
|
||||
|
@ -367,7 +367,7 @@ class Config(object):
|
|||
|
||||
"""
|
||||
log.debug('Calling all set functions..')
|
||||
for key, value in self.__set_functions.iteritems():
|
||||
for key, value in self.__set_functions.items():
|
||||
for func in value:
|
||||
func(key, self.__config[key])
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ class _ConfigManager(object):
|
|||
"""Get a reference to the Config object for this filename"""
|
||||
log.debug('Getting config: %s', config_file)
|
||||
# Create the config object if not already created
|
||||
if config_file not in self.config_files.keys():
|
||||
if config_file not in self.config_files:
|
||||
self.config_files[config_file] = Config(config_file, defaults,
|
||||
config_dir=self.config_directory,
|
||||
file_version=file_version)
|
||||
|
|
|
@ -27,12 +27,8 @@ AUTH_LEVELS_MAPPING = {
|
|||
'READONLY': AUTH_LEVEL_READONLY,
|
||||
'DEFAULT': AUTH_LEVEL_NORMAL,
|
||||
'NORMAL': AUTH_LEVEL_DEFAULT,
|
||||
'ADMIN': AUTH_LEVEL_ADMIN
|
||||
}
|
||||
|
||||
AUTH_LEVELS_MAPPING_REVERSE = {}
|
||||
for key, value in AUTH_LEVELS_MAPPING.iteritems():
|
||||
AUTH_LEVELS_MAPPING_REVERSE[value] = key
|
||||
'ADMIN': AUTH_LEVEL_ADMIN}
|
||||
AUTH_LEVELS_MAPPING_REVERSE = {v: k for k, v in AUTH_LEVELS_MAPPING.items()}
|
||||
|
||||
|
||||
class Account(object):
|
||||
|
|
|
@ -25,6 +25,7 @@ import deluge.common
|
|||
import deluge.component as component
|
||||
from deluge import path_chooser_common
|
||||
from deluge._libtorrent import lt
|
||||
from deluge.common import PY2
|
||||
from deluge.configmanager import ConfigManager, get_config_dir
|
||||
from deluge.core.alertmanager import AlertManager
|
||||
from deluge.core.authmanager import (AUTH_LEVEL_ADMIN, AUTH_LEVEL_NONE, AUTH_LEVELS_MAPPING,
|
||||
|
@ -40,6 +41,12 @@ from deluge.error import AddTorrentError, DelugeError, InvalidPathError, Invalid
|
|||
from deluge.event import NewVersionAvailableEvent, SessionPausedEvent, SessionResumedEvent, TorrentQueueChangedEvent
|
||||
from deluge.httpdownloader import download_file
|
||||
|
||||
try:
|
||||
from urllib.request import urlopen, URLError
|
||||
except ImportError:
|
||||
# PY2 fallback
|
||||
from urllib2 import urlopen, URLError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
OLD_SESSION_STATUS_KEYS = {
|
||||
|
@ -293,7 +300,6 @@ class Core(component.Component):
|
|||
|
||||
def get_new_release(self):
|
||||
log.debug('get_new_release')
|
||||
from urllib2 import urlopen, URLError
|
||||
try:
|
||||
self.new_release = urlopen('http://download.deluge-torrent.org/version-1.0').read().strip()
|
||||
except URLError as ex:
|
||||
|
@ -596,7 +602,7 @@ class Core(component.Component):
|
|||
status_dict, plugin_keys = args
|
||||
# Ask the plugin manager to fill in the plugin keys
|
||||
if len(plugin_keys) > 0:
|
||||
for key in status_dict.keys():
|
||||
for key in status_dict:
|
||||
status_dict[key].update(self.pluginmanager.get_status(key, plugin_keys))
|
||||
return status_dict
|
||||
d.addCallback(add_plugin_fields)
|
||||
|
@ -635,7 +641,7 @@ class Core(component.Component):
|
|||
def set_config(self, config):
|
||||
"""Set the config with values from dictionary"""
|
||||
# Load all the values into the configuration
|
||||
for key in config.keys():
|
||||
for key in config:
|
||||
if self.read_only_config_keys and key in self.read_only_config_keys:
|
||||
continue
|
||||
self.config[key] = config[key]
|
||||
|
@ -710,7 +716,7 @@ class Core(component.Component):
|
|||
if 'owner' in options and not self.core.authmanager.has_account(options['owner']):
|
||||
raise DelugeError('Username "%s" is not known.' % options['owner'])
|
||||
|
||||
if not isinstance(torrent_ids, (list, tuple)):
|
||||
if isinstance(torrent_ids, str if not PY2 else basestring):
|
||||
torrent_ids = [torrent_ids]
|
||||
|
||||
for torrent_id in torrent_ids:
|
||||
|
|
|
@ -12,7 +12,7 @@ from __future__ import unicode_literals
|
|||
import logging
|
||||
|
||||
import deluge.component as component
|
||||
from deluge.common import TORRENT_STATE
|
||||
from deluge.common import PY2, TORRENT_STATE
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
@ -133,7 +133,7 @@ class FilterManager(component.Component):
|
|||
|
||||
# Sanitize input: filter-value must be a list of strings
|
||||
for key, value in filter_dict.items():
|
||||
if not isinstance(value, (list, tuple)):
|
||||
if isinstance(value, str if not PY2 else basestring):
|
||||
filter_dict[key] = [value]
|
||||
|
||||
# Optimized filter for id
|
||||
|
@ -171,11 +171,11 @@ class FilterManager(component.Component):
|
|||
if not filter_dict:
|
||||
return torrent_ids
|
||||
|
||||
torrent_keys, plugin_keys = self.torrents.separate_keys(filter_dict.keys(), torrent_ids)
|
||||
torrent_keys, plugin_keys = self.torrents.separate_keys(list(filter_dict), torrent_ids)
|
||||
# Leftover filter arguments, default filter on status fields.
|
||||
for torrent_id in list(torrent_ids):
|
||||
status = self.core.create_torrent_status(torrent_id, torrent_keys, plugin_keys)
|
||||
for field, values in filter_dict.iteritems():
|
||||
for field, values in filter_dict.items():
|
||||
if field in status and status[field] in values:
|
||||
continue
|
||||
elif torrent_id in torrent_ids:
|
||||
|
@ -212,9 +212,7 @@ class FilterManager(component.Component):
|
|||
self._hide_state_items(items[cat])
|
||||
|
||||
# Return a dict of tuples:
|
||||
sorted_items = {}
|
||||
for field in tree_keys:
|
||||
sorted_items[field] = sorted(items[field].iteritems())
|
||||
sorted_items = {field: sorted(items[field].items()) for field in tree_keys}
|
||||
|
||||
if 'state' in tree_keys:
|
||||
sorted_items['state'].sort(self._sort_state_items)
|
||||
|
|
|
@ -12,6 +12,7 @@ from __future__ import unicode_literals
|
|||
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import threading
|
||||
|
||||
|
@ -28,6 +29,13 @@ try:
|
|||
except ImportError:
|
||||
GeoIP = None
|
||||
|
||||
try:
|
||||
from urllib.parse import quote_plus
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
from urllib import quote_plus
|
||||
from urllib2 import urlopen
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_PREFS = {
|
||||
|
@ -322,9 +330,6 @@ class PreferencesManager(component.Component):
|
|||
now = time.time()
|
||||
# check if we've done this within the last week or never
|
||||
if (now - self.config['info_sent']) >= (60 * 60 * 24 * 7):
|
||||
from urllib import quote_plus
|
||||
from urllib2 import urlopen
|
||||
import platform
|
||||
try:
|
||||
url = 'http://deluge-torrent.org/stats_get.php?processor=' + \
|
||||
platform.machine() + '&python=' + platform.python_version() \
|
||||
|
|
|
@ -437,7 +437,7 @@ class RPCServer(component.Component):
|
|||
:returns: the exported methods
|
||||
:rtype: list
|
||||
"""
|
||||
return self.factory.methods.keys()
|
||||
return list(self.factory.methods.keys())
|
||||
|
||||
def get_session_id(self):
|
||||
"""
|
||||
|
|
|
@ -159,7 +159,7 @@ class TorrentOptions(dict):
|
|||
'stop_ratio': 'stop_seed_ratio',
|
||||
'super_seeding': 'super_seeding'
|
||||
}
|
||||
for opt_k, conf_k in options_conf_map.iteritems():
|
||||
for opt_k, conf_k in options_conf_map.items():
|
||||
self[opt_k] = config[conf_k]
|
||||
self['file_priorities'] = []
|
||||
self['mapped_files'] = {}
|
||||
|
@ -924,7 +924,7 @@ class Torrent(object):
|
|||
self.update_status(self.handle.status())
|
||||
|
||||
if all_keys:
|
||||
keys = self.status_funcs.keys()
|
||||
keys = self.status_funcs
|
||||
|
||||
status_dict = {}
|
||||
|
||||
|
@ -1307,7 +1307,7 @@ class Torrent(object):
|
|||
torrent.waiting_on_folder_rename = [_dir for _dir in torrent.waiting_on_folder_rename if _dir]
|
||||
component.get('TorrentManager').save_resume_data((self.torrent_id,))
|
||||
|
||||
d = DeferredList(wait_on_folder.values())
|
||||
d = DeferredList(list(wait_on_folder.values()))
|
||||
d.addBoth(on_folder_rename_complete, self, folder, new_folder)
|
||||
return d
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"""TorrentManager handles Torrent objects"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import cPickle
|
||||
import cPickle as pickle
|
||||
import datetime
|
||||
import logging
|
||||
import operator
|
||||
|
@ -262,7 +262,7 @@ class TorrentManager(component.Component):
|
|||
list: A list of torrent_ids.
|
||||
|
||||
"""
|
||||
torrent_ids = self.torrents.keys()
|
||||
torrent_ids = list(self.torrents.keys())
|
||||
if component.get('RPCServer').get_session_auth_level() == AUTH_LEVEL_ADMIN:
|
||||
return torrent_ids
|
||||
|
||||
|
@ -493,8 +493,8 @@ class TorrentManager(component.Component):
|
|||
log.info('Loading torrent state: %s', filepath)
|
||||
try:
|
||||
with open(filepath, 'rb') as _file:
|
||||
state = cPickle.load(_file)
|
||||
except (IOError, EOFError, cPickle.UnpicklingError) as ex:
|
||||
state = pickle.load(_file)
|
||||
except (IOError, EOFError, pickle.UnpicklingError) as ex:
|
||||
log.warning('Unable to load %s: %s', filepath, ex)
|
||||
state = None
|
||||
else:
|
||||
|
@ -640,10 +640,10 @@ class TorrentManager(component.Component):
|
|||
try:
|
||||
log.debug('Creating the temporary file: %s', filepath_tmp)
|
||||
with open(filepath_tmp, 'wb', 0) as _file:
|
||||
cPickle.dump(state, _file)
|
||||
pickle.dump(state, _file)
|
||||
_file.flush()
|
||||
os.fsync(_file.fileno())
|
||||
except (OSError, cPickle.PicklingError) as ex:
|
||||
except (OSError, pickle.PicklingError) as ex:
|
||||
log.error('Unable to save %s: %s', filename, ex)
|
||||
return
|
||||
|
||||
|
@ -680,7 +680,7 @@ class TorrentManager(component.Component):
|
|||
|
||||
"""
|
||||
if torrent_ids is None:
|
||||
torrent_ids = (t[0] for t in self.torrents.iteritems() if t[1].handle.need_save_resume_data())
|
||||
torrent_ids = (tid for tid, t in self.torrents.items() if t.handle.need_save_resume_data())
|
||||
|
||||
def on_torrent_resume_save(dummy_result, torrent_id):
|
||||
"""Recieved torrent resume_data alert so remove from waiting list"""
|
||||
|
@ -852,8 +852,8 @@ class TorrentManager(component.Component):
|
|||
|
||||
def cleanup_torrents_prev_status(self):
|
||||
"""Run cleanup_prev_status for each registered torrent"""
|
||||
for torrent in self.torrents.iteritems():
|
||||
torrent[1].cleanup_prev_status()
|
||||
for torrent in self.torrents.values():
|
||||
torrent.cleanup_prev_status()
|
||||
|
||||
def on_set_max_connections_per_torrent(self, key, value):
|
||||
"""Sets the per-torrent connection limit"""
|
||||
|
@ -1270,7 +1270,7 @@ class TorrentManager(component.Component):
|
|||
if self.torrents:
|
||||
for torrent_id in torrent_ids:
|
||||
if torrent_id in self.torrents:
|
||||
status_keys = self.torrents[torrent_id].status_funcs.keys()
|
||||
status_keys = list(self.torrents[torrent_id].status_funcs.keys())
|
||||
leftover_keys = list(set(keys) - set(status_keys))
|
||||
torrent_keys = list(set(keys) - set(leftover_keys))
|
||||
return torrent_keys, leftover_keys
|
||||
|
|
|
@ -27,9 +27,9 @@ log = logging.getLogger(__name__)
|
|||
ignore = ['core', 'CVS', 'Thumbs.db', 'desktop.ini']
|
||||
|
||||
noncharacter_translate = {}
|
||||
for i in xrange(0xD800, 0xE000):
|
||||
for i in range(0xD800, 0xE000):
|
||||
noncharacter_translate[i] = ord('-')
|
||||
for i in xrange(0xFDD0, 0xFDF0):
|
||||
for i in range(0xFDD0, 0xFDF0):
|
||||
noncharacter_translate[i] = ord('-')
|
||||
for i in (0xFFFE, 0xFFFF):
|
||||
noncharacter_translate[i] = ord('-')
|
||||
|
|
|
@ -88,7 +88,7 @@ class PluginManagerBase(object):
|
|||
|
||||
def get_enabled_plugins(self):
|
||||
"""Returns a list of enabled plugins"""
|
||||
return self.plugins.keys()
|
||||
return list(self.plugins.keys())
|
||||
|
||||
def scan_for_plugins(self):
|
||||
"""Scans for available plugins"""
|
||||
|
@ -245,14 +245,14 @@ class PluginManagerBase(object):
|
|||
for line in self.pkg_env[name][0].get_metadata('PKG-INFO').splitlines():
|
||||
if not line:
|
||||
continue
|
||||
if line[0] in ' \t' and (len(line.split(':', 1)) == 1 or line.split(':', 1)[0] not in info.keys()):
|
||||
if line[0] in ' \t' and (len(line.split(':', 1)) == 1 or line.split(':', 1)[0] not in list(info.keys())):
|
||||
# This is a continuation
|
||||
cont_lines.append(line.strip())
|
||||
else:
|
||||
if cont_lines:
|
||||
info[last_header] = '\n'.join(cont_lines).strip()
|
||||
cont_lines = []
|
||||
if line.split(':', 1)[0] in info.keys():
|
||||
if line.split(':', 1)[0] in list(info.keys()):
|
||||
last_header = line.split(':', 1)[0]
|
||||
info[last_header] = line.split(':', 1)[1].strip()
|
||||
return info
|
||||
|
|
|
@ -101,7 +101,7 @@ class Core(CorePluginBase):
|
|||
|
||||
def enable_looping(self):
|
||||
# Enable all looping calls for enabled watchdirs here
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
for watchdir_id, watchdir in self.watchdirs.items():
|
||||
if watchdir['enabled']:
|
||||
self.enable_watchdir(watchdir_id)
|
||||
|
||||
|
@ -110,7 +110,7 @@ class Core(CorePluginBase):
|
|||
component.get('EventManager').deregister_event_handler(
|
||||
'PreTorrentRemovedEvent', self.__on_pre_torrent_removed
|
||||
)
|
||||
for loopingcall in self.update_timers.itervalues():
|
||||
for loopingcall in self.update_timers.values():
|
||||
loopingcall.stop()
|
||||
self.config.save()
|
||||
|
||||
|
@ -130,12 +130,12 @@ class Core(CorePluginBase):
|
|||
check_input(
|
||||
os.path.isdir(options['abspath']), _('Path does not exist.')
|
||||
)
|
||||
for w_id, w in self.watchdirs.iteritems():
|
||||
for w_id, w in self.watchdirs.items():
|
||||
if options['abspath'] == w['abspath'] and watchdir_id != w_id:
|
||||
raise Exception('Path is already being watched.')
|
||||
for key in options:
|
||||
if key not in OPTIONS_AVAILABLE:
|
||||
if key not in [key2 + '_toggle' for key2 in OPTIONS_AVAILABLE.iterkeys()]:
|
||||
if key not in [key2 + '_toggle' for key2 in OPTIONS_AVAILABLE]:
|
||||
raise Exception('autoadd: Invalid options key:%s' % key)
|
||||
# disable the watch loop if it was active
|
||||
if watchdir_id in self.update_timers:
|
||||
|
@ -225,7 +225,7 @@ class Core(CorePluginBase):
|
|||
watchdir['stop_ratio_toggle'] = watchdir['stop_at_ratio_toggle']
|
||||
# We default to True when reading _toggle values, so a config
|
||||
# without them is valid, and applies all its settings.
|
||||
for option, value in watchdir.iteritems():
|
||||
for option, value in watchdir.items():
|
||||
if OPTIONS_AVAILABLE.get(option):
|
||||
if watchdir.get(option + '_toggle', True) or option in ['owner', 'seed_mode']:
|
||||
opts[option] = value
|
||||
|
@ -383,12 +383,12 @@ class Core(CorePluginBase):
|
|||
return self.watchdirs
|
||||
|
||||
watchdirs = {}
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
for watchdir_id, watchdir in self.watchdirs.items():
|
||||
if watchdir.get('owner', 'localclient') == session_user:
|
||||
watchdirs[watchdir_id] = watchdir
|
||||
|
||||
log.debug('Current logged in user %s is not an ADMIN, send only '
|
||||
'his watchdirs: %s', session_user, watchdirs.keys())
|
||||
'his watchdirs: %s', session_user, list(watchdirs.keys()))
|
||||
return watchdirs
|
||||
|
||||
def _make_unicode(self, options):
|
||||
|
@ -411,7 +411,7 @@ class Core(CorePluginBase):
|
|||
os.access(abswatchdir, os.R_OK | os.W_OK),
|
||||
'You must have read and write access to watch folder.'
|
||||
)
|
||||
if abswatchdir in [wd['abspath'] for wd in self.watchdirs.itervalues()]:
|
||||
if abswatchdir in [wd['abspath'] for wd in self.watchdirs.values()]:
|
||||
raise Exception('Path is already being watched.')
|
||||
options.setdefault('enabled', False)
|
||||
options['abspath'] = abswatchdir
|
||||
|
@ -436,7 +436,7 @@ class Core(CorePluginBase):
|
|||
component.get('EventManager').emit(AutoaddOptionsChangedEvent())
|
||||
|
||||
def __migrate_config_1_to_2(self, config):
|
||||
for watchdir_id in config['watchdirs'].iterkeys():
|
||||
for watchdir_id in config['watchdirs']:
|
||||
config['watchdirs'][watchdir_id]['owner'] = 'localclient'
|
||||
return config
|
||||
|
||||
|
@ -449,7 +449,7 @@ class Core(CorePluginBase):
|
|||
torrent_id)
|
||||
return
|
||||
torrent_fname = torrent.filename
|
||||
for watchdir in self.watchdirs.itervalues():
|
||||
for watchdir in self.watchdirs.values():
|
||||
if not watchdir.get('copy_torrent_toggle', False):
|
||||
# This watchlist does copy torrents
|
||||
continue
|
||||
|
|
|
@ -403,7 +403,7 @@ class GtkUI(GtkPluginBase):
|
|||
|
||||
def create_model(self):
|
||||
store = gtk.ListStore(str, bool, str, str)
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
for watchdir_id, watchdir in self.watchdirs.items():
|
||||
store.append([
|
||||
watchdir_id, watchdir['enabled'],
|
||||
watchdir.get('owner', 'localclient'), watchdir['path']
|
||||
|
@ -476,7 +476,7 @@ class GtkUI(GtkPluginBase):
|
|||
|
||||
def on_apply_prefs(self):
|
||||
log.debug('applying prefs for AutoAdd')
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
for watchdir_id, watchdir in self.watchdirs.items():
|
||||
client.autoadd.set_options(watchdir_id, watchdir)
|
||||
|
||||
def on_show_prefs(self):
|
||||
|
@ -490,7 +490,7 @@ class GtkUI(GtkPluginBase):
|
|||
log.trace('Got whatchdirs from core: %s', watchdirs)
|
||||
self.watchdirs = watchdirs or {}
|
||||
self.store.clear()
|
||||
for watchdir_id, watchdir in self.watchdirs.iteritems():
|
||||
for watchdir_id, watchdir in self.watchdirs.items():
|
||||
self.store.append([
|
||||
watchdir_id, watchdir['enabled'],
|
||||
watchdir.get('owner', 'localclient'), watchdir['path']
|
||||
|
|
|
@ -134,7 +134,7 @@ class Core(CorePluginBase):
|
|||
def disable(self):
|
||||
self.config.save()
|
||||
event_manager = component.get('EventManager')
|
||||
for event, handler in self.registered_events.iteritems():
|
||||
for event, handler in self.registered_events.items():
|
||||
event_manager.deregister_event_handler(event, handler)
|
||||
log.debug('Execute core plugin disabled!')
|
||||
|
||||
|
|
|
@ -40,14 +40,18 @@ if windows_check():
|
|||
'C:\\Program Files (x86)\\7-Zip\\7z.exe',
|
||||
]
|
||||
|
||||
import _winreg
|
||||
try:
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Software\\7-Zip')
|
||||
import winreg
|
||||
except ImportError:
|
||||
import _winreg as winreg # For Python 2.
|
||||
|
||||
try:
|
||||
hkey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Software\\7-Zip')
|
||||
except WindowsError:
|
||||
pass
|
||||
else:
|
||||
win_7z_path = os.path.join(_winreg.QueryValueEx(hkey, 'Path')[0], '7z.exe')
|
||||
_winreg.CloseKey(hkey)
|
||||
win_7z_path = os.path.join(winreg.QueryValueEx(hkey, 'Path')[0], '7z.exe')
|
||||
winreg.CloseKey(hkey)
|
||||
win_7z_exes.insert(1, win_7z_path)
|
||||
|
||||
switch_7z = 'x -y'
|
||||
|
|
|
@ -109,7 +109,7 @@ class Core(CorePluginBase):
|
|||
|
||||
def init_filter_dict(self):
|
||||
filter_dict = dict([(label, 0) for label in self.labels.keys()])
|
||||
filter_dict['All'] = len(self.torrents.keys())
|
||||
filter_dict['All'] = len(self.torrents)
|
||||
return filter_dict
|
||||
|
||||
# Plugin hooks #
|
||||
|
@ -119,7 +119,7 @@ class Core(CorePluginBase):
|
|||
log.debug('post_torrent_add')
|
||||
torrent = self.torrents[torrent_id]
|
||||
|
||||
for label_id, options in self.labels.iteritems():
|
||||
for label_id, options in self.labels.items():
|
||||
if options['auto_add']:
|
||||
if self._has_auto_match(torrent, options):
|
||||
self.set_torrent(torrent_id, label_id)
|
||||
|
@ -133,7 +133,7 @@ class Core(CorePluginBase):
|
|||
# Utils #
|
||||
def clean_config(self):
|
||||
"""remove invalid data from config-file"""
|
||||
for torrent_id, label_id in list(self.torrent_labels.iteritems()):
|
||||
for torrent_id, label_id in list(self.torrent_labels.items()):
|
||||
if (label_id not in self.labels) or (torrent_id not in self.torrents):
|
||||
log.debug('label: rm %s:%s', torrent_id, label_id)
|
||||
del self.torrent_labels[torrent_id]
|
||||
|
@ -143,7 +143,7 @@ class Core(CorePluginBase):
|
|||
*add any new keys in OPTIONS_DEFAULTS
|
||||
*set all None values to default <-fix development config
|
||||
"""
|
||||
log.debug(self.labels.keys())
|
||||
log.debug(list(self.labels.keys()))
|
||||
for key in self.labels.keys():
|
||||
options = dict(OPTIONS_DEFAULTS)
|
||||
options.update(self.labels[key])
|
||||
|
@ -267,14 +267,14 @@ class Core(CorePluginBase):
|
|||
self.labels[label_id].update(options_dict)
|
||||
|
||||
# apply
|
||||
for torrent_id, label in self.torrent_labels.iteritems():
|
||||
for torrent_id, label in self.torrent_labels.items():
|
||||
if label_id == label and torrent_id in self.torrents:
|
||||
self._set_torrent_options(torrent_id, label_id)
|
||||
|
||||
# auto add
|
||||
options = self.labels[label_id]
|
||||
if options['auto_add']:
|
||||
for torrent_id, torrent in self.torrents.iteritems():
|
||||
for torrent_id, torrent in self.torrents.items():
|
||||
if self._has_auto_match(torrent, options):
|
||||
self.set_torrent(torrent_id, label_id)
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ class OptionsDialog(object):
|
|||
self.dialog.run()
|
||||
|
||||
def load_options(self, options):
|
||||
log.debug(options.keys())
|
||||
log.debug(list(options.keys()))
|
||||
|
||||
for spin_id in self.spin_ids + self.spin_int_ids:
|
||||
self.glade.get_widget(spin_id).set_value(options[spin_id])
|
||||
|
|
|
@ -19,15 +19,10 @@ import logging
|
|||
from twisted.internet import defer
|
||||
|
||||
from deluge import component
|
||||
from deluge.event import known_events
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from deluge.event import known_events
|
||||
except ImportError:
|
||||
# Old deluge version
|
||||
known_events = {}
|
||||
|
||||
|
||||
def get_resource(filename):
|
||||
import os
|
||||
|
@ -49,8 +44,8 @@ class CustomNotifications(object):
|
|||
pass
|
||||
|
||||
def disable(self):
|
||||
for kind in self.custom_notifications.iterkeys():
|
||||
for eventtype in self.custom_notifications[kind].copy().iterkeys():
|
||||
for kind in self.custom_notifications:
|
||||
for eventtype in list(self.custom_notifications[kind]):
|
||||
wrapper, handler = self.custom_notifications[kind][eventtype]
|
||||
self._deregister_custom_provider(kind, eventtype)
|
||||
|
||||
|
|
|
@ -67,10 +67,10 @@ DEFAULT_PREFS = {
|
|||
},
|
||||
}
|
||||
|
||||
RECIPIENT_FIELD, RECIPIENT_EDIT = range(2)
|
||||
RECIPIENT_FIELD, RECIPIENT_EDIT = list(range(2))
|
||||
(SUB_EVENT, SUB_EVENT_DOC, SUB_NOT_EMAIL, SUB_NOT_POPUP, SUB_NOT_BLINK,
|
||||
SUB_NOT_SOUND) = range(6)
|
||||
SND_EVENT, SND_EVENT_DOC, SND_NAME, SND_PATH = range(4)
|
||||
SUB_NOT_SOUND) = list(range(6))
|
||||
SND_EVENT, SND_EVENT_DOC, SND_NAME, SND_PATH = list(range(4))
|
||||
|
||||
|
||||
class GtkUiNotifications(CustomNotifications):
|
||||
|
|
|
@ -32,7 +32,7 @@ DEFAULT_PREFS = {
|
|||
'low_active': -1,
|
||||
'low_active_down': -1,
|
||||
'low_active_up': -1,
|
||||
'button_state': [[0] * 7 for dummy in xrange(24)]
|
||||
'button_state': [[0] * 7 for dummy in range(24)]
|
||||
}
|
||||
|
||||
STATES = {
|
||||
|
|
|
@ -43,7 +43,7 @@ class SchedulerSelectWidget(gtk.DrawingArea):
|
|||
self.colors = [[115 / 255, 210 / 255, 22 / 255],
|
||||
[237 / 255, 212 / 255, 0 / 255],
|
||||
[204 / 255, 0 / 255, 0 / 255]]
|
||||
self.button_state = [[0] * 7 for dummy in xrange(24)]
|
||||
self.button_state = [[0] * 7 for dummy in range(24)]
|
||||
|
||||
self.start_point = [0, 0]
|
||||
self.hover_point = [-1, -1]
|
||||
|
@ -67,8 +67,8 @@ class SchedulerSelectWidget(gtk.DrawingArea):
|
|||
width = self.window.get_size()[0]
|
||||
height = self.window.get_size()[1]
|
||||
|
||||
for y in xrange(7):
|
||||
for x in xrange(24):
|
||||
for y in range(7):
|
||||
for x in range(24):
|
||||
context.set_source_rgba(self.colors[self.button_state[x][y]][0],
|
||||
self.colors[self.button_state[x][y]][1],
|
||||
self.colors[self.button_state[x][y]][2], 0.7)
|
||||
|
@ -130,8 +130,8 @@ class SchedulerSelectWidget(gtk.DrawingArea):
|
|||
if self.mouse_press:
|
||||
points = [[self.hover_point[0], self.start_point[0]], [self.hover_point[1], self.start_point[1]]]
|
||||
|
||||
for x in xrange(min(points[0]), max(points[0]) + 1):
|
||||
for y in xrange(min(points[1]), max(points[1]) + 1):
|
||||
for x in range(min(points[0]), max(points[0]) + 1):
|
||||
for y in range(min(points[1]), max(points[1]) + 1):
|
||||
self.button_state[x][y] = self.button_state[self.start_point[0]][self.start_point[1]]
|
||||
|
||||
self.queue_draw()
|
||||
|
|
|
@ -136,7 +136,7 @@ class Core(CorePluginBase):
|
|||
|
||||
# extract the ones we are interested in
|
||||
# adding them to the 1s array
|
||||
for stat, stat_list in self.stats[1].iteritems():
|
||||
for stat, stat_list in self.stats[1].items():
|
||||
if stat in stats:
|
||||
stat_list.insert(0, int(stats[stat]))
|
||||
else:
|
||||
|
@ -150,7 +150,7 @@ class Core(CorePluginBase):
|
|||
self.last_update[interval] = update_time
|
||||
self.count[interval] = 0
|
||||
current_stats = self.stats[interval]
|
||||
for stat, stat_list in self.stats[base].iteritems():
|
||||
for stat, stat_list in self.stats[base].items():
|
||||
try:
|
||||
avg = mean(stat_list[0:multiplier])
|
||||
except ValueError:
|
||||
|
|
|
@ -135,7 +135,7 @@ class Graph(object):
|
|||
# this doesnt allow for dst and timezones...
|
||||
seconds_to_step = math.ceil(start / x_step) * x_step - start
|
||||
|
||||
for i in xrange(0, duration // x_step + 1):
|
||||
for i in range(0, duration // x_step + 1):
|
||||
text = time.strftime('%H:%M', time.localtime(start + seconds_to_step + i * x_step))
|
||||
# + 0.5 to allign x to nearest pixel
|
||||
x = int(ratio * (seconds_to_step + i * x_step) + left) + 0.5
|
||||
|
@ -220,7 +220,7 @@ class Graph(object):
|
|||
else:
|
||||
interval = interval * 2
|
||||
|
||||
intervals = [i * interval * scale for i in xrange(1 + int(math.ceil(x / interval)))]
|
||||
intervals = [i * interval * scale for i in range(1 + int(math.ceil(x / interval)))]
|
||||
return intervals
|
||||
|
||||
def draw_left_axis(self, bounds, y_ticks, y_tick_text):
|
||||
|
@ -244,7 +244,7 @@ class Graph(object):
|
|||
self.draw_y_text(y_tick_text[i], left, y)
|
||||
self.draw_line(gray, left, top, left, bottom)
|
||||
|
||||
for stat, info in stats.iteritems():
|
||||
for stat, info in stats.items():
|
||||
if len(info['values']) > 0:
|
||||
self.draw_value_poly(info['values'], info['color'], max_value, bounds)
|
||||
self.draw_value_poly(info['values'], info['fill_color'], max_value, bounds, info['fill'])
|
||||
|
|
|
@ -129,7 +129,7 @@ class GraphsTab(Tab):
|
|||
return False
|
||||
|
||||
def update(self):
|
||||
d1 = client.stats.get_stats(self.graph.stat_info.keys(), self.selected_interval)
|
||||
d1 = client.stats.get_stats(list(self.graph.stat_info.keys()), self.selected_interval)
|
||||
d1.addCallback(self.graph.set_stats)
|
||||
|
||||
def _update_complete(result):
|
||||
|
|
|
@ -18,7 +18,7 @@ from deluge.ui.client import client
|
|||
|
||||
|
||||
def print_totals(totals):
|
||||
for name, value in totals.iteritems():
|
||||
for name, value in totals.items():
|
||||
print(name, fsize(value))
|
||||
|
||||
print('overhead:')
|
||||
|
|
|
@ -60,6 +60,7 @@ same rencode version throughout your project.
|
|||
|
||||
import struct
|
||||
import sys
|
||||
from future_builtins import zip
|
||||
from threading import Lock
|
||||
|
||||
__version__ = ('Python', 1, 0, 4)
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import base64
|
||||
import sys
|
||||
from hashlib import sha1 as sha
|
||||
|
||||
import pytest
|
||||
|
@ -23,6 +22,7 @@ from twisted.web.static import File
|
|||
import deluge.common
|
||||
import deluge.component as component
|
||||
import deluge.core.torrent
|
||||
from deluge.common import PY2
|
||||
from deluge.core.core import Core
|
||||
from deluge.core.rpcserver import RPCServer
|
||||
from deluge.error import AddTorrentError, InvalidTorrentError
|
||||
|
@ -270,10 +270,7 @@ class CoreTestCase(BaseTestCase):
|
|||
def test_get_free_space(self):
|
||||
space = self.core.get_free_space('.')
|
||||
# get_free_space returns long on Python 2 (32-bit).
|
||||
if sys.version_info >= (3, 0):
|
||||
self.assertTrue(isinstance(space, int))
|
||||
else:
|
||||
self.assertTrue(isinstance(space, (int, long)))
|
||||
self.assertTrue(isinstance(space, int if not PY2 else (int, long)))
|
||||
self.assertTrue(space >= 0)
|
||||
self.assertEquals(self.core.get_free_space('/someinvalidpath'), -1)
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ class RPCRaiseDelugeErrorJSONTestCase(JSONBase):
|
|||
self.assertTrue('testclass.test' in methods)
|
||||
|
||||
request = MagicMock()
|
||||
request.getCookie = MagicMock(return_value=auth.config['sessions'].keys()[0])
|
||||
request.getCookie = MagicMock(return_value=list(auth.config['sessions'].keys())[0])
|
||||
json_data = {'method': 'testclass.test', 'id': 0, 'params': []}
|
||||
request.json = json_lib.dumps(json_data)
|
||||
request_id, result, error = json._handle_request(request)
|
||||
|
|
|
@ -35,7 +35,7 @@ class Core(object):
|
|||
|
||||
def get_torrent_status(self, torrent_id, keys, diff=False):
|
||||
if not keys:
|
||||
keys = self.torrents[torrent_id].keys()
|
||||
keys = list(self.torrents[torrent_id].keys())
|
||||
|
||||
if not diff:
|
||||
ret = {}
|
||||
|
@ -57,9 +57,9 @@ class Core(object):
|
|||
|
||||
def get_torrents_status(self, filter_dict, keys, diff=False):
|
||||
if not filter_dict:
|
||||
filter_dict['id'] = self.torrents.keys()
|
||||
filter_dict['id'] = list(self.torrents.keys())
|
||||
if not keys:
|
||||
keys = self.torrents['a'].keys()
|
||||
keys = list(self.torrents['a'].keys())
|
||||
if not diff:
|
||||
if 'id' in filter_dict:
|
||||
torrents = filter_dict['id']
|
||||
|
|
|
@ -152,7 +152,7 @@ class GtkUIBaseTestCase(UIBaseTestCase):
|
|||
"""Implement all GtkUI tests here"""
|
||||
|
||||
def test_start_gtkui(self):
|
||||
self.patch(sys, 'argv', self.var['sys_arg_cmd'])
|
||||
self.patch(sys, 'argv', utf8_encode_structure(self.var['sys_arg_cmd']))
|
||||
|
||||
from deluge.ui.gtkui import gtkui
|
||||
with mock.patch.object(gtkui.GtkUI, 'start', autospec=True):
|
||||
|
@ -168,7 +168,7 @@ class GtkUIDelugeScriptEntryTestCase(BaseTestCase, GtkUIBaseTestCase):
|
|||
|
||||
self.var['cmd_name'] = 'deluge gtk'
|
||||
self.var['start_cmd'] = ui_entry.start_ui
|
||||
self.var['sys_arg_cmd'] = utf8_encode_structure(['./deluge', 'gtk'])
|
||||
self.var['sys_arg_cmd'] = ['./deluge', 'gtk']
|
||||
|
||||
def set_up(self):
|
||||
return GtkUIBaseTestCase.set_up(self)
|
||||
|
|
|
@ -48,6 +48,7 @@ from __future__ import division, unicode_literals
|
|||
|
||||
import logging
|
||||
import struct
|
||||
from future_builtins import zip
|
||||
|
||||
import PIL.BmpImagePlugin
|
||||
import PIL.Image
|
||||
|
@ -77,9 +78,9 @@ class Win32IcoFile(object):
|
|||
self.nb_items = header[2]
|
||||
|
||||
dir_fields = ('width', 'height', 'nb_color', 'reserved', 'planes', 'bpp', 'size', 'offset')
|
||||
for i in xrange(self.nb_items):
|
||||
for i in range(self.nb_items):
|
||||
directory = list(struct.unpack('<4B2H2I', buf.read(16)))
|
||||
for j in xrange(3):
|
||||
for j in range(3):
|
||||
if not directory[j]:
|
||||
directory[j] = 256
|
||||
icon_header = dict(zip(dir_fields, directory))
|
||||
|
|
|
@ -397,7 +397,7 @@ class DaemonSSLProxy(DaemonProxy):
|
|||
# We need to tell the daemon what events we're interested in receiving
|
||||
if self.__factory.event_handlers:
|
||||
self.call('daemon.set_event_interest',
|
||||
self.__factory.event_handlers.keys())
|
||||
list(self.__factory.event_handlers.keys()))
|
||||
|
||||
self.call('core.get_auth_levels_mappings').addCallback(
|
||||
self.__on_auth_levels_mappings
|
||||
|
|
|
@ -207,7 +207,7 @@ class TorrentInfo(object):
|
|||
item.update(paths[path])
|
||||
item['download'] = True
|
||||
|
||||
file_tree = FileTree2(paths.keys())
|
||||
file_tree = FileTree2(list(paths.keys()))
|
||||
file_tree.walk(walk)
|
||||
else:
|
||||
def walk(path, item):
|
||||
|
|
|
@ -12,8 +12,6 @@ from __future__ import unicode_literals
|
|||
|
||||
import base64
|
||||
import os
|
||||
from urllib import url2pathname
|
||||
from urlparse import urlparse
|
||||
|
||||
from twisted.internet import defer
|
||||
|
||||
|
@ -23,6 +21,14 @@ from deluge.ui.client import client
|
|||
|
||||
from . import BaseCommand
|
||||
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import url2pathname
|
||||
except ImportError:
|
||||
# PY2 fallback
|
||||
from urlparse import urlparse # pylint: disable=ungrouped-imports
|
||||
from urllib import url2pathname # pylint: disable=ungrouped-imports
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Add torrents"""
|
||||
|
|
|
@ -123,7 +123,7 @@ class Command(BaseCommand):
|
|||
self.console.write('{!error!}%s' % ex)
|
||||
return
|
||||
|
||||
if key not in config.keys():
|
||||
if key not in list(config.keys()):
|
||||
self.console.write('{!error!}Invalid key: %s' % key)
|
||||
return
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ class Command(BaseCommand):
|
|||
self.console.write('{!error!}Unknown sort key: ' + sort_key + ', will sort on name')
|
||||
sort_key = 'name'
|
||||
sort_reverse = False
|
||||
for key, value in sorted(status.items(), key=lambda x: x[1].get(sort_key), reverse=sort_reverse):
|
||||
for key, value in sorted(list(status.items()), key=lambda x: x[1].get(sort_key), reverse=sort_reverse):
|
||||
self.show_info(key, status[key], options.verbose, options.detailed)
|
||||
|
||||
def on_torrents_status_fail(reason):
|
||||
|
|
|
@ -12,6 +12,7 @@ from __future__ import unicode_literals
|
|||
import base64
|
||||
import logging
|
||||
import os
|
||||
from future_builtins import zip
|
||||
|
||||
import deluge.common
|
||||
import deluge.component as component
|
||||
|
@ -513,9 +514,9 @@ class AddTorrents(BaseMode):
|
|||
elif chr(c) == 'M':
|
||||
if self.last_mark != -1:
|
||||
if self.last_mark > self.cursel:
|
||||
m = range(self.cursel, self.last_mark)
|
||||
m = list(range(self.cursel, self.last_mark))
|
||||
else:
|
||||
m = range(self.last_mark, self.cursel + 1)
|
||||
m = list(range(self.last_mark, self.cursel + 1))
|
||||
|
||||
for i in m:
|
||||
s = self.raw_rows[i][0]
|
||||
|
|
|
@ -68,7 +68,7 @@ arrow to edit the other value, and escape to get back to the check box.
|
|||
|
||||
class ZONE(object):
|
||||
length = 3
|
||||
CATEGORIES, PREFRENCES, ACTIONS = range(length)
|
||||
CATEGORIES, PREFRENCES, ACTIONS = list(range(length))
|
||||
|
||||
|
||||
class PreferenceSidebar(Sidebar):
|
||||
|
|
|
@ -79,7 +79,7 @@ class QueueMode(object):
|
|||
self.torrentview.cursel = 1 + sorted(self.torrentview.marked).index(self.torrentview.cursel)
|
||||
else:
|
||||
self.torrentview.cursel = 1
|
||||
self.torrentview.marked = range(1, selected_num + 1)
|
||||
self.torrentview.marked = list(range(1, selected_num + 1))
|
||||
elif qact == ACTION.QUEUE_UP:
|
||||
self.torrentview.cursel = max(1, self.torrentview.cursel - 1)
|
||||
self.torrentview.marked = [marked - 1 for marked in self.torrentview.marked]
|
||||
|
@ -94,7 +94,7 @@ class QueueMode(object):
|
|||
sorted(self.torrentview.marked).index(self.torrentview.cursel))
|
||||
else:
|
||||
self.torrentview.cursel = queue_length
|
||||
self.torrentview.marked = range(queue_length - selected_num + 1, queue_length + 1)
|
||||
self.torrentview.marked = list(range(queue_length - selected_num + 1, queue_length + 1))
|
||||
|
||||
def do_queue(self, qact, *args, **kwargs):
|
||||
if qact == ACTION.QUEUE_TOP:
|
||||
|
|
|
@ -103,7 +103,7 @@ def action_torrent_info(mode=None, torrent_ids=None, **kwargs):
|
|||
|
||||
def _do_set_torrent_options(torrent_ids, result):
|
||||
options = {}
|
||||
for opt, val in result.iteritems():
|
||||
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)
|
||||
|
|
|
@ -235,7 +235,7 @@ class TorrentView(InputKeyHandler):
|
|||
|
||||
# Get first element so we can check if it has given field
|
||||
# and if it's a string
|
||||
first_element = state[state.keys()[0]]
|
||||
first_element = state[list(state.keys())[0]]
|
||||
if field in first_element:
|
||||
def sort_key(s):
|
||||
try:
|
||||
|
@ -449,9 +449,9 @@ class TorrentView(InputKeyHandler):
|
|||
elif c == ord('M'):
|
||||
if self.last_mark >= 0:
|
||||
if self.cursel > self.last_mark:
|
||||
mrange = range(self.last_mark, self.cursel + 1)
|
||||
mrange = list(range(self.last_mark, self.cursel + 1))
|
||||
else:
|
||||
mrange = range(self.cursel, self.last_mark)
|
||||
mrange = list(range(self.cursel, self.last_mark))
|
||||
self.add_marked(mrange, self.cursel)
|
||||
affected_lines = mrange
|
||||
else:
|
||||
|
|
|
@ -260,7 +260,7 @@ class SelectablePopup(BaseInputPane, Popup):
|
|||
@overrides(Popup, BaseInputPane)
|
||||
def handle_read(self, c):
|
||||
if c in [curses.KEY_ENTER, util.KEY_ENTER2]:
|
||||
for k, v in self.get_values().iteritems():
|
||||
for k, v in self.get_values().items():
|
||||
if v['active']:
|
||||
if self.selection_cb(k, **dict(self.cb_args, data=self.cb_arg)):
|
||||
self.close(None)
|
||||
|
|
|
@ -299,7 +299,7 @@ class AddTorrentDialog(component.Component):
|
|||
|
||||
def add_files(self, parent_iter, split_files):
|
||||
ret = 0
|
||||
for key, value in split_files.iteritems():
|
||||
for key, value in split_files.items():
|
||||
if key.endswith(os.path.sep):
|
||||
chunk_iter = self.files_treestore.append(
|
||||
parent_iter, [True, key, 0, -1, False, gtk.STOCK_DIRECTORY])
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import contextlib
|
||||
import cPickle
|
||||
import cPickle as pickle
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
@ -143,7 +143,7 @@ def reparent_iter(treestore, itr, parent, move_siblings=False):
|
|||
|
||||
def move_children(i, dest):
|
||||
while i:
|
||||
n_cols = treestore.append(dest, treestore.get(i, *xrange(treestore.get_n_columns())))
|
||||
n_cols = treestore.append(dest, treestore.get(i, *range(treestore.get_n_columns())))
|
||||
to_remove = i
|
||||
if treestore.iter_children(i):
|
||||
move_children(treestore.iter_children(i), n_cols)
|
||||
|
@ -188,29 +188,32 @@ def associate_magnet_links(overwrite=False):
|
|||
"""
|
||||
|
||||
if windows_check():
|
||||
import _winreg
|
||||
try:
|
||||
import winreg
|
||||
except ImportError:
|
||||
import _winreg as winreg # For Python 2.
|
||||
|
||||
try:
|
||||
hkey = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
hkey = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
except WindowsError:
|
||||
overwrite = True
|
||||
else:
|
||||
_winreg.CloseKey(hkey)
|
||||
winreg.CloseKey(hkey)
|
||||
|
||||
if overwrite:
|
||||
deluge_exe = os.path.join(os.path.dirname(sys.executable), 'deluge.exe')
|
||||
try:
|
||||
magnet_key = _winreg.CreateKey(_winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
magnet_key = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, 'Magnet')
|
||||
except WindowsError:
|
||||
# Could not create for all users, falling back to current user
|
||||
magnet_key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, 'Software\\Classes\\Magnet')
|
||||
magnet_key = winreg.CreateKey(winreg.HKEY_CURRENT_USER, 'Software\\Classes\\Magnet')
|
||||
|
||||
_winreg.SetValue(magnet_key, '', _winreg.REG_SZ, 'URL:Magnet Protocol')
|
||||
_winreg.SetValueEx(magnet_key, 'URL Protocol', 0, _winreg.REG_SZ, '')
|
||||
_winreg.SetValueEx(magnet_key, 'BrowserFlags', 0, _winreg.REG_DWORD, 0x8)
|
||||
_winreg.SetValue(magnet_key, 'DefaultIcon', _winreg.REG_SZ, '{},0'.format(deluge_exe))
|
||||
_winreg.SetValue(magnet_key, r'shell\open\command', _winreg.REG_SZ, '"{}" "%1"'.format(deluge_exe))
|
||||
_winreg.CloseKey(magnet_key)
|
||||
winreg.SetValue(magnet_key, '', winreg.REG_SZ, 'URL:Magnet Protocol')
|
||||
winreg.SetValueEx(magnet_key, 'URL Protocol', 0, winreg.REG_SZ, '')
|
||||
winreg.SetValueEx(magnet_key, 'BrowserFlags', 0, winreg.REG_DWORD, 0x8)
|
||||
winreg.SetValue(magnet_key, 'DefaultIcon', winreg.REG_SZ, '{},0'.format(deluge_exe))
|
||||
winreg.SetValue(magnet_key, r'shell\open\command', winreg.REG_SZ, '"{}" "%1"'.format(deluge_exe))
|
||||
winreg.CloseKey(magnet_key)
|
||||
|
||||
# Don't try associate magnet on OSX see: #2420
|
||||
elif not osx_check():
|
||||
|
@ -259,11 +262,11 @@ def save_pickled_state_file(filename, state):
|
|||
try:
|
||||
with open(filepath_tmp, 'wb') as _file:
|
||||
# Pickle the state object
|
||||
cPickle.dump(state, _file)
|
||||
pickle.dump(state, _file)
|
||||
_file.flush()
|
||||
os.fsync(_file.fileno())
|
||||
shutil.move(filepath_tmp, filepath)
|
||||
except (IOError, EOFError, cPickle.PicklingError) as ex:
|
||||
except (IOError, EOFError, pickle.PicklingError) as ex:
|
||||
log.error('Unable to save %s: %s', filename, ex)
|
||||
if os.path.isfile(filepath_bak):
|
||||
log.info('Restoring backup of %s from: %s', filename, filepath_bak)
|
||||
|
@ -288,8 +291,8 @@ def load_pickled_state_file(filename):
|
|||
log.info('Opening %s for load: %s', filename, _filepath)
|
||||
try:
|
||||
with open(_filepath, 'rb') as _file:
|
||||
state = cPickle.load(_file)
|
||||
except (IOError, cPickle.UnpicklingError) as ex:
|
||||
state = pickle.load(_file)
|
||||
except (IOError, pickle.UnpicklingError) as ex:
|
||||
log.warning('Unable to load %s: %s', _filepath, ex)
|
||||
else:
|
||||
log.info('Successfully loaded %s: %s', filename, _filepath)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
from __future__ import division, unicode_literals
|
||||
|
||||
import cPickle
|
||||
import cPickle as pickle
|
||||
import logging
|
||||
import os.path
|
||||
|
||||
|
@ -344,7 +344,7 @@ class FilesTab(Tab):
|
|||
|
||||
def add_files(self, parent_iter, split_files):
|
||||
chunk_size_total = 0
|
||||
for key, value in split_files.iteritems():
|
||||
for key, value in split_files.items():
|
||||
if key.endswith('/'):
|
||||
chunk_iter = self.treestore.append(parent_iter,
|
||||
[key, 0, '', 0, 0, -1, gtk.STOCK_DIRECTORY])
|
||||
|
@ -623,7 +623,7 @@ class FilesTab(Tab):
|
|||
p_itr = self.get_iter_at_path('/'.join(parent_path) + '/')
|
||||
old_name_itr = self.get_iter_at_path(old_name)
|
||||
self.treestore.append(p_itr,
|
||||
self.treestore.get(old_name_itr, *xrange(self.treestore.get_n_columns())))
|
||||
self.treestore.get(old_name_itr, *range(self.treestore.get_n_columns())))
|
||||
self.treestore.remove(old_name_itr)
|
||||
|
||||
# Remove old parent path
|
||||
|
@ -637,7 +637,7 @@ class FilesTab(Tab):
|
|||
parent_iter, [f + '/', 0, '', 0, 0, -1, gtk.STOCK_DIRECTORY])
|
||||
child = self.get_iter_at_path(old_name)
|
||||
self.treestore.append(parent_iter,
|
||||
self.treestore.get(child, *xrange(self.treestore.get_n_columns())))
|
||||
self.treestore.get(child, *range(self.treestore.get_n_columns())))
|
||||
self.treestore.remove(child)
|
||||
|
||||
else:
|
||||
|
@ -750,12 +750,12 @@ class FilesTab(Tab):
|
|||
|
||||
def _on_drag_data_get_data(self, treeview, context, selection, target_id, etime):
|
||||
paths = self.listview.get_selection().get_selected_rows()[1]
|
||||
selection.set_text(cPickle.dumps(paths))
|
||||
selection.set_text(pickle.dumps(paths))
|
||||
|
||||
def _on_drag_data_received_data(self, treeview, context, x, y, selection, info, etime):
|
||||
try:
|
||||
selected = cPickle.loads(selection.data)
|
||||
except cPickle.UnpicklingError:
|
||||
selected = pickle.loads(selection.data)
|
||||
except pickle.UnpicklingError:
|
||||
log.debug('Invalid selection data: %s', selection.data)
|
||||
return
|
||||
log.debug('selection.data: %s', selected)
|
||||
|
|
|
@ -161,7 +161,7 @@ class FilterTreeView(component.Component):
|
|||
|
||||
# update rows
|
||||
visible_filters = []
|
||||
for cat, filters in filter_items.iteritems():
|
||||
for cat, filters in filter_items.items():
|
||||
for value, count in filters:
|
||||
self.update_row(cat, value, count)
|
||||
visible_filters.append((cat, value))
|
||||
|
|
|
@ -15,8 +15,6 @@ import os
|
|||
import sys
|
||||
from glob import glob
|
||||
from tempfile import mkstemp
|
||||
from urllib import url2pathname
|
||||
from urlparse import urlparse
|
||||
|
||||
import twisted.internet.error
|
||||
from twisted.internet import reactor
|
||||
|
@ -32,6 +30,14 @@ try:
|
|||
except ImportError:
|
||||
import deluge.rencode as rencode # pylint: disable=ungrouped-imports
|
||||
|
||||
try:
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import url2pathname
|
||||
except ImportError:
|
||||
# PY2 fallback
|
||||
from urlparse import urlparse # pylint: disable=ungrouped-imports
|
||||
from urllib import url2pathname # pylint: disable=ungrouped-imports
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ class ListView(object):
|
|||
|
||||
def set_col_attributes(self, renderer, add=True, **kw):
|
||||
if add is True:
|
||||
for attr, value in kw.iteritems():
|
||||
for attr, value in kw.items():
|
||||
self.add_attribute(renderer, attr, value)
|
||||
else:
|
||||
self.set_attributes(renderer, **kw)
|
||||
|
|
|
@ -39,7 +39,7 @@ class _GtkBuilderSignalsHolder(object):
|
|||
def connect_signals(self, mapping_or_class):
|
||||
|
||||
if isinstance(mapping_or_class, dict):
|
||||
for name, handler in mapping_or_class.iteritems():
|
||||
for name, handler in mapping_or_class.items():
|
||||
if hasattr(self, name):
|
||||
raise RuntimeError(
|
||||
'A handler for signal %r has already been registered: %s' %
|
||||
|
|
|
@ -411,7 +411,7 @@ class MenuBar(component.Component):
|
|||
'menuitem_max_connections': 'max_connections',
|
||||
'menuitem_upload_slots': 'max_upload_slots'
|
||||
}
|
||||
if widget.get_name() in funcs.keys():
|
||||
if widget.get_name() in list(funcs.keys()):
|
||||
torrent_ids = component.get('TorrentView').get_selected_torrents()
|
||||
client.core.set_torrent_options(torrent_ids, {funcs[widget.get_name()]: -1})
|
||||
|
||||
|
@ -494,7 +494,7 @@ class MenuBar(component.Component):
|
|||
known_accounts_to_log = []
|
||||
for account in known_accounts:
|
||||
account_to_log = {}
|
||||
for key, value in account.copy().iteritems():
|
||||
for key, value in account.copy().items():
|
||||
if key == 'password':
|
||||
value = '*' * len(value)
|
||||
account_to_log[key] = value
|
||||
|
@ -537,7 +537,7 @@ class MenuBar(component.Component):
|
|||
return
|
||||
|
||||
torrent_owner = component.get('TorrentView').get_torrent_status(selected[0])['owner']
|
||||
for username, item in self.change_owner_submenu_items.iteritems():
|
||||
for username, item in self.change_owner_submenu_items.items():
|
||||
item.set_active(username == torrent_owner)
|
||||
|
||||
def _on_change_owner_toggled(self, widget, username):
|
||||
|
|
|
@ -116,7 +116,7 @@ class OptionsTab(Tab):
|
|||
# We only want to update values that have been applied in the core. This
|
||||
# is so we don't overwrite the user changes that haven't been applied yet.
|
||||
if self.prev_status is None:
|
||||
self.prev_status = {}.fromkeys(status.keys(), None)
|
||||
self.prev_status = {}.fromkeys(list(status.keys()), None)
|
||||
|
||||
if status != self.prev_status:
|
||||
if status['max_download_speed'] != self.prev_status['max_download_speed']:
|
||||
|
|
|
@ -60,7 +60,7 @@ class PathChoosersHandler(component.Component):
|
|||
self.config_properties.update(config)
|
||||
for chooser in self.path_choosers:
|
||||
chooser.set_config(config)
|
||||
keys = self.config_keys_to_funcs_mapping.keys()
|
||||
keys = list(self.config_keys_to_funcs_mapping.keys())
|
||||
keys += self.paths_list_keys
|
||||
client.core.get_config_values(keys).addCallback(_on_config_values)
|
||||
|
||||
|
@ -109,7 +109,7 @@ class PathChoosersHandler(component.Component):
|
|||
chooser.set_values(values)
|
||||
|
||||
def get_config_keys(self):
|
||||
keys = self.config_keys_to_funcs_mapping.keys()
|
||||
keys = list(self.config_keys_to_funcs_mapping.keys())
|
||||
keys += self.paths_list_keys
|
||||
return keys
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ except ImportError:
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
ACCOUNTS_USERNAME, ACCOUNTS_LEVEL, ACCOUNTS_PASSWORD = range(3)
|
||||
COLOR_MISSING, COLOR_WAITING, COLOR_DOWNLOADING, COLOR_COMPLETED = range(4)
|
||||
ACCOUNTS_USERNAME, ACCOUNTS_LEVEL, ACCOUNTS_PASSWORD = list(range(3))
|
||||
COLOR_MISSING, COLOR_WAITING, COLOR_DOWNLOADING, COLOR_COMPLETED = list(range(4))
|
||||
|
||||
COLOR_STATES = {
|
||||
'missing': COLOR_MISSING,
|
||||
|
@ -1020,7 +1020,7 @@ class Preferences(component.Component):
|
|||
known_accounts_to_log = []
|
||||
for account in known_accounts:
|
||||
account_to_log = {}
|
||||
for key, value in account.copy().iteritems():
|
||||
for key, value in account.copy().items():
|
||||
if key == 'password':
|
||||
value = '*' * len(value)
|
||||
account_to_log[key] = value
|
||||
|
|
|
@ -287,7 +287,7 @@ class StatusBar(component.Component):
|
|||
This is called when we receive a ConfigValueChangedEvent from
|
||||
the core.
|
||||
"""
|
||||
if key in self.config_value_changed_dict.keys():
|
||||
if key in list(self.config_value_changed_dict.keys()):
|
||||
self.config_value_changed_dict[key](value)
|
||||
|
||||
def _on_max_connections_global(self, max_connections):
|
||||
|
|
|
@ -179,7 +179,7 @@ class SystemTray(component.Component):
|
|||
def config_value_changed(self, key, value):
|
||||
"""This is called when we received a config_value_changed signal from
|
||||
the core."""
|
||||
if key in self.config_value_changed_dict.keys():
|
||||
if key in list(self.config_value_changed_dict.keys()):
|
||||
self.config_value_changed_dict[key](value)
|
||||
|
||||
def _on_max_download_speed(self, max_download_speed):
|
||||
|
|
|
@ -129,7 +129,7 @@ class TorrentDetails(component.Component):
|
|||
# We need to rename the tab in the state for backwards compat
|
||||
self.state = [(tab_name.replace('Statistics', 'Status'), visible) for tab_name, visible in state]
|
||||
|
||||
for tab in default_tabs.itervalues():
|
||||
for tab in default_tabs.values():
|
||||
self.add_tab(tab(), generate_menu=False)
|
||||
|
||||
# Generate the checklist menu
|
||||
|
@ -140,7 +140,7 @@ class TorrentDetails(component.Component):
|
|||
# Determine insert position based on weight
|
||||
# weights is a list of visible tab names in weight order
|
||||
|
||||
weights = sorted([(tab.weight, name) for name, tab in self.tabs.iteritems() if tab.is_visible])
|
||||
weights = sorted([(tab.weight, name) for name, tab in self.tabs.items() if tab.is_visible])
|
||||
|
||||
log.debug('weights: %s', weights)
|
||||
log.debug('weight of tab: %s', weight)
|
||||
|
@ -219,7 +219,7 @@ class TorrentDetails(component.Component):
|
|||
def hide_all_tabs(self):
|
||||
"""Hides all tabs"""
|
||||
log.debug('n_pages: %s', self.notebook.get_n_pages())
|
||||
for n in xrange(self.notebook.get_n_pages() - 1, -1, -1):
|
||||
for n in range(self.notebook.get_n_pages() - 1, -1, -1):
|
||||
self.notebook.remove_page(n)
|
||||
|
||||
for tab in self.tabs:
|
||||
|
@ -243,7 +243,7 @@ class TorrentDetails(component.Component):
|
|||
self.generate_menu()
|
||||
|
||||
show = False
|
||||
for name, tab in self.tabs.iteritems():
|
||||
for name, tab in self.tabs.items():
|
||||
show = show or tab.is_visible
|
||||
|
||||
self.visible(show)
|
||||
|
|
|
@ -413,7 +413,7 @@ class TorrentView(ListView, component.Component):
|
|||
|
||||
if columns is None:
|
||||
# We need to iterate through all columns
|
||||
columns = self.columns.keys()
|
||||
columns = list(self.columns.keys())
|
||||
|
||||
# Iterate through supplied list of columns to update
|
||||
for column in columns:
|
||||
|
@ -486,7 +486,7 @@ class TorrentView(ListView, component.Component):
|
|||
|
||||
# Get the columns to update from one of the torrents
|
||||
if status:
|
||||
torrent_id = status.keys()[0]
|
||||
torrent_id = list(status.keys())[0]
|
||||
fields_to_update = []
|
||||
for column in self.columns_to_update:
|
||||
column_index = self.get_column_index(column)
|
||||
|
@ -626,7 +626,7 @@ class TorrentView(ListView, component.Component):
|
|||
return {}
|
||||
|
||||
def get_visible_torrents(self):
|
||||
return self.status.keys()
|
||||
return list(self.status.keys())
|
||||
|
||||
# Callbacks #
|
||||
def on_button_press_event(self, widget, event):
|
||||
|
|
|
@ -92,7 +92,7 @@ class SessionProxy(component.Component):
|
|||
keys_to_remove = keys_diff_cached
|
||||
else:
|
||||
# Not the same keys so create a new diff
|
||||
keys_to_remove = set(sd[torrent_id].iterkeys()) - keys
|
||||
keys_to_remove = set(sd[torrent_id]) - keys
|
||||
# Update the cached diff
|
||||
keys_diff_cached = keys_to_remove
|
||||
keys_len = len(sd[torrent_id])
|
||||
|
@ -180,7 +180,7 @@ class SessionProxy(component.Component):
|
|||
def on_status(result, torrent_ids, keys):
|
||||
# Update the internal torrent status dict with the update values
|
||||
t = time()
|
||||
for key, value in result.iteritems():
|
||||
for key, value in result.items():
|
||||
try:
|
||||
self.torrents[key][0] = t
|
||||
self.torrents[key][1].update(value)
|
||||
|
@ -192,7 +192,7 @@ class SessionProxy(component.Component):
|
|||
|
||||
# Create the status dict
|
||||
if not torrent_ids:
|
||||
torrent_ids = result.keys()
|
||||
torrent_ids = list(result.keys())
|
||||
|
||||
return self.create_status_dict(torrent_ids, keys)
|
||||
|
||||
|
@ -216,13 +216,13 @@ class SessionProxy(component.Component):
|
|||
if not filter_dict:
|
||||
# This means we want all the torrents status
|
||||
# We get a list of any torrent_ids with expired status dicts
|
||||
to_fetch = find_torrents_to_fetch(self.torrents.keys())
|
||||
to_fetch = find_torrents_to_fetch(list(self.torrents.keys()))
|
||||
if to_fetch:
|
||||
d = client.core.get_torrents_status({'id': to_fetch}, keys, True)
|
||||
return d.addCallback(on_status, self.torrents.keys(), keys)
|
||||
return d.addCallback(on_status, list(self.torrents.keys()), keys)
|
||||
|
||||
# Don't need to fetch anything
|
||||
return maybeDeferred(self.create_status_dict, self.torrents.keys(), keys)
|
||||
return maybeDeferred(self.create_status_dict, list(self.torrents.keys()), keys)
|
||||
|
||||
if len(filter_dict) == 1 and 'id' in filter_dict:
|
||||
# At this point we should have a filter with just "id" in it
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import __builtin__
|
||||
import gettext
|
||||
import locale
|
||||
import logging
|
||||
|
@ -22,7 +23,6 @@ log.addHandler(logging.NullHandler()) # Silence: No handlers could be found for
|
|||
|
||||
|
||||
def set_dummy_trans(warn_msg=None):
|
||||
import __builtin__
|
||||
|
||||
def _func(*txt):
|
||||
if warn_msg:
|
||||
|
@ -122,9 +122,7 @@ def setup_translations(setup_gettext=True, setup_pygtk=False):
|
|||
gettext.bindtextdomain(domain, translations_path)
|
||||
gettext.bind_textdomain_codeset(domain, 'UTF-8')
|
||||
gettext.textdomain(domain)
|
||||
gettext.install(domain, translations_path, unicode=True)
|
||||
import __builtin__
|
||||
__builtin__.__dict__['_n'] = gettext.ngettext
|
||||
gettext.install(domain, translations_path)
|
||||
except Exception as ex:
|
||||
log.error('Unable to initialize gettext/locale!')
|
||||
log.exception(ex)
|
||||
|
|
|
@ -90,7 +90,7 @@ class Auth(JSONComponent):
|
|||
self.worker.stop()
|
||||
|
||||
def _clean_sessions(self):
|
||||
session_ids = self.config['sessions'].keys()
|
||||
session_ids = list(self.config['sessions'].keys())
|
||||
|
||||
now = time.gmtime()
|
||||
for session_id in session_ids:
|
||||
|
|
|
@ -918,7 +918,7 @@ class WebApi(JSONComponent):
|
|||
"""
|
||||
|
||||
return {
|
||||
'enabled_plugins': component.get('Web.PluginManager').plugins.keys(),
|
||||
'enabled_plugins': list(component.get('Web.PluginManager').plugins.keys()),
|
||||
'available_plugins': component.get('Web.PluginManager').available_plugins
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ known_third_party =
|
|||
# Ignore Windows specific modules.
|
||||
bbfreeze, win32verstamp,
|
||||
# Ignore gtk modules, primarily for tox testing.
|
||||
pygtk, gtk, gobject, gtk.gdk, pango, cairo, pangocairo
|
||||
pygtk, gtk, gobject, gtk.gdk, pango, cairo, pangocairo,
|
||||
six
|
||||
known_first_party = msgfmt, deluge
|
||||
order_by_type = true
|
||||
line_length = 120
|
||||
|
|
Loading…
Add table
Reference in a new issue