Files
OBS_Earthquakes/generate_earthquakes.py
bryce cb5dbcd487 attempt to get it running ...
quits without any error right after starting with no output on either
terminal or browser console and nothing on the html page.
2025-07-22 20:09:44 +12:00

179 lines
7.3 KiB
Python

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"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Latest Earthquakes NZ</title>
<link rel="stylesheet" href="{css_file}">
</head>
<body>
<div class="earthquake-list">
"""
if not quakes:
html_content += """
<div class="earthquake-item">
<div class="mmi-box" style="background-color: #444; color: white;">--</div>
"""
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"""
<div class="earthquake-item{deleted_class}">
<div class="mmi-box {mmi_box_clases}">{mmi_box_content}</div>
<div class="detail-label status-line">Status: <span style="font-weight: normal; color: white;">{status_display}</span></div>
<div class="detail-label mag-depth">
<span>Magnitude: <span style="font-weight: normal; color: white;">{magnitude_display}</span></span>
<span>Depth: <span style="font-weight: normal; color: white;">{depth_display}</span></span>
</div>
<div class="detail-label location">Where: <span style="font-weight: normal; color: white;">{location_display}</span></div>
<div class="detail-label time">When: <span style="font-weight: normal; color: white;">{time_display}</span></div>
<div class="detail-label id-line">Quake ID: <span style="font-weight: normal; color: white;">{id_display}</span></div>
"""
html_content += """
</div>
</body>
</html>
"""
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)