UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

313 lines 12.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.StatisticsHandler = void 0; const base_handler_1 = require("./base.handler"); const statistics_service_sdk_1 = require("../services/statistics.service.sdk"); const fs = __importStar(require("fs")); const api_command_1 = require("../utils/api-command"); class StatisticsHandler extends base_handler_1.BaseHandler { constructor(authConfig, serviceConfig, statisticsService) { super(); this.statisticsService = statisticsService ?? new statistics_service_sdk_1.StatisticsServiceSdk(authConfig, serviceConfig); } async viewStatistics(options) { return this.executeWithErrorHandling(async () => { const contents = await this.statisticsService.getDailyViewStatistics(options); this.displayStatistics(contents, options.channelId, options.output); }, 'statistics.view'); } async listSessionSummary(options) { return this.executeWithErrorHandling(async () => { this.displayData(await this.statisticsService.getSessionStatsSummaryList((0, api_command_1.apiParams)(options)), options.output || 'table'); }, 'statistics.session-summary.list'); } async listInviterPoster(options) { return this.executeWithErrorHandling(async () => { this.displayData(await this.statisticsService.getInviterPosterList((0, api_command_1.apiParams)(options)), options.output || 'table'); }, 'statistics.inviter-poster.list'); } displayStatistics(contents, channelId, format = 'table') { if (contents.length === 0) { this.displayInfo(`No statistics data found for channel ${channelId}`); return; } this.displayInfo(`Statistics for channel: ${channelId}`); this.displayInfo(`Records: ${contents.length}`); if (format === 'json') { this.displayData(contents, 'json'); } else { this.displayStatisticsTable(contents); } } displayStatisticsTable(contents) { const tableData = contents.map((stat) => ({ '日期': stat.currentDay, 'PC PV': stat.pcVideoView, 'PC UV': stat.pcUniqueViewer, '移动PV': stat.mobileVideoView, '移动UV': stat.mobileUniqueViewer, 'PC播放(分钟)': stat.pcPlayDuration, '移动播放(分钟)': stat.mobilePlayDuration, })); this.displayAsTable(tableData); } async viewConcurrency(options) { return this.executeWithErrorHandling(async () => { const contents = await this.statisticsService.getConcurrencyData(options); this.displayConcurrency(contents, options.channelId, options.output); }, 'statistics.concurrency'); } displayConcurrency(contents, channelId, format = 'table') { if (contents.length === 0) { this.displayInfo(`No concurrency data found for channel ${channelId}`); return; } this.displayInfo(`Concurrency data for channel: ${channelId}`); this.displayInfo(`Records: ${contents.length}`); if (format === 'json') { this.displayData(contents, 'json'); } else { this.displayConcurrencyTable(contents); } } displayConcurrencyTable(contents) { const tableData = contents.map((item) => ({ '日期': item.day, '时间': item.minute, '并发人数': item.viewers, })); this.displayAsTable(tableData); } async viewMaxConcurrent(options) { return this.executeWithErrorHandling(async () => { const maxConcurrent = await this.statisticsService.getMaxConcurrent(options); this.displayMaxConcurrent(maxConcurrent, options, options.output); }, 'statistics.max-concurrent'); } displayMaxConcurrent(maxConcurrent, options, format = 'table') { if (format === 'json') { const result = { channelId: options.channelId, startTime: options.startTime, endTime: options.endTime, maxConcurrent, }; this.displayData(result, 'json'); } else { const startDate = new Date(options.startTime).toLocaleString('zh-CN'); const endDate = new Date(options.endTime).toLocaleString('zh-CN'); this.displayInfo(`历史最高并发人数: ${maxConcurrent}`); this.displayInfo(`时间范围: ${startDate} - ${endDate}`); } } async viewRegionDistribution(options) { return this.executeWithErrorHandling(async () => { const contents = await this.statisticsService.getRegionDistribution(options); this.displayRegion(contents, options.channelId, options.output); }, 'statistics.audience.region'); } displayRegion(contents, channelId, format = 'table') { if (contents.length === 0) { this.displayInfo(`No region distribution data found for channel ${channelId}`); return; } this.displayInfo(`Region distribution for channel: ${channelId}`); this.displayInfo(`Records: ${contents.length}`); if (format === 'json') { this.displayData(contents, 'json'); } else { this.displayRegionTable(contents); } } displayRegionTable(contents) { const tableData = contents.map((item) => ({ '地区': item.region, '播放次数': item.plays, '观众数': item.viewers, 'IP数': item.ips, '播放时长(分钟)': item.playDuration, '占比': item.percent, })); this.displayAsTable(tableData); } async viewDeviceDistribution(options) { return this.executeWithErrorHandling(async () => { const contents = await this.statisticsService.getDeviceDistribution(options); this.displayDevice(contents, options.channelId, options.output); }, 'statistics.audience.device'); } displayDevice(contents, channelId, format = 'table') { if (contents.length === 0) { this.displayInfo(`No device distribution data found for channel ${channelId}`); return; } this.displayInfo(`Device distribution for channel: ${channelId}`); this.displayInfo(`Records: ${contents.length}`); if (format === 'json') { this.displayData(contents, 'json'); } else { this.displayDeviceTable(contents); } } displayDeviceTable(contents) { const tableData = contents.map((item) => ({ '浏览器': item.name, '平台': item.platform, '播放次数': item.plays, '观众数': item.viewers, 'IP数': item.ips, '播放时长(分钟)': item.playDuration, '占比': item.percent, })); this.displayAsTable(tableData); } async exportViewlog(options) { return this.executeWithErrorHandling(async () => { const contents = await this.statisticsService.getViewlog(options); if (contents.length === 0) { this.displayInfo('No viewlog data found for the specified criteria'); return; } this.displayInfo(`观看日志导出成功`); this.displayInfo(`时间范围: ${options.startTime} - ${options.endTime}`); this.displayInfo(`总记录数: ${contents.length} 条`); if (options.output === 'json') { this.displayData(contents, 'json'); } else { this.displayInfo(`\n预览(前${Math.min(10, contents.length)}条):`); this.displayViewlogTable(contents.slice(0, 10)); } if (options.outputFile) { this.exportViewlogToCsv(contents, options.outputFile); this.displayInfo(`\n已导出到: ${options.outputFile}`); } }, 'statistics.export.viewlog'); } displayViewlogTable(contents) { const tableData = contents.map((item) => ({ '播放ID': item.playId, '观众ID': item.viewerId, '观众昵称': item.viewerName, '观看类型': item.watchType, '播放时长(秒)': item.playDuration, '停留时长(秒)': item.stayDuration, '场次ID': item.sessionId, 'IP地址': item.ipAddress, '国家/省份': item.region, '操作系统': item.operatingSystem, '浏览器': item.browser, '是否移动端': item.isMobile, '日期': item.date, })); this.displayAsTable(tableData); } exportViewlogToCsv(contents, filePath) { const headers = [ '播放ID', '观众ID', '观众昵称', '观看类型', '播放时长(秒)', '停留时长(秒)', '场次ID', 'IP地址', '国家', '省份', '城市', 'ISP', '操作系统', '浏览器', '是否移动端', '日期', '创建时间', ]; const csvRows = [headers.join(',')]; for (const item of contents) { const row = [ this.escapeCsvField(item.playId), this.escapeCsvField(item.viewerId), this.escapeCsvField(item.viewerName), this.escapeCsvField(item.watchType), item.playDuration, item.stayDuration, this.escapeCsvField(item.sessionId), this.escapeCsvField(item.ipAddress), this.escapeCsvField(item.region.split('/')[0] || ''), this.escapeCsvField(item.region.split('/')[1] || ''), '', '', this.escapeCsvField(item.operatingSystem), this.escapeCsvField(item.browser), this.escapeCsvField(item.isMobile), this.escapeCsvField(item.date), item.createdTime, ]; csvRows.push(row.join(',')); } fs.writeFileSync(filePath, '\ufeff' + csvRows.join('\n'), 'utf8'); } escapeCsvField(field) { if (field === null || field === undefined) { return ''; } const str = String(field); if (str.includes(',') || str.includes('\n') || str.includes('"')) { return `"${str.replace(/"/g, '""')}"`; } return str; } async exportSessionStats(options) { return this.executeWithErrorHandling(async () => { const result = await this.statisticsService.exportSessionStats(options); this.displayInfo(`场次报表导出成功\n`); this.displayInfo(`频道号: ${result.channelId}`); this.displayInfo(`场次号: ${result.sessionId}\n`); this.displayInfo(`下载链接: ${result.downloadUrl}`); this.displayInfo(`链接有效期: ${result.expiresIn}`); if (options.output === 'json') { this.displayData(result, 'json'); } }, 'statistics.export.session'); } } exports.StatisticsHandler = StatisticsHandler; //# sourceMappingURL=statistics.handler.js.map