From fa0a7bba8aa96e57aeb9b30babe247d15dce0971 Mon Sep 17 00:00:00 2001 From: BTCforPlebs Date: Fri, 26 Sep 2025 23:59:18 -0400 Subject: [PATCH] Services Monitor --- .DS_Store | Bin 8196 -> 8196 bytes .gitignore | 65 ++-------------------- README.md | 35 ++++++++++++ checklinks.js | 93 ++++++++++++++++++++++++++++++++ config.js | 9 ++++ package.json | 26 +++++++++ public/assets/js/home.js | 92 +++++++++++++++++++++++++++++++ public/assets/js/scripts.js | 25 +-------- public/index.html | 33 ++++++------ public/learn-bitcoin/index.html | 8 ++- public/learn-cashu/index.html | 8 ++- public/learn-nostr/index.html | 7 ++- public/parts/footer.html | 2 +- 13 files changed, 297 insertions(+), 106 deletions(-) create mode 100644 README.md create mode 100644 checklinks.js create mode 100644 config.js create mode 100644 package.json create mode 100644 public/assets/js/home.js diff --git a/.DS_Store b/.DS_Store index 7d6b81d28b90129ca08ceb8bd85d13e9683963e4..efa7e636120d8c05635093763a00cb55092dcebb 100644 GIT binary patch delta 16 XcmZp1XmQwJCOFwcKyb6W;9foeFk1yu delta 14 VcmZp1XmQwJCdkOR* { + console.log("Received request:", req.url); + const origin = req.headers.origin; + if (config.allowedOrigins.includes(origin)) { + res.header("Access-Control-Allow-Origin", origin); + } + next(); +}); + +app.get("/api/link-status", async (req, res) => { + console.log("Checking link statuses..."); // Add this line + const results = {}; + + const agent = new https.Agent({ + rejectUnauthorized: false // This helps with self-signed certificates + }); + + for (const url of links) { + try { + console.log(`Checking ${url}...`); + const response = await fetch(url, { + method: "GET", + headers: { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" + }, + timeout: 10000, + agent + }); + console.log(`${url} status: ${response.status}`); + + // If response is OK, it's online + if (response.ok) { + results[url] = "online"; + continue; + } + + // Special check for mint.btcforplebs.com + if (url.includes("mint.btcforplebs.com")) { + try { + const text = await response.text(); + console.log(`Mint response text:`, text); + const json = JSON.parse(text); + console.log(`Mint parsed JSON:`, json); + console.log(`Content-Type:`, response.headers.get('content-type')); + if (json.detail === "Not Found") { + console.log(`Mint matched expected response, marking as online`); + results[url] = "online"; + } else { + console.log(`Mint response didn't match expected format`); + results[url] = "offline"; + } + } catch (error) { + console.error(`Error processing mint response:`, error); + results[url] = "offline"; + } + } else { + // For all other URLs, if not OK then offline + results[url] = "offline"; + } + } catch (error) { + console.error(`Error checking ${url}:`, error.message); + results[url] = "offline"; + } + } + + console.log("Final results:", results); + res.json(results); +}); + +app.listen(config.port, () => { + console.log(`Link status API running on port ${config.port}`); +}); \ No newline at end of file diff --git a/config.js b/config.js new file mode 100644 index 0000000..8ce8fe3 --- /dev/null +++ b/config.js @@ -0,0 +1,9 @@ +module.exports = { + port: process.env.PORT || 5252, + // Add any other configuration variables here + allowedOrigins: [ + 'http://localhost:5252', + 'https://btcforplebs.com', + 'https://www.btcforplebs.com' + ] +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..27bb228 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "btcforplebs.com", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node checklinks.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/btcforplebs/BTCforPlebs.com.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "bugs": { + "url": "https://github.com/btcforplebs/BTCforPlebs.com/issues" + }, + "homepage": "https://github.com/btcforplebs/BTCforPlebs.com#readme", + "dependencies": { + "express": "^5.1.0", + "node-fetch": "^2.7.0" + } +} diff --git a/public/assets/js/home.js b/public/assets/js/home.js new file mode 100644 index 0000000..e0e63ad --- /dev/null +++ b/public/assets/js/home.js @@ -0,0 +1,92 @@ +// Store statuses globally +let linkStatuses = {}; + +// Fetch statuses on page load +document.addEventListener('DOMContentLoaded', () => { + // Fetch statuses immediately but keep folders closed + fetch("http://localhost:5252/api/link-status") + .then(res => res.json()) + .then(statuses => { + linkStatuses = statuses; // Store for later use + console.log("Cached link statuses:", linkStatuses); + }) + .catch(error => console.error("Error:", error)); +}); + +// Helper function to update status emojis +function updateFolderStatuses(folder, statuses) { + folder.querySelectorAll("a").forEach(link => { + const url = link.href; + const matchingUrl = Object.keys(statuses).find(statusUrl => + url.includes(new URL(statusUrl).hostname) + ); + const status = matchingUrl ? statuses[matchingUrl] : "unknown"; + const emoji = status === "online" ? "🟢" : "🔴"; + + const statusSpan = link.querySelector('.status-emoji'); + if (statusSpan) { + statusSpan.textContent = emoji; + } + }); +} + +function toggleFolder(folderId, buttonId) { + const folder = document.getElementById(folderId); + const button = document.getElementById(buttonId); + if (!folder || !button) return; + + if (folder.style.display === "none" || folder.style.display === "") { + folder.style.display = "block"; + button.innerHTML = button.innerHTML.replace("↓", "↑"); + + // Use cached statuses if available, otherwise fetch new ones + if (Object.keys(linkStatuses).length > 0) { + updateFolderStatuses(folder, linkStatuses); + } else { + fetch("http://localhost:5252/api/link-status") + .then(res => res.json()) + .then(statuses => { + linkStatuses = statuses; + updateFolderStatuses(folder, statuses); + }) + .catch(error => console.error("Error:", error)); + } + } else { + folder.style.display = "none"; + button.innerHTML = button.innerHTML.replace("↑", "↓"); + } +// Wait for both DOM and fetch to complete +async function init() { + try { + // Fetch the status first + console.log("Fetching statuses..."); + const response = await fetch("http://localhost:5252/api/link-status"); + const statuses = await response.json(); + console.log("Got statuses:", statuses); + + // Now update the links + document.querySelectorAll(".links a").forEach(link => { + const url = link.href; + console.log('Checking link:', url); // Debug log + const matchingUrl = Object.keys(statuses).find(statusUrl => { + const linkHostname = new URL(url).hostname; + const statusHostname = new URL(statusUrl).hostname; + console.log('Comparing:', linkHostname, 'with', statusHostname); // Debug log + return linkHostname === statusHostname; + }); + console.log('Matching URL found:', matchingUrl); // Debug log + const status = matchingUrl ? statuses[matchingUrl] : "unknown"; + console.log('Status for', url, 'is', status); // Debug log + const emoji = status === "online" ? "🟢" : "🔴"; + + // Find the span inside this link and update it + const statusSpan = link.querySelector('.status-emoji'); + if (statusSpan) { + statusSpan.textContent = emoji; + } + }); + } catch (error) { + console.error("Error:", error); + } +} +} \ No newline at end of file diff --git a/public/assets/js/scripts.js b/public/assets/js/scripts.js index e9a7a58..a2f2531 100644 --- a/public/assets/js/scripts.js +++ b/public/assets/js/scripts.js @@ -26,32 +26,9 @@ document.addEventListener('DOMContentLoaded', () => { } } -function navigateToSection(select) { - const sectionId = select.value; - if (sectionId) { - document.getElementById(sectionId).scrollIntoView({ behavior: 'smooth' }); - } -} - // Function to prefetch a URL - function prefetch(url) { - const link = document.createElement('link'); - link.rel = 'prefetch'; - link.href = url; - document.head.appendChild(link); -} - // Add event listeners to your links - const links = document.querySelectorAll('a.prefetch'); - -links.forEach(link => { - link.addEventListener('mouseenter', () => { - const url = link.href; // Get the link URL - prefetch(url); // Call prefetch function - }); -}); - - // Footer Loader and Event Listeners +// Footer Loader and Event Listeners fetch('/parts/footer.html') .then(response => response.text()) .then(data => { diff --git a/public/index.html b/public/index.html index 34baaf5..3e57b3a 100644 --- a/public/index.html +++ b/public/index.html @@ -17,8 +17,8 @@ - + @@ -40,32 +40,35 @@ - BTCforPlebs Live + BTCforPlebs Live

- + + + diff --git a/public/learn-bitcoin/index.html b/public/learn-bitcoin/index.html index bf5a12d..c8d87a3 100644 --- a/public/learn-bitcoin/index.html +++ b/public/learn-bitcoin/index.html @@ -6,7 +6,6 @@ Learn Bitcoin - @@ -194,7 +193,12 @@
🔝 - + \ No newline at end of file diff --git a/public/learn-cashu/index.html b/public/learn-cashu/index.html index 70749a1..47ba820 100644 --- a/public/learn-cashu/index.html +++ b/public/learn-cashu/index.html @@ -9,7 +9,6 @@ - @@ -107,5 +106,10 @@
🔝 - + diff --git a/public/learn-nostr/index.html b/public/learn-nostr/index.html index 8e8c7ca..0bd1ec4 100644 --- a/public/learn-nostr/index.html +++ b/public/learn-nostr/index.html @@ -48,7 +48,12 @@ 🔝 - + diff --git a/public/parts/footer.html b/public/parts/footer.html index 91f6dcf..dcd6922 100644 --- a/public/parts/footer.html +++ b/public/parts/footer.html @@ -1,6 +1,6 @@