From c7d11b95f435bb87e824438f4203b527e1f13a36 Mon Sep 17 00:00:00 2001 From: Valerio Souza Date: Wed, 18 May 2022 13:33:22 -0300 Subject: [PATCH 1/3] RapidAPI --- __main__.py | 82 +++++++++++++++++++++++++++++++++++++++----- configs/mainconf.ini | 24 ++++++------- configs/plane1.ini | 2 +- defRpdADSBX.py | 80 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 defRpdADSBX.py diff --git a/__main__.py b/__main__.py index 4ac9890..f0cf849 100644 --- a/__main__.py +++ b/__main__.py @@ -1,5 +1,4 @@ import configparser -from logging import DEBUG import time from colorama import Fore, Back, Style import platform @@ -49,11 +48,11 @@ main_config.read('./configs/mainconf.ini') source = main_config.get('DATA', 'SOURCE') if main_config.getboolean('DISCORD', 'ENABLE'): from defDiscord import sendDis - sendDis("Started", main_config, role_id = main_config.get('DISCORD', 'ROLE_ID')) + sendDis("Started", main_config) def service_exit(signum, frame): if main_config.getboolean('DISCORD', 'ENABLE'): from defDiscord import sendDis - sendDis("Service Stop", main_config, role_id = main_config.get('DISCORD', 'ROLE_ID')) + sendDis("Service Stop", main_config) raise SystemExit("Service Stop") signal.signal(signal.SIGTERM, service_exit) if os.path.isfile("lookup_route.py"): @@ -83,7 +82,6 @@ try: except pytz.exceptions.UnknownTimeZoneError: tz = pytz.UTC last_ra_count = None - print(len(planes), "Planes configured") while True: datetime_tz = datetime.now(tz) if datetime_tz.hour == 0 and datetime_tz.minute == 0: @@ -140,12 +138,75 @@ try: for planeData in data['ac']: data_indexed[planeData[icao_key].upper()] = planeData for key, obj in planes.items(): - if key in data_indexed.keys(): + try: if api_version == 1: obj.run_adsbx_v1(data_indexed[key.upper()]) elif api_version == 2: obj.run_adsbx_v2(data_indexed[key.upper()]) - else: + except KeyError: + obj.run_empty() + else: + for obj in planes.values(): + obj.run_empty() + else: + failed_count += 1 + elif source == "RpdADSBX": + #ACAS data + from defADSBX import pull_date_ras + import ast + today = datetime.utcnow() + date = today.strftime("%Y/%m/%d") + ras = pull_date_ras(date) + sorted_ras = {} + if ras is not None: + #Testing RAs + #if last_ra_count is not None: + # with open('./testing/acastest.json') as f: + # data = f.readlines() + # ras += data + ra_count = len(ras) + if last_ra_count is not None and ra_count != last_ra_count: + print(abs(ra_count - last_ra_count), "new Resolution Advisories") + for ra_num, ra in enumerate(ras[last_ra_count:]): + ra = ast.literal_eval(ra) + if ra['hex'].upper() in planes.keys(): + if ra['hex'].upper() not in sorted_ras.keys(): + sorted_ras[ra['hex'].upper()] = [ra] + else: + sorted_ras[ra['hex'].upper()].append(ra) + else: + print("No new Resolution Advisories") + last_ra_count = ra_count + for key, obj in planes.items(): + if sorted_ras != {} and key in sorted_ras.keys(): + print(key, "has", len(sorted_ras[key]), "RAs") + obj.check_new_ras(sorted_ras[key]) + obj.expire_ra_types() + icao_key = 'hex' + from defRpdADSBX import pull_rpdadsbx + # print("Planes list: \n"+str((list(planes.keys())))) + # print("\nLen planes:\n"+str(len(planes))) + p = 0 + data = dict.fromkeys(['ac']) + # print(data) + while p < len(planes): + planeInfo = pull_rpdadsbx(str(list(planes.keys())[p])) + if p == 0: + data['ac'] = (planeInfo)['ac'] + else: + data['ac'].extend((planeInfo)['ac']) + # print("p = "+str(p)) + # print(str(list(planes.keys())[p]) + ": " + str(data)) + p += 1 + if data is not None: + if data['ac'] is not None: + data_indexed = {} + for planeData in data['ac']: + data_indexed[planeData[icao_key].upper()] = planeData + for key, obj in planes.items(): + try: + obj.run_adsbx_v2(data_indexed[key.upper()]) + except KeyError: obj.run_empty() else: for obj in planes.values(): @@ -186,7 +247,10 @@ try: footer = "-------- " + str(running_Count) + " -------- " + str(datetime_tz.strftime("%I:%M:%S %p")) + " ------------------------Elapsed Time- " + str(round(elapsed_calc_time, 3)) + " -------------------------------------" print (Back.GREEN + Fore.BLACK + footer[0:100] + Style.RESET_ALL) - sleep_sec = 30 + if main_config.has_section('SLEEP'): + sleep_sec = int(main_config.get('SLEEP', 'SLEEPSEC')) + else: + sleep_sec = 30 for i in range(sleep_sec,0,-1): if i < 10: i = " " + str(i) @@ -208,10 +272,10 @@ except Exception as e: except OSError: pass import logging - logging.basicConfig(filename='crash_latest.log', filemode='w', format='%(asctime)s - %(message)s',level=logging.DEBUG) + logging.basicConfig(filename='crash_latest.log', filemode='w', format='%(asctime)s - %(message)s') logging.Formatter.converter = time.gmtime logging.error(e) logging.error(str(traceback.format_exc())) from defDiscord import sendDis - sendDis(str("Error Exiting: " + str(e) + " Failed on " + "https://globe.adsbexchange.com/?icao=" + key), main_config, main_config.get('DISCORD', 'ROLE_ID'), "crash_latest.log") + sendDis(str("Error Exiting: " + str(e) + "Failed on " + key), main_config, "crash_latest.log") raise e \ No newline at end of file diff --git a/configs/mainconf.ini b/configs/mainconf.ini index 5c0619f..0a3c999 100644 --- a/configs/mainconf.ini +++ b/configs/mainconf.ini @@ -2,8 +2,8 @@ #Source to pull data from #SHOULD BE ADSBX which is ADS-B Exchange or OPENS which is OpenSky #By default configured with OpenSky which anyone can use without a login -#ADS-B Exchange has better data but is not avalible unless you pay (see: https://www.adsbexchange.com/data/ ) -SOURCE = OPENS +#ADS-B Exchange has better data but is not avalible unless you feed their network or pay. +SOURCE = RpdADSBX #Default amount of time after data loss to trigger a landing when under 10k ft DATA_LOSS_MINS = 5 #Failover from one source to the other, only enable if you have both sources setup. @@ -28,6 +28,15 @@ PROXY_HOST = USERNAME = None PASSWORD = None +#ADS-B Exchange on RapidAPI https://rapidapi.com/adsbx/api/adsbexchange-com1/ +[RpdADSBX] +API_KEY = none +API_VERSION = 2 + +#Define the delay interval in seconds between each data request. This is usefull if you have limited requests in the API. +[SLEEP] +SLEEPSEC = 60 + [GOOGLE] #API KEY for Google Static Maps only if you using this on any of the planes. API_KEY = googleapikey @@ -36,13 +45,4 @@ API_KEY = googleapikey [DISCORD] ENABLE = FALSE USERNAME = usernamehere -URL = webhookurl - -[TFRS] -URL = http://127.0.0.1:5000/detailed_all - -[TWITTER] -#GLOBAL TWITTER CONSUMER KEY AND CONSUMERS SECRET ONLY NEED TO BE HERE NOW -ENABLE = False -CONSUMER_KEY = ck -CONSUMER_SECRET = cs +URL = webhookurl \ No newline at end of file diff --git a/configs/plane1.ini b/configs/plane1.ini index 7891fa0..ac167d8 100644 --- a/configs/plane1.ini +++ b/configs/plane1.ini @@ -54,4 +54,4 @@ ACCESS_TOKEN = ENABLE = FALSE TITLE = Title Of Telegram message ROOM_ID = -100xxxxxxxxxx -BOT_TOKEN = xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +BOT_TOKEN = xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ No newline at end of file diff --git a/defRpdADSBX.py b/defRpdADSBX.py new file mode 100644 index 0000000..727be14 --- /dev/null +++ b/defRpdADSBX.py @@ -0,0 +1,80 @@ +import requests +import json +import configparser +from datetime import datetime +from http.client import IncompleteRead +import http.client as http +import urllib3 +import socket +main_config = configparser.ConfigParser() +main_config.read('./configs/mainconf.ini') +api_version = main_config.get('RpdADSBX', 'API_VERSION') + +# def pull(url, headers): +# try: +# response = requests.get(url, headers = headers, timeout=30) +# print ("HTTP Status Code:", response.status_code) +# response.raise_for_status() +# except (requests.HTTPError, ConnectionError, requests.Timeout, urllib3.exceptions.ConnectionError) as error_message: +# print("Basic Connection Error") +# print(error_message) +# response = None +# except (requests.RequestException, IncompleteRead, ValueError, socket.timeout, socket.gaierror) as error_message: +# print("Connection Error") +# print(error_message) +# response = None +# except Exception as error_message: +# print("Connection Error uncaught, basic exception for all") +# print(error_message) +# response = None +# return response + +def pull_rpdadsbx(planes): + api_version = int(main_config.get('RpdADSBX', 'API_VERSION')) + if api_version != 2: + raise ValueError("Bad RapidAPI ADSBX API Version") + url = "https://adsbexchange-com1.p.rapidapi.com/v2/icao/" + planes + "/" + headers = { + "X-RapidAPI-Host": "adsbexchange-com1.p.rapidapi.com", + "X-RapidAPI-Key": main_config.get('RpdADSBX', 'API_KEY') + } + try: + response = requests.get(url, headers = headers, timeout=30) + except Exception as error: + print('err.args:' + str(error.args)) + response = None + if response is not None: + try: + data = json.loads(response.text) + except (json.decoder.JSONDecodeError, ValueError) as error_message: + print("Error with JSON") + print(error_message) + data = None + except TypeError as error_message: + print("Type Error", error_message) + data = None + else: + if "msg" in data.keys() and data['msg'] != "No error": + raise ValueError("Error from ADSBX: msg = ", data['msg']) + if "ctime" in data.keys(): + data_ctime = float(data['ctime']) / 1000.0 + print("Data ctime:",datetime.utcfromtimestamp(data_ctime)) + if "now" in data.keys(): + data_now = float(data['now']) / 1000.0 + print("Data now time:",datetime.utcfromtimestamp(data_now)) + print("Current UTC:", datetime.utcnow()) + else: + data = None + return data + +# def pull_date_ras(date): +# url = f"https://globe.adsbexchange.com/globe_history/{date}/acas/acas.json" +# headers = { +# 'Accept-Encoding': 'gzip' +# } +# response = pull(url, headers) +# if response is not None: +# data = response.text.splitlines() +# else: +# data = None +# return data \ No newline at end of file From 1bebad1a9cf552ee0e4fdf6b65b7dcac87cfafd6 Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Mon, 20 Jun 2022 17:56:10 -0400 Subject: [PATCH 2/3] codacy fixes removed unused imports removed commented out code --- defRpdADSBX.py | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/defRpdADSBX.py b/defRpdADSBX.py index 727be14..d524943 100644 --- a/defRpdADSBX.py +++ b/defRpdADSBX.py @@ -3,32 +3,11 @@ import json import configparser from datetime import datetime from http.client import IncompleteRead -import http.client as http -import urllib3 -import socket + main_config = configparser.ConfigParser() main_config.read('./configs/mainconf.ini') api_version = main_config.get('RpdADSBX', 'API_VERSION') -# def pull(url, headers): -# try: -# response = requests.get(url, headers = headers, timeout=30) -# print ("HTTP Status Code:", response.status_code) -# response.raise_for_status() -# except (requests.HTTPError, ConnectionError, requests.Timeout, urllib3.exceptions.ConnectionError) as error_message: -# print("Basic Connection Error") -# print(error_message) -# response = None -# except (requests.RequestException, IncompleteRead, ValueError, socket.timeout, socket.gaierror) as error_message: -# print("Connection Error") -# print(error_message) -# response = None -# except Exception as error_message: -# print("Connection Error uncaught, basic exception for all") -# print(error_message) -# response = None -# return response - def pull_rpdadsbx(planes): api_version = int(main_config.get('RpdADSBX', 'API_VERSION')) if api_version != 2: @@ -66,15 +45,3 @@ def pull_rpdadsbx(planes): else: data = None return data - -# def pull_date_ras(date): -# url = f"https://globe.adsbexchange.com/globe_history/{date}/acas/acas.json" -# headers = { -# 'Accept-Encoding': 'gzip' -# } -# response = pull(url, headers) -# if response is not None: -# data = response.text.splitlines() -# else: -# data = None -# return data \ No newline at end of file From 11383c7c0d04790ef712743fb9557781a07f5638 Mon Sep 17 00:00:00 2001 From: Mark Bumiller Date: Mon, 20 Jun 2022 21:05:54 -0400 Subject: [PATCH 3/3] removing unused import --- defRpdADSBX.py | 1 - 1 file changed, 1 deletion(-) diff --git a/defRpdADSBX.py b/defRpdADSBX.py index d524943..cce4c35 100644 --- a/defRpdADSBX.py +++ b/defRpdADSBX.py @@ -2,7 +2,6 @@ import requests import json import configparser from datetime import datetime -from http.client import IncompleteRead main_config = configparser.ConfigParser() main_config.read('./configs/mainconf.ini')