quits without any error right after starting with no output on either terminal or browser console and nothing on the html page.
179 lines
7.3 KiB
Python
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)
|