checkpoint rpc county fixed

This commit is contained in:
2025-12-07 12:17:53 +00:00
parent f525151c5e
commit facc2a486e
6 changed files with 695 additions and 59 deletions

163
test.py Normal file
View File

@@ -0,0 +1,163 @@
import json
import os
def decode_gwt_rpc(payload):
"""
Decodes a GWT-RPC payload to extract outage data for Counties.
"""
# 1. Clean the payload
# GWT responses often start with //OK. We strip that.
if payload.startswith("//OK"):
payload = payload[4:]
# 2. Parse the FULL payload as JSON
# The GWT payload is structurally a JSON array: [stream_data..., [string_table], flags...]
try:
full_data = json.loads(payload)
except json.JSONDecodeError as e:
print(f"Error parsing payload JSON: {e}")
return None
# 3. Separate Stream and String Table
# The String Table is a list of strings located near the end of the main array.
# The "Stream" is everything before that string table.
string_table = None
stream_raw = []
# Iterate through the parsed array to find the string table (which is a list)
for item in full_data:
if isinstance(item, list):
string_table = item
# Once we find the table, we assume the rest are flags and stop adding to stream
break
else:
stream_raw.append(item)
if not string_table:
print("Error: String table not found in payload.")
return None
# 4. Normalize the Stream
# The decoder logic relies on integers (1-based indices).
# The raw stream might contain floats or strings that we need to cast or filter.
stream = []
for token in stream_raw:
if isinstance(token, int):
stream.append(token)
elif isinstance(token, float):
stream.append(int(token))
elif isinstance(token, str):
# Sometimes numeric values are sent as strings in the stream
try:
stream.append(int(float(token)))
except ValueError:
# If it's a non-numeric string token (like a cache ID), ignore it
pass
# 5. Decode Logic
try:
# Define the signatures we are looking for in the String Table
REGION_SIG = "cc.nisc.oms.clientandserver.v2.pojo.Region/3192921568"
INTEGER_SIG = "java.lang.Integer/3438268394"
CATEGORY_KEY = "County"
# Helper to find 1-based index
def get_index(val):
try: return string_table.index(val) + 1
except ValueError: return 0
region_type_id = get_index(REGION_SIG)
integer_type_id = get_index(INTEGER_SIG)
county_type_id = get_index(CATEGORY_KEY)
if region_type_id == 0:
print("Error: Region type signature not found in string table.")
# Debug: Print first few strings to verify if signatures changed
# print("Available strings:", string_table[:10])
return None
results = []
i = 0
stream_len = len(stream)
# Iterate through the stream looking for Region objects
while i < stream_len:
if stream[i] == region_type_id:
try:
# We found a Region. The next few integers define its properties.
# Pointer 'p' is relative to current index 'i'
p = i + 1
# --- Field 1: Total Served ---
# Logic: Value is valid if followed by Integer Type ID
served = 0
val1 = stream[p]
p += 1
if p < stream_len and stream[p] == integer_type_id:
served = val1
p += 1 # Skip type ID
# --- Field 2: Number Out ---
out = 0
val2 = stream[p]
p += 1
if p < stream_len and stream[p] == integer_type_id:
out = val2
p += 1 # Skip type ID
# --- Field 3: Name Index ---
name_idx = stream[p]
p += 1
# --- Field 4: Category Index ---
cat_idx = stream[p]
# Check if this is a County
if cat_idx == county_type_id:
name = "Unknown"
if 0 < name_idx <= len(string_table):
name = string_table[name_idx - 1]
percent = 0.0
if served > 0:
percent = (out / served) * 100
results.append({
"county": name,
"served": served,
"out": out,
"percent": percent
})
except IndexError:
pass
i += 1
return results
except Exception as e:
print(f"Error during stream traversal: {e}")
return None
if __name__ == "__main__":
filename = "outage_data.txt"
if os.path.exists(filename):
with open(filename, "r", encoding="utf-8") as f:
raw_content = f.read().strip()
data = decode_gwt_rpc(raw_content)
if data:
# Sort A-Z
data.sort(key=lambda x: x['county'])
print(f"{'County':<20} | {'Served':>8} | {'Out':>8} | {'Percent':>8}")
print("-" * 55)
for row in data:
print(f"{row['county']:<20} | {row['served']:>8} | {row['out']:>8} | {row['percent']:>7.2f}%")
else:
print("No data found.")
else:
print(f"File '{filename}' not found. Please create it and paste the payload.")