add video backend server, fix styling and more #54
+79
-26
@@ -4,16 +4,65 @@ const moment = require("moment-timezone");
|
|||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
let latestCommitCache = null;
|
|
||||||
let lastFetchedTime = 0;
|
|
||||||
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
|
const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes in milliseconds
|
||||||
|
const TIMEZONE = "America/New_York";
|
||||||
|
|
||||||
|
// Cache is stored in the exact response shape expected by the client.
|
||||||
|
let latestCommitCache = null;
|
||||||
|
|
||||||
|
// Avoid noisy logs when GitHub isn't configured or is temporarily unavailable.
|
||||||
|
let lastLogTime = 0;
|
||||||
|
const LOG_THROTTLE_MS = 60 * 60 * 1000; // 1h
|
||||||
|
|
||||||
|
function nowFormatted() {
|
||||||
|
return moment(Date.now()).tz(TIMEZONE).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGitHubConfig() {
|
||||||
|
const owner = typeof process.env.GITHUB_OWNER === "string" ? process.env.GITHUB_OWNER.trim() : "";
|
||||||
|
const repo = typeof process.env.GITHUB_REPO === "string" ? process.env.GITHUB_REPO.trim() : "";
|
||||||
|
return { owner, repo, configured: !!owner && !!repo };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPackageVersion() {
|
||||||
|
try {
|
||||||
|
// routes/version.js -> ../package.json
|
||||||
|
const pkg = require("../package.json");
|
||||||
|
return typeof pkg?.version === "string" && pkg.version.trim() ? pkg.version.trim() : "dev";
|
||||||
|
} catch (_) {
|
||||||
|
return "dev";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFallbackCache(message, { configured } = { configured: false }) {
|
||||||
|
latestCommitCache = {
|
||||||
|
version: getPackageVersion(),
|
||||||
|
message: message || "Version info not available.",
|
||||||
|
author: "",
|
||||||
|
date: nowFormatted(),
|
||||||
|
configured: !!configured,
|
||||||
|
source: "fallback",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function logThrottled(...args) {
|
||||||
|
const t = Date.now();
|
||||||
|
if (t - lastLogTime < LOG_THROTTLE_MS) return;
|
||||||
|
lastLogTime = t;
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(...args);
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchLatestCommitFromGitHub() {
|
async function fetchLatestCommitFromGitHub() {
|
||||||
const githubOwner = process.env.GITHUB_OWNER;
|
const { owner, repo, configured } = getGitHubConfig();
|
||||||
const githubRepo = process.env.GITHUB_REPO;
|
if (!configured) {
|
||||||
|
// Never attempt GitHub calls if not configured.
|
||||||
|
setFallbackCache("Version endpoint is not configured.", { configured: false });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = `https://api.github.com/repos/${githubOwner}/${githubRepo}/commits`;
|
const url = `https://api.github.com/repos/${owner}/${repo}/commits`;
|
||||||
const response = await axios.get(url, {
|
const response = await axios.get(url, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -23,40 +72,44 @@ async function fetchLatestCommitFromGitHub() {
|
|||||||
if (response.data && response.data.length > 0) {
|
if (response.data && response.data.length > 0) {
|
||||||
const latestCommit = response.data[0];
|
const latestCommit = response.data[0];
|
||||||
latestCommitCache = {
|
latestCommitCache = {
|
||||||
sha: latestCommit.sha,
|
version: String(latestCommit.sha || "").substring(0, 5),
|
||||||
message: latestCommit.commit.message,
|
message: latestCommit?.commit?.message || "",
|
||||||
author: latestCommit.commit.author.name,
|
author: latestCommit?.commit?.author?.name || "",
|
||||||
date: latestCommit.commit.author.date,
|
date: moment(latestCommit?.commit?.author?.date || Date.now())
|
||||||
|
.tz(TIMEZONE)
|
||||||
|
.format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
configured: true,
|
||||||
|
source: "github",
|
||||||
};
|
};
|
||||||
lastFetchedTime = Date.now();
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("No commits found.");
|
throw new Error("No commits found.");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching commit:", error.message);
|
// Keep serving a non-500 response, and don't spam logs.
|
||||||
|
logThrottled("Error fetching commit:", error?.message || error);
|
||||||
|
setFallbackCache("GitHub commit data is not available.", { configured: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial fetch to populate cache
|
// Initialize cache (without crashing / spamming when not configured).
|
||||||
fetchLatestCommitFromGitHub();
|
const initialCfg = getGitHubConfig();
|
||||||
|
if (!initialCfg.configured) {
|
||||||
// Refresh cache every 5 minutes
|
setFallbackCache("Version endpoint is not configured.", { configured: false });
|
||||||
setInterval(fetchLatestCommitFromGitHub, CACHE_DURATION);
|
} else {
|
||||||
|
fetchLatestCommitFromGitHub();
|
||||||
|
const timer = setInterval(fetchLatestCommitFromGitHub, CACHE_DURATION);
|
||||||
|
// Don't keep the process alive just for this polling.
|
||||||
|
if (typeof timer.unref === "function") timer.unref();
|
||||||
|
}
|
||||||
|
|
||||||
// Route to get the latest commit (cached)
|
// Route to get the latest commit (cached)
|
||||||
router.get("/", async (req, res) => {
|
router.get("/", async (req, res) => {
|
||||||
|
// Always return something (client clears footer on non-2xx).
|
||||||
if (!latestCommitCache) {
|
if (!latestCommitCache) {
|
||||||
return res.status(500).json({ message: "Commit data is not available yet." });
|
const cfg = getGitHubConfig();
|
||||||
|
setFallbackCache("Version info not available.", { configured: cfg.configured });
|
||||||
}
|
}
|
||||||
|
return res.status(200).json(latestCommitCache);
|
||||||
res.json({
|
|
||||||
version: latestCommitCache.sha.substring(0, 5),
|
|
||||||
message: latestCommitCache.message,
|
|
||||||
author: latestCommitCache.author,
|
|
||||||
date: moment(latestCommitCache.date)
|
|
||||||
.tz("America/New_York")
|
|
||||||
.format("YYYY-MM-DD HH:mm:ss"),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
Reference in New Issue
Block a user