generated from nathanwoodburn/python-webserver-template
feat: Speed up covanent using bulk
This commit is contained in:
73
server.py
73
server.py
@@ -198,11 +198,18 @@ def namehash_api(namehash):
|
|||||||
|
|
||||||
@app.route("/api/v1/status")
|
@app.route("/api/v1/status")
|
||||||
def api_status():
|
def api_status():
|
||||||
|
# Count number of names in database
|
||||||
|
db = get_db()
|
||||||
|
cur = db.execute("SELECT COUNT(*) as count FROM names")
|
||||||
|
row = cur.fetchone()
|
||||||
|
name_count = row["count"] if row else 0
|
||||||
|
|
||||||
return jsonify(
|
return jsonify(
|
||||||
{
|
{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"service": "FireExplorer",
|
"service": "FireExplorer",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
"names_cached": name_count,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -242,6 +249,72 @@ def hip02(domain: str):
|
|||||||
@app.route("/api/v1/covenant", methods=["POST"])
|
@app.route("/api/v1/covenant", methods=["POST"])
|
||||||
def covenant_api():
|
def covenant_api():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
|
|
||||||
|
if isinstance(data, list):
|
||||||
|
covenants = data
|
||||||
|
results = []
|
||||||
|
|
||||||
|
# Collect all namehashes needed
|
||||||
|
namehashes = set()
|
||||||
|
for cov in covenants:
|
||||||
|
items = cov.get("items", [])
|
||||||
|
if items:
|
||||||
|
namehashes.add(items[0])
|
||||||
|
|
||||||
|
# Batch DB lookup
|
||||||
|
db = get_db()
|
||||||
|
known_names = {}
|
||||||
|
if namehashes:
|
||||||
|
placeholders = ",".join("?" for _ in namehashes)
|
||||||
|
cur = db.execute(
|
||||||
|
f"SELECT namehash, name FROM names WHERE namehash IN ({placeholders})",
|
||||||
|
list(namehashes),
|
||||||
|
)
|
||||||
|
for row in cur:
|
||||||
|
known_names[row["namehash"]] = row["name"]
|
||||||
|
|
||||||
|
# Identify missing namehashes
|
||||||
|
missing_hashes = [nh for nh in namehashes if nh not in known_names]
|
||||||
|
|
||||||
|
# Fetch missing from HSD
|
||||||
|
session = requests.Session()
|
||||||
|
for nh in missing_hashes:
|
||||||
|
try:
|
||||||
|
req = session.get(f"https://hsd.hns.au/api/v1/namehash/{nh}")
|
||||||
|
if req.status_code == 200:
|
||||||
|
name = req.json().get("result")
|
||||||
|
if name:
|
||||||
|
known_names[nh] = name
|
||||||
|
# Update DB
|
||||||
|
db.execute(
|
||||||
|
"INSERT OR REPLACE INTO names (namehash, name) VALUES (?, ?)",
|
||||||
|
(nh, name),
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching namehash {nh}: {e}")
|
||||||
|
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
for cov in covenants:
|
||||||
|
action = cov.get("action")
|
||||||
|
items = cov.get("items", [])
|
||||||
|
|
||||||
|
if not action:
|
||||||
|
results.append({"covenant": cov, "display": "Unknown"})
|
||||||
|
continue
|
||||||
|
|
||||||
|
display = f"{action}"
|
||||||
|
if items:
|
||||||
|
nh = items[0]
|
||||||
|
if nh in known_names:
|
||||||
|
name = known_names[nh]
|
||||||
|
display += f' <a href="/name/{name}">{name}</a>'
|
||||||
|
|
||||||
|
results.append({"covenant": cov, "display": display})
|
||||||
|
|
||||||
|
return jsonify(results)
|
||||||
|
|
||||||
# Get the covenant data
|
# Get the covenant data
|
||||||
action = data.get("action")
|
action = data.get("action")
|
||||||
items = data.get("items", [])
|
items = data.get("items", [])
|
||||||
|
|||||||
@@ -944,7 +944,8 @@
|
|||||||
// Update covenant information from API
|
// Update covenant information from API
|
||||||
async function updateCovenants() {
|
async function updateCovenants() {
|
||||||
const elements = document.querySelectorAll('[data-covenant-action]');
|
const elements = document.querySelectorAll('[data-covenant-action]');
|
||||||
const cache = {};
|
const covenantsToFetch = [];
|
||||||
|
const elementMap = new Map(); // Map JSON string -> Array of elements
|
||||||
|
|
||||||
for (const el of elements) {
|
for (const el of elements) {
|
||||||
const action = el.dataset.covenantAction;
|
const action = el.dataset.covenantAction;
|
||||||
@@ -965,39 +966,46 @@
|
|||||||
|
|
||||||
if (!covenantData) continue;
|
if (!covenantData) continue;
|
||||||
|
|
||||||
// Create a cache key based on the full covenant data
|
const key = JSON.stringify(covenantData);
|
||||||
const cacheKey = JSON.stringify(covenantData);
|
if (!elementMap.has(key)) {
|
||||||
|
elementMap.set(key, []);
|
||||||
|
covenantsToFetch.push(covenantData);
|
||||||
|
}
|
||||||
|
elementMap.get(key).push(el);
|
||||||
|
}
|
||||||
|
|
||||||
let display = action;
|
if (covenantsToFetch.length === 0) return;
|
||||||
if (cache[cacheKey]) {
|
|
||||||
display = cache[cacheKey];
|
try {
|
||||||
} else {
|
const res = await fetch(`/api/v1/covenant`, {
|
||||||
try {
|
method: 'POST',
|
||||||
const res = await fetch(`/api/v1/covenant`, {
|
headers: {
|
||||||
method: 'POST',
|
'Content-Type': 'application/json'
|
||||||
headers: {
|
},
|
||||||
'Content-Type': 'application/json'
|
body: JSON.stringify(covenantsToFetch)
|
||||||
},
|
});
|
||||||
body: JSON.stringify(covenantData)
|
|
||||||
});
|
if (res.ok) {
|
||||||
|
const results = await res.json();
|
||||||
if (res.ok) {
|
|
||||||
const data = await res.json();
|
for (const result of results) {
|
||||||
display = data.display || action;
|
const key = JSON.stringify(result.covenant);
|
||||||
cache[cacheKey] = display;
|
const els = elementMap.get(key);
|
||||||
|
|
||||||
|
if (els) {
|
||||||
|
for (const el of els) {
|
||||||
|
if (el.classList.contains('tx-covenant')) {
|
||||||
|
el.innerHTML = `Covenant: ${result.display}`;
|
||||||
|
} else {
|
||||||
|
el.innerHTML = result.display;
|
||||||
|
}
|
||||||
|
el.dataset.covenantUpdated = "true";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to fetch covenant info:', e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
// Check if it's the .tx-covenant div which includes "Covenant: " text
|
console.error('Failed to fetch covenant info:', e);
|
||||||
if (el.classList.contains('tx-covenant')) {
|
|
||||||
el.innerHTML = `Covenant: ${display}`;
|
|
||||||
} else {
|
|
||||||
el.textContent = display;
|
|
||||||
}
|
|
||||||
el.dataset.covenantUpdated = "true";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user