polyv-live-cli
Version:
CLI tool for managing PolyV live streaming services.
232 lines (221 loc) • 9.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateOutputFormat = validateOutputFormat;
exports.validateDateTimeFormat = validateDateTimeFormat;
exports.validateWatchType = validateWatchType;
exports.validateSameMonth = validateSameMonth;
exports.registerStatisticsExportCommands = registerStatisticsExportCommands;
const statistics_handler_1 = require("../handlers/statistics.handler");
const manager_1 = require("../config/manager");
const auth_adapter_1 = require("../config/auth-adapter");
const errors_1 = require("../utils/errors");
async function loadAuthAndServiceConfig(parentOptions) {
const authResult = auth_adapter_1.authAdapter.tryGetAuthConfig(parentOptions);
if (!authResult) {
throw new Error(auth_adapter_1.authAdapter.getStatusMessage(parentOptions));
}
let configResult;
try {
configResult = await manager_1.configManager.load({
cliOptions: parentOptions,
});
}
catch (error) {
if (error instanceof Error && error.message.includes('Auth configuration is incomplete')) {
configResult = {
config: {
baseUrl: 'https://api.polyv.net',
timeout: 30000,
debug: false
}
};
}
else {
throw error;
}
}
const serviceConfig = {
baseUrl: configResult.config.baseUrl,
timeout: configResult.config.timeout,
debug: configResult.config.debug
};
const isVerbose = !!parentOptions.verbose;
if (isVerbose) {
console.log(`Authentication Source: ${authResult.source}`);
if (authResult.accountName) {
console.log(`Account: ${authResult.accountName}`);
}
console.log('');
}
const result = {
authConfig: authResult.config,
serviceConfig,
isVerbose,
};
if (authResult.source) {
result.authSource = authResult.source;
}
if (authResult.accountName) {
result.accountName = authResult.accountName;
}
return result;
}
function validateOutputFormat(value) {
if (!['table', 'json'].includes(value)) {
throw new Error('Output format must be either "table" or "json"');
}
return value;
}
function validateDateTimeFormat(value) {
const regex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
if (!regex.test(value)) {
throw new Error('DateTime format must be yyyy-MM-dd HH:mm:ss');
}
const date = new Date(value);
if (isNaN(date.getTime())) {
throw new Error(`Invalid datetime: ${value}`);
}
return value;
}
function validateWatchType(value) {
if (!['live', 'vod'].includes(value)) {
throw new Error('watchType must be either "live" or "vod"');
}
return value;
}
function validateSameMonth(startDate, endDate) {
const startMonth = startDate.substring(0, 7);
const endMonth = endDate.substring(0, 7);
if (startMonth !== endMonth) {
throw new Error('startDate and endDate must be in the same month');
}
}
function registerStatisticsExportCommands(program) {
const statisticsCmd = program.commands.find((cmd) => cmd.name() === 'statistics');
if (!statisticsCmd) {
return;
}
const exportCmd = statisticsCmd.command('export');
exportCmd.description('export statistics data');
const viewlogCmd = exportCmd
.command('viewlog')
.description('Export channel viewlog (观看日志) data')
.requiredOption('-c, --channel-id <channelId>', 'Channel ID')
.requiredOption('--start-time <datetime>', 'Start time (yyyy-MM-dd HH:mm:ss)', validateDateTimeFormat)
.requiredOption('--end-time <datetime>', 'End time (yyyy-MM-dd HH:mm:ss)', validateDateTimeFormat)
.option('--watch-type <type>', 'Watch type filter (live or vod)', validateWatchType)
.option('-o, --output <format>', 'Output format (table or json)', validateOutputFormat, 'table')
.option('--output-file <path>', 'Output CSV file path for export')
.action(async (options) => {
try {
validateSameMonth(options.startTime, options.endTime);
const parentOptions = program.opts();
const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
const viewlogOptions = {
channelId: options.channelId,
startTime: options.startTime,
endTime: options.endTime,
output: options.output,
};
if (options.watchType) {
viewlogOptions.watchType = options.watchType;
}
if (options.outputFile) {
viewlogOptions.outputFile = options.outputFile;
}
await statisticsHandler.exportViewlog(viewlogOptions);
}
catch (error) {
if (error instanceof Error && error.message.includes('Authentication')) {
const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
console.error('\nAuthentication Diagnostics:');
diagnostics.availableSources.forEach(source => {
const status = source.appId && source.appSecret ? 'OK' : 'X';
console.error(` ${status} ${source.metadata.source}: ${source.type}`);
});
if (diagnostics.errors.length > 0) {
console.error('\nErrors:');
diagnostics.errors.forEach(err => console.error(` - ${err}`));
}
}
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
viewlogCmd.addHelpText('after', `
Examples:
# Export viewlog data for a channel
$ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59"
# Export with watch type filter
$ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --watch-type live
# Export to CSV file
$ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --output-file ./viewlog.csv
# Output in JSON format
$ polyv-live-cli statistics export viewlog -c "3151318" --start-time "2024-01-01 00:00:00" --end-time "2024-01-31 23:59:59" --output json
DateTime Format:
--start-time Start time in yyyy-MM-dd HH:mm:ss format (required)
--end-time End time in yyyy-MM-dd HH:mm:ss format (required)
Note: Start and end time must be in the same month
Watch Types:
live Live streaming
vod Video on demand (playback)
Output Formats:
table Formatted table output (default)
json JSON format for programmatic use
Output Options:
--output-file Path to save CSV file with Chinese headers
`);
const sessionCmd = exportCmd
.command('session')
.description('Export channel session statistics report - 场次报表 (returns download link)')
.requiredOption('-c, --channel-id <channelId>', 'Channel ID')
.requiredOption('--session-id <sessionId>', 'Session ID')
.option('-o, --output <format>', 'Output format (table or json)', validateOutputFormat, 'table')
.action(async (options) => {
try {
const parentOptions = program.opts();
const { authConfig, serviceConfig } = await loadAuthAndServiceConfig(parentOptions);
const statisticsHandler = new statistics_handler_1.StatisticsHandler(authConfig, serviceConfig);
const sessionOptions = {
channelId: options.channelId,
sessionId: options.sessionId,
output: options.output,
};
await statisticsHandler.exportSessionStats(sessionOptions);
}
catch (error) {
if (error instanceof Error && error.message.includes('Authentication')) {
const diagnostics = auth_adapter_1.authAdapter.getDiagnostics(program.opts());
console.error('\nAuthentication Diagnostics:');
diagnostics.availableSources.forEach(source => {
const status = source.appId && source.appSecret ? '[OK]' : '[FAIL]';
console.error(` ${status} ${source.metadata.source}: ${source.type}`);
});
if (diagnostics.errors.length > 0) {
console.error('\nErrors:');
diagnostics.errors.forEach(err => console.error(` - ${err}`));
}
}
(0, errors_1.logError)(error instanceof Error ? error : new Error(String(error)));
process.exit(1);
}
});
sessionCmd.addHelpText('after', `
Examples:
# Export session statistics report
$ polyv-live-cli statistics export session -c "3151318" --session-id "fv3ma84e63"
# Output in JSON format
$ polyv-live-cli statistics export session -c "3151318" --session-id "fv3ma84e63" --output json
Parameters:
--channel-id Channel ID (required)
--session-id Session ID (required)
Output Formats:
table Formatted table output (default)
json JSON format for programmatic use
Notes:
- Returns a download URL for the session report
- Download link is valid for 60 days
`);
}
//# sourceMappingURL=statistics.commands.export.js.map