Complete.Org: Mailing Lists: Archives: offlineimap: April 2009:
NetworkManager
Home

NetworkManager

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: offlineimap@xxxxxxxxxxxx
Subject: NetworkManager
From: Ben Willard <benwillard@xxxxxxxxx>
Date: Wed, 22 Apr 2009 21:08:35 -0400

I use offlineimap on my laptop to check my mail and I'm always switching
wireless networks.

Anyway, I wanted three things from offlineimap:
 - Only try to sync when I'm connected to a network
 - As soon as I have connected to a network, start a sync immediately
 - Show something graphically when a sync is occurring

I tried using the /etc/network/if-up.d/ hooks in Debian for a while
(which seemed silly), and since I used NetworkManager for wireless I
eventually ended up writing a script to listen to dbus for
NetworkManager events.  This, combined with the GnomeUI (which is
_excellent_, by the way), does pretty much exactly what I want.

Anyway, would it make sense for me to try and make offlineimap
optionally "NetworkManager-aware"?  Or is this sort of thing better off
left to a script which calls offlineimap?

--
Ben

In case anyone's interested, here's the script I'm using:
(I don't regularly use Python, so please excuse the quality of this code.)

#!/usr/bin/python
from __future__ import with_statement
import dbus
import dbus.glib
import gobject
import gtk
import os
import signal
import subprocess
import sys
import threading
import time

# This number gets sent in the StateChanged message when the network goes up
NETWORK_UP_CODE = 3

# Sleep this many seconds after offlineimap exits
SLEEP_TIME_ON_EXIT=60

# Which offlineimap UI to use
OFFLINEIMAP_UI = 'Gnome.GnomeUI'

# Threading events that we'll update when we get NetworkManager messages
network_up      = threading.Event()
network_down    = threading.Event()

# processrunning is guarded by plock
processrunning = False
plock = threading.Lock()

# This gets called by the dbus event loop thread every time the network status
# changes
def stateChanged(state):
        global processrunning
        global process
        if state == NETWORK_UP_CODE:
                network_up.set()
                network_down.clear()
        else:
                network_up.clear()
                network_down.set()
                with plock:
                        if processrunning:
                                os.kill(process, signal.SIGINT) 

# Connect to the NetworkManager signal we want
bus = dbus.SystemBus()
nm_obj = bus.get_object('org.freedesktop.NetworkManager',
        '/org/freedesktop/NetworkManager')
interface = dbus.Interface(nm_obj, 'org.freedesktop.NetworkManager')
interface.connect_to_signal('StateChanged', stateChanged)

# This thread is responsible for launching offlineimap over and over
class LauncherThread(threading.Thread):
        def run(self):
                global processrunning
                global process
                while True:
                        network_up.wait()
                        while True:
                                with plock:     
                                        process = os.spawnlp(os.P_NOWAIT,
                                                'offlineimap', 'offlineimap',
                                                '-u', OFFLINEIMAP_UI)
                                        processrunning = True
                                os.wait()
                                with plock: processrunning = False
                                if not network_up.isSet(): break
                                # Sleep, but stop if the network goes down (so
                                # that we are ready in case it comes back up
                                # again)
                                network_down.wait(timeout=SLEEP_TIME_ON_EXIT)
                                if not network_up.isSet(): break

# Call stateChanged once to initialize the state of network_up
stateChanged(nm_obj.state())
                        
# Start the launcher thread and the main loop which handles all the dbus stuff
LauncherThread().start()
loop = gobject.MainLoop()
# Black magic needed so that the MainLoop doesn't prevent other threads from
# running
gobject.threads_init()
loop.run()




[Prev in Thread] Current Thread [Next in Thread]
  • NetworkManager, Ben Willard <=