polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
313 lines • 12.9 kB
JavaScript
;
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