244 lines
8.2 KiB
Django/Jinja
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html.jinja" %} {% block content %}
<h1>Welcome to SciPaperLoader</h1>
<div id="results-container"></div>
{% if success %}
<div class="alert alert-success mt-3">{{ success }}</div>
{% endif %} {% if error_message %}
<div class="alert alert-warning mt-3">
<h4>{{ error_message }}</h4>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Row</th>
<th>DOI</th>
<th>Error</th>
</tr>
</thead>
<tbody>
{% for error in error_samples %}
<tr>
<td>{{ error.row }}</td>
<td>{{ error.doi }}</td>
<td>{{ error.error }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ url_for('upload.download_error_log') }}" class="btn btn-outline-secondary">Download Full Error Log</a>
</div>
{% endif %}
<div class="alert alert-info">
<p>
<strong>Instructions:</strong> Please upload a CSV file containing academic
paper metadata. The file must include the following columns:
</p>
<ul>
<li><code>alternative_id</code> an alternative title or abbreviation</li>
<li><code>journal</code> the journal name</li>
<li><code>doi</code> the digital object identifier</li>
<li><code>issn</code> the ISSN of the journal</li>
<li><code>title</code> the title of the paper</li>
</ul>
</div>
<form method="post" action="{{ url_for('upload.upload') }}" enctype="multipart/form-data" id="upload-form">
<div class="form-group">
<label for="file">Upload CSV File</label>
<input type="file" name="file" id="file" class="form-control" required />
</div>
<div class="form-group mt-3">
<label for="delimiter">Choose CSV Delimiter</label>
<select name="delimiter" id="delimiter" class="form-control">
<option value=",">Comma (,)</option>
<option value=";">Semicolon (;)</option>
<option value="\t">Tab (\\t)</option>
<option value="|">Pipe (|)</option>
</select>
</div>
<div class="form-group mt-3">
<label for="duplicate_strategy">Duplicate Handling Strategy</label>
<select name="duplicate_strategy" id="duplicate_strategy" class="form-control">
{% for strategy_id, strategy in duplicate_strategies.items() %}
<option value="{{ strategy_id }}" {% if strategy.is_default %}selected{% endif %}>
{{ strategy.name }} - {{ strategy.description }}
</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mt-3">Upload</button>
</form>
<!-- Progress Modal -->
<div id="progressModal" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Processing Your Upload</h5>
</div>
<div class="modal-body">
<div class="progress">
<div id="progressBar" class="progress-bar" role="progressbar">0%</div>
</div>
<p id="progressStatus" class="mt-2 text-center">Starting...</p>
</div>
</div>
</div>
</div>
<script>
const form = document.getElementById("upload-form");
form.addEventListener("submit", function (e) {
e.preventDefault();
// Display loading state immediately
const progressModal = new bootstrap.Modal(document.getElementById("progressModal"));
progressModal.show();
const progressBar = document.getElementById("progressBar");
progressBar.style.width = "5%";
progressBar.textContent = "Starting...";
const formData = new FormData(form);
// Disable the form while processing
const submitButton = form.querySelector("button[type='submit']");
submitButton.disabled = true;
fetch(form.action, {
method: "POST",
body: formData,
})
.then((response) => response.json())
.then((data) => {
if (data.error) {
// Handle error
progressModal.hide();
alert(`Error: ${data.error}`);
submitButton.disabled = false;
return;
}
const taskId = data.task_id;
const interval = setInterval(() => {
fetch("{{ url_for('upload.task_status', task_id='') }}" + taskId)
.then((response) => response.json())
.then((status) => {
console.log("Task status:", status);
if (status.state === "SUCCESS") {
clearInterval(interval);
progressBar.style.width = "100%";
progressBar.textContent = "Completed!";
setTimeout(() => {
progressModal.hide();
showResults(status.result);
submitButton.disabled = false;
}, 1000);
} else if (status.state === "FAILURE") {
clearInterval(interval);
progressBar.style.width = "100%";
progressBar.classList.add("bg-danger");
progressBar.textContent = "Failed!";
setTimeout(() => {
progressModal.hide();
alert(`Task failed: ${status.error || "Unknown error"}`);
submitButton.disabled = false;
}, 1000);
} else {
// Update progress bar with more information
const progress = status.progress || 0;
progressBar.style.width = `${progress}%`;
progressBar.textContent = `${progress}% complete`;
document.getElementById("progressStatus").innerText = `Processing... (${status.state})`;
}
})
.catch((err) => {
console.error("Failed to check task status:", err);
});
}, 1000);
})
.catch((err) => {
console.error("Upload failed:", err);
progressModal.hide();
alert("Upload failed. Please try again.");
submitButton.disabled = false;
});
});
const showResults = (result) => {
const message = `Upload completed! Added: ${result.added}, Updated: ${result.updated}, Skipped: ${result.skipped}, Errors: ${result.error_count}`;
let resultHTML = `<div class="alert alert-success">${message}</div>`;
// Add skipped records information
if (result.skipped > 0) {
resultHTML += `
<div class="alert alert-info">
<h4>${result.skipped} records were skipped</h4>
<p>${result.skipped_reason_summary || "Records were skipped because they already exist in the database."}</p>
${result.skipped_records && result.skipped_records.length > 0 ? `
<p>Examples of skipped records:</p>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Row</th>
<th>DOI</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
${result.skipped_records.map(record => `
<tr>
<td>${record.row}</td>
<td>${record.doi}</td>
<td>${record.reason}</td>
</tr>
`).join('')}
</tbody>
</table>
` : ''}
</div>`;
}
// Existing error display code
if (result.error_count > 0) {
resultHTML += `
<div class="alert alert-warning">
<h4>Some errors occurred (${result.error_count} total)</h4>
<p>Showing first ${result.errors.length} of ${result.error_count} errors:</p>
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Row</th>
<th>DOI</th>
<th>Error</th>
</tr>
</thead>
<tbody>`;
result.errors.forEach(error => {
resultHTML += `
<tr>
<td>${error.row}</td>
<td>${error.doi}</td>
<td>${error.error}</td>
</tr>`;
});
resultHTML += `
</tbody>
</table>
<p class="mt-2">Download the complete error log with all ${result.error_count} errors:</p>
<a href="/upload/download_error_log/${result.task_id}" class="btn btn-outline-secondary">
Download Full Error Log
</a>
</div>`;
}
document.getElementById("results-container").innerHTML = resultHTML;
};
</script>
{% endblock content %}