On 11/22/06, Stephen Kennedy <[EMAIL PROTECTED]> wrote:
> > I just noticed that my patch will cause two problems:
> > 1) The dbus binding class MeldDbus is a child of dbus.service.Object,
> > which is not defined if the python-dbus module is not installed and
> > will therefore lead to a ValueError exception
> > 2) in the case that the python-dbus module is installed while dbus
> > itself isn't, meld will print a stacktrace instead of launching.
> > > http://kacper.doesntexist.org/hacks/meld-dbus.patch

> Hi Kacper, thanks for the work. It's something that is long overdue.
> This week is very hectic, so it could be a while before review/merge.
> Meanwhile...

No problem, I know how it is.

> In the past I've used fake stubs for optional modules. e.g.

Attached is an improved patch that handles the above cases using a
dummy dbus interface as suggested.

Attached patch applies over previous patch and can be found at:
http://kacper.doesntexist.org/hacks/meld-dbus-improvement-diff.patch
I've also prepared a patch against meld 1.1.3:
http://kacper.doesntexist.org/hacks/meld-dbus-improved.patch

> Also, it would be really nice if the three-way-merge command could
> return an exit status. Right now, because of the tabbed interface,
> there's no single return value from the program. But there could be
> from the dbus invocation which would make interfacing with source
> control much easier.

I'm not sure how to do this. My dbus stuff just calls the arg parsing
which in turn calls one of the MeldApp.append_* methods, then returns
to caller.

  I think that what you're suggesting requires an async method that
blocks until the opened diff tab is closed (and hence has a return
value). I say async because it can't block the gui application, just
the client calling over dbus. Or a callback to the client that says
"ok, the tab you opened was just closed with retval X".

If it's simpler than that, do let me know :-) otherwise I'll leave it
to someone who knows what they're doing with this gui stuff.

-Kacper

diff -Naurp meld-1.1.3/dummydbus.py meld-1.1.3-kw/dummydbus.py
--- meld-1.1.3/dummydbus.py     1970-01-01 01:00:00.000000000 +0100
+++ meld-1.1.3-kw/dummydbus.py  2006-11-24 01:13:36.046227404 +0100
@@ -0,0 +1,14 @@
+# Replacement dummy classes in case dbus isn't available
+class DBusObject:
+    def __init__(self, bus_name, object_path):
+        pass
+
+class DBusException:
+    def __init__(self):
+        pass
+
+def method(iface):
+    def decorator(func):
+        return func
+    return decorator
+
diff -Naurp meld-1.1.3/meldapp.py meld-1.1.3-kw/meldapp.py
--- meld-1.1.3/meldapp.py       2006-11-24 01:23:32.057619900 +0100
+++ meld-1.1.3-kw/meldapp.py    2006-11-24 01:15:41.967084524 +0100
@@ -40,16 +40,19 @@ dbus_available = 0
 try:
     import dbus
     import dbus.service
+    # following may be too implementation-dependent
+    from dbus.service import Object as DBusObject
+    from dbus.decorators import method
+    from dbus import DBusException
     if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
         import dbus.glib
         dbus_available = 1
     else:
         pass # dbus version too old
  except ImportError:
-    pass
-    # FIXME: Do I print this error or give the silent treatement?
-    #print "Oops, no dbus. Please install the python-dbus package."
-    #print "Meld will not be able to launch new diffs in existing window."
+    # @method decorator, DBusException, DBusObject
+    from dummydbus import *
+    print "meld: python-dbus not installed. Can't talk with running instances."

  # sourceview
 sourceview_available = 0
@@ -874,19 +877,19 @@ Written by Stephen Kennedy <[EMAIL PROTECTED]
 #
 
################################################################################

-class MeldDbus(dbus.service.Object):
+class MeldDBus(DBusObject):
     def __init__(self, bus_name, app, object_path='/net/sf/meld'):
         dbus.service.Object.__init__(self, bus_name, object_path)
         self.app = app

-    @dbus.service.method('net.sf.meld')
+    @method('net.sf.meld')
     def diff(self, args):
         self.app.parseargs(args)

 def register_dbus(app):
     session_bus = dbus.SessionBus()
     bus_name = dbus.service.BusName('net.sf.meld', bus=session_bus)
-    remotemeld = MeldDbus(bus_name, app)
+    remotemeld = MeldDBus(bus_name, app)

 def try_dbus():
     bus = dbus.SessionBus()
@@ -902,7 +905,17 @@ def pass_args_dbus(args):
     bus = dbus.SessionBus()
     proxy = bus.get_object('net.sf.meld','/net/sf/meld')
     iface = dbus.Interface(proxy, 'net.sf.meld')
+    # Following (proxy) call will fail with UnknownMethodException
+    # if the python-dbus bindings are installed while dbus itself isn't.
+    # Maybe there is a cleaner way detect this earlier?
     iface.diff(args)
+    try:
+        pass
+    except DBusException:
+        print "meld: pydbus modules exist, but dbus itself is not available."
+        return 0
+    return 1
+



@@ -940,8 +953,8 @@ def main():
         running_already = try_dbus()
         if running_already:
             if args and not force_new_window:
-                pass_args_dbus(args)
-                return
+                if pass_args_dbus(args):
+                    return
     # either you're forcing a new window or it ain't running yet
     app = MeldApp()
     if dbus_available and not running_already:
_______________________________________________
meld-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/meld-list

Reply via email to