Report-Generator / templates /json_upload.html
Jaimodiji's picture
Upload folder using huggingface_hub
c001f24
{% extends "base.html" %}
{% block title %}Upload JSON{% endblock %}
{% block head %}
<script>
MathJax = {
tex: {
inlineMath: [['\(', '\)']]
},
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
{% endblock %}
{% block content %}
<div class="container mt-5">
<div class="card bg-dark text-white">
<div class="card-header">
<h2>Upload JSON Data</h2>
</div>
<div class="card-body">
<form id="json-upload-form">
<div class="mb-3">
<label for="json-data" class="form-label">Paste your JSON data here:</label>
<textarea class="form-control" id="json-data" rows="15" required></textarea>
</div>
<div class="mb-3">
<label class="form-label">Process Questions with Status:</label>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="correct" id="status_correct">
<label class="form-check-label" for="status_correct">
Correct
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="wrong" id="status_wrong" checked>
<label class="form-check-label" for="status_wrong">
Wrong
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="unattempted" id="status_unattempted" checked>
<label class="form-check-label" for="status_unattempted">
Unattempted
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Process JSON</button>
</form>
<div id="status" class="mt-3"></div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
// Function to fix font-family declarations in HTML strings
function fixFontFamilyQuotes(htmlString) {
// First, handle escaped quotes in the HTML
// This regex matches font-family declarations with escaped quotes
htmlString = htmlString.replace(/font-family:\\?"([^\\]+(?:\\.[^\\]*)*)"(?=[\s;>])/g, function(match, fontValue) {
// Unescape the font value
let unescapedValue = fontValue.replace(/\\"/g, '"');
// Replace double quotes with single quotes in the font names
let fixedValue = unescapedValue.replace(/"/g, "'");
return `font-family:'${fixedValue}'`;
});
// Also handle non-escaped font-family declarations
htmlString = htmlString.replace(/font-family:\s*"([^"]+(?:,\s*"[^"]+"\s*)*)"(?=[\s;>])/g, function(match) {
// Extract the full font-family value including all fonts
let fontDeclaration = match.match(/font-family:\s*(.+)/)[1];
// Replace outer quotes and inner quotes appropriately
fontDeclaration = fontDeclaration.replace(/^"|"$/g, "'");
fontDeclaration = fontDeclaration.replace(/","/g, "','");
return `font-family:${fontDeclaration}`;
});
// Handle a more complex pattern where font-family might span multiple quoted sections
htmlString = htmlString.replace(/style="([^"]*)"/g, function(match, styleContent) {
// Process font-family within style attributes
let fixedStyle = styleContent.replace(/font-family:([^;]+)(;|$)/g, function(m, fontValue, ending) {
// Clean up the font value
fontValue = fontValue.trim();
// If it starts and ends with quotes, process it
if ((fontValue.startsWith('"') && fontValue.endsWith('"')) ||
(fontValue.startsWith("'") && fontValue.endsWith("'"))) {
// Remove outer quotes
fontValue = fontValue.slice(1, -1);
// Replace any internal double quotes with single quotes
fontValue = fontValue.replace(/"/g, "'");
return `font-family:'${fontValue}'${ending}`;
}
return m; // Return unchanged if doesn't match pattern
});
return `style="${fixedStyle}"`;
});
return htmlString;
}
document.getElementById('json-upload-form').addEventListener('submit', async (e) => {
e.preventDefault();
let jsonData = document.getElementById('json-data').value;
const statusDiv = document.getElementById('status');
const cardBody = document.querySelector('.card-body');
const selectedStatuses = Array.from(document.querySelectorAll('input[type="checkbox"][id^="status_"]:checked')).map(cb => cb.value);
try {
jsonData = fixFontFamilyQuotes(jsonData);
const data = JSON.parse(jsonData);
let testName;
let bodyPayload;
let endpoint;
if (data.version && String(data.version) === "2.1") {
testName = data.test_name;
bodyPayload = data;
endpoint = '/json_upload';
} else if (data.data && data.data.root) {
testName = data.data.root._testAttempt4d9rq8.test.name;
bodyPayload = { data: data, statuses: selectedStatuses };
endpoint = '/process_json';
} else {
if (data.test_name) {
testName = data.test_name;
bodyPayload = data;
endpoint = '/json_upload';
} else {
throw new Error("Unknown JSON format. Could not determine structure.");
}
}
statusDiv.innerHTML = '<div class="alert alert-info">Processing JSON...</div>';
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(bodyPayload)
});
const result = await response.json();
if (result.success) {
if (result.edit_url) {
window.location.href = result.edit_url;
return;
}
const form = document.createElement('form');
form.action = '/save_processed_json';
form.method = 'post';
const questionsInput = document.createElement('input');
questionsInput.type = 'hidden';
questionsInput.name = 'questions_data';
questionsInput.value = JSON.stringify(result.questions);
form.appendChild(questionsInput);
const testNameInput = document.createElement('input');
testNameInput.type = 'hidden';
testNameInput.name = 'test_name';
testNameInput.value = testName;
form.appendChild(testNameInput);
const table = document.createElement('table');
table.className = 'table table-dark';
const thead = document.createElement('thead');
thead.innerHTML = '<tr><th>Question</th><th>Your Answer</th><th>Correct Answer</th><th>Status</th></tr>';
table.appendChild(thead);
const tbody = document.createElement('tbody');
result.questions.forEach(q => {
let badgeClass = 'bg-warning text-dark';
if (q.status === 'wrong') badgeClass = 'bg-danger';
if (q.status === 'correct') badgeClass = 'bg-success';
const row = document.createElement('tr');
row.innerHTML = `<td>${q.question}</td><td>${q.yourAnswer}</td><td>${q.correctAnswer}</td><td><span class="badge ${badgeClass}">${q.status}</span></td>`;
tbody.appendChild(row);
});
table.appendChild(tbody);
form.appendChild(table);
const button = document.createElement('button');
button.type = 'submit';
button.className = 'btn btn-primary mt-3';
button.textContent = 'Save and Go to Question Entry';
form.appendChild(button);
cardBody.innerHTML = '';
cardBody.appendChild(form);
if (window.MathJax) {
MathJax.typesetPromise();
}
} else {
statusDiv.innerHTML = `<div class="alert alert-danger">Error: ${result.error}</div>`;
}
} catch (error) {
statusDiv.innerHTML = `<div class="alert alert-danger">Invalid JSON format or processing error: ${error.message}</div>`;
}
});
</script>
{% endblock %}