diff --git a/README.markdown b/README.markdown index 76e69be..306f9d0 100644 --- a/README.markdown +++ b/README.markdown @@ -1,12 +1,13 @@ -# Speed-test and IP change scripts +# Monitoring scripts for IP changes and connection speed ## Requirements -* Python 3 with modules `mysql-connector-python` and `speedtest-cli` -* A SQL database (MariaDB is recommended) +* Python 3 with the modules from `requirements.txt` +* A MySQL database (I use MariaDB) +* A DynDNS server that supports the [Remote Access Update API](https://help.dyn.com/remote-access-api/) + ## Usage -1. Create tables in the database using `tables.sql` -2. Configure the scripts in the fields provided -3. Add cron-jobs for the scripts. I currently use an interval of 15 seconds +1. Configure the two scripts using `config.ini` +1. Set cronjobs for the two scripts. I currently run them every 15 minutes. \ No newline at end of file diff --git a/config.ini b/config.ini new file mode 100644 index 0000000..3df0a75 --- /dev/null +++ b/config.ini @@ -0,0 +1,11 @@ +[db] +user = +password = +host = +database = +[dyndns] +user = +password = +url = + + diff --git a/ipch.py b/ipch.py index ba2833e..bfc4d4c 100755 --- a/ipch.py +++ b/ipch.py @@ -2,23 +2,47 @@ import requests import mysql.connector import datetime +import configparser +import sys # Configuration -DYNDNS_AUTH = {'user':'','pass':''} -DYNDNS_URL = '' -DB_CONFIG = { - 'user': '', - 'password': '', - 'host': '', - 'db': '' - } -result = requests.get(DYNDNS_URL, auth=(DYNDNS_AUTH['user'], DYNDNS_AUTH['pass'])) +cfg = configparser.ConfigParser() +with open('config.ini', 'r') as f: + cfg.read_file(f) + +DYN_CFG = cfg['dyndns'] + +IPCH_TABLE_CMD = """CREATE TABLE IF NOT EXISTS ipch ( +time DATETIME, +status NATIONAL CHARACTER VARYING(8), +ip NATIONAL CHARACTER VARYING(15) +); +""" + +for s in 'user', 'password', 'url': + if s not in DYN_CFG: + print(f'{s} missing. Please add the {s} property to your config.ini\'s [dyndns] section.') + exit(1) + +DB_CONFIG = {k: v for k, v in cfg['db'].items() if k in ['user', 'password', 'host', 'database']} + +result = requests.get(DYN_CFG['url'], auth=(DYN_CFG['user'], DYN_CFG['password'])) s = result.content.decode("unicode_escape").rstrip('\n').split(' ') -cx=mysql.connector.connect(**DB_CONFIG) -c=cx.cursor() -data = (datetime.datetime.now(),s[0],s[1]) +cx = mysql.connector.connect(**DB_CONFIG) +c = cx.cursor() +if s[0] in ['nochg', 'good']: + data = (datetime.datetime.now(), s[0], s[1]) +elif s[0] == 'badauth': + exit('Bad DynDNS authentication provided. Please check the [dyndns] section in config.ini.') +elif s[0] == 'nohost': + exit('The server says this host does not exist.') +else: + print(f'status unknown: {s[0]}', file=sys.stderr) + data = (datetime.datetime.now(), s[0], None) + try: - c.execute("INSERT INTO ipch_he (time,status,ip) values (%s,%s,%s)",data) + c.execute(IPCH_TABLE_CMD) + c.execute('INSERT INTO ipch (time, status, ip) values (%s, %s, %s)', data) cx.commit() except: cx.rollback() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..05c606d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +speedtest-cli +mysql-connector-python +requests \ No newline at end of file diff --git a/st.py b/st.py index 29a88af..0625d24 100755 --- a/st.py +++ b/st.py @@ -1,60 +1,76 @@ #!/usr/bin/env python3 -import speedtest -import csv +import sys import datetime +import configparser import mysql.connector -import os +import speedtest +from socket import timeout -db_config = { - 'user': 'm_imp', - 'password': '123', - 'host': '127.0.0.1', - 'database': 'speedtests' - } +cfg = configparser.ConfigParser() +with open('config.ini') as f: + cfg.read_file(f) + +db_config = {k: v for k, v in cfg['db'].items() if k in ['user', 'password', 'host', 'database']} + + +SPEEDTEST_TABLE_CMD = """CREATE TABLE IF NOT EXISTS sts ( +test_no INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT, +server_id INTEGER, +sponsor NATIONAL CHARACTER VARYING(40), +time DATETIME, +distance FLOAT UNSIGNED, +ping FLOAT UNSIGNED, +download FLOAT UNSIGNED, +upload FLOAT UNSIGNED +); +""" try: - cx=mysql.connector.connect(**db_config) - c=cx.cursor() + cx = mysql.connector.connect(**db_config) + c = cx.cursor() + upload_statement = """INSERT INTO sts (server_id, sponsor, time, distance, ping, download, upload) + VALUES (%s, %s, %s, %s, %s, %s, %s)""" + + try: + s = speedtest.Speedtest() + s.get_servers() + s.get_best_server() + s.download() + s.upload() + d = s.results.dict() + u = ( + d['server']['id'], + d['server']['sponsor'], + d['timestamp'], + d['server']['d'], # distance + d['server']['latency'], + d['download'], + d['upload'] + ) + except (speedtest.SpeedtestException, timeout): + u = ( + None, + None, + str(datetime.datetime.utcnow().isoformat()) + 'Z', + None, + None, + None, + None + ) + print("Speedtest failed", file=sys.stderr) + try: + c.execute(SPEEDTEST_TABLE_CMD) + c.execute(upload_statement, u) + + cx.commit() + except mysql.connector.Error: + cx.rollback() + raise + c.close() + cx.close() except mysql.connector.Error as err: + print(err) exit('Could not open database') -upload_statement = "INSERT INTO sts (server_id,sponsor,serv_name,time,distance,ping,download,upload) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)" -try: - s=speedtest.Speedtest() - s.get_servers() - s.get_best_server() - s.download() - s.upload() - d=s.results.dict() - u=( - d['server']['id'], - d['server']['sponsor'], - d['server']['name'], - d['timestamp'], - d['server']['d'], # distance - d['server']['latency'], - d['download'], - d['upload'] - ) -except speedtest.SpeedtestException: - u=( - None, - str(datetime.datetime.utcnow().isoformat())+'Z', - None, - None, - None, - None, - None, - None - ) - -try: - c.execute(upload_statement, u) - cx.commit() -except: - cx.rollback() - raise -c.close() -cx.close() -#print("Uploaded" + str(u)) +# print("Uploaded" + str(u)) diff --git a/tables.sql b/tables.sql deleted file mode 100644 index 423e955..0000000 --- a/tables.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TABLE IF NOT EXISTS ipch ( - time datetime, - status text, - ip text -); -CREATE TABLE IF NOT EXISTS sts ( - test_no integer unsigned primary key auto_increment, - server_id tinytext, - sponsor tinytext, - time datetime, - distance float unsigned, - ping float unsigned, - download float unsigned, - upload float unsigned -);