scripts/bin/ncupdate.py

121 lines
2.4 KiB
Python
Executable file

#!/usr/bin/env python3
import json, signal, sys, time, traceback
from datetime import datetime
from pathlib import Path
from urllib.request import urlopen
def quit(*args):
print('Bye! :3')
sys.exit()
class Config(dict):
def __init__(self, path):
super().__init__()
self.path = Path(path)
self.load()
def load(self):
with self.path.open() as fd:
self.update(json.load(fd))
def save(self):
with self.path.open('w') as fd:
fd.write(json.dumps(self, indent='\t'))
class Log(object):
def __init__(self):
self.levels = {'merp': 0, 'verbose': 10, 'debug': 20, 'info': 30, 'error': 40}
for level, num in self.levels.items():
self.AddLevel(level, num)
def AddLevel(self, name, num):
self.levels[name] = num
setattr(self, name, lambda *args: self.log(name.upper(), *args))
def log(self, level, *args):
if len(args) == 0:
self.log('ERROR', 'Not enough args specified for Log.log')
return
d = datetime.now().strftime('%y-%m-%d, %H:%M:%S')
message = ' '.join([str(arg) for arg in args])
sys.stdout.write(f'[{d}] {level}: {message}\n')
sys.stdout.flush()
def GetIp():
try:
resp = urlopen('https://ident.me')
except Exception as e:
traceback.print_exc()
return
return resp.read().decode()
def main():
config = Config(Path('~/.config/ncdns.json').expanduser())
address = config.get('lastip')
domain = config.get('domain')
password = config.get('password')
hosts = config.get('hosts')
cycle = config.get('cycle', 3600)
if None in [domain, password, hosts]:
logging.error('Setup the domain, password, and hosts config options')
sys.exit()
while True:
new = GetIp()
if not new:
logging.error('Failed to get IP. Retrying in 60 seconds')
time.sleep(60)
continue
if new != address:
logging.info('Updating DNS with new IP:', new)
address = new
config['lastip'] = new
config.save()
for host in hosts:
try:
urlopen(f'https://dynamicdns.park-your-domain.com/update?host={host}&domain={domain}&password={password}&ip={new}')
except Exception as e:
traceback.print_exc()
logging.error(f'Failed to update {host}:', e)
logging.info('Done! :3')
time.sleep(config.get('cycle', 3600))
if __name__ == '__main__':
logging = Log()
signal.signal(signal.SIGTERM, quit)
signal.signal(signal.SIGINT, quit)
try:
logging.info('Starting Dynamic DNS Updater')
main()
except KeyboardInterrupt:
pass
logging.info('Bye! :3')