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 gettext
Gtk: Gtk:
dbus-python
python-notify (libnotify python wrapper) python-notify (libnotify python wrapper)
pygame pygame
pygtk >= 2.10 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 # ipcinterface.py
# #
# Copyright (C) 2008 Andrew Resch <andrewresch@gmail.com> # Copyright (C) 2008-2009 Andrew Resch <andrewresch@gmail.com>
# #
# Deluge is free software. # Deluge is free software.
# #
@ -27,53 +27,57 @@ import sys
import os.path import os.path
import base64 import base64
import deluge.rencode
import deluge.component as component import deluge.component as component
from deluge.ui.client import client from deluge.ui.client import client
import deluge.common import deluge.common
from deluge.configmanager import ConfigManager from deluge.configmanager import ConfigManager
from deluge.log import LOG as log 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): class IPCInterface(component.Component):
def __init__(self, args): def __init__(self, args):
component.Component.__init__(self, "IPCInterface") 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"))
socket = os.path.join(deluge.configmanager.get_config_dir("ipc"), "deluge-gtk")
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: try:
import dbusinterface self.factory = Factory()
self.dbusinterface = dbusinterface.DbusInterface(args) self.factory.protocol = IPCProtocolServer
except Exception, e: reactor.listenUNIX(socket, self.factory, wantPID=True)
log.warning("Unable to start DBUS component: %s", e) except twisted.internet.error.CannotListenError, e:
log.info("Deluge is already running! Sending arguments to running instance..")
def shutdown(self): self.factory = ClientFactory()
if deluge.common.windows_check(): self.factory.args = args
import win32api self.factory.protocol = IPCProtocolClient
win32api.CloseHandle(self.mutex) reactor.connectUNIX(socket, self.factory, checkPID=True)
reactor.run()
sys.exit(0)
def process_args(args): def process_args(args):
"""Process arguments sent to already running Deluge""" """Process arguments sent to already running Deluge"""
# Pythonize the values from Dbus # Make sure args is a list
dbus_args = args args = list(args)
args = []
for arg in dbus_args:
args.append(str(arg))
log.debug("Processing args from other process: %s", args) log.debug("Processing args from other process: %s", args)
if not client.connected(): if not client.connected():
# We're not connected so add these to the queue # We're not connected so add these to the queue