Keep running even when connection is down
This commit is contained in:
		
							parent
							
								
									c9195b13cf
								
							
						
					
					
						commit
						9d6be61051
					
				
							
								
								
									
										5
									
								
								install
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								install
									
									
									
									
									
								
							@ -1,6 +1,8 @@
 | 
				
			|||||||
#! /usr/bin/env python3
 | 
					#! /usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from string import Template
 | 
					from string import Template
 | 
				
			||||||
from subprocess import check_call
 | 
					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)
 | 
					EXEC_PATH        = os.path.join(CURRENT_DIR, EXEC)
 | 
				
			||||||
SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE)
 | 
					SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE)
 | 
				
			||||||
SERVICE_FILE     = os.path.join(SYSTEM_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:
 | 
					with open(SERVICE_TEMPLATE) as f:
 | 
				
			||||||
    serviceTemplate = Template(f.read())
 | 
					    serviceTemplate = Template(f.read())
 | 
				
			||||||
 | 
				
			|||||||
@ -3,30 +3,89 @@ from subprocess import CalledProcessError, check_output
 | 
				
			|||||||
from sys import exit
 | 
					from sys import exit
 | 
				
			||||||
from time import sleep
 | 
					from time import sleep
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INITIAL_DELAY_IN_SECONDS = 40
 | 
				
			||||||
PING_INTERVAL_IN_SECONDS = 80
 | 
					PING_INTERVAL_IN_SECONDS = 80
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signal(SIGTERM, lambda signum, frame: exit(0))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WifiKeepalive:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getDefaultRoute():
 | 
					    def __init__(self):
 | 
				
			||||||
    routes = check_output(['route', '-n']).decode('utf-8').splitlines()
 | 
					        self.defaultRoute = self.getDefaultWifiRoute()
 | 
				
			||||||
    defaults = [r.split()[1] for r in routes if r.startswith('0.0.0.0')]
 | 
					        self.initialDelay = INITIAL_DELAY_IN_SECONDS
 | 
				
			||||||
 | 
					        self.pingInterval = PING_INTERVAL_IN_SECONDS
 | 
				
			||||||
 | 
					        self.isConnected = True
 | 
				
			||||||
 | 
					        self.pingCommand = 'ping -c 1 -W 2 -n'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        sleep(self.initialDelay)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while self.isRunning():
 | 
				
			||||||
 | 
					            self.keepalive()
 | 
				
			||||||
 | 
					            sleep(self.pingInterval)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def isRunning(self):
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def keepalive(self):
 | 
				
			||||||
 | 
					        if self.defaultRoute:
 | 
				
			||||||
 | 
					            self.pingDefaultRoute()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.attemptWifiConnection()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def pingDefaultRoute(self):
 | 
				
			||||||
 | 
					        if not self.isConnected:
 | 
				
			||||||
 | 
					            print('Connected to Wifi', flush=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.isConnected = True
 | 
				
			||||||
 | 
					        isPingSuccess = self.ping()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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
 | 
					        return defaults[0] if defaults else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getRoutes(self):
 | 
				
			||||||
 | 
					        outputLines = check_output(
 | 
				
			||||||
 | 
					            ['route', '-n']
 | 
				
			||||||
 | 
					        ).decode('utf-8').splitlines()[2:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def keepalive(defaultRoute):
 | 
					        routes = map(lambda r: self.parseRoute(r), outputLines)
 | 
				
			||||||
    while True:
 | 
					
 | 
				
			||||||
        sleep(PING_INTERVAL_IN_SECONDS)
 | 
					        return routes
 | 
				
			||||||
        ping(defaultRoute)
 | 
					
 | 
				
			||||||
 | 
					    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 ping(address):
 | 
					def main():
 | 
				
			||||||
    try:
 | 
					    signal(SIGTERM, lambda s, f: exit(0))
 | 
				
			||||||
        check_output(['ping', '-c', '1', address])
 | 
					    WifiKeepalive().run()
 | 
				
			||||||
    except CalledProcessError as e:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defaultRoute = getDefaultRoute()
 | 
					if __name__ == '__main__':
 | 
				
			||||||
keepalive(defaultRoute) if defaultRoute else print('No default route')
 | 
					    main()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user