157 lines
4.4 KiB
JavaScript
157 lines
4.4 KiB
JavaScript
/**
|
|
* Activity monitoring and display functionality
|
|
*/
|
|
|
|
class ActivityMonitor {
|
|
constructor() {
|
|
this.activityLog = document.getElementById("activityLog");
|
|
this.notificationsToggle = document.getElementById("notificationsToggle");
|
|
this.notificationsEnabled = true;
|
|
this.lastPaperTimestamp = new Date().toISOString();
|
|
|
|
this.initEventListeners();
|
|
this.setupWebSocket();
|
|
}
|
|
|
|
/**
|
|
* Initialize event listeners
|
|
*/
|
|
initEventListeners() {
|
|
if (this.notificationsToggle) {
|
|
this.notificationsToggle.addEventListener("click", () => {
|
|
this.notificationsEnabled = this.notificationsToggle.checked;
|
|
});
|
|
}
|
|
|
|
// Time range buttons
|
|
document.querySelectorAll(".time-range-btn").forEach((btn) => {
|
|
btn.addEventListener("click", () => {
|
|
document
|
|
.querySelectorAll(".time-range-btn")
|
|
.forEach((b) => b.classList.remove("active"));
|
|
btn.classList.add("active");
|
|
const currentTimeRange = parseInt(btn.dataset.hours);
|
|
|
|
// Trigger chart refresh if callback is provided
|
|
if (this.onChartRefresh) {
|
|
this.onChartRefresh(currentTimeRange);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Load and render recent activity
|
|
*/
|
|
async loadRecentActivity() {
|
|
if (!this.activityLog) return;
|
|
|
|
try {
|
|
const data = await apiRequest(
|
|
"/api/activity_logs?category=scraper_activity&category=scraper_command&limit=50"
|
|
);
|
|
this.renderActivityLog(data);
|
|
console.log("Activity log refreshed with latest data");
|
|
} catch (error) {
|
|
console.error("Failed to load activity logs:", error);
|
|
// If the API endpoint doesn't exist, just show a message
|
|
this.activityLog.innerHTML =
|
|
'<tr><td colspan="4" class="text-center">Activity log API not available</td></tr>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render activity log data
|
|
* @param {Array} logs - Array of log entries
|
|
*/
|
|
renderActivityLog(logs) {
|
|
if (!this.activityLog) return;
|
|
|
|
this.activityLog.innerHTML = "";
|
|
|
|
if (!logs || logs.length === 0) {
|
|
this.activityLog.innerHTML =
|
|
'<tr><td colspan="4" class="text-center">No recent activity</td></tr>';
|
|
return;
|
|
}
|
|
|
|
logs.forEach((log) => {
|
|
const row = document.createElement("tr");
|
|
|
|
// Format timestamp
|
|
const timeStr = formatTimestamp(log.timestamp);
|
|
|
|
// Create status badge
|
|
const statusBadge = createStatusBadge(log.status);
|
|
|
|
row.innerHTML = `
|
|
<td>${timeStr}</td>
|
|
<td>${log.action}</td>
|
|
<td>${statusBadge}</td>
|
|
<td>${log.description || ""}</td>
|
|
`;
|
|
|
|
this.activityLog.appendChild(row);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Setup WebSocket for real-time notifications
|
|
*/
|
|
setupWebSocket() {
|
|
// If WebSocket is available, implement it here
|
|
// For now we'll poll the server periodically for new papers
|
|
setInterval(() => this.checkForNewPapers(), 10000); // Check every 10 seconds
|
|
}
|
|
|
|
/**
|
|
* Check for new papers and show notifications
|
|
*/
|
|
async checkForNewPapers() {
|
|
if (!this.notificationsEnabled) return;
|
|
|
|
try {
|
|
const data = await apiRequest(
|
|
`/api/activity_logs?category=scraper_activity&category=scraper_command&action=scrape_paper&after=${this.lastPaperTimestamp}&limit=5`
|
|
);
|
|
|
|
if (data && data.length > 0) {
|
|
// Update the timestamp
|
|
this.lastPaperTimestamp = new Date().toISOString();
|
|
|
|
// Show notifications for new papers
|
|
data.forEach((log) => {
|
|
const extraData = log.extra_data ? JSON.parse(log.extra_data) : {};
|
|
if (log.status === "success") {
|
|
showFlashMessage(
|
|
`New paper scraped: ${extraData.title || "Unknown title"}`,
|
|
"success"
|
|
);
|
|
} else if (log.status === "error") {
|
|
showFlashMessage(
|
|
`Failed to scrape paper: ${log.description}`,
|
|
"error"
|
|
);
|
|
}
|
|
});
|
|
|
|
// Refresh the activity chart and log
|
|
if (this.onChartRefresh) {
|
|
this.onChartRefresh();
|
|
}
|
|
this.loadRecentActivity();
|
|
}
|
|
} catch (error) {
|
|
// If the API endpoint doesn't exist, do nothing
|
|
console.debug("Activity polling failed (this may be expected):", error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set callback for chart refresh
|
|
*/
|
|
setChartRefreshCallback(callback) {
|
|
this.onChartRefresh = callback;
|
|
}
|
|
}
|