';
}
}
/**
* Process a single paper
* @param {string} paperId - The ID of the paper to process
*/
async processSinglePaper(paperId) {
if (!this.processingStatus || !this.scraperSelect) return;
// Disable all process buttons to prevent multiple clicks
document.querySelectorAll(".process-paper-btn").forEach((btn) => {
btn.disabled = true;
});
// Show processing status
this.processingStatus.textContent = "Processing paper...";
this.processingStatus.classList.remove("d-none");
// Get selected scraper
const selectedScraper = this.scraperSelect.value;
try {
const data = await apiRequest(`/scraper/process_single/${paperId}`, {
method: "POST",
body: JSON.stringify({
scraper_module: selectedScraper,
}),
});
if (data.success) {
this.processingStatus.textContent = data.message;
this.processingStatus.className = "alert alert-success mt-3";
// Update status in the search results
const row = document
.querySelector(`.process-paper-btn[data-paper-id="${paperId}"]`)
?.closest("tr");
if (row) {
const statusCell = row.querySelector("td:nth-child(4)");
if (statusCell) {
statusCell.innerHTML = createStatusBadge("Pending");
}
}
// Show notification
showFlashMessage(data.message, "success");
// Set up polling to check paper status and refresh activity
this.pollPaperStatus(paperId, 3000, 20);
} else {
this.processingStatus.textContent = data.message;
this.processingStatus.className = "alert alert-danger mt-3";
showFlashMessage(data.message, "error");
}
} catch (error) {
console.error("Error processing paper:", error);
this.processingStatus.textContent = "Error: Could not process paper";
this.processingStatus.className = "alert alert-danger mt-3";
showFlashMessage("Error processing paper", "error");
} finally {
// Re-enable the process buttons after a short delay
setTimeout(() => {
document.querySelectorAll(".process-paper-btn").forEach((btn) => {
if (btn.getAttribute("data-paper-id") !== paperId) {
btn.disabled = false;
}
});
}, 1000);
}
}
/**
* Poll paper status until it changes from Pending
* @param {string} paperId - The paper ID to poll
* @param {number} interval - Polling interval in milliseconds
* @param {number} maxAttempts - Maximum number of polling attempts
*/
pollPaperStatus(paperId, interval = 3000, maxAttempts = 20) {
let attempts = 0;
// Immediately refresh activity log to show the initial pending status
if (this.onActivityRefresh) {
this.onActivityRefresh();
}
const checkStatus = async () => {
attempts++;
console.log(
`Checking status of paper ${paperId}, attempt ${attempts}/${maxAttempts}`
);
try {
const data = await apiRequest(`/api/papers/${paperId}`);
if (data && data.paper) {
const paper = data.paper;
console.log(`Paper status: ${paper.status}`);
// Update the UI with the current status
const row = document
.querySelector(`.process-paper-btn[data-paper-id="${paperId}"]`)
?.closest("tr");
if (row) {
const statusCell = row.querySelector("td:nth-child(4)");
if (statusCell) {
statusCell.innerHTML = createStatusBadge(paper.status);
}
// Update processing status message if status changed
if (paper.status !== "Pending") {
if (paper.status === "Done") {
this.processingStatus.textContent = `Paper processed successfully: ${paper.title}`;
this.processingStatus.className = "alert alert-success mt-3";
} else if (paper.status === "Failed") {
this.processingStatus.textContent = `Paper processing failed: ${
paper.error_msg || "Unknown error"
}`;
this.processingStatus.className = "alert alert-danger mt-3";
}
}
}
// Always refresh activity log
if (this.onActivityRefresh) {
this.onActivityRefresh();
}
// If status is still pending and we haven't reached max attempts, check again
if (paper.status === "Pending" && attempts < maxAttempts) {
setTimeout(checkStatus, interval);
} else {
// If status changed or we reached max attempts, refresh chart data too
if (this.onChartRefresh) {
this.onChartRefresh();
}
// Show notification if status changed
if (paper.status !== "Pending") {
const status = paper.status === "Done" ? "success" : "error";
const message =
paper.status === "Done"
? `Paper processed successfully: ${paper.title}`
: `Paper processing failed: ${
paper.error_msg || "Unknown error"
}`;
showFlashMessage(message, status);
}
// If we hit max attempts but status is still pending, show a message
if (paper.status === "Pending" && attempts >= maxAttempts) {
this.processingStatus.textContent =
"Paper is still being processed. Check the activity log for updates.";
this.processingStatus.className = "alert alert-info mt-3";
}
}
}
} catch (error) {
console.error(`Error polling paper status: ${error}`);
// If there's an error, we can still try again if under max attempts
if (attempts < maxAttempts) {
setTimeout(checkStatus, interval);
}
}
};
// Start checking
setTimeout(checkStatus, interval);
}
/**
* Set callback for activity refresh
*/
setActivityRefreshCallback(callback) {
this.onActivityRefresh = callback;
}
/**
* Set callback for chart refresh
*/
setChartRefreshCallback(callback) {
this.onChartRefresh = callback;
}
}