mirror of
https://github.com/codex-storage/deluge.git
synced 2025-01-29 20:56:31 +00:00
Merge SVN and HG heads.
This commit is contained in:
parent
535940e2e6
commit
8a6ec7232d
@ -101,6 +101,13 @@ class ComponentRegistry:
|
||||
if depend != None:
|
||||
self.depend[name] = depend
|
||||
|
||||
def deregister(self, name):
|
||||
"""Deregisters a component"""
|
||||
if name in self.components:
|
||||
log.debug("Deregistering Component: %s", name)
|
||||
self.stop_component(name)
|
||||
del self.components[name]
|
||||
|
||||
def get(self, name):
|
||||
"""Returns a reference to the component 'name'"""
|
||||
return self.components[name]
|
||||
@ -126,8 +133,14 @@ class ComponentRegistry:
|
||||
|
||||
def stop(self):
|
||||
"""Stops all components"""
|
||||
for component in self.components.keys():
|
||||
self.stop_component(component)
|
||||
# We create a separate list of the keys and do an additional check to
|
||||
# make sure the key still exists in the components dict.
|
||||
# This is because components could be deregistered during a stop and
|
||||
# the dictionary would get modified while iterating through it.
|
||||
components = self.components.keys()
|
||||
for component in components:
|
||||
if component in self.components:
|
||||
self.stop_component(component)
|
||||
|
||||
def stop_component(self, component):
|
||||
if self.components[component].get_state() != \
|
||||
@ -187,6 +200,10 @@ def register(name, obj, depend=None):
|
||||
"""Registers a component with the registry"""
|
||||
_ComponentRegistry.register(name, obj, depend)
|
||||
|
||||
def deregister(name):
|
||||
"""Deregisters a component"""
|
||||
_ComponentRegistry.deregister(name)
|
||||
|
||||
def start(component=None):
|
||||
"""Starts all components"""
|
||||
if component == None:
|
||||
|
@ -131,7 +131,7 @@ class DelugeRPCProtocol(Protocol):
|
||||
try:
|
||||
request = rencode.loads(dobj.decompress(data))
|
||||
except Exception, e:
|
||||
log.debug("Received possible invalid message (%r): %s", data, e)
|
||||
#log.debug("Received possible invalid message (%r): %s", data, e)
|
||||
# This could be cut-off data, so we'll save this in the buffer
|
||||
# and try to prepend it on the next dataReceived()
|
||||
self.__buffer = data
|
||||
|
@ -210,8 +210,11 @@ class TorrentManager(component.Component):
|
||||
|
||||
def stop(self):
|
||||
# Stop timers
|
||||
self.save_state_timer.stop()
|
||||
self.save_resume_data_timer.stop()
|
||||
if self.save_state_timer.running:
|
||||
self.save_state_timer.stop()
|
||||
|
||||
if self.save_resume_data_timer.running:
|
||||
self.save_resume_data_timer.stop()
|
||||
|
||||
# Save state on shutdown
|
||||
self.save_state()
|
||||
|
@ -41,6 +41,16 @@ and subsequently emitted to the clients.
|
||||
|
||||
"""
|
||||
|
||||
event_list = []
|
||||
|
||||
class DelugeEventMetaClass(type):
|
||||
"""
|
||||
This metaclass simply keeps a list of all events classes created.
|
||||
"""
|
||||
def __init__(cls, name, bases, dct):
|
||||
event_list.append(name)
|
||||
super(DelugeEventMetaClass, cls).__init__(name, bases, dct)
|
||||
|
||||
class DelugeEvent(object):
|
||||
"""
|
||||
The base class for all events.
|
||||
@ -49,6 +59,8 @@ class DelugeEvent(object):
|
||||
:prop args: a list of the attribute values
|
||||
|
||||
"""
|
||||
__metaclass__ = DelugeEventMetaClass
|
||||
|
||||
def _get_name(self):
|
||||
return self.__class__.__name__
|
||||
|
||||
|
@ -87,7 +87,7 @@ class PluginManagerBase:
|
||||
def disable_plugins(self):
|
||||
# Disable all plugins that are enabled
|
||||
for key in self.plugins.keys():
|
||||
self.plugins[key].disable()
|
||||
self.disable_plugin(key)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.plugins[key]
|
||||
@ -153,6 +153,7 @@ class PluginManagerBase:
|
||||
"""Disables a plugin"""
|
||||
try:
|
||||
self.plugins[name].disable()
|
||||
component.deregister(self.plugins[name].plugin.get_component_name())
|
||||
del self.plugins[name]
|
||||
self.config["enabled_plugins"].remove(name)
|
||||
except KeyError:
|
||||
|
@ -49,3 +49,18 @@ def raiseError(error):
|
||||
raise error
|
||||
return new
|
||||
return safer
|
||||
|
||||
def remove_zeros(ip):
|
||||
"""
|
||||
Removes unneeded zeros from ip addresses.
|
||||
|
||||
Example: 000.000.000.003 -> 0.0.0.3
|
||||
|
||||
:param ip: the ip address
|
||||
:type ip: string
|
||||
|
||||
:returns: the ip address without the unneeded zeros
|
||||
:rtype: string
|
||||
|
||||
"""
|
||||
return ".".join([part.lstrip("0").zfill(1) for part in ip.split(".")])
|
||||
|
@ -128,6 +128,8 @@ class Core(CorePluginBase):
|
||||
self.use_cache = False
|
||||
self.failed_attempts = 0
|
||||
self.auto_detected = False
|
||||
if force:
|
||||
self.reader = None
|
||||
|
||||
# Start callback chain
|
||||
d = self.download_list()
|
||||
@ -218,8 +220,8 @@ class Core(CorePluginBase):
|
||||
if self.config["last_update"] and not self.force_download:
|
||||
headers['If-Modified-Since'] = self.config["last_update"]
|
||||
|
||||
log.debug("Attempting to download blocklist %s" % url)
|
||||
log.debug("Sending headers: %s" % headers)
|
||||
log.debug("Attempting to download blocklist %s", url)
|
||||
log.debug("Sending headers: %s", headers)
|
||||
self.up_to_date = False
|
||||
self.is_downloading = True
|
||||
return download_file(url, deluge.configmanager.get_config_dir("blocklist.download"), on_retrieve_data, headers)
|
||||
@ -239,7 +241,7 @@ class Core(CorePluginBase):
|
||||
# Handle redirect errors
|
||||
location = error_msg.split(" to ")[1]
|
||||
if "Moved Permanently" in error_msg:
|
||||
log.debug("Setting blocklist url to %s" % location)
|
||||
log.debug("Setting blocklist url to %s", location)
|
||||
self.config["url"] = location
|
||||
f.trap(f.type)
|
||||
d = self.download_list(url=location)
|
||||
@ -291,7 +293,7 @@ class Core(CorePluginBase):
|
||||
self.auto_detect(blocklist)
|
||||
self.auto_detected = True
|
||||
|
||||
log.debug("Importing using reader: %s",self.reader)
|
||||
log.debug("Importing using reader: %s", self.reader)
|
||||
log.debug("Reader type: %s compression: %s", self.config["list_type"], self.config["list_compression"])
|
||||
d = threads.deferToThread(self.reader(blocklist).read, on_read_ip_range)
|
||||
d.addCallback(on_finish_read)
|
||||
@ -327,7 +329,7 @@ class Core(CorePluginBase):
|
||||
elif os.path.exists(blocklist) and not self.use_cache:
|
||||
# If we have a backup and we haven't already used it
|
||||
e = f.trap(Exception)
|
||||
log.warning("Error reading blocklist: ", e)
|
||||
log.warning("Error reading blocklist: %s", e)
|
||||
self.use_cache = True
|
||||
try_again = True
|
||||
|
||||
@ -347,7 +349,7 @@ class Core(CorePluginBase):
|
||||
"""
|
||||
self.config["list_compression"] = detect_compression(blocklist)
|
||||
self.config["list_type"] = detect_format(blocklist, self.config["list_compression"])
|
||||
log.debug("Auto-detected type: %s compression: %s", self.config["list_type"], self.config["list_compression"])
|
||||
log.debug("Auto-detected type: %s compression: %s", self.config["list_type"], self.config["list_compression"])
|
||||
if not self.config["list_type"]:
|
||||
self.config["list_compression"] = ""
|
||||
raise UnknownFormatError
|
||||
|
@ -77,5 +77,4 @@ def create_reader(format, compression=""):
|
||||
decompressor = DECOMPRESSERS.get(compression)
|
||||
if decompressor:
|
||||
reader = decompressor(reader)
|
||||
|
||||
return reader
|
||||
|
@ -33,29 +33,9 @@
|
||||
#
|
||||
#
|
||||
|
||||
from deluge.log import LOG as log
|
||||
from common import raiseError
|
||||
from common import raiseError, remove_zeros
|
||||
import re
|
||||
|
||||
def remove_zeros(ip):
|
||||
"""
|
||||
Removes unneeded zeros from ip addresses.
|
||||
|
||||
Example: 000.000.000.003 -> 0.0.0.3
|
||||
|
||||
:param ip: the ip address
|
||||
:type ip: string
|
||||
|
||||
:returns: the ip address without the unneeded zeros
|
||||
:rtype: string
|
||||
|
||||
"""
|
||||
new_ip = []
|
||||
for part in ip.split("."):
|
||||
while part[0] == "0" and len(part) > 1:
|
||||
part = part[1:]
|
||||
new_ip.append(part)
|
||||
return ".".join(new_ip)
|
||||
|
||||
class ReaderParseError(Exception):
|
||||
pass
|
||||
|
||||
@ -90,6 +70,9 @@ class BaseReader(object):
|
||||
if not self.is_ignored(line):
|
||||
try:
|
||||
(start, end) = self.parse(line)
|
||||
if not re.match("^(\d{1,3}\.){4}$", start + ".") or \
|
||||
not re.match("^(\d{1,3}\.){4}$", end + "."):
|
||||
valid = False
|
||||
except:
|
||||
valid = False
|
||||
finally:
|
||||
@ -115,7 +98,7 @@ class SafePeerReader(BaseReader):
|
||||
"""Blocklist reader for SafePeer style blocklists"""
|
||||
@raiseError(ReaderParseError)
|
||||
def parse(self, line):
|
||||
return line.strip().split(":")[1].split("-")
|
||||
return line.strip().split(":")[-1].split("-")
|
||||
|
||||
class PeerGuardianReader(SafePeerReader):
|
||||
"""Blocklist reader for PeerGuardian style blocklists"""
|
||||
|
@ -249,7 +249,7 @@ class ConsoleUI(component.Component):
|
||||
|
||||
"""
|
||||
self.batch_write = batch
|
||||
if not batch:
|
||||
if not batch and self.interactive:
|
||||
self.screen.refresh()
|
||||
|
||||
def write(self, line):
|
||||
|
@ -35,6 +35,8 @@
|
||||
|
||||
"""Common functions for various parts of gtkui to use."""
|
||||
|
||||
import os
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk, gtk.glade
|
||||
|
@ -3,7 +3,6 @@
|
||||
<!-- interface-requires gtk+ 2.12 -->
|
||||
<!-- interface-naming-policy toplevel-contextual -->
|
||||
<widget class="GtkDialog" id="dialog_add_torrent">
|
||||
<property name="height_request">560</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="title" translatable="yes">Add Torrents</property>
|
||||
@ -14,12 +13,14 @@
|
||||
<widget class="GtkVBox" id="dialog-vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkVPaned" id="vpaned1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame2">
|
||||
<property name="visible">True</property>
|
||||
@ -37,6 +38,7 @@
|
||||
<widget class="GtkVBox" id="vbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
@ -345,6 +347,7 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame7">
|
||||
@ -425,6 +428,7 @@
|
||||
<widget class="GtkVBox" id="vbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<widget class="GtkRadioButton" id="radio_full">
|
||||
<property name="label" translatable="yes">Full</property>
|
||||
@ -657,6 +661,7 @@
|
||||
<widget class="GtkVBox" id="vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="chk_paused">
|
||||
@ -901,6 +906,8 @@
|
||||
<signal name="clicked" handler="on_button_cancel_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -915,6 +922,8 @@
|
||||
<signal name="clicked" handler="on_button_add_clicked"/>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -942,11 +951,13 @@
|
||||
<widget class="GtkVBox" id="dialog-vbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox6">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox7">
|
||||
@ -1053,6 +1064,8 @@
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -1069,6 +1082,8 @@
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -1096,11 +1111,13 @@
|
||||
<widget class="GtkVBox" id="dialog-vbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox8">
|
||||
@ -1246,6 +1263,8 @@
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
@ -1262,6 +1281,8 @@
|
||||
<property name="use_stock">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
@ -309,10 +309,7 @@ Please see the details below for more information."), details=traceback.format_e
|
||||
dialogs.ErrorDialog(
|
||||
_("Error Starting Daemon"),
|
||||
_("There was an error starting the daemon process. Try running it from a console to see if there is an error.")).run()
|
||||
|
||||
# We'll try 30 reconnects at 500ms intervals
|
||||
try_counter = 30
|
||||
|
||||
|
||||
def on_connect(connector):
|
||||
component.start()
|
||||
def on_connect_fail(result, try_counter):
|
||||
@ -323,15 +320,15 @@ Please see the details below for more information."), details=traceback.format_e
|
||||
try_counter -= 1
|
||||
import time
|
||||
time.sleep(0.5)
|
||||
do_connect()
|
||||
do_connect(try_counter)
|
||||
return result
|
||||
|
||||
def do_connect():
|
||||
|
||||
def do_connect(try_counter):
|
||||
client.connect(*host[1:]).addCallback(on_connect).addErrback(on_connect_fail, try_counter)
|
||||
|
||||
|
||||
if try_connect:
|
||||
do_connect()
|
||||
|
||||
do_connect(6)
|
||||
break
|
||||
|
||||
if self.config["show_connection_manager_on_start"]:
|
||||
# XXX: We need to call a simulate() here, but this could be a bug in twisted
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
import os
|
||||
import base64
|
||||
|
||||
import deluge.rencode
|
||||
@ -104,6 +104,20 @@ class IPCInterface(component.Component):
|
||||
reactor.run()
|
||||
sys.exit(0)
|
||||
else:
|
||||
lockfile = socket + ".lock"
|
||||
log.debug("Checking if lockfile exists: %s", lockfile)
|
||||
if os.path.lexists(lockfile):
|
||||
try:
|
||||
os.kill(int(os.readlink(lockfile)), 0)
|
||||
except OSError:
|
||||
log.debug("Removing lockfile since it's stale.")
|
||||
try:
|
||||
os.remove(lockfile)
|
||||
os.remove(socket)
|
||||
except Exception, e:
|
||||
log.error("Problem deleting lockfile or socket file!")
|
||||
log.exception(e)
|
||||
|
||||
try:
|
||||
self.factory = Factory()
|
||||
self.factory.protocol = IPCProtocolServer
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Deluge: Web UI (alpha) ${version}</title>
|
||||
<title>Deluge: Web UI ${version}</title>
|
||||
|
||||
<link rel="shortcut icon" href="/icons/deluge.png" type="image/png" />
|
||||
<link rel="icon" href="/icons/deluge.png" type="image/png" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user