mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-10 02:18:41 +00:00
Use stdlib json
Some flake8 changes and DEPENDS tidyup
This commit is contained in:
parent
49c2be40ab
commit
7b53486821
4 changed files with 54 additions and 75 deletions
22
DEPENDS
22
DEPENDS
|
@ -1,30 +1,24 @@
|
||||||
=== Core ===
|
=== Core ===
|
||||||
|
* libtorrent (rasterbar) >= 0.16.7
|
||||||
* python >= 2.6
|
* python >= 2.6
|
||||||
|
* setuptools
|
||||||
* twisted >= 8.1
|
* twisted >= 8.1
|
||||||
* pyopenssl
|
* pyopenssl
|
||||||
* setuptools
|
|
||||||
* gettext
|
|
||||||
* intltool
|
|
||||||
* pyxdg
|
* pyxdg
|
||||||
* chardet
|
* chardet
|
||||||
|
* gettext
|
||||||
* geoip-database (optional)
|
* geoip-database (optional)
|
||||||
* setproctitle (optional)
|
* setproctitle (optional)
|
||||||
* rencode >= 1.0.2 (optional), Python port is included
|
* rencode >= 1.0.2 (optional), python port bundled.
|
||||||
|
|
||||||
* libtorrent (rasterbar) >= 0.16.7
|
=== Gtk UI ===
|
||||||
|
|
||||||
* If building libtorrent:
|
|
||||||
* boost >= 1.40
|
|
||||||
* openssl
|
|
||||||
* zlib
|
|
||||||
|
|
||||||
=== Gtk ===
|
|
||||||
* pygtk >= 2.16
|
* pygtk >= 2.16
|
||||||
* librsvg
|
* librsvg
|
||||||
* xdg-utils
|
* xdg-utils
|
||||||
|
* intltool
|
||||||
* python-notify (optional)
|
* python-notify (optional)
|
||||||
* pygame (optional)
|
* pygame (optional)
|
||||||
|
|
||||||
=== Web ===
|
=== Web UI ===
|
||||||
* mako
|
* mako
|
||||||
* slimit
|
* slimit (optional), minifies JS files.
|
||||||
|
|
|
@ -49,30 +49,10 @@ import locale
|
||||||
import base64
|
import base64
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
try:
|
|
||||||
import json
|
|
||||||
except ImportError:
|
|
||||||
import simplejson as json
|
|
||||||
|
|
||||||
from deluge.error import InvalidPathError
|
from deluge.error import InvalidPathError
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Do a little hack here just in case the user has json-py installed since it
|
|
||||||
# has a different api
|
|
||||||
if not hasattr(json, "dumps"):
|
|
||||||
json.dumps = json.write
|
|
||||||
json.loads = json.read
|
|
||||||
|
|
||||||
def dump(obj, fp, **kw):
|
|
||||||
fp.write(json.dumps(obj))
|
|
||||||
|
|
||||||
def load(fp, **kw):
|
|
||||||
return json.loads(fp.read())
|
|
||||||
|
|
||||||
json.dump = dump
|
|
||||||
json.load = load
|
|
||||||
|
|
||||||
LT_TORRENT_STATE = {
|
LT_TORRENT_STATE = {
|
||||||
"Queued": 0,
|
"Queued": 0,
|
||||||
"Checking": 1,
|
"Checking": 1,
|
||||||
|
@ -142,15 +122,15 @@ def get_default_config_dir(filename=None):
|
||||||
|
|
||||||
if windows_check():
|
if windows_check():
|
||||||
def save_config_path(resource):
|
def save_config_path(resource):
|
||||||
appDataPath = os.environ.get("APPDATA")
|
app_data_path = os.environ.get("APPDATA")
|
||||||
if not appDataPath:
|
if not app_data_path:
|
||||||
import _winreg
|
import _winreg
|
||||||
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
|
hkey = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
|
||||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders")
|
||||||
appDataReg = _winreg.QueryValueEx(hkey, "AppData")
|
app_data_reg = _winreg.QueryValueEx(hkey, "AppData")
|
||||||
appDataPath = appDataReg[0]
|
app_data_path = app_data_reg[0]
|
||||||
_winreg.CloseKey(hkey)
|
_winreg.CloseKey(hkey)
|
||||||
return os.path.join(appDataPath, resource)
|
return os.path.join(app_data_path, resource)
|
||||||
else:
|
else:
|
||||||
from xdg.BaseDirectory import save_config_path
|
from xdg.BaseDirectory import save_config_path
|
||||||
if not filename:
|
if not filename:
|
||||||
|
@ -785,7 +765,7 @@ class VersionSplit(object):
|
||||||
"""
|
"""
|
||||||
def __init__(self, ver):
|
def __init__(self, ver):
|
||||||
import re
|
import re
|
||||||
VERSION_RE = re.compile(r'''
|
version_re = re.compile(r'''
|
||||||
^
|
^
|
||||||
(?P<version>\d+\.\d+) # minimum 'N.N'
|
(?P<version>\d+\.\d+) # minimum 'N.N'
|
||||||
(?P<extraversion>(?:\.\d+)*) # any number of extra '.N' segments
|
(?P<extraversion>(?:\.\d+)*) # any number of extra '.N' segments
|
||||||
|
@ -798,7 +778,7 @@ class VersionSplit(object):
|
||||||
$''', re.VERBOSE)
|
$''', re.VERBOSE)
|
||||||
|
|
||||||
# Check for PEP 386 compliant version
|
# Check for PEP 386 compliant version
|
||||||
match = re.search(VERSION_RE, ver)
|
match = re.search(version_re, ver)
|
||||||
if match:
|
if match:
|
||||||
group = [(x if x is not None else '') for x in match.group(1, 2, 3, 4, 8)]
|
group = [(x if x is not None else '') for x in match.group(1, 2, 3, 4, 8)]
|
||||||
vs = [''.join(group[0:2]), ''.join(group[2:4]), group[4].lstrip('.')]
|
vs = [''.join(group[0:2]), ''.join(group[2:4]), group[4].lstrip('.')]
|
||||||
|
@ -1024,17 +1004,17 @@ def unicode_argv():
|
||||||
from ctypes import POINTER, byref, cdll, c_int, windll
|
from ctypes import POINTER, byref, cdll, c_int, windll
|
||||||
from ctypes.wintypes import LPCWSTR, LPWSTR
|
from ctypes.wintypes import LPCWSTR, LPWSTR
|
||||||
|
|
||||||
GetCommandLineW = cdll.kernel32.GetCommandLineW
|
get_cmd_linew = cdll.kernel32.GetCommandLineW
|
||||||
GetCommandLineW.argtypes = []
|
get_cmd_linew.argtypes = []
|
||||||
GetCommandLineW.restype = LPCWSTR
|
get_cmd_linew.restype = LPCWSTR
|
||||||
|
|
||||||
CommandLineToArgvW = windll.shell32.CommandLineToArgvW
|
cmdline_to_argvw = windll.shell32.CommandLineToArgvW
|
||||||
CommandLineToArgvW.argtypes = [LPCWSTR, POINTER(c_int)]
|
cmdline_to_argvw.argtypes = [LPCWSTR, POINTER(c_int)]
|
||||||
CommandLineToArgvW.restype = POINTER(LPWSTR)
|
cmdline_to_argvw.restype = POINTER(LPWSTR)
|
||||||
|
|
||||||
cmd = GetCommandLineW()
|
cmd = get_cmd_linew()
|
||||||
argc = c_int(0)
|
argc = c_int(0)
|
||||||
argv = CommandLineToArgvW(cmd, byref(argc))
|
argv = cmdline_to_argvw(cmd, byref(argc))
|
||||||
if argc.value > 0:
|
if argc.value > 0:
|
||||||
# Remove Python executable and commands if present
|
# Remove Python executable and commands if present
|
||||||
start = argc.value - len(sys.argv)
|
start = argc.value - len(sys.argv)
|
||||||
|
|
|
@ -71,12 +71,13 @@ import cPickle as pickle
|
||||||
import logging
|
import logging
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
import deluge.common
|
from deluge.common import get_default_config_dir, utf8_encoded
|
||||||
|
|
||||||
json = deluge.common.json
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
callLater = None # Necessary for the config tests
|
callLater = None # Necessary for the config tests
|
||||||
|
|
||||||
|
|
||||||
def prop(func):
|
def prop(func):
|
||||||
"""Function decorator for defining property attributes
|
"""Function decorator for defining property attributes
|
||||||
|
@ -94,6 +95,7 @@ def prop(func):
|
||||||
"""
|
"""
|
||||||
return property(doc=func.__doc__, **func())
|
return property(doc=func.__doc__, **func())
|
||||||
|
|
||||||
|
|
||||||
def find_json_objects(s):
|
def find_json_objects(s):
|
||||||
"""
|
"""
|
||||||
Find json objects in a string.
|
Find json objects in a string.
|
||||||
|
@ -157,7 +159,7 @@ class Config(object):
|
||||||
if config_dir:
|
if config_dir:
|
||||||
self.__config_file = os.path.join(config_dir, filename)
|
self.__config_file = os.path.join(config_dir, filename)
|
||||||
else:
|
else:
|
||||||
self.__config_file = deluge.common.get_default_config_dir(filename)
|
self.__config_file = get_default_config_dir(filename)
|
||||||
|
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
|
@ -193,8 +195,7 @@ what is currently in the config and it could not convert the value
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
value = deluge.common.utf8_encoded(value)
|
value = utf8_encoded(value)
|
||||||
|
|
||||||
|
|
||||||
if not self.__config.has_key(key):
|
if not self.__config.has_key(key):
|
||||||
self.__config[key] = value
|
self.__config[key] = value
|
||||||
|
@ -274,7 +275,6 @@ what is currently in the config and it could not convert the value
|
||||||
else:
|
else:
|
||||||
return self.__config[key]
|
return self.__config[key]
|
||||||
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
"""
|
"""
|
||||||
Gets the value of item 'key' if key is in the config, else default.
|
Gets the value of item 'key' if key is in the config, else default.
|
||||||
|
@ -299,7 +299,6 @@ what is currently in the config and it could not convert the value
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
"""
|
"""
|
||||||
See
|
See
|
||||||
|
@ -329,7 +328,6 @@ what is currently in the config and it could not convert the value
|
||||||
if not self._save_timer or not self._save_timer.active():
|
if not self._save_timer or not self._save_timer.active():
|
||||||
self._save_timer = callLater(5, self.save)
|
self._save_timer = callLater(5, self.save)
|
||||||
|
|
||||||
|
|
||||||
def register_change_callback(self, callback):
|
def register_change_callback(self, callback):
|
||||||
"""
|
"""
|
||||||
Registers a callback function that will be called when a value is changed in the config dictionary
|
Registers a callback function that will be called when a value is changed in the config dictionary
|
||||||
|
@ -452,7 +450,7 @@ what is currently in the config and it could not convert the value
|
||||||
log.warning("Unable to load config file: %s", filename)
|
log.warning("Unable to load config file: %s", filename)
|
||||||
|
|
||||||
log.debug("Config %s version: %s.%s loaded: %s", filename,
|
log.debug("Config %s version: %s.%s loaded: %s", filename,
|
||||||
self.__version["format"], self.__version["file"], self.__config)
|
self.__version["format"], self.__version["file"], self.__config)
|
||||||
|
|
||||||
def save(self, filename=None):
|
def save(self, filename=None):
|
||||||
"""
|
"""
|
||||||
|
@ -535,7 +533,7 @@ what is currently in the config and it could not convert the value
|
||||||
|
|
||||||
if self.__version["file"] not in input_range:
|
if self.__version["file"] not in input_range:
|
||||||
log.debug("File version %s is not in input_range %s, ignoring converter function..",
|
log.debug("File version %s is not in input_range %s, ignoring converter function..",
|
||||||
self.__version["file"], input_range)
|
self.__version["file"], input_range)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -543,7 +541,7 @@ what is currently in the config and it could not convert the value
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
log.exception(e)
|
log.exception(e)
|
||||||
log.error("There was an exception try to convert config file %s %s to %s",
|
log.error("There was an exception try to convert config file %s %s to %s",
|
||||||
self.__config_file, self.__version["file"], output_version)
|
self.__config_file, self.__version["file"], output_version)
|
||||||
raise e
|
raise e
|
||||||
else:
|
else:
|
||||||
self.__version["file"] = output_version
|
self.__version["file"] = output_version
|
||||||
|
@ -558,6 +556,7 @@ what is currently in the config and it could not convert the value
|
||||||
"""The config dictionary"""
|
"""The config dictionary"""
|
||||||
def fget(self):
|
def fget(self):
|
||||||
return self.__config
|
return self.__config
|
||||||
|
|
||||||
def fdel(self):
|
def fdel(self):
|
||||||
return self.save()
|
return self.save()
|
||||||
return locals()
|
return locals()
|
||||||
|
|
|
@ -40,6 +40,7 @@ import shutil
|
||||||
import logging
|
import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import json
|
||||||
from urlparse import urljoin
|
from urlparse import urljoin
|
||||||
from urllib import unquote_plus
|
from urllib import unquote_plus
|
||||||
|
|
||||||
|
@ -50,7 +51,8 @@ from twisted.web import http, resource, server
|
||||||
import twisted.web.client
|
import twisted.web.client
|
||||||
import twisted.web.error
|
import twisted.web.error
|
||||||
|
|
||||||
from deluge import common, component, httpdownloader
|
from deluge.common import is_magnet
|
||||||
|
from deluge import component, httpdownloader
|
||||||
from deluge.configmanager import ConfigManager, get_config_dir
|
from deluge.configmanager import ConfigManager, get_config_dir
|
||||||
from deluge.ui import common as uicommon
|
from deluge.ui import common as uicommon
|
||||||
from deluge.ui.client import client, Client
|
from deluge.ui.client import client, Client
|
||||||
|
@ -58,19 +60,20 @@ from deluge.ui.coreconfig import CoreConfig
|
||||||
from deluge.ui.sessionproxy import SessionProxy
|
from deluge.ui.sessionproxy import SessionProxy
|
||||||
|
|
||||||
from deluge.ui.web.common import _, compress
|
from deluge.ui.web.common import _, compress
|
||||||
json = common.json
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
AUTH_LEVEL_DEFAULT = None
|
AUTH_LEVEL_DEFAULT = None
|
||||||
AuthError = None
|
AuthError = None
|
||||||
|
|
||||||
|
|
||||||
class JSONComponent(component.Component):
|
class JSONComponent(component.Component):
|
||||||
def __init__(self, name, interval=1, depend=None):
|
def __init__(self, name, interval=1, depend=None):
|
||||||
super(JSONComponent, self).__init__(name, interval, depend)
|
super(JSONComponent, self).__init__(name, interval, depend)
|
||||||
self._json = component.get("JSON")
|
self._json = component.get("JSON")
|
||||||
self._json.register_object(self, name)
|
self._json.register_object(self, name)
|
||||||
|
|
||||||
|
|
||||||
def export(auth_level=AUTH_LEVEL_DEFAULT):
|
def export(auth_level=AUTH_LEVEL_DEFAULT):
|
||||||
"""
|
"""
|
||||||
Decorator function to register an object's method as a RPC. The object
|
Decorator function to register an object's method as a RPC. The object
|
||||||
|
@ -84,7 +87,7 @@ def export(auth_level=AUTH_LEVEL_DEFAULT):
|
||||||
"""
|
"""
|
||||||
global AUTH_LEVEL_DEFAULT, AuthError
|
global AUTH_LEVEL_DEFAULT, AuthError
|
||||||
if AUTH_LEVEL_DEFAULT is None:
|
if AUTH_LEVEL_DEFAULT is None:
|
||||||
from deluge.ui.web.auth import AUTH_LEVEL_DEFAULT, AuthError
|
from deluge.ui.web.auth import AUTH_LEVEL_DEFAULT
|
||||||
|
|
||||||
def wrap(func, *args, **kwargs):
|
def wrap(func, *args, **kwargs):
|
||||||
func._json_export = True
|
func._json_export = True
|
||||||
|
@ -98,11 +101,13 @@ def export(auth_level=AUTH_LEVEL_DEFAULT):
|
||||||
else:
|
else:
|
||||||
return wrap
|
return wrap
|
||||||
|
|
||||||
|
|
||||||
class JSONException(Exception):
|
class JSONException(Exception):
|
||||||
def __init__(self, inner_exception):
|
def __init__(self, inner_exception):
|
||||||
self.inner_exception = inner_exception
|
self.inner_exception = inner_exception
|
||||||
Exception.__init__(self, str(inner_exception))
|
Exception.__init__(self, str(inner_exception))
|
||||||
|
|
||||||
|
|
||||||
class JSON(resource.Resource, component.Component):
|
class JSON(resource.Resource, component.Component):
|
||||||
"""
|
"""
|
||||||
A Twisted Web resource that exposes a JSON-RPC interface for web clients \
|
A Twisted Web resource that exposes a JSON-RPC interface for web clients \
|
||||||
|
@ -290,7 +295,7 @@ class JSON(resource.Resource, component.Component):
|
||||||
try:
|
try:
|
||||||
request.content.seek(0)
|
request.content.seek(0)
|
||||||
request.json = request.content.read()
|
request.json = request.content.read()
|
||||||
d = self._on_json_request(request)
|
self._on_json_request(request)
|
||||||
return server.NOT_DONE_YET
|
return server.NOT_DONE_YET
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
return self._on_json_request_failed(e, request)
|
return self._on_json_request_failed(e, request)
|
||||||
|
@ -336,6 +341,7 @@ HOSTS_INFO = 4
|
||||||
|
|
||||||
FILES_KEYS = ["files", "file_progress", "file_priorities"]
|
FILES_KEYS = ["files", "file_progress", "file_priorities"]
|
||||||
|
|
||||||
|
|
||||||
class EventQueue(object):
|
class EventQueue(object):
|
||||||
"""
|
"""
|
||||||
This class subscribes to events from the core and stores them until all
|
This class subscribes to events from the core and stores them until all
|
||||||
|
@ -418,6 +424,7 @@ class EventQueue(object):
|
||||||
del self.__events[event]
|
del self.__events[event]
|
||||||
del self.__handlers[event]
|
del self.__handlers[event]
|
||||||
|
|
||||||
|
|
||||||
class WebApi(JSONComponent):
|
class WebApi(JSONComponent):
|
||||||
"""
|
"""
|
||||||
The component that implements all the methods required for managing
|
The component that implements all the methods required for managing
|
||||||
|
@ -467,6 +474,7 @@ class WebApi(JSONComponent):
|
||||||
:rtype: list
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
d = Deferred()
|
d = Deferred()
|
||||||
|
|
||||||
def on_connected(methods):
|
def on_connected(methods):
|
||||||
d.callback(methods)
|
d.callback(methods)
|
||||||
host = self.get_host(host_id)
|
host = self.get_host(host_id)
|
||||||
|
@ -737,7 +745,7 @@ class WebApi(JSONComponent):
|
||||||
if info_hash:
|
if info_hash:
|
||||||
if not name:
|
if not name:
|
||||||
name = info_hash
|
name = info_hash
|
||||||
return {"name":name, "info_hash":info_hash, "files_tree":''}
|
return {"name": name, "info_hash": info_hash, "files_tree": ''}
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@export
|
@export
|
||||||
|
@ -751,14 +759,14 @@ class WebApi(JSONComponent):
|
||||||
|
|
||||||
**Usage**
|
**Usage**
|
||||||
|
|
||||||
>>> json_api.web.add_torrents([{
|
json_api.web.add_torrents([{
|
||||||
"path": "/tmp/deluge-web/some-torrent-file.torrent",
|
"path": "/tmp/deluge-web/some-torrent-file.torrent",
|
||||||
"options": {"download_location": "/home/deluge/"}
|
"options": {"download_location": "/home/deluge/"}
|
||||||
}])
|
}])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for torrent in torrents:
|
for torrent in torrents:
|
||||||
if common.is_magnet(torrent["path"]):
|
if is_magnet(torrent["path"]):
|
||||||
log.info("Adding torrent from magnet uri `%s` with options `%r`",
|
log.info("Adding torrent from magnet uri `%s` with options `%r`",
|
||||||
torrent["path"], torrent["options"])
|
torrent["path"], torrent["options"])
|
||||||
client.core.add_torrent_magnet(torrent["path"], torrent["options"])
|
client.core.add_torrent_magnet(torrent["path"], torrent["options"])
|
||||||
|
@ -792,7 +800,7 @@ class WebApi(JSONComponent):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
host_id, host, port, user, password = self.get_host(host_id)
|
host_id, host, port, user, password = self.get_host(host_id)
|
||||||
except TypeError, e:
|
except TypeError:
|
||||||
host = None
|
host = None
|
||||||
port = None
|
port = None
|
||||||
return response(_("Offline"))
|
return response(_("Offline"))
|
||||||
|
@ -809,16 +817,14 @@ class WebApi(JSONComponent):
|
||||||
if not connected:
|
if not connected:
|
||||||
return response(_("Offline"))
|
return response(_("Offline"))
|
||||||
|
|
||||||
return c.daemon.info(
|
return c.daemon.info().addCallback(on_info, c).addErrback(on_info_fail, c)
|
||||||
).addCallback(on_info, c
|
|
||||||
).addErrback(on_info_fail, c)
|
|
||||||
|
|
||||||
def on_connect_failed(reason, host_id):
|
def on_connect_failed(reason, host_id):
|
||||||
return response(_("Offline"))
|
return response(_("Offline"))
|
||||||
|
|
||||||
if client.connected() and (host, port, "localclient" if not
|
if client.connected() and (host, port, "localclient" if not
|
||||||
user and host in ("127.0.0.1", "localhost") else
|
user and host in ("127.0.0.1", "localhost") else
|
||||||
user) == client.connection_info():
|
user) == client.connection_info():
|
||||||
def on_info(info):
|
def on_info(info):
|
||||||
return response(_("Connected"), info)
|
return response(_("Connected"), info)
|
||||||
|
|
||||||
|
@ -826,8 +832,8 @@ class WebApi(JSONComponent):
|
||||||
else:
|
else:
|
||||||
c = Client()
|
c = Client()
|
||||||
return c.connect(host, port, user, password
|
return c.connect(host, port, user, password
|
||||||
).addCallback(on_connect, c, host_id
|
).addCallback(on_connect, c, host_id
|
||||||
).addErrback(on_connect_failed, host_id)
|
).addErrback(on_connect_failed, host_id)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def start_daemon(self, port):
|
def start_daemon(self, port):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue