UNPKG

peertube-plugin-static-files-light

Version:

PeerTube Plugin zum Hochladen und Verwalten statischer Dateien mit Admin-Statistiken (einfache Version)

223 lines (191 loc) 6.9 kB
class StatsRoutes { constructor(peertubeHelpers, settingsManager) { this.peertubeHelpers = peertubeHelpers; this.settingsManager = settingsManager; } async checkStatsAccess(req, res, next) { try { const user = await this.peertubeHelpers.user.getAuthUser(res); if (!user || (user.role !== 0 && user.role !== 1)) { return res.status(403).json({ status: "failure", message: "Sie haben keine Berechtigung für Statistiken" }); } req.user = user; next(); } catch (error) { res.status(401).json({ status: "failure", message: "Authentifizierung erforderlich" }); } } async getInstanceStats(req, res) { try { const { from, to, groupBy } = req.query; // Используем встроенный Date вместо moment const now = new Date(); const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1); let usersCount = 0; let usersThisMonth = 0; let videosCount = 0; let videosThisMonth = 0; let openAbusesCount = 0; let videoViewsStats = []; try { // Users count let request = await this.peertubeHelpers.database.query( 'SELECT COUNT(*) AS "count" FROM "user"', { type: "SELECT" } ); if (request && request.length > 0) { usersCount = parseInt(request[0].count) || 0; } // Users this month request = await this.peertubeHelpers.database.query( 'SELECT COUNT(*) AS "count" FROM "user" WHERE "createdAt" > $dat', { type: "SELECT", bind: { dat: startOfMonth.toISOString() } } ); if (request && request.length > 0) { usersThisMonth = parseInt(request[0].count) || 0; } // Videos count request = await this.peertubeHelpers.database.query( 'SELECT COUNT(*) AS "count" FROM "video" WHERE "remote" = $remote', { type: "SELECT", bind: { remote: false } } ); if (request && request.length > 0) { videosCount = parseInt(request[0].count) || 0; } // Videos this month request = await this.peertubeHelpers.database.query( 'SELECT COUNT(*) AS "count" FROM "video" WHERE "createdAt" > $dat AND "remote" = $remote', { type: "SELECT", bind: { dat: startOfMonth.toISOString(), remote: false } } ); if (request && request.length > 0) { videosThisMonth = parseInt(request[0].count) || 0; } // Open abuse count request = await this.peertubeHelpers.database.query( 'SELECT COUNT(*) AS "count" FROM "abuse" WHERE "state" = $state', { type: "SELECT", bind: { state: 1 } } ); if (request && request.length > 0) { openAbusesCount = parseInt(request[0].count) || 0; } // Video views stats - только если запрашиваются if (from && to) { videoViewsStats = await this.getVideoViewsStats(from, to, groupBy); } } catch (dbError) { this.peertubeHelpers.logger.error('Database query error:', dbError); // Возвращаем пустые данные вместо ошибки } res.json({ status: "success", data: { usersCount, usersThisMonth, videosCount, videosThisMonth, openAbusesCount, videoViewsStats } }); } catch (error) { this.peertubeHelpers.logger.error('Stats error:', error); res.status(500).json({ status: "failure", message: "Fehler beim Laden der Statistiken" }); } } async getVideoViewsStats(from, to, groupBy = 'day') { try { const fromDate = new Date(from); const toDate = new Date(to); // Проверяем валидность дат if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) { return []; } const request = await this.peertubeHelpers.database.query( 'SELECT "videoId", "views", "startDate" FROM "videoView" WHERE "startDate" >= $start AND "startDate" <= $end AND "videoId" IN (SELECT "id" FROM "video" WHERE "remote" = $remote) ORDER BY "startDate"', { type: "SELECT", bind: { start: fromDate.toISOString(), end: toDate.toISOString(), remote: false } } ); if (!request || request.length === 0) { return []; } return this.groupVideoViewsStats(request, groupBy); } catch (error) { this.peertubeHelpers.logger.error('Video views stats error:', error); return []; } } groupVideoViewsStats(request, groupBy) { const groupedStats = {}; for (const videoView of request) { const date = new Date(videoView.startDate); let dateKey; // Упрощенная группировка без moment switch (groupBy) { case 'month': dateKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; break; case 'year': dateKey = `${date.getFullYear()}`; break; default: // day dateKey = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } const videoKey = videoView.videoId; if (!groupedStats[dateKey]) { groupedStats[dateKey] = {}; } if (!groupedStats[dateKey][videoKey]) { groupedStats[dateKey][videoKey] = { views: 0 }; } groupedStats[dateKey][videoKey].views += parseInt(videoView.views) || 0; } // Преобразуем в массив и сортируем const videoViewsStats = Object.keys(groupedStats) .sort() // Простая сортировка строк (работает для формата YYYY-MM-DD) .map(dateKey => ({ date: dateKey, items: Object.keys(groupedStats[dateKey]).map(videoKey => ({ videoId: parseInt(videoKey), views: groupedStats[dateKey][videoKey].views })) })); return videoViewsStats; } registerRoutes(router) { router.get('/admin/stats', this.checkStatsAccess.bind(this), this.getInstanceStats.bind(this) ); } } module.exports = StatsRoutes;