#!/usr/bin/env python2 # -*- coding: utf-8 -*- # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA. # from __future__ import with_statement import gtk import gobject import os import subprocess import os.path import re TIMEOUT = 5 def default_interface(): '''returns the interface of the default route''' interface = None stdout = subprocess.check_output(['ip', 'route', 'list', 'scope', 'global']) for line in stdout.split('\n'): route = line.split(' ') if (len(route) >= 5 and (route[0], route[1], route[3]) == ('default', 'via', 'dev')): interface = route[4] break return interface def carrier_ok(iface): '''check if the interface is connected''' iface_dir = '/sys/class/net/%s' % iface with open(iface_dir + '/carrier') as f: line = f.next().strip() return line == '1' def wpa_status(): '''returns the output of wpa_cli status.''' return subprocess.check_output(['wpa_cli', 'status']).strip() def eth_status(iface): '''returns the status of the given interface (for the tooltip)''' stdout = subprocess.check_output(['ip', 'addr', 'show', 'dev', iface]) res = '' for line in stdout.split('\n'): m = re.search('(inet6? [^ ]*) ', line) if m: res = '\n'.join([res,m.group(1)]) return res def interface_type(iface): '''http://stackoverflow.com/questions/4475420/detect-network-connection-type-in-linux/16060638#16060638)''' res = 'wired' iface_dir = '/sys/class/net/%s' % iface with open(iface_dir + '/type') as f: line = f.next().strip() if line == '1': res = 'wired' if ('wireless' in os.listdir(iface_dir) or 'phy80211' in os.listdir(iface_dir)): res = 'wireless' return res class MainApp: def __init__(self): self.icon = gtk.StatusIcon() self.update_icon() gobject.timeout_add_seconds(TIMEOUT, self.update_icon) def get_network_info(self): interface = default_interface() connected = False if interface: connected = carrier_ok(interface) return {'interface': interface, 'connected': connected} def get_icon_name(self, interface, connected): if connected: return 'network-%s' % interface_type(interface) else: return 'network-error' def get_tooltip(self, interface, connected): if not connected: res = 'Disconnected' else: res = 'Connected on %s' % interface if interface_type(interface) == 'wireless': res = '\n'.join([res, wpa_status()]) elif interface_type(interface) == 'wired': res = '\n'.join([res, eth_status(interface)]) return res def update_icon(self): info = self.get_network_info() icon_name = self.get_icon_name(info['interface'], info['connected']) self.icon.set_from_icon_name(icon_name) tooltip = self.get_tooltip(info['interface'], info['connected']) self.icon.set_tooltip_text(tooltip) return True if __name__ == '__main__': try: MainApp() gtk.main() except KeyboardInterrupt: pass