pvanand commited on
Commit
78b1a19
·
verified ·
1 Parent(s): 5f07afe

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +74 -59
public/index.html CHANGED
@@ -13,7 +13,6 @@
13
  --border-color: #dee2e6;
14
  --background-color: #f8f9fa;
15
  }
16
-
17
  body {
18
  font-family: system-ui, -apple-system, sans-serif;
19
  line-height: 1.6;
@@ -21,7 +20,6 @@
21
  padding: 20px;
22
  background: var(--background-color);
23
  }
24
-
25
  .container {
26
  max-width: 1200px;
27
  margin: 0 auto;
@@ -30,7 +28,6 @@
30
  border-radius: 8px;
31
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
32
  }
33
-
34
  textarea {
35
  width: 100%;
36
  height: 200px;
@@ -42,32 +39,27 @@
42
  resize: vertical;
43
  margin-bottom: 15px;
44
  }
45
-
46
  .options-container {
47
  background: var(--background-color);
48
  padding: 20px;
49
  border-radius: 8px;
50
  margin: 20px 0;
51
  }
52
-
53
  .option-grid {
54
  display: grid;
55
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
56
  gap: 15px;
57
  }
58
-
59
  .option-item {
60
  display: flex;
61
  align-items: center;
62
  gap: 10px;
63
  }
64
-
65
  .button-group {
66
  display: flex;
67
  gap: 10px;
68
  margin: 15px 0;
69
  }
70
-
71
  button {
72
  background: var(--primary-color);
73
  color: white;
@@ -77,21 +69,17 @@
77
  cursor: pointer;
78
  transition: background 0.2s;
79
  }
80
-
81
  button:hover {
82
  background: #0056b3;
83
  }
84
-
85
  .results-container {
86
  margin-top: 30px;
87
  }
88
-
89
  .results-tabs {
90
  display: flex;
91
  gap: 10px;
92
  margin-bottom: 15px;
93
  }
94
-
95
  .tab {
96
  padding: 8px 16px;
97
  cursor: pointer;
@@ -99,18 +87,15 @@
99
  border-radius: 4px;
100
  transition: all 0.2s;
101
  }
102
-
103
  .tab.active {
104
  background: var(--primary-color);
105
  color: white;
106
  }
107
-
108
  .result-panel {
109
  border: 1px solid var(--border-color);
110
  border-radius: 4px;
111
  overflow: hidden;
112
  }
113
-
114
  .result-header {
115
  display: flex;
116
  justify-content: space-between;
@@ -119,33 +104,28 @@
119
  background: var(--background-color);
120
  border-bottom: 1px solid var(--border-color);
121
  }
122
-
123
  .result-content {
124
  padding: 15px;
125
  overflow: auto;
126
  max-height: 500px;
127
  }
128
-
129
  .stats-grid {
130
  display: grid;
131
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
132
  gap: 15px;
133
  margin: 20px 0;
134
  }
135
-
136
  .stat-item {
137
  background: white;
138
  padding: 15px;
139
  border-radius: 4px;
140
  border: 1px solid var(--border-color);
141
  }
142
-
143
  .stat-value {
144
  font-size: 1.2em;
145
  font-weight: bold;
146
  color: var(--primary-color);
147
  }
148
-
149
  .copy-feedback {
150
  position: fixed;
151
  bottom: 20px;
@@ -156,21 +136,18 @@
156
  border-radius: 4px;
157
  display: none;
158
  }
159
-
160
  .operation-status {
161
  margin: 20px 0;
162
  padding: 15px;
163
  border: 1px solid var(--border-color);
164
  border-radius: 4px;
165
  }
166
-
167
  .status-grid {
168
  display: grid;
169
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
170
  gap: 10px;
171
  margin-top: 10px;
172
  }
173
-
174
  .status-item {
175
  display: flex;
176
  align-items: center;
@@ -179,7 +156,6 @@
179
  border-radius: 4px;
180
  background: var(--background-color);
181
  }
182
-
183
  .status-icon {
184
  width: 20px;
185
  height: 20px;
@@ -190,26 +166,21 @@
190
  color: white;
191
  font-size: 12px;
192
  }
193
-
194
  .status-success {
195
  background: var(--success-color);
196
  }
197
-
198
  .status-error {
199
  background: #dc3545;
200
  }
201
-
202
  .status-message {
203
  font-size: 0.9em;
204
  color: #666;
205
  margin-top: 4px;
206
  }
207
-
208
  pre {
209
  margin: 0;
210
  border-radius: 4px;
211
  }
212
-
213
  code {
214
  font-family: 'Monaco', 'Menlo', monospace;
215
  font-size: 14px;
@@ -283,6 +254,7 @@
283
  <div class="results-tabs">
284
  <div class="tab active" data-view="html">Compressed HTML</div>
285
  <div class="tab" data-view="json">JSON Structure</div>
 
286
  </div>
287
 
288
  <div class="result-panel" id="htmlView">
@@ -310,12 +282,24 @@
310
  <pre><code class="language-json" id="jsonOutput"></code></pre>
311
  </div>
312
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  </div>
314
 
315
  <div class="copy-feedback">Copied to clipboard!</div>
316
  </div>
317
 
318
- <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
319
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
320
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-markup.min.js"></script>
321
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-json.min.js"></script>
@@ -330,14 +314,12 @@
330
  // Tab switching
331
  document.querySelectorAll('.tab').forEach(tab => {
332
  tab.addEventListener('click', () => {
333
- // Update tabs
334
  document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
335
  tab.classList.add('active');
336
-
337
- // Update views
338
  const view = tab.dataset.view;
339
  document.getElementById('htmlView').style.display = view === 'html' ? 'block' : 'none';
340
  document.getElementById('jsonView').style.display = view === 'json' ? 'block' : 'none';
 
341
  });
342
  });
343
 
@@ -354,35 +336,32 @@
354
  // Form submission
355
  form.addEventListener('submit', async (e) => {
356
  e.preventDefault();
357
-
358
  const formData = new FormData(form);
359
-
360
- // Add checkbox states
361
  document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
362
  formData.set(checkbox.name, checkbox.checked);
363
  });
364
-
365
  try {
 
366
  const response = await fetch('/process', {
367
  method: 'POST',
368
  body: formData,
369
  });
370
-
371
  const data = await response.json();
372
-
373
  if (data.error) {
374
  alert(data.error);
375
  return;
376
  }
377
 
378
- // Display operation status
379
  const statusContainer = document.querySelector('#operationStatus');
380
  const statusGrid = statusContainer.querySelector('.status-grid');
381
  statusContainer.style.display = 'block';
382
-
383
  statusGrid.innerHTML = Object.entries(data.operationStatus)
384
- .map(([operation, status]) => `
385
- <div class="status-item">
386
  <div class="status-icon ${status.success ? 'status-success' : 'status-error'}">
387
  ${status.success ? '✓' : '✗'}
388
  </div>
@@ -390,30 +369,63 @@
390
  <div>${formatLabel(operation)}</div>
391
  ${status.error ? `<div class="status-message">Error: ${status.error}</div>` : ''}
392
  </div>
393
- </div>
394
- `).join('');
395
 
396
- // Display stats
397
  statsContainer.style.display = 'grid';
398
  statsContainer.innerHTML = Object.entries(data.stats)
399
- .map(([key, value]) => `
400
- <div class="stat-item">
401
  <div class="stat-label">${formatLabel(key)}</div>
402
  <div class="stat-value">${value}</div>
403
- </div>
404
- `).join('');
405
 
406
- // Show results container
407
  resultsContainer.style.display = 'block';
408
-
409
- // Update outputs with syntax highlighting
410
  document.getElementById('htmlOutput').textContent = data.result.html;
411
  document.getElementById('jsonOutput').textContent = data.result.json;
412
-
413
- // Trigger Prism highlighting
414
  Prism.highlightAll();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  } catch (err) {
416
- alert('Error processing HTML: ' + err.message);
417
  }
418
  });
419
 
@@ -428,7 +440,8 @@
428
  }
429
 
430
  async function copyResult(type) {
431
- const content = document.getElementById(`${type}Output`).textContent;
 
432
  try {
433
  await navigator.clipboard.writeText(content);
434
  showCopyFeedback();
@@ -438,12 +451,14 @@
438
  }
439
 
440
  function downloadResult(type) {
441
- const content = document.getElementById(`${type}Output`).textContent;
 
 
442
  const blob = new Blob([content], { type: 'text/plain' });
443
  const url = URL.createObjectURL(blob);
444
  const a = document.createElement('a');
445
  a.href = url;
446
- a.download = `compressed.${type}`;
447
  document.body.appendChild(a);
448
  a.click();
449
  document.body.removeChild(a);
 
13
  --border-color: #dee2e6;
14
  --background-color: #f8f9fa;
15
  }
 
16
  body {
17
  font-family: system-ui, -apple-system, sans-serif;
18
  line-height: 1.6;
 
20
  padding: 20px;
21
  background: var(--background-color);
22
  }
 
23
  .container {
24
  max-width: 1200px;
25
  margin: 0 auto;
 
28
  border-radius: 8px;
29
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
30
  }
 
31
  textarea {
32
  width: 100%;
33
  height: 200px;
 
39
  resize: vertical;
40
  margin-bottom: 15px;
41
  }
 
42
  .options-container {
43
  background: var(--background-color);
44
  padding: 20px;
45
  border-radius: 8px;
46
  margin: 20px 0;
47
  }
 
48
  .option-grid {
49
  display: grid;
50
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
51
  gap: 15px;
52
  }
 
53
  .option-item {
54
  display: flex;
55
  align-items: center;
56
  gap: 10px;
57
  }
 
58
  .button-group {
59
  display: flex;
60
  gap: 10px;
61
  margin: 15px 0;
62
  }
 
63
  button {
64
  background: var(--primary-color);
65
  color: white;
 
69
  cursor: pointer;
70
  transition: background 0.2s;
71
  }
 
72
  button:hover {
73
  background: #0056b3;
74
  }
 
75
  .results-container {
76
  margin-top: 30px;
77
  }
 
78
  .results-tabs {
79
  display: flex;
80
  gap: 10px;
81
  margin-bottom: 15px;
82
  }
 
83
  .tab {
84
  padding: 8px 16px;
85
  cursor: pointer;
 
87
  border-radius: 4px;
88
  transition: all 0.2s;
89
  }
 
90
  .tab.active {
91
  background: var(--primary-color);
92
  color: white;
93
  }
 
94
  .result-panel {
95
  border: 1px solid var(--border-color);
96
  border-radius: 4px;
97
  overflow: hidden;
98
  }
 
99
  .result-header {
100
  display: flex;
101
  justify-content: space-between;
 
104
  background: var(--background-color);
105
  border-bottom: 1px solid var(--border-color);
106
  }
 
107
  .result-content {
108
  padding: 15px;
109
  overflow: auto;
110
  max-height: 500px;
111
  }
 
112
  .stats-grid {
113
  display: grid;
114
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
115
  gap: 15px;
116
  margin: 20px 0;
117
  }
 
118
  .stat-item {
119
  background: white;
120
  padding: 15px;
121
  border-radius: 4px;
122
  border: 1px solid var(--border-color);
123
  }
 
124
  .stat-value {
125
  font-size: 1.2em;
126
  font-weight: bold;
127
  color: var(--primary-color);
128
  }
 
129
  .copy-feedback {
130
  position: fixed;
131
  bottom: 20px;
 
136
  border-radius: 4px;
137
  display: none;
138
  }
 
139
  .operation-status {
140
  margin: 20px 0;
141
  padding: 15px;
142
  border: 1px solid var(--border-color);
143
  border-radius: 4px;
144
  }
 
145
  .status-grid {
146
  display: grid;
147
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
148
  gap: 10px;
149
  margin-top: 10px;
150
  }
 
151
  .status-item {
152
  display: flex;
153
  align-items: center;
 
156
  border-radius: 4px;
157
  background: var(--background-color);
158
  }
 
159
  .status-icon {
160
  width: 20px;
161
  height: 20px;
 
166
  color: white;
167
  font-size: 12px;
168
  }
 
169
  .status-success {
170
  background: var(--success-color);
171
  }
 
172
  .status-error {
173
  background: #dc3545;
174
  }
 
175
  .status-message {
176
  font-size: 0.9em;
177
  color: #666;
178
  margin-top: 4px;
179
  }
 
180
  pre {
181
  margin: 0;
182
  border-radius: 4px;
183
  }
 
184
  code {
185
  font-family: 'Monaco', 'Menlo', monospace;
186
  font-size: 14px;
 
254
  <div class="results-tabs">
255
  <div class="tab active" data-view="html">Compressed HTML</div>
256
  <div class="tab" data-view="json">JSON Structure</div>
257
+ <div class="tab" data-view="extracted">Extracted Data</div>
258
  </div>
259
 
260
  <div class="result-panel" id="htmlView">
 
282
  <pre><code class="language-json" id="jsonOutput"></code></pre>
283
  </div>
284
  </div>
285
+
286
+ <div class="result-panel" id="extractedView" style="display: none;">
287
+ <div class="result-header">
288
+ <h3>Extracted Data</h3>
289
+ <div class="button-group">
290
+ <button onclick="copyResult('extracted')">Copy</button>
291
+ <button onclick="downloadResult('extracted')">Download</button>
292
+ </div>
293
+ </div>
294
+ <div class="result-content">
295
+ <pre><code class="language-json" id="extractedOutput"></code></pre>
296
+ </div>
297
+ </div>
298
  </div>
299
 
300
  <div class="copy-feedback">Copied to clipboard!</div>
301
  </div>
302
 
 
303
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/prism.min.js"></script>
304
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-markup.min.js"></script>
305
  <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/components/prism-json.min.js"></script>
 
314
  // Tab switching
315
  document.querySelectorAll('.tab').forEach(tab => {
316
  tab.addEventListener('click', () => {
 
317
  document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
318
  tab.classList.add('active');
 
 
319
  const view = tab.dataset.view;
320
  document.getElementById('htmlView').style.display = view === 'html' ? 'block' : 'none';
321
  document.getElementById('jsonView').style.display = view === 'json' ? 'block' : 'none';
322
+ document.getElementById('extractedView').style.display = view === 'extracted' ? 'block' : 'none';
323
  });
324
  });
325
 
 
336
  // Form submission
337
  form.addEventListener('submit', async (e) => {
338
  e.preventDefault();
 
339
  const formData = new FormData(form);
340
+
 
341
  document.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
342
  formData.set(checkbox.name, checkbox.checked);
343
  });
344
+
345
  try {
346
+ // Process HTML compression
347
  const response = await fetch('/process', {
348
  method: 'POST',
349
  body: formData,
350
  });
 
351
  const data = await response.json();
352
+
353
  if (data.error) {
354
  alert(data.error);
355
  return;
356
  }
357
 
358
+ // Update UI elements
359
  const statusContainer = document.querySelector('#operationStatus');
360
  const statusGrid = statusContainer.querySelector('.status-grid');
361
  statusContainer.style.display = 'block';
 
362
  statusGrid.innerHTML = Object.entries(data.operationStatus)
363
+ .map(([operation, status]) =>
364
+ `<div class="status-item">
365
  <div class="status-icon ${status.success ? 'status-success' : 'status-error'}">
366
  ${status.success ? '✓' : '✗'}
367
  </div>
 
369
  <div>${formatLabel(operation)}</div>
370
  ${status.error ? `<div class="status-message">Error: ${status.error}</div>` : ''}
371
  </div>
372
+ </div>`
373
+ ).join('');
374
 
 
375
  statsContainer.style.display = 'grid';
376
  statsContainer.innerHTML = Object.entries(data.stats)
377
+ .map(([key, value]) =>
378
+ `<div class="stat-item">
379
  <div class="stat-label">${formatLabel(key)}</div>
380
  <div class="stat-value">${value}</div>
381
+ </div>`
382
+ ).join('');
383
 
 
384
  resultsContainer.style.display = 'block';
 
 
385
  document.getElementById('htmlOutput').textContent = data.result.html;
386
  document.getElementById('jsonOutput').textContent = data.result.json;
 
 
387
  Prism.highlightAll();
388
+
389
+ // Generate Cheerio script
390
+ const scriptResponse = await fetch(
391
+ 'https://elevatics-ai-web-scraper-chat.hf.space/api/v1/generate-cheerio-script',
392
+ {
393
+ method: 'POST',
394
+ headers: {
395
+ 'accept': 'application/json',
396
+ 'X-API-Key': 'ae54a922-ed3a-4634-be4a-4e4dd470800a',
397
+ 'Content-Type': 'application/json'
398
+ },
399
+ body: JSON.stringify({
400
+ html: data.result.html,
401
+ user_input: "",
402
+ api_key: ""
403
+ })
404
+ }
405
+ );
406
+
407
+ const scriptData = await scriptResponse.json();
408
+ if (scriptData.status !== 'success') {
409
+ throw new Error('Script generation failed: ' + scriptData.message);
410
+ }
411
+
412
+ // Extract data using generated script
413
+ const extractResponse = await fetch('/extract', {
414
+ method: 'POST',
415
+ headers: { 'Content-Type': 'application/json' },
416
+ body: JSON.stringify({
417
+ html: data.result.html,
418
+ script: scriptData.cheerio_script
419
+ })
420
+ });
421
+
422
+ const extractedData = await extractResponse.json();
423
+ document.getElementById('extractedOutput').textContent =
424
+ JSON.stringify(extractedData, null, 2);
425
+ Prism.highlightAll();
426
+
427
  } catch (err) {
428
+ alert(`Processing error: ${err.message}`);
429
  }
430
  });
431
 
 
440
  }
441
 
442
  async function copyResult(type) {
443
+ const elementId = `${type}Output`;
444
+ const content = document.getElementById(elementId).textContent;
445
  try {
446
  await navigator.clipboard.writeText(content);
447
  showCopyFeedback();
 
451
  }
452
 
453
  function downloadResult(type) {
454
+ const elementId = `${type}Output`;
455
+ const content = document.getElementById(elementId).textContent;
456
+ const ext = type === 'extracted' ? 'json' : type;
457
  const blob = new Blob([content], { type: 'text/plain' });
458
  const url = URL.createObjectURL(blob);
459
  const a = document.createElement('a');
460
  a.href = url;
461
+ a.download = `compressed.${ext}`;
462
  document.body.appendChild(a);
463
  a.click();
464
  document.body.removeChild(a);