Created
December 24, 2024 23:41
-
-
Save HBIDamian/4385dde50d1c7a3011da77e7feaa49e2 to your computer and use it in GitHub Desktop.
A CLI Santa Tracker, because why not π
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import argparse | |
import sys | |
import curses | |
from selenium import webdriver | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.ui import WebDriverWait | |
from selenium.webdriver.support import expected_conditions as EC | |
import time | |
import requests | |
import urllib.parse | |
# Function to convert longitude and latitude to a location | |
def longLatToLocation(longitude, latitude): | |
api_url = f"https://api.bigdatacloud.net/data/reverse-geocode-client?latitude={latitude}&longitude={longitude}&localityLanguage=en" | |
headers = { | |
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3" | |
} | |
response = requests.get(api_url, headers=headers) | |
return response.json() | |
def print_location_data(stdscr, lng_value, lat_value, ground_speed_value, use_reverse_api): | |
stdscr.clear() | |
stdscr.addstr(0, 0, f"Tracking the location of Santa's sleigh...\n") | |
stdscr.addstr(1, 0, f"Longitude: {lng_value}") | |
stdscr.addstr(2, 0, f"Latitude: {lat_value}") | |
stdscr.addstr(3, 0, f"Ground Speed: {ground_speed_value}\n") | |
if use_reverse_api: | |
location = longLatToLocation(lng_value, lat_value) | |
pluscode = location.get('plusCode', '') | |
urlencoded_pluscode = urllib.parse.quote_plus(pluscode) | |
pluscode_url = f"https://www.google.com/maps/place/{urlencoded_pluscode}" | |
def get_or_unknown(value): | |
return value if value else "Unknown" | |
stdscr.addstr(5, 0, f"Continent: {get_or_unknown(location.get('continent', 'Unknown'))}") | |
stdscr.addstr(6, 0, f"Country: {get_or_unknown(location.get('countryName', 'Unknown'))}") | |
stdscr.addstr(7, 0, f"Principal Subdivision: {get_or_unknown(location.get('principalSubdivision', 'Unknown'))}") | |
stdscr.addstr(8, 0, f"City: {get_or_unknown(location.get('city', 'Unknown'))}") | |
stdscr.addstr(9, 0, f"Google Maps: {pluscode_url}\n") | |
stdscr.addstr(10, 0, f"API Url: https://api.bigdatacloud.net/data/reverse-geocode-client?latitude={lng_value}&longitude={lat_value}&localityLanguage=en") | |
stdscr.refresh() | |
def main(stdscr): | |
# Parse command-line arguments | |
parser = argparse.ArgumentParser(description="Track Santa's sleigh using Flightradar24.", usage="%(prog)s [options]", epilog="Happy Holidays!", add_help=True, allow_abbrev=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="track.py", prefix_chars="-", conflict_handler="resolve") | |
parser.add_argument("-l", "--loop", action="store_true", help="Run the tracker in a loop, refreshing results every 10 seconds.") | |
parser.add_argument("-r", "--noReverse", action="store_false", help="Do not use the reverse-geocode-client API.") | |
parser.add_argument("--lock", action="store_true", help="Prevent quitting the program, except with CTRL+C.") | |
# Check for help argument and show help if requested | |
if '-h' in sys.argv or '--help' in sys.argv: | |
parser.print_help() | |
sys.exit(0) | |
args = parser.parse_args() | |
loop_mode = args.loop # Handle the loop mode | |
use_reverse_api = args.noReverse | |
lock_mode = args.lock # Handle the lock mode | |
# Initialize the Selenium WebDriver, headless mode | |
options = webdriver.ChromeOptions() | |
options.add_argument("--headless") | |
options.add_argument("--no-sandbox") | |
driver = webdriver.Chrome(options=options) | |
# Configure the curses screen | |
stdscr.nodelay(True) # Make getch non-blocking | |
stdscr.clear() | |
stdscr.addstr(0, 0, "Loading... Please wait.") | |
stdscr.refresh() | |
try: | |
while True: | |
if not lock_mode: | |
key = stdscr.getch() | |
if key != -1: # If any key is pressed | |
break | |
# Open the website | |
url = "https://www.flightradar24.com/R3DN053/3875f013" | |
driver.get(url) | |
# Wait for the longitude, latitude, and ground speed elements | |
wait = WebDriverWait(driver, 30) | |
lng_element = wait.until( | |
EC.presence_of_element_located((By.CSS_SELECTOR, "p[data-testid='aircraft-panel__lng']")) | |
) | |
lat_element = wait.until( | |
EC.presence_of_element_located((By.CSS_SELECTOR, "p[data-testid='aircraft-panel__lat']")) | |
) | |
ground_speed_element = wait.until( | |
EC.presence_of_element_located((By.CSS_SELECTOR, "div[data-testid='aircraft-panel__ground-speed-tooltip'] div")) | |
) | |
# If the elements are not found, quit the program with an error message | |
if not lng_element or not lat_element or not ground_speed_element: | |
raise Exception("Could not find the required elements on the page") | |
# Extract values | |
lng_value = lng_element.text | |
lat_value = lat_element.text | |
ground_speed_value = ground_speed_element.get_attribute("innerText") | |
# Print the location data | |
print_location_data(stdscr, lng_value, lat_value, ground_speed_value, use_reverse_api) | |
# Break the loop if not in loop mode | |
if not loop_mode: | |
break | |
# Wait for 10 seconds before refreshing | |
time.sleep(10) | |
except Exception as e: | |
stdscr.addstr(11, 0, f"An error occurred: {e}") | |
stdscr.refresh() | |
time.sleep(3) | |
finally: | |
# Close the driver | |
driver.quit() | |
if __name__ == "__main__": | |
curses.wrapper(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment