import json
import pandas as pd
from nsepython import *
import html
import html
import pandas as pd
def build_indices_html():
"""
Generate HTML:
- main table
- dates table
- tables for all categories
- charts ONLY for key == "INDICES ELIGIBLE IN DERIVATIVES"
- flexible chart layout (no grid, auto-fit)
"""
p = indices() # your existing function
data_df = p.get("data", pd.DataFrame())
dates_df = p.get("dates", pd.DataFrame())
records = data_df.to_dict(orient="records") if not data_df.empty else []
# Columns to hide in category tables
hidden_cols = {
"key","chartTodayPath","chart30dPath","chart30Path","chart365dPath",
"date365dAgo","date30dAgo","previousDay","oneWeekAgo","oneMonthAgoVal",
"oneWeekAgoVal","oneYearAgoVal","index","indicativeClose"
}
# ----------- BASIC TABLE BUILDER -----------
def build_table_from_records(recs, cols=None):
if not recs:
return "
No data available.
"
if cols is None:
cols = []
for r in recs:
for k in r.keys():
if k not in cols:
cols.append(k)
header = "".join(f"{html.escape(str(c))} | " for c in cols)
body_rows = []
for r in recs:
tds = []
for c in cols:
v = r.get(c, "")
if isinstance(v, (list, dict)):
v = str(v)
tds.append(f"{html.escape('' if v is None else str(v))} | ")
body_rows.append("" + "".join(tds) + "
")
return f"""
{header}
{''.join(body_rows)}
"""
# ----------- FLEXIBLE CHART BLOCK -----------
def build_chart_grid_for_record(r):
"""
Flexible chart layout: auto-fit, no fixed grid.
ONLY for INDICES ELIGIBLE IN DERIVATIVES category.
"""
def iframe_if_exists(src, label):
if src and isinstance(src, str) and src.strip():
return f"""
"""
return ""
today_src = r.get("chartTodayPath") or r.get("chartToday") or ""
month30_src = r.get("chart30dPath") or r.get("chart30Path") or ""
year365_src = r.get("chart365dPath") or r.get("chart365") or ""
block = (
iframe_if_exists(today_src, "Today Chart") +
iframe_if_exists(month30_src, "30d Chart") +
iframe_if_exists(year365_src, "365d Chart")
)
if not block.strip():
return ""
title = r.get("index") or r.get("indexSymbol") or r.get("symbol") or ""
return f"""
{html.escape(str(title))}
{block}
"""
# ----------- MAIN TABLE -----------
main_table_html = build_table_from_records(records)
# ----------- DATES TABLE -----------
dates_table_html = ""
if not dates_df.empty:
dates_records = dates_df.to_dict(orient="records")
dates_table_html = build_table_from_records(dates_records)
# ----------- GROUP BY KEY ----------
from collections import defaultdict
groups = defaultdict(list)
for r in records:
groups[r.get("key") or "UNCLASSIFIED"].append(r)
per_key_sections = []
# ----------- PER CATEGORY SECTIONS ----------
for key_name, recs in groups.items():
# Determine visible columns
first = recs[0]
cols = [c for c in first.keys() if c not in hidden_cols]
# Preferred order
preferred = ["indexSymbol", "index", "symbol", "name"]
ordered = []
for pkey in preferred:
if pkey in cols:
ordered.append(pkey)
for c in cols:
if c not in ordered:
ordered.append(c)
table_html = build_table_from_records(recs, ordered)
# CHARTS ONLY FOR INDICES ELIGIBLE IN DERIVATIVES
if str(key_name).strip().upper() == "INDICES ELIGIBLE IN DERIVATIVES":
charts_html = "\n".join(build_chart_grid_for_record(r) for r in recs)
else:
charts_html = "" # no charts for other categories
per_key_sections.append(f"""
Category: {html.escape(str(key_name))} (Total: {len(recs)})
{table_html}
{charts_html}
""")
# ----------- CSS -----------
css = """
"""
# ----------- FINAL HTML ASSEMBLY -----------
html_parts = [
"",
"NSE Indices",
css,
"",
"NSE Indices — Full Static Render
",
f"Generated: {html.escape(pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S'))}
",
"Main Indices Table
",
"", main_table_html, "
",
"Dates / Meta
" if dates_table_html else "",
"" if dates_table_html else "",
dates_table_html,
"
" if dates_table_html else "",
"Categories
",
*per_key_sections,
""
]
return "\n".join(str(x) for x in html_parts)