import requests import json import os from datetime import datetime, timedelta import re import pytz def parse_geonet_title(title): match = re.search(r'\d+\skm\s(north|south|west|east|north-east|north-west|south-east|south-west|of)?\s*(.*)', title) if match: location = match.group(2).strip() location = location.replace('region', '').strip() return location if location else "Unknown Location" match = re.match(r'M\s\d+\.?\d*,\s*(.*)', title) if match: location = match.group(1).strip() location = location.replace('region', '').strip() return location if location else "Unknown Location" return title def get_earthquakes(min_mmi=1, limit=20, from_today_only=True): url = "https://api.geonet.org.nz/quakes/services/quake/" try: response = requests.get(url) response.raise_for_status() data = response.json() all_quakes = [] utc_timezone = pytz.utc nzt_timezone = pytz.timezone('Pacific/Auckland') current_nzt_date = datetime.now(nzt_timezone).date() for feature in data.get('features', []): props = feature.get('properties', {}) mmi = props.get('mmi') time_utc_ms = props.get('time') status = props.get('status', 'latest') quake_id = feature.get('id') if time_utc_ms is None: continue dt_object_utc_aware = utc_timezone.localize(datetime.fromtimestamp(time_utc_ms / 1000)) dt_object_nzt = dt_object_utc_aware.astimezone(nzt_timezone) if from_today_only: if dt_object_nzt.date() != current_nzt_date: continue if status != 'deleted': if mmi is None or mmi < min_mmi: continue title = props.get('title', 'Unknown Event') time_str = dt_object_nzt.strftime("%d - %b - %Y %I:%M %p %z") location = parse_geonet_title(title) all_quakes.append({ 'mmi': mmi, 'magnitude': props.get('magnitude'), 'depth': props.get('depth'), 'location': location, 'time': time_str, 'id': quake_id, 'utc_timestamp': time_utc_ms, 'status': status }) all_quakes.sort(key=lambda x: x['utc_timestamp'], reverse=True) return all_quakes[:limit] except requests.exceptions.RequestException as e: print(f"Error fetching data from Geonet API: {e}") return [] def generate_html(quakes, output_file="geonet_earthquakes.html", css_file="style.css"): html_content = f""" Latest Earthquakes NZ
""" if not quakes: html_content += """
--
""" else: for quake in quakes: deleted_class = " deleted-item" if quake['status'] == 'deleted' else "" mmi_box_classes = "" mmi_box_content = "" if quake['status'] == 'deleted': mmi_box_classes = "deleted-marker" mmi_box_content = "X" else: mmi_class_value = min(quake['mmi'] if quake['mmi'] is not None else 0, 11) if mmi_class_value >= 1: mmi_box_classes = "mmi-1" else: mmi_box_classes = f"mmi-{mmi_class_value}" mmi_box_content = str(quake['mmi']) if quake['mmi'] is not None else '--' magnitude_display = f"M{quake['magnitude']:.1f}" if quake['magnitude'] is not None else '--' depth_display = f"{quake['depth']}km" if quake['depth'] is not None else '--km' location_display = quake['location'] if quake['location'] else 'Unknown Location' time_display = quake['time'] if quake['time'] else 'Unknown Time' status_display = quake['status'].capitalize() if quake['status'] else '--' id_display = quake['id'] if quake['id'] else '--' html_content += f"""
{mmi_box_content}
Status: {status_display}
Magnitude: {magnitude_display} Depth: {depth_display}
Where: {location_display}
When: {time_display}
Quake ID: {id_display}
""" html_content += """
""" with open(output_file, "w", encoding="utf-8") as f: f.write(html_content) print(f"Generated {output_file} with {len(quakes)} earthquakes.") if __name__ == "__main__": output_html_file = "geonet_earthquakes_list.html" css_file_name = "style.css" min_mmi_threshold = 1 earthquake_limit = 20 filter_today_only = False update_interval_minutes = 1 print(f"Starting Geonet Earthquake Display Generator. HTML file: '{output_html_file}'") print(f"Updating every {update_interval_minutes} minute(s).") print(f"Filtering for MMI {min_mmi_threshold}+, max {earthquake_limit} from today (NZT), including deleted events from today.") latest_quakes = get_earthquakes( min_mmi=min_mmi_threshold, limmit=earthquake_limit, from_today_only=filter_today_only ) generate_html(latest_quakes, output_html_file, css_file_name) # continuous updater loop untl ctrl+C import time while True: try: latest_quakes = get_earthquakes( min_mmi=min_mmi_threshold, limit=earthquake_limit, from_today_only=filter_today_only ) generate_html(latest_quakes, output_html_file, css_file_name) except Exception as e: print(f"An error occurred during update: {e}") time.sleep(update_interval_minutes * 60)