|
|
|
@ -1,4 +1,7 @@
|
|
|
|
|
#!/usr/bin/env python3 |
|
|
|
|
|
|
|
|
|
# Partially written with ChatGPT |
|
|
|
|
|
|
|
|
|
import os |
|
|
|
|
import time |
|
|
|
|
import json |
|
|
|
@ -6,18 +9,13 @@ import sqlite3
|
|
|
|
|
import argparse |
|
|
|
|
import requests |
|
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser() |
|
|
|
|
parser.add_argument("config_file") |
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
with open(args.config_file) as f: |
|
|
|
|
config = json.load(f) |
|
|
|
|
def load_config(config_file): |
|
|
|
|
with open(config_file) as f: |
|
|
|
|
return json.load(f) |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
if config["pid_file"]: |
|
|
|
|
with open(config["pid_file"], "w+") as f: |
|
|
|
|
f.write(str(os.getpid())) |
|
|
|
|
|
|
|
|
|
def load_database(config): |
|
|
|
|
con = sqlite3.connect(config["database"]) |
|
|
|
|
|
|
|
|
|
con.execute( |
|
|
|
@ -25,38 +23,63 @@ try:
|
|
|
|
|
) |
|
|
|
|
con.commit() |
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
|
response = requests.get(config["data"]) |
|
|
|
|
return con |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_last_seen_time(con, sub_id): |
|
|
|
|
con.execute( |
|
|
|
|
"UPDATE subscriptions SET last_seen = ? WHERE rowid = ?", (time.time(), sub_id) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_text_message(phone, message, key): |
|
|
|
|
request = {"phone": phone, "message": message, "key": key} |
|
|
|
|
resp = requests.post("https://textbelt.com/text", request) |
|
|
|
|
print(resp.json()) |
|
|
|
|
|
|
|
|
|
planes = response.json()["aircraft"] |
|
|
|
|
data = {plane["hex"]: plane for plane in planes} |
|
|
|
|
|
|
|
|
|
cur = con.execute( |
|
|
|
|
"SELECT rowid, phone, icao, description, last_seen FROM subscriptions" |
|
|
|
|
) |
|
|
|
|
for sub_id, phone, icao, description, last_seen in cur.fetchall(): |
|
|
|
|
if icao in data and data[icao]["seen"] < config["max_age"]: |
|
|
|
|
if last_seen + config["min_disappearance"] < time.time(): |
|
|
|
|
message = f"{description}\n{config['tracker']}?icao={icao}" |
|
|
|
|
def process_subscriptions(con, config, data): |
|
|
|
|
cur = con.execute( |
|
|
|
|
"SELECT rowid, phone, icao, description, last_seen FROM subscriptions" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for sub_id, phone, icao, description, last_seen in cur.fetchall(): |
|
|
|
|
if icao in data and data[icao]["seen"] < config["max_age"]: |
|
|
|
|
if last_seen + config["min_disappearance"] < time.time(): |
|
|
|
|
message = f"{description}\n{config['tracker']}?icao={icao}" |
|
|
|
|
|
|
|
|
|
request = { |
|
|
|
|
"phone": phone, |
|
|
|
|
"message": message, |
|
|
|
|
"key": config["textbelt_key"], |
|
|
|
|
} |
|
|
|
|
send_text_message(phone, message, config["textbelt_key"]) |
|
|
|
|
|
|
|
|
|
resp = requests.post("https://textbelt.com/text", request) |
|
|
|
|
print(f"{phone}: {message}") |
|
|
|
|
|
|
|
|
|
print(f"{phone}: {message}") |
|
|
|
|
print(resp.json()) |
|
|
|
|
update_last_seen_time(con, sub_id) |
|
|
|
|
|
|
|
|
|
con.execute( |
|
|
|
|
"UPDATE subscriptions SET last_seen = ? WHERE rowid = ?", |
|
|
|
|
(time.time(), sub_id), |
|
|
|
|
) |
|
|
|
|
con.commit() |
|
|
|
|
con.commit() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_current_data(config): |
|
|
|
|
response = requests.get(config["data"]) |
|
|
|
|
planes = response.json()["aircraft"] |
|
|
|
|
return {plane["hex"]: plane for plane in planes} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run(config): |
|
|
|
|
con = load_database(config) |
|
|
|
|
|
|
|
|
|
while True: |
|
|
|
|
data = get_current_data(config) |
|
|
|
|
|
|
|
|
|
process_subscriptions(con, config, data) |
|
|
|
|
|
|
|
|
|
time.sleep(config["delay"]) |
|
|
|
|
finally: |
|
|
|
|
if config["pid_file"]: |
|
|
|
|
os.unlink(config["pid_file"]) |
|
|
|
|
|
|
|
|
|
con.close() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
parser = argparse.ArgumentParser() |
|
|
|
|
parser.add_argument("config_file") |
|
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
config = load_config(args.config_file) |
|
|
|
|
run(config) |
|
|
|
|