def process_alert(config, plane):
    pf.log(f"Building Discord alert for {plane['icao']}")

    dbinfo = pf.get_plane_info(plane['icao'])

    fa_link = pf.flightaware_link(plane['icao'], plane['tail_num'])

    title = f"Plane Alert - {plane['plane_desc']}"
    color = 0xf2e718
    squawk = plane.get('squawk', "")
    if pf.is_emergency(squawk):
        title = f"Air Emergency! {plane['tail_num']} squawked {squawk}"
        color = 0xff0000

    description = f""
    if plane.get('owner', "") != "":
        description = f"Operated by **{plane.get('owner')}**"

    location = get_readable_location(plane)
    if location == "":
        # No location info, just embed ADSBX link
        description += f"\nTrack on [ADSB Exchange]({plane['adsbx_url']})"
    else:
        description += f"\nSeen near [**{location}**]({plane['adsbx_url']})"

    webhook, embed = pf.discord.build(config["DISCORD_FEEDER_NAME"],
                                      config["PA_DISCORD_WEBHOOKS"],
                                      title,
                                      description,
                                      color=color)
    pf.attach_media(config, "PA", dbinfo, webhook, embed)

    # Attach data fields
    pf.discord.field(embed, "ICAO", plane['icao'])
    pf.discord.field(embed, "Tail Number", f"[{plane['tail_num']}]({fa_link})")

    if plane.get('callsign', "") != "":
        pf.discord.field(embed, "Callsign", plane['callsign'])

    if plane.get('time', "") != "":
        pf.discord.field(embed, "First Seen",
                         f"{plane['time']} {pf.get_timezone_str()}")

    if dbinfo.get('category', "") != "":
        pf.discord.field(embed, "Category", dbinfo['category'])

    if dbinfo.get('tag1', "") != "":
        pf.discord.field(embed, "Tag", dbinfo['tag1'])

    if dbinfo.get('tag2', "") != "":
        pf.discord.field(embed, "Tag", dbinfo['tag2'])

    if dbinfo.get('tag3', "") != "":
        pf.discord.field(embed, "Tag", dbinfo['tag3'])

    if dbinfo.get('link', "") != "":
        pf.discord.field(embed, "Link", f"[Learn More]({dbinfo['link']})")

    # Send the message
    pf.send(webhook, config)
def get_readable_location(plane):
    loc = geolocator.reverse("{}, {}".format(plane['lat'], plane['long']),
                             exactly_one=True,
                             language='en')
    if loc is None:
        pf.log("[error] No geolocation information return for '{}, {}'".format(
            plane['lat'], plane['long']))
        return ""

    adr = loc.raw.get('address', {})

    print("Location data:")
    print(adr)

    village = adr.get('village', "")
    municipality = adr.get('municipality', "")
    city = adr.get('city', "")
    town = adr.get('town', "")
    country = adr.get('country', "")
    country_code = adr.get('country_code', "").upper()

    place = city or town or village or municipality

    if country_code == "US":
        state = pf.get_us_state_abbrev(adr.get('state', ""))

        return f"{place}, {state}, {country_code}"
    else:
        return f"{place}, {country}"
def main():
    pf.init_log("plane-alert/send-discord-alert")

    # Load configuration
    config = pf.load_config()

    if len(sys.argv) != 2:
        print(
            "No input record passed\n\tUsage: ./send-discord-alert.py <csvline>"
        )
        sys.exit(1)

    # CSV format is:
    #      ICAO,TailNr,Owner,PlaneDescription,date,time,lat,lon,callsign,adsbx_url,squawk
    row = sys.argv[1].split(',')
    alert = {
        "icao": row[0].strip(),
        "tail_num": row[1].strip(),
        "owner": row[2].strip(),
        "plane_desc": row[3],
        "date": row[4],
        "time": row[5],
        "lat": row[6],
        "long": row[7],
        "callsign": row[8].strip(),
        "adsbx_url": row[9],
        "squawk": row[10] if len(row) > 10 else "",
    }

    # Process file and send alerts
    process_alert(config, alert)

    pf.log(f"Done sending Discord alert for {alert['icao']}")
Esempio n. 4
0
def main():
    pf.init_log("planefence/send-discord-alert")

    # Load configuration
    config = pf.load_config()

    if len(sys.argv) < 2:
        print("No input file passed\n\tUsage: ./send-discord-alert.py <csvline> <airline?>")
        sys.exit(1)

    record = sys.argv[1].split(',')

    alert = {
        "icao": record[0],
        "tail_num": record[1].lstrip("@"),
        "first_seen": record[2],
        "last_seen": record[3],
        "alt": int(record[4]) if record[4].isdigit() else 0,
        "min_dist": record[5],
        "adsbx_url": record[6],
        "airline": sys.argv[2] if len(sys.argv) == 3 else ""
    }

    process_alert(config, alert)

    pf.log(f"Done sending alerts to Discord")
Esempio n. 5
0
def process_alert(config, plane):
    pf.log(f"Building discord message for {plane['icao']}")

    # Gather up some info for the message
    name = plane['tail_num']
    if plane["airline"] != "":
        name = plane['airline']

    fa_link = pf.flightaware_link(plane['icao'], plane['tail_num'])

    webhook, embed = pf.discord.build(
        config["DISCORD_FEEDER_NAME"],
        config["PF_DISCORD_WEBHOOKS"],
        f"{name} is overhead at {pf.altitude_str(config, plane['alt'])}",
        f"[Track on ADS-B Exchange]({plane['adsbx_url']})")

    pf.attach_media(config, "PF", plane, webhook, embed)

    # Attach data fields
    pf.discord.field(embed, "ICAO", plane['icao'])
    pf.discord.field(embed, "Tail Number", f"[{plane['tail_num']}]({fa_link})")
    pf.discord.field(embed, "Distance", f"{plane['min_dist']}{pf.distance_unit(config)}")

    time_seen = plane['first_seen'].split(" ")[1]
    pf.discord.field(embed, "First Seen", f"{time_seen} {pf.get_timezone_str()}")

    # Send the message
    pf.send(webhook, config)
Esempio n. 6
0
def load_alerts(alerts_file):
    alerts = []
    with open(alerts_file) as csvfile:
        reader = csv.reader(csvfile)
        for row in reader:
            # Format:
            # ICAO,Registration,FirstSeen,LastSeen,Alt,MinDist,adsbx_url,,,,,,tweet_url
            #         Fields after adsbx_url are optional
            #   If FlightNum has an @ prefixing the tail number it was tweeted
            alert = {
                "icao": row[0].strip(),
                "tail_num": row[1].strip(),
                "first_seen": row[2],
                "last_seen": row[3],
                "alt": row[4],
                "min_dist": row[5],
                "adsbx_url": row[6],
            }
            alerts.append(alert)

    pf.log(f"Loaded {len(alerts)} Planefence alerts")
    return alerts