UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

232 lines (221 loc) 9.68 kB
"use strict"; 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