import {db} from '../databases/databases'; import {config} from '../config'; import {Request, Response} from 'express'; import fetch from 'node-fetch'; import {Logger} from '../utils/logger'; // A cache of the number of chrome web store users let chromeUsersCache = 0; let firefoxUsersCache = 0; // By the privacy friendly user counter let apiUsersCache = 0; let lastUserCountCheck = 0; export async function getTotalStats(req: Request, res: Response) { let row = await db.prepare('get', `SELECT COUNT(DISTINCT "userID") as "userCount", COUNT(*) as "totalSubmissions", SUM("views") as "viewCount", SUM(("endTime" - "startTime") / 60 * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "shadowHidden" != 1 AND "votes" >= 0`, []); if (row !== undefined) { let extensionUsers = chromeUsersCache + firefoxUsersCache; //send this result res.send({ userCount: row.userCount, activeUsers: extensionUsers, apiUsers: Math.max(apiUsersCache, extensionUsers), viewCount: row.viewCount, totalSubmissions: row.totalSubmissions, minutesSaved: row.minutesSaved, }); // Check if the cache should be updated (every ~14 hours) let now = Date.now(); if (now - lastUserCountCheck > 5000000) { lastUserCountCheck = now; updateExtensionUsers(); } } } function updateExtensionUsers() { if (config.userCounterURL) { fetch(config.userCounterURL + "/api/v1/userCount") .then(res => res.json()) .then(data => { apiUsersCache = Math.max(apiUsersCache, data.userCount); }) .catch(() => Logger.debug("Failing to connect to user counter at: " + config.userCounterURL)); } const mozillaAddonsUrl = "https://addons.mozilla.org/api/v3/addons/addon/sponsorblock/"; const chromeExtensionUrl = "https://chrome.google.com/webstore/detail/sponsorblock-for-youtube/mnjggcdmjocbbbhaepdhchncahnbgone"; fetch(mozillaAddonsUrl) .then(res => res.json()) .then(data => { firefoxUsersCache = data.average_daily_users; fetch(chromeExtensionUrl) .then(res => res.text()) .then(body => { // 2021-01-05 // [...]= 0) { const closingQuoteIndex = body.indexOf('"', userDownloadsStartIndex + matchingStringLen); const userDownloadsStr = body.substr(userDownloadsStartIndex + matchingStringLen, closingQuoteIndex - userDownloadsStartIndex).replace(',','').replace('.',''); chromeUsersCache = parseInt(userDownloadsStr); } else { lastUserCountCheck = 0; } }) .catch(() => Logger.debug("Failing to connect to " + chromeExtensionUrl)); }) .catch(err => { Logger.debug("Failing to connect to " + mozillaAddonsUrl); }); }