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)