eshan6704 commited on
Commit
84a8842
·
verified ·
1 Parent(s): fff5460

Create indices_html.py

Browse files
Files changed (1) hide show
  1. app/indices_html.py +215 -0
app/indices_html.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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"
80
+ frameborder="0" title="{html.escape(label)}"></iframe>
81
+ </div>
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;
165
+ gap: 10px;
166
+ }
167
+
168
+ .chart-flex-item {
169
+ flex: 1 1 300px;
170
+ min-height: 180px;
171
+ border: 1px solid #ccc;
172
+ border-radius: 6px;
173
+ overflow: hidden;
174
+ }
175
+
176
+ .chart-flex-item iframe {
177
+ width: 100%;
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