Merge SVN and HG heads.

This commit is contained in:
Pedro Algarvio 2009-11-22 02:34:51 +00:00
parent 535940e2e6
commit 8a6ec7232d
15 changed files with 116 additions and 50 deletions

View File

@ -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:

View File

@ -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

View File

@ -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()

View File

@ -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__

View File

@ -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:

View File

@ -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(".")])

View File

@ -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

View File

@ -77,5 +77,4 @@ def create_reader(format, compression=""):
decompressor = DECOMPRESSERS.get(compression)
if decompressor:
reader = decompressor(reader)
return reader

View File

@ -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"""

View File

@ -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):

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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" />