eshan6704 commited on
Commit
44f388b
·
verified ·
1 Parent(s): 6641aca

Update indices_html.py

Browse files
Files changed (1) hide show
  1. indices_html.py +80 -97
indices_html.py CHANGED
@@ -1,84 +1,79 @@
1
- import json
2
  import pandas as pd
3
  from nsepython import *
4
  import html
5
  from datetime import datetime as dt
6
  from collections import defaultdict
7
 
8
- # persist helpers (already exist in your project)
9
  from persist import exists, load, save
10
 
11
 
12
  def build_indices_html():
13
  """
14
- Generate HTML:
15
- - main table
16
- - dates table
17
- - tables for all categories
18
- - charts ONLY for key == "INDICES ELIGIBLE IN DERIVATIVES"
19
- - flexible chart layout (no grid, auto-fit)
20
- - DAILY CACHE ENABLED
21
  """
22
 
23
- # ================= CACHE =================
24
- today = dt.now().strftime("%Y-%m-%d")
25
- cache_key = "indices_html"
26
 
27
- if exists(cache_key):
28
- cached = load(cache_key)
29
- if isinstance(cached, dict) and cached.get("date") == today:
30
- return cached.get("html")
31
 
32
  # ================= FETCH DATA =================
33
- p = indices() # your existing function
34
  data_df = p.get("data", pd.DataFrame())
35
  dates_df = p.get("dates", pd.DataFrame())
36
 
37
  records = data_df.to_dict(orient="records") if not data_df.empty else []
38
 
39
- # Columns to hide in category tables
40
  hidden_cols = {
41
- "key","chartTodayPath","chart30dPath","chart30Path","chart365dPath",
42
- "date365dAgo","date30dAgo","previousDay","oneWeekAgo","oneMonthAgoVal",
43
- "oneWeekAgoVal","oneYearAgoVal","index","indicativeClose"
 
44
  }
45
 
46
- # ----------- BASIC TABLE BUILDER -----------
47
- def build_table_from_records(recs, cols=None):
48
  if not recs:
49
  return "<p>No data available.</p>"
50
 
51
  if cols is None:
52
  cols = []
53
  for r in recs:
54
- for k in r.keys():
55
  if k not in cols:
56
  cols.append(k)
57
 
58
  header = "".join(f"<th>{html.escape(str(c))}</th>" for c in cols)
59
 
60
- body_rows = []
61
  for r in recs:
62
  tds = []
63
  for c in cols:
64
  v = r.get(c, "")
65
- if isinstance(v, (list, dict)):
66
  v = str(v)
67
- tds.append(f"<td>{html.escape('' if v is None else str(v))}</td>")
68
- body_rows.append("<tr>" + "".join(tds) + "</tr>")
69
 
70
  return f"""
71
  <table>
72
  <thead><tr>{header}</tr></thead>
73
- <tbody>{''.join(body_rows)}</tbody>
74
  </table>
75
  """
76
 
77
- # ----------- FLEXIBLE CHART BLOCK -----------
78
- def build_chart_grid_for_record(r):
79
-
80
- def iframe_if_exists(src, label):
81
- if src and isinstance(src, str) and src.strip():
82
  return f"""
83
  <div class="chart-flex-item">
84
  <iframe src="{html.escape(src)}" loading="lazy"
@@ -87,101 +82,83 @@ def build_indices_html():
87
  """
88
  return ""
89
 
90
- today_src = r.get("chartTodayPath") or r.get("chartToday") or ""
91
- month30_src = r.get("chart30dPath") or r.get("chart30Path") or ""
92
- year365_src = r.get("chart365dPath") or r.get("chart365") or ""
93
-
94
- block = (
95
- iframe_if_exists(today_src, "Today Chart") +
96
- iframe_if_exists(month30_src, "30d Chart") +
97
- iframe_if_exists(year365_src, "365d Chart")
98
  )
99
 
100
- if not block.strip():
101
  return ""
102
 
103
- title = r.get("index") or r.get("indexSymbol") or r.get("symbol") or ""
104
 
105
  return f"""
106
  <div class="chart-flex-block">
107
- <div class="chart-title"><strong>{html.escape(str(title))}</strong></div>
108
- <div class="chart-flex-container">
109
- {block}
110
- </div>
111
  </div>
112
  """
113
 
114
- # ----------- MAIN TABLE -----------
115
- main_table_html = build_table_from_records(records)
116
 
117
- # ----------- DATES TABLE -----------
118
  dates_table_html = ""
119
  if not dates_df.empty:
120
- dates_table_html = build_table_from_records(
121
  dates_df.to_dict(orient="records")
122
  )
123
 
124
- # ----------- GROUP BY KEY ----------
125
  groups = defaultdict(list)
126
  for r in records:
127
  groups[r.get("key") or "UNCLASSIFIED"].append(r)
128
 
129
- per_key_sections = []
130
 
131
- # ----------- PER CATEGORY SECTIONS ----------
132
  for key_name, recs in groups.items():
133
-
134
  first = recs[0]
135
- cols = [c for c in first.keys() if c not in hidden_cols]
136
 
137
  preferred = ["indexSymbol", "index", "symbol", "name"]
138
- ordered = [c for c in preferred if c in cols] + [c for c in cols if c not in preferred]
 
 
 
139
 
140
- table_html = build_table_from_records(recs, ordered)
141
 
142
- # Charts only for derivative-eligible indices
143
  if str(key_name).strip().upper() == "INDICES ELIGIBLE IN DERIVATIVES":
144
- charts_html = "\n".join(build_chart_grid_for_record(r) for r in recs)
145
- else:
146
- charts_html = ""
147
 
148
- per_key_sections.append(f"""
149
  <section class="key-section">
150
- <h3>Category: {html.escape(str(key_name))} (Total: {len(recs)})</h3>
151
- <div class="key-table">{table_html}</div>
152
  {charts_html}
153
  </section>
154
  """)
155
 
156
- # ----------- CSS -----------
157
  css = """
158
  <style>
159
  body { font-family: Arial; padding: 16px; background: #fff; color: #111; }
160
- table { border-collapse: collapse; width: 100%; margin-bottom: 14px; }
161
  th, td { border: 1px solid #ccc; padding: 6px 8px; font-size: 13px; }
162
- th { background: #007bff; color: white; position: sticky; top: 0; }
163
 
164
- .scroll { max-height: 420px; overflow: auto; padding: 6px; background: #fafafa;
165
- margin-bottom: 16px; border: 1px solid #ddd; }
166
 
167
  .key-section {
168
- border: 1px solid #e6eef6;
169
- background: #fbfeff;
170
  border-radius: 6px;
171
  padding: 10px;
172
  margin-bottom: 30px;
 
173
  }
174
 
175
- .chart-flex-block {
176
- border: 1px solid #ddd;
177
- background: #fff;
178
- padding: 8px;
179
- border-radius: 6px;
180
- margin-bottom: 14px;
181
- }
182
-
183
- .chart-title { margin-bottom: 6px; font-size: 14px; }
184
-
185
  .chart-flex-container {
186
  display: flex;
187
  flex-wrap: wrap;
@@ -201,32 +178,38 @@ def build_indices_html():
201
  height: 100%;
202
  border: 0;
203
  }
 
 
 
 
 
204
  </style>
205
  """
206
 
207
- # ----------- FINAL HTML -----------
208
  html_out = "\n".join([
209
  "<!DOCTYPE html>",
210
- "<html><head><meta charset='utf-8'><title>NSE Indices</title>",
 
 
 
211
  css,
212
- "</head><body>",
213
- "<h1>NSE Indices — Full Static Render</h1>",
214
- f"<div class='meta'>Generated: {html.escape(dt.now().strftime('%Y-%m-%d %H:%M:%S'))}</div>",
215
- "<h2>Main Indices Table</h2>",
 
216
  "<div class='scroll'>", main_table_html, "</div>",
217
- "<h2>Dates / Meta</h2>" if dates_table_html else "",
218
  "<div class='scroll'>" if dates_table_html else "",
219
  dates_table_html,
220
  "</div>" if dates_table_html else "",
221
  "<h2>Categories</h2>",
222
- *per_key_sections,
223
  "</body></html>"
224
  ])
225
 
226
- # ================= SAVE CACHE =================
227
- save(cache_key, {
228
- "date": today,
229
- "html": html_out
230
- })
231
 
232
- return html_out
 
 
1
  import pandas as pd
2
  from nsepython import *
3
  import html
4
  from datetime import datetime as dt
5
  from collections import defaultdict
6
 
7
+ # persist helpers (HF only)
8
  from persist import exists, load, save
9
 
10
 
11
  def build_indices_html():
12
  """
13
+ Generates full static HTML for NSE Indices
14
+ - Tables for all indices
15
+ - Category-wise tables
16
+ - Charts ONLY for 'INDICES ELIGIBLE IN DERIVATIVES'
17
+ - DAILY cache via persist.py (HTML only)
 
 
18
  """
19
 
20
+ # ================= CACHE (TTL handled by persist) =================
21
+ cache_name = "DAILY_INDICES_HTML"
 
22
 
23
+ if exists(cache_name, "html"):
24
+ cached_html = load(cache_name, "html")
25
+ if isinstance(cached_html, str):
26
+ return cached_html
27
 
28
  # ================= FETCH DATA =================
29
+ p = indices()
30
  data_df = p.get("data", pd.DataFrame())
31
  dates_df = p.get("dates", pd.DataFrame())
32
 
33
  records = data_df.to_dict(orient="records") if not data_df.empty else []
34
 
 
35
  hidden_cols = {
36
+ "key", "chartTodayPath", "chart30dPath", "chart30Path", "chart365dPath",
37
+ "date365dAgo", "date30dAgo", "previousDay", "oneWeekAgo",
38
+ "oneMonthAgoVal", "oneWeekAgoVal", "oneYearAgoVal",
39
+ "index", "indicativeClose"
40
  }
41
 
42
+ # ================= TABLE BUILDER =================
43
+ def build_table(recs, cols=None):
44
  if not recs:
45
  return "<p>No data available.</p>"
46
 
47
  if cols is None:
48
  cols = []
49
  for r in recs:
50
+ for k in r:
51
  if k not in cols:
52
  cols.append(k)
53
 
54
  header = "".join(f"<th>{html.escape(str(c))}</th>" for c in cols)
55
 
56
+ body = []
57
  for r in recs:
58
  tds = []
59
  for c in cols:
60
  v = r.get(c, "")
61
+ if isinstance(v, (dict, list)):
62
  v = str(v)
63
+ tds.append(f"<td>{html.escape(str(v) if v is not None else '')}</td>")
64
+ body.append("<tr>" + "".join(tds) + "</tr>")
65
 
66
  return f"""
67
  <table>
68
  <thead><tr>{header}</tr></thead>
69
+ <tbody>{''.join(body)}</tbody>
70
  </table>
71
  """
72
 
73
+ # ================= CHART BUILDER =================
74
+ def build_chart_block(r):
75
+ def iframe(src, label):
76
+ if src and isinstance(src, str):
 
77
  return f"""
78
  <div class="chart-flex-item">
79
  <iframe src="{html.escape(src)}" loading="lazy"
 
82
  """
83
  return ""
84
 
85
+ charts = (
86
+ iframe(r.get("chartTodayPath"), "Today") +
87
+ iframe(r.get("chart30dPath"), "30 Days") +
88
+ iframe(r.get("chart365dPath"), "1 Year")
 
 
 
 
89
  )
90
 
91
+ if not charts.strip():
92
  return ""
93
 
94
+ title = r.get("indexSymbol") or r.get("index") or r.get("symbol") or ""
95
 
96
  return f"""
97
  <div class="chart-flex-block">
98
+ <div class="chart-title"><strong>{html.escape(title)}</strong></div>
99
+ <div class="chart-flex-container">{charts}</div>
 
 
100
  </div>
101
  """
102
 
103
+ # ================= MAIN TABLE =================
104
+ main_table_html = build_table(records)
105
 
106
+ # ================= DATES TABLE =================
107
  dates_table_html = ""
108
  if not dates_df.empty:
109
+ dates_table_html = build_table(
110
  dates_df.to_dict(orient="records")
111
  )
112
 
113
+ # ================= GROUP BY CATEGORY =================
114
  groups = defaultdict(list)
115
  for r in records:
116
  groups[r.get("key") or "UNCLASSIFIED"].append(r)
117
 
118
+ sections = []
119
 
 
120
  for key_name, recs in groups.items():
 
121
  first = recs[0]
122
+ cols = [c for c in first if c not in hidden_cols]
123
 
124
  preferred = ["indexSymbol", "index", "symbol", "name"]
125
+ ordered_cols = (
126
+ [c for c in preferred if c in cols] +
127
+ [c for c in cols if c not in preferred]
128
+ )
129
 
130
+ table_html = build_table(recs, ordered_cols)
131
 
132
+ charts_html = ""
133
  if str(key_name).strip().upper() == "INDICES ELIGIBLE IN DERIVATIVES":
134
+ charts_html = "\n".join(build_chart_block(r) for r in recs)
 
 
135
 
136
+ sections.append(f"""
137
  <section class="key-section">
138
+ <h3>{html.escape(str(key_name))} (Total: {len(recs)})</h3>
139
+ {table_html}
140
  {charts_html}
141
  </section>
142
  """)
143
 
144
+ # ================= CSS =================
145
  css = """
146
  <style>
147
  body { font-family: Arial; padding: 16px; background: #fff; color: #111; }
148
+ table { border-collapse: collapse; width: 100%; margin-bottom: 12px; }
149
  th, td { border: 1px solid #ccc; padding: 6px 8px; font-size: 13px; }
150
+ th { background: #007bff; color: #fff; position: sticky; top: 0; }
151
 
152
+ .scroll { max-height: 420px; overflow: auto; margin-bottom: 20px; }
 
153
 
154
  .key-section {
155
+ border: 1px solid #e0e0e0;
 
156
  border-radius: 6px;
157
  padding: 10px;
158
  margin-bottom: 30px;
159
+ background: #fafcff;
160
  }
161
 
 
 
 
 
 
 
 
 
 
 
162
  .chart-flex-container {
163
  display: flex;
164
  flex-wrap: wrap;
 
178
  height: 100%;
179
  border: 0;
180
  }
181
+
182
+ .chart-title {
183
+ font-size: 14px;
184
+ margin-bottom: 6px;
185
+ }
186
  </style>
187
  """
188
 
189
+ # ================= FINAL HTML =================
190
  html_out = "\n".join([
191
  "<!DOCTYPE html>",
192
+ "<html>",
193
+ "<head>",
194
+ "<meta charset='utf-8'>",
195
+ "<title>NSE Indices</title>",
196
  css,
197
+ "</head>",
198
+ "<body>",
199
+ "<h1>NSE Indices</h1>",
200
+ f"<div>Generated: {dt.now().strftime('%Y-%m-%d %H:%M:%S')}</div>",
201
+ "<h2>Main Indices</h2>",
202
  "<div class='scroll'>", main_table_html, "</div>",
203
+ "<h2>Dates</h2>" if dates_table_html else "",
204
  "<div class='scroll'>" if dates_table_html else "",
205
  dates_table_html,
206
  "</div>" if dates_table_html else "",
207
  "<h2>Categories</h2>",
208
+ *sections,
209
  "</body></html>"
210
  ])
211
 
212
+ # ================= SAVE HTML (HF only) =================
213
+ save(cache_name, html_out, "html")
 
 
 
214
 
215
+ return html_out