Implement new IPC system. There is no longer a dependency on DBUS and this system should work on

all platforms.
This commit is contained in:
Andrew Resch 2009-02-26 01:47:40 +00:00
parent 72ce4eede7
commit 7b682f4f60
3 changed files with 38 additions and 121 deletions

1
README
View File

@ -49,7 +49,6 @@ Dependencies:
gettext
Gtk:
dbus-python
python-notify (libnotify python wrapper)
pygame
pygtk >= 2.10

View File

@ -1,86 +0,0 @@
#
# dbusinterface.py
#
# Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
import sys
import os
# Import DBUS
import dbus, dbus.service
if dbus.version >= (0,41,0) and dbus.version < (0,80,0):
import dbus.glib
elif dbus.version >= (0,80,0):
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
import deluge.component as component
import deluge.common
from deluge.log import LOG as log
class DbusInterface(dbus.service.Object, component.Component):
def __init__(self, args, path="/org/deluge_torrent/Deluge"):
component.Component.__init__(self, "DbusInterface")
# Check to see if the daemon is already running and if not, start it
bus = dbus.SessionBus()
obj = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus")
iface = dbus.Interface(obj, "org.freedesktop.DBus")
if iface.NameHasOwner("org.deluge_torrent.Deluge"):
# Deluge client already running.. Lets exit.
log.info("Deluge already running..")
log.debug("args: %s", args)
# Convert the paths to absolutes
new_args = []
for arg in args:
if not deluge.common.is_url(arg) and not deluge.common.is_magnet(arg):
new_args.append(os.path.abspath(arg))
else:
new_args.append(arg)
args = new_args
# Send the args to the running session
if args != [] and args != None:
bus = dbus.SessionBus()
proxy = bus.get_object("org.deluge_torrent.Deluge",
"/org/deluge_torrent/Deluge")
ui = dbus.Interface(proxy, "org.deluge_torrent.Deluge")
ui.process_args(args)
# Exit
log.debug("Exiting..")
sys.exit(0)
# Process the args if any
self.process_args(args)
# Register Deluge with Dbus
log.info("Registering with DBUS..")
bus_name = dbus.service.BusName("org.deluge_torrent.Deluge",
bus=dbus.SessionBus())
dbus.service.Object.__init__(self, bus_name, path)
@dbus.service.method("org.deluge_torrent.Deluge", in_signature="as")
def process_args(self, args):
"""Process arguments sent to already running Deluge"""
from ipcinterface import process_args
process_args(args)

View File

@ -1,7 +1,7 @@
#
# ipcinterface.py
#
# Copyright (C) 2008 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2008-2009 Andrew Resch <andrewresch@gmail.com>
#
# Deluge is free software.
#
@ -27,53 +27,57 @@ import sys
import os.path
import base64
import deluge.rencode
import deluge.component as component
from deluge.ui.client import client
import deluge.common
from deluge.configmanager import ConfigManager
from deluge.log import LOG as log
from twisted.internet.protocol import Factory, Protocol, ClientFactory
from twisted.internet import reactor
import twisted.internet.error
class IPCProtocolServer(Protocol):
def dataReceived(self, data):
data = deluge.rencode.loads(data)
log.debug("Data received: %s", data)
process_args(data)
class IPCProtocolClient(Protocol):
def connectionMade(self):
log.debug("Connection made!")
self.transport.write(deluge.rencode.dumps(self.factory.args))
self.transport.loseConnection()
def connectionLost(self, reason):
reactor.stop()
class IPCInterface(component.Component):
def __init__(self, args):
component.Component.__init__(self, "IPCInterface")
log.debug("args: %s", args)
if not os.path.exists(deluge.configmanager.get_config_dir("ipc")):
os.makedirs(deluge.configmanager.get_config_dir("ipc"))
if deluge.common.windows_check():
# If we're on windows we need to check the global mutex to see if deluge is
# already running.
import win32event
import win32api
import winerror
self.mutex = win32event.CreateMutex(None, False, "deluge")
if win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS:
# We already have a running session, send a XMLRPC to the existing session
config = ConfigManager("gtkui.conf")
# XXX: Need new IPC method
# uri = "http://localhost:" + str(config["signal_port"])
# import deluge.xmlrpclib as xmlrpclib
# rpc = xmlrpclib.ServerProxy(uri, allow_none=True)
# rpc.emit_signal("args_from_external", args)
sys.exit(0)
else:
process_args(args)
else:
try:
import dbusinterface
self.dbusinterface = dbusinterface.DbusInterface(args)
except Exception, e:
log.warning("Unable to start DBUS component: %s", e)
socket = os.path.join(deluge.configmanager.get_config_dir("ipc"), "deluge-gtk")
def shutdown(self):
if deluge.common.windows_check():
import win32api
win32api.CloseHandle(self.mutex)
try:
self.factory = Factory()
self.factory.protocol = IPCProtocolServer
reactor.listenUNIX(socket, self.factory, wantPID=True)
except twisted.internet.error.CannotListenError, e:
log.info("Deluge is already running! Sending arguments to running instance..")
self.factory = ClientFactory()
self.factory.args = args
self.factory.protocol = IPCProtocolClient
reactor.connectUNIX(socket, self.factory, checkPID=True)
reactor.run()
sys.exit(0)
def process_args(args):
"""Process arguments sent to already running Deluge"""
# Pythonize the values from Dbus
dbus_args = args
args = []
for arg in dbus_args:
args.append(str(arg))
# Make sure args is a list
args = list(args)
log.debug("Processing args from other process: %s", args)
if not client.connected():
# We're not connected so add these to the queue