parent
fd7488bd04
commit
808f5c1d22
|
@ -185,57 +185,147 @@ def get_launches(
|
||||||
return [summarize_launch(launch) for launch in data["results"]]
|
return [summarize_launch(launch) for launch in data["results"]]
|
||||||
|
|
||||||
|
|
||||||
def format_launch_changes(differences: StrDict) -> str:
|
def format_date(dt: datetime) -> str:
|
||||||
"""Convert deepdiff output to human-readable format."""
|
"""Human readable date."""
|
||||||
changes = []
|
return dt.strftime("%d %b %Y at %H:%M UTC")
|
||||||
# Handle value changes
|
|
||||||
if "values_changed" in differences:
|
|
||||||
for path, change in differences["values_changed"].items():
|
def format_datetime_change(field_name: str, old_val: str, new_val: str) -> str:
|
||||||
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
"""Format a datetime field change with proper error handling."""
|
||||||
old_val = change["old_value"]
|
try:
|
||||||
new_val = change["new_value"]
|
old_dt = datetime.fromisoformat(old_val.replace("Z", "+00:00"))
|
||||||
# Format specific fields nicely
|
new_dt = datetime.fromisoformat(new_val.replace("Z", "+00:00"))
|
||||||
if field == "net":
|
return (
|
||||||
try:
|
f"{field_name} changed from {format_date(old_dt)} to {format_date(new_dt)}"
|
||||||
old_dt = datetime.fromisoformat(old_val.replace("Z", "+00:00"))
|
)
|
||||||
new_dt = datetime.fromisoformat(new_val.replace("Z", "+00:00"))
|
except (ValueError, AttributeError):
|
||||||
changes.append(
|
return f"{field_name} changed from {old_val} to {new_val}"
|
||||||
"Launch time changed from "
|
|
||||||
+ old_dt.strftime("%d %b %Y at %H:%M UTC")
|
|
||||||
+ " to "
|
def format_datetime_update(field_name: str, new_val: str) -> str:
|
||||||
+ new_dt.strftime("%d %b %Y at %H:%M UTC")
|
"""Format a datetime field update (showing only the new value)."""
|
||||||
)
|
try:
|
||||||
except:
|
new_dt = datetime.fromisoformat(new_val.replace("Z", "+00:00"))
|
||||||
changes.append(f"Launch time changed from {old_val} to {new_val}")
|
return f"{field_name}: {format_date(new_dt)}"
|
||||||
elif field == "name":
|
except (ValueError, AttributeError):
|
||||||
changes.append(f"Mission name changed from '{old_val}' to '{new_val}'")
|
return f"{field_name}: {new_val}"
|
||||||
elif field == "probability":
|
|
||||||
if old_val is None:
|
|
||||||
changes.append(f"Launch probability set to {new_val}%")
|
def format_probability_change(old_val: int, new_val: int) -> str:
|
||||||
elif new_val is None:
|
"""Format probability field changes."""
|
||||||
changes.append("Launch probability removed")
|
if old_val is None:
|
||||||
else:
|
return f"Launch probability set to {new_val}%"
|
||||||
changes.append(
|
elif new_val is None:
|
||||||
f"Launch probability changed from {old_val}% to {new_val}%"
|
return "Launch probability removed"
|
||||||
)
|
else:
|
||||||
elif "status" in field:
|
return f"Launch probability changed from {old_val}% to {new_val}%"
|
||||||
|
|
||||||
|
|
||||||
|
def handle_value_changes(differences: StrDict) -> tuple[list[str], set[str]]:
|
||||||
|
"""Handle value changes in launch data."""
|
||||||
|
changes: list[str] = []
|
||||||
|
processed_paths: set[str] = set()
|
||||||
|
|
||||||
|
# Skip fields that aren't useful to users
|
||||||
|
SKIP_FIELDS = {
|
||||||
|
"agency_launch_attempt_count",
|
||||||
|
"agency_launch_attempt_count_year",
|
||||||
|
"location_launch_attempt_count",
|
||||||
|
"location_launch_attempt_count_year",
|
||||||
|
"pad_launch_attempt_count",
|
||||||
|
"pad_launch_attempt_count_year",
|
||||||
|
"orbital_launch_attempt_count",
|
||||||
|
"orbital_launch_attempt_count_year",
|
||||||
|
}
|
||||||
|
|
||||||
|
if "values_changed" not in differences:
|
||||||
|
return changes, processed_paths
|
||||||
|
|
||||||
|
for path, change in differences["values_changed"].items():
|
||||||
|
if any(path.startswith(processed) for processed in processed_paths):
|
||||||
|
continue
|
||||||
|
|
||||||
|
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
||||||
|
old_val = change["old_value"]
|
||||||
|
new_val = change["new_value"]
|
||||||
|
|
||||||
|
match field:
|
||||||
|
case "status['name']":
|
||||||
changes.append(f"Status changed from '{old_val}' to '{new_val}'")
|
changes.append(f"Status changed from '{old_val}' to '{new_val}'")
|
||||||
else:
|
processed_paths.update(
|
||||||
changes.append(
|
[
|
||||||
f"{field.replace('_', ' ').title()} changed "
|
"root['status']['id']",
|
||||||
+ f"from '{old_val}' to '{new_val}'"
|
"root['status']['name']",
|
||||||
|
"root['status']['abbrev']",
|
||||||
|
"root['status']['description']",
|
||||||
|
]
|
||||||
)
|
)
|
||||||
# Handle additions
|
|
||||||
|
case x if x.startswith("status["):
|
||||||
|
continue
|
||||||
|
|
||||||
|
case "net_precision['name']":
|
||||||
|
changes.append(
|
||||||
|
f"Launch precision changed from '{old_val}' to '{new_val}'"
|
||||||
|
)
|
||||||
|
processed_paths.update(
|
||||||
|
[
|
||||||
|
"root['net_precision']['id']",
|
||||||
|
"root['net_precision']['name']",
|
||||||
|
"root['net_precision']['abbrev']",
|
||||||
|
"root['net_precision']['description']",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
case x if x.startswith("net_precision["):
|
||||||
|
continue
|
||||||
|
|
||||||
|
case "net":
|
||||||
|
changes.append(format_datetime_change("Launch time", old_val, new_val))
|
||||||
|
|
||||||
|
case "window_start":
|
||||||
|
changes.append(
|
||||||
|
format_datetime_change("Launch window start", old_val, new_val)
|
||||||
|
)
|
||||||
|
|
||||||
|
case "window_end":
|
||||||
|
changes.append(
|
||||||
|
format_datetime_change("Launch window end", old_val, new_val)
|
||||||
|
)
|
||||||
|
|
||||||
|
case "last_updated":
|
||||||
|
changes.append(format_datetime_update("Last updated", new_val))
|
||||||
|
|
||||||
|
case "name":
|
||||||
|
changes.append(f"Mission name changed from '{old_val}' to '{new_val}'")
|
||||||
|
|
||||||
|
case "probability":
|
||||||
|
changes.append(format_probability_change(old_val, new_val))
|
||||||
|
|
||||||
|
case x if x in SKIP_FIELDS:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case _:
|
||||||
|
changes.append(f"{field} changed from '{old_val}' to '{new_val}'")
|
||||||
|
|
||||||
|
return changes, processed_paths
|
||||||
|
|
||||||
|
|
||||||
|
def format_launch_changes(differences: StrDict) -> str:
|
||||||
|
"""Convert deepdiff output to human-readable format using match/case."""
|
||||||
|
changes, processed_paths = handle_value_changes(differences)
|
||||||
|
|
||||||
|
# Handle other difference types...
|
||||||
if "dictionary_item_added" in differences:
|
if "dictionary_item_added" in differences:
|
||||||
for path in differences["dictionary_item_added"]:
|
for path in differences["dictionary_item_added"]:
|
||||||
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
||||||
changes.append(f"New field added: {field.replace('_', ' ').title()}")
|
changes.append(f"New field added: {field.replace('_', ' ').title()}")
|
||||||
# Handle removals
|
|
||||||
if "dictionary_item_removed" in differences:
|
if "dictionary_item_removed" in differences:
|
||||||
for path in differences["dictionary_item_removed"]:
|
for path in differences["dictionary_item_removed"]:
|
||||||
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
||||||
changes.append(f"Field removed: {field.replace('_', ' ').title()}")
|
changes.append(f"Field removed: {field.replace('_', ' ').title()}")
|
||||||
# Handle type changes
|
|
||||||
if "type_changes" in differences:
|
if "type_changes" in differences:
|
||||||
for path, change in differences["type_changes"].items():
|
for path, change in differences["type_changes"].items():
|
||||||
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
field = path.replace("root['", "").replace("']", "").replace("root.", "")
|
||||||
|
@ -243,6 +333,7 @@ def format_launch_changes(differences: StrDict) -> str:
|
||||||
f"{field.replace('_', ' ').title()} type changed "
|
f"{field.replace('_', ' ').title()} type changed "
|
||||||
+ f"from {change['old_type'].__name__} to {change['new_type'].__name__}"
|
+ f"from {change['old_type'].__name__} to {change['new_type'].__name__}"
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
"\n".join(f"• {change}" for change in changes)
|
"\n".join(f"• {change}" for change in changes)
|
||||||
if changes
|
if changes
|
||||||
|
|
Loading…
Reference in a new issue