WiFi Keepalive [master]

Keep running even when connection is down

=> 9d6be61051ecd82d37ed8517fce32c8422655ea6

diff --git a/install b/install
index 791a711..3546814 100755
--- a/install
+++ b/install
@@ -1,6 +1,8 @@
 #! /usr/bin/env python3
 
 import os
+import sys
+
 from string import Template
 from subprocess import check_call
 
@@ -12,7 +14,8 @@ CURRENT_DIR      = os.path.dirname(os.path.realpath(__file__))
 EXEC_PATH        = os.path.join(CURRENT_DIR, EXEC)
 SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE)
 SERVICE_FILE     = os.path.join(SYSTEM_DIR, SERVICE)
-EXEC_START       = f'python3 {EXEC}'
+PYTHON           = sys.executable
+EXEC_START       = f'{PYTHON} {EXEC}'
 
 with open(SERVICE_TEMPLATE) as f:
     serviceTemplate = Template(f.read())
diff --git a/wifi-keepalive.py b/wifi-keepalive.py
index 92f318c..0061ac2 100644
--- a/wifi-keepalive.py
+++ b/wifi-keepalive.py
@@ -3,30 +3,89 @@ from subprocess import CalledProcessError, check_output
 from sys import exit
 from time import sleep
 
+INITIAL_DELAY_IN_SECONDS = 40
 PING_INTERVAL_IN_SECONDS = 80
 
-signal(SIGTERM, lambda signum, frame: exit(0))
 
+class WifiKeepalive:
 
-def getDefaultRoute():
-    routes = check_output(['route', '-n']).decode('utf-8').splitlines()
-    defaults = [r.split()[1] for r in routes if r.startswith('0.0.0.0')]
+    def __init__(self):
+        self.defaultRoute = self.getDefaultWifiRoute()
+        self.initialDelay = INITIAL_DELAY_IN_SECONDS
+        self.pingInterval = PING_INTERVAL_IN_SECONDS
+        self.isConnected = True
+        self.pingCommand = 'ping -c 1 -W 2 -n'
 
-    return defaults[0] if defaults else None
+    def run(self):
+        sleep(self.initialDelay)
 
+        while self.isRunning():
+            self.keepalive()
+            sleep(self.pingInterval)
 
-def keepalive(defaultRoute):
-    while True:
-        sleep(PING_INTERVAL_IN_SECONDS)
-        ping(defaultRoute)
+    def isRunning(self):
+        return True
 
+    def keepalive(self):
+        if self.defaultRoute:
+            self.pingDefaultRoute()
+        else:
+            self.attemptWifiConnection()
 
-def ping(address):
-    try:
-        check_output(['ping', '-c', '1', address])
-    except CalledProcessError as e:
-        pass
+    def pingDefaultRoute(self):
+        if not self.isConnected:
+            print('Connected to Wifi', flush=True)
 
+        self.isConnected = True
+        isPingSuccess = self.ping()
 
-defaultRoute = getDefaultRoute()
-keepalive(defaultRoute) if defaultRoute else print('No default route')
+        if not isPingSuccess:
+            self.defaultRoute = self.getDefaultWifiRoute()
+
+    def attemptWifiConnection(self):
+        if self.isConnected:
+            print('No Wifi Connection', flush=True)
+
+        self.isConnected = False
+        self.defaultRoute = self.getDefaultWifiRoute()
+
+    def ping(self):
+        try:
+            check_output([*self.pingCommand.split(), self.defaultRoute])
+        except CalledProcessError as e:
+            return False
+
+        return True
+
+    def getDefaultWifiRoute(self):
+        defaults = [
+            r['gateway'] for r in self.getRoutes() if self.isDefaultWifiRoute(r)
+        ]
+
+        return defaults[0] if defaults else None
+
+    def getRoutes(self):
+        outputLines = check_output(
+            ['route', '-n']
+        ).decode('utf-8').splitlines()[2:]
+
+        routes = map(lambda r: self.parseRoute(r), outputLines)
+
+        return routes
+
+    def parseRoute(self, routeLine):
+        destination, gateway, _, _, _, _, _, interface = routeLine.split()
+
+        return {'destination': destination, 'gateway': gateway, 'interface': interface}
+
+    def isDefaultWifiRoute(self, route):
+        return route['destination'] == '0.0.0.0' and route['interface'].startswith('w')
+
+
+def main():
+    signal(SIGTERM, lambda s, f: exit(0))
+    WifiKeepalive().run()
+
+
+if __name__ == '__main__':
+    main()
Proxy Information
Original URL
gemini://git.cifelli.xyz/wifi-keepalive/master/cdiff/9d6be61051ecd82d37ed8517fce32c8422655ea6
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
487.853519 milliseconds
Gemini-to-HTML Time
0.19543 milliseconds

This content has been proxied by September (3851b).