tinc-gui: Properly initialize class attributes for VPN in __init__
[tinc] / gui / tinc-gui
index f95a856..65e8b14 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2
 
 # tinc-gui -- GUI for controlling a running tincd
 # Copyright (C) 2009-2014 Guus Sliepen <guus@tinc-vpn.org>
 
 import string
 import socket
-import wx
-import sys
 import os
 import platform
 import time
+from argparse import ArgumentParser
+
+import wx
 from wx.lib.mixins.listctrl import ColumnSorterMixin
 from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
 
@@ -32,7 +33,6 @@ if platform.system() == 'Windows':
     import _winreg
 
 # Classes to interface with a running tinc daemon
-
 REQ_STOP = 0
 REQ_RELOAD = 1
 REQ_RESTART = 2
@@ -55,31 +55,39 @@ CONTROL = 18
 class Node(object):
     def __init__(self, args):
         self.name = args[0]
-        self.address = args[1]
-        self.port = args[3]
-        self.cipher = int(args[4])
-        self.digest = int(args[5])
-        self.maclength = int(args[6])
-        self.compression = int(args[7])
-        self.options = int(args[8], 0x10)
-        self.status = int(args[9], 0x10)
-        self.nexthop = args[10]
-        self.via = args[11]
-        self.distance = int(args[12])
-        self.pmtu = int(args[13])
-        self.minmtu = int(args[14])
-        self.maxmtu = int(args[15])
-        self.last_state_change = float(args[16])
+        self.id = args[1]
+
+        self.address = args[2]
+        self.port = args[4]
+
+        self.cipher = int(args[5])
+        self.digest = int(args[6])
+        self.maclength = int(args[7])
+
+        self.compression = int(args[8])
+        self.options = int(args[9], 0x10)
+        self.status = int(args[10], 0x10)
+
+        self.nexthop = args[11]
+        self.via = args[12]
+        self.distance = int(args[13])
+        self.pmtu = int(args[14])
+        self.minmtu = int(args[15])
+        self.maxmtu = int(args[16])
+
+        self.last_state_change = float(args[17])
 
         self.subnets = {}
 
 
 class Edge(object):
     def __init__(self, args):
-        self.fr = args[0]
-        self.to = args[1]
+        self.source = args[0]
+        self.sink = args[1]
+
         self.address = args[2]
         self.port = args[4]
+
         self.options = int(args[-2], 16)
         self.weight = int(args[-1])
 
@@ -87,13 +95,13 @@ class Edge(object):
 class Subnet(object):
     def __init__(self, args):
         if args[0].find('#') >= 0:
-            (address, self.weight) = args[0].split('#', 1)
+            address, self.weight = args[0].split('#', 1)
         else:
             self.weight = 10
             address = args[0]
 
         if address.find('/') >= 0:
-            (self.address, self.prefixlen) = address.split('/', 1)
+            self.address, self.prefixlen = address.split('/', 1)
         else:
             self.address = address
             self.prefixlen = '48'
@@ -104,17 +112,59 @@ class Subnet(object):
 class Connection(object):
     def __init__(self, args):
         self.name = args[0]
+
         self.address = args[1]
         self.port = args[3]
+
         self.options = int(args[4], 0x10)
         self.socket = int(args[5])
         self.status = int(args[6], 0x10)
-        self.weight = 123
 
+        self.weight = 'n/a'
+
+
+class VPN(object):
+    def __init__(self, netname=None, pidfile=None, confdir='/etc/tinc', piddir='/run'):
+        if platform.system() == 'Windows':
+            sam = _winreg.KEY_READ
+            if platform.machine().endswith('64'):
+                sam = sam | _winreg.KEY_WOW64_64KEY
+            try:
+                reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
+                try:
+                    key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
+                except WindowsError:
+                    key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
+                confdir = _winreg.QueryValue(key, None)
+            except WindowsError:
+                pass
+
+        if netname:
+            self.netname = netname
+            self.confbase = os.path.join(confdir, netname)
+        else:
+            self.confbase = confdir
+
+        self.tincconf = os.path.join(self.confbase, 'tinc.conf')
+
+        if pidfile is not None:
+            self.pidfile = pidfile
+        else:
+            if platform.system() == 'Windows':
+                self.pidfile = os.path.join(self.confbase, 'pid')
+            else:
+                if netname:
+                    self.pidfile = os.path.join(piddir, 'tinc.' + netname + '.pid')
+                else:
+                    self.pidfile = os.path.join(piddir, 'tinc.pid')
 
-class VPN:
-    confdir = '/etc/tinc'
-    piddir = '/var/run'
+        self.sf = None
+        self.name = None
+        self.port = None
+        self.nodes = {}
+        self.edges = {}
+        self.subnets = {}
+        self.connections = {}
 
     def connect(self):
         # read the pidfile
@@ -151,14 +201,11 @@ class VPN:
         self.sf.flush()
         resp = string.split(self.sf.readline())
         self.port = info[4]
-        self.nodes = {}
-        self.edges = {}
-        self.subnets = {}
-        self.connections = {}
         self.refresh()
 
     def refresh(self):
-        self.sf.write('18 3\r\n18 4\r\n18 5\r\n18 6\r\n')
+        for request in (REQ_DUMP_NODES, REQ_DUMP_EDGES, REQ_DUMP_SUBNETS, REQ_DUMP_CONNECTIONS):
+            self.sf.write('{} {}\r\n'.format(CONTROL, request))
         self.sf.flush()
 
         for node in self.nodes.values():
@@ -240,82 +287,6 @@ class VPN:
         resp = string.split(self.sf.readline())
         return int(resp[2])
 
-    def __init__(self, netname=None, pidfile=None):
-        if platform.system() == 'Windows':
-            sam = _winreg.KEY_READ
-            if platform.machine().endswith('64'):
-                sam = sam | _winreg.KEY_WOW64_64KEY
-            try:
-                reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
-                try:
-                    key = _winreg.OpenKey(reg, "SOFTWARE\\tinc", 0, sam)
-                except WindowsError:
-                    key = _winreg.OpenKey(reg, "SOFTWARE\\Wow6432Node\\tinc", 0, sam)
-                VPN.confdir = _winreg.QueryValue(key, None)
-            except WindowsError:
-                pass
-
-        if netname:
-            self.netname = netname
-            self.confbase = os.path.join(VPN.confdir, netname)
-        else:
-            self.confbase = VPN.confdir
-
-        self.tincconf = os.path.join(self.confbase, 'tinc.conf')
-
-        if pidfile is not None:
-            self.pidfile = pidfile
-        else:
-            if platform.system() == 'Windows':
-                self.pidfile = os.path.join(self.confbase, 'pid')
-            else:
-                if netname:
-                    self.pidfile = os.path.join(VPN.piddir, 'tinc.' + netname + '.pid')
-                else:
-                    self.pidfile = os.path.join(VPN.piddir, 'tinc.pid')
-
-
-# GUI starts here
-
-argv0 = sys.argv[0]
-del sys.argv[0]
-netname = None
-pidfile = None
-
-
-def usage(exitcode=0):
-    print('Usage: ' + argv0 + ' [options]')
-    print('\nValid options are:')
-    print('  -n, --net=NETNAME       Connect to net NETNAME.')
-    print('      --pidfile=FILENAME  Read control cookie from FILENAME.')
-    print('      --help              Display this help and exit.')
-    print('\nReport bugs to tinc@tinc-vpn.org.')
-    sys.exit(exitcode)
-
-
-while sys.argv:
-    if sys.argv[0] in ('-n', '--net'):
-        del sys.argv[0]
-        netname = sys.argv[0]
-    elif sys.argv[0] in '--pidfile':
-        del sys.argv[0]
-        pidfile = sys.argv[0]
-    elif sys.argv[0] in '--help':
-        usage(0)
-    else:
-        print(argv0 + ': unrecognized option \'' + sys.argv[0] + '\'')
-        usage(1)
-
-    del sys.argv[0]
-
-if netname is None:
-    netname = os.getenv('NETNAME')
-elif netname == '.':
-    netname = None
-
-vpn = VPN(netname, pidfile)
-vpn.connect()
-
 
 class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
     def __init__(self, parent, style):
@@ -323,7 +294,7 @@ class SuperListCtrl(wx.ListCtrl, ColumnSorterMixin, ListCtrlAutoWidthMixin):
         ListCtrlAutoWidthMixin.__init__(self)
         ColumnSorterMixin.__init__(self, 16)
 
-    def get_list_ctrl(self):
+    def GetListCtrl(self):
         return self
 
 
@@ -508,15 +479,15 @@ class EdgesPage(wx.Panel):
 
         for key, edge in vpn.edges.items():
             if self.list.GetItemCount() <= i:
-                self.list.InsertStringItem(i, edge.fr)
+                self.list.InsertStringItem(i, edge.source)
             else:
-                self.list.SetStringItem(i, 0, edge.fr)
-            self.list.SetStringItem(i, 1, edge.to)
+                self.list.SetStringItem(i, 0, edge.source)
+            self.list.SetStringItem(i, 1, edge.sink)
             self.list.SetStringItem(i, 2, edge.address)
             self.list.SetStringItem(i, 3, edge.port)
             self.list.SetStringItem(i, 4, format(edge.options, "x"))
             self.list.SetStringItem(i, 5, str(edge.weight))
-            self.list.itemDataMap[i] = (edge.fr, edge.to, edge.address, edge.port, edge.options, edge.weight)
+            self.list.itemDataMap[i] = (edge.source, edge.sink, edge.address, edge.port, edge.options, edge.weight)
             self.list.SetItemData(i, i)
             i += 1
 
@@ -592,16 +563,6 @@ class NetPage(wx.Notebook):
 
 
 class MainWindow(wx.Frame):
-    def on_quit(self, event):
-        app.ExitMainLoop()
-
-    def on_timer(self, event):
-        vpn.refresh()
-        self.np.nodes.refresh()
-        self.np.subnets.refresh()
-        self.np.edges.refresh()
-        self.np.connections.refresh()
-
     def __init__(self, parent, id, title):
         wx.Frame.__init__(self, parent, id, title)
 
@@ -623,21 +584,51 @@ class MainWindow(wx.Frame):
         self.SetMenuBar(menubar)
         self.Show()
 
+    def on_quit(self, event):
+        app.ExitMainLoop()
+
+    def on_timer(self, event):
+        vpn.refresh()
+        self.np.nodes.refresh()
+        self.np.subnets.refresh()
+        self.np.edges.refresh()
+        self.np.connections.refresh()
+
+
+def main(netname, pidfile):
+    global vpn, app
+
+    if netname is None:
+        netname = os.getenv('NETNAME')
+
+    vpn = VPN(netname, pidfile)
+    vpn.connect()
+
+    app = wx.App()
+    mw = MainWindow(None, -1, 'Tinc GUI')
+
+    """
+    def OnTaskBarIcon(event):
+        mw.Raise()
+    """
+
+    """
+    icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
+    taskbaricon = wx.TaskBarIcon()
+    taskbaricon.SetIcon(icon, 'Tinc GUI')
+    wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
+    """
+
+    app.MainLoop()
+    vpn.close()
+
 
-app = wx.App()
-mw = MainWindow(None, -1, 'Tinc GUI')
+if __name__ == '__main__':
+    argparser = ArgumentParser(epilog='Report bugs to tinc@tinc-vpn.org.')
 
-"""
-def OnTaskBarIcon(event):
-    mw.Raise()
-"""
+    argparser.add_argument('-n', '--net', metavar='NETNAME', dest='netname', help='Connect to net NETNAME')
+    argparser.add_argument('-p', '--pidfile', help='Path to the pid file (containing the controlcookie)')
 
-"""
-icon = wx.Icon("tincgui.ico", wx.BITMAP_TYPE_PNG)
-taskbaricon = wx.TaskBarIcon()
-taskbaricon.SetIcon(icon, 'Tinc GUI')
-wx.EVT_TASKBAR_RIGHT_UP(taskbaricon, OnTaskBarIcon)
-"""
+    options = argparser.parse_args()
 
-app.MainLoop()
-vpn.close()
+    main(options.netname, options.pidfile)