UNPKG

cloudapp-dl

Version:

CloudApp/Zight API client and CLI. Use as a CLI tool to download videos or as a programmatic library to interact with the Zight API.

521 lines (489 loc) 15.9 kB
#!/usr/bin/env node import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; import { handleLogin, handleLogout, handleAccount, handleConfig, handleList, handleWhoami, handleExport, handleDownloadById, handleDownloadByUrl, handleDownloadList, handleBulkDownload, handleVideoRequest, handleVideoRequestQuick, handleCollections, handleRequestsList, handleRequestEdit, handleRequestDelete, handleRequestDetails, handleRequestDownload, handleUpload, handleBulkUpload, handleDelete, handleRestore, handleTrash, handleEmptyTrash, handleNotifications, handleMarkNotificationsRead } from './lib/commands.js'; // Configure yargs with commands const argv = yargs(hideBin(process.argv)) .scriptName('cloudapp-dl') .usage('$0 <command> [options]') // Login command .command('login', 'Login to your Zight account', (yargs) => { return yargs .option('email', { alias: 'e', type: 'string', description: 'Your Zight email address' }) .option('password', { alias: 'p', type: 'string', description: 'Your Zight password' }); }, handleLogin) // Logout command .command('logout', 'Logout and clear session', () => {}, handleLogout) // Account command .command('account', 'Display your Zight account details', () => {}, handleAccount) // Whoami command .command('whoami', 'Show current login status', () => {}, handleWhoami) // Config command .command('config', 'View or manage configuration', (yargs) => { return yargs .option('clear', { type: 'boolean', description: 'Clear all configuration data' }) .option('path', { type: 'boolean', description: 'Show config file path' }); }, handleConfig) // List command .command('list', 'List your drops/files from Zight', (yargs) => { return yargs .option('page', { type: 'number', default: 1, description: 'Page number' }) .option('per-page', { alias: 'perPage', type: 'number', default: 12, description: 'Items per page (multiples of 12). Multiple pages fetched with delays.' }); }, handleList) // Export command .command('export', 'Export items to CSV file', (yargs) => { return yargs .option('out', { alias: 'o', type: 'string', description: 'Output CSV file path (default: zight-export-YYYY-MM-DD.csv)' }) .option('start-page', { alias: 'startPage', type: 'number', description: 'Start from this page (default: 1)' }) .option('end-page', { alias: 'endPage', type: 'number', description: 'End at this page (default: last page)' }); }, handleExport) // Get command - download a single file by ID .command('get <id>', 'Download a single file by ID', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The file ID to download (e.g., WnuPyJR5)' }) .option('out', { alias: 'o', type: 'string', default: '.', description: 'Output directory' }) .option('no-title', { type: 'boolean', description: 'Use file ID as filename instead of title' }); }, (argv) => handleDownloadById({ ...argv, title: !argv.noTitle })) // Download command - download a single file by URL .command('download <url>', 'Download a single file by URL', (yargs) => { return yargs .positional('url', { type: 'string', description: 'The Zight share URL (e.g., https://share.zight.com/ABC123)' }) .option('out', { alias: 'o', type: 'string', default: '.', description: 'Output directory' }) .option('no-title', { type: 'boolean', description: 'Use file ID as filename instead of title' }); }, (argv) => handleDownloadByUrl({ ...argv, title: !argv.noTitle })) // Download list command - download multiple files from a URL list .command('download-list <file>', 'Download multiple files from a URL list file', (yargs) => { return yargs .positional('file', { type: 'string', description: 'Path to text file containing URLs (one per line)' }) .option('out', { alias: 'o', type: 'string', default: './downloads', description: 'Output directory for downloaded files' }) .option('prefix', { alias: 'p', type: 'string', description: 'Prefix for filenames (e.g., "video" → video-1.mp4, video-2.mp4)' }) .option('timeout', { alias: 't', type: 'number', default: 2000, description: 'Delay between downloads in milliseconds' }) .option('no-title', { type: 'boolean', description: 'Use file IDs as filenames instead of titles' }); }, (argv) => handleDownloadList({ ...argv, title: !argv.noTitle })) // Bulk download command - download from account .command('bulk-download', 'Bulk download files from your Zight account', (yargs) => { return yargs .option('out', { alias: 'o', type: 'string', default: './downloads', description: 'Output directory for downloaded files' }) .option('start-page', { alias: 'startPage', type: 'number', description: 'Start from this page (default: 1)' }) .option('end-page', { alias: 'endPage', type: 'number', description: 'End at this page (default: last page)' }) .option('limit', { type: 'number', description: 'Maximum number of files to download' }) .option('videos-only', { alias: 'videosOnly', type: 'boolean', description: 'Only download video files' }) .option('timeout', { alias: 't', type: 'number', default: 2000, description: 'Delay between downloads in milliseconds' }) .option('no-title', { type: 'boolean', description: 'Use file IDs as filenames instead of titles' }); }, (argv) => handleBulkDownload({ ...argv, title: !argv.noTitle })) // Video request command - create a link for others to record a video .command('request', 'Create a video recording request link (interactive)', (yargs) => { return yargs .option('title', { alias: 't', type: 'string', description: 'Title for the request' }) .option('message', { alias: 'm', type: 'string', description: 'Message/instructions for the recorder' }) .option('custom-id', { alias: 'customId', type: 'string', description: 'Custom identifier for the request' }) .option('expires', { alias: 'e', type: 'string', description: 'Expiration date (e.g., "12/31/2025 5:00pm")' }) .option('collection', { alias: 'c', type: 'string', description: 'Collection ID to add recordings to' }); }, handleVideoRequest) // Quick video request command - instant generation .command('request-quick', 'Instantly create a video request link', (yargs) => { return yargs .option('title', { alias: 't', type: 'string', description: 'Custom title (default: "[email] needs your help with a short video.")' }) .option('message', { alias: 'm', type: 'string', description: 'Custom message (default: generic help message)' }) .option('custom-id', { alias: 'customId', type: 'string', description: 'Custom identifier for the request' }) .option('expires', { alias: 'e', type: 'string', description: 'Expiration date (e.g., "12/31/2025 5:00pm")' }) .option('collection', { alias: 'c', type: 'string', description: 'Collection ID to add recordings to' }); }, handleVideoRequestQuick) // Collections command - list your collections .command('collections', 'List your collections', () => {}, handleCollections) // List video requests command .command('requests', 'List your video recording requests', (yargs) => { return yargs .option('verbose', { alias: 'v', type: 'boolean', description: 'Show full request links' }); }, handleRequestsList) // Edit video request command .command('request-edit <id>', 'Edit a video recording request', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The request ID to edit' }) .option('title', { alias: 't', type: 'string', description: 'New title' }) .option('message', { alias: 'm', type: 'string', description: 'New message' }) .option('custom-id', { alias: 'customId', type: 'string', description: 'New custom identifier' }) .option('expires', { alias: 'e', type: 'string', description: 'New expiration date (e.g., "12/31/2025 5:00pm" or "never")' }) .option('collection', { alias: 'c', type: 'string', description: 'New collection ID (empty string to remove)' }); }, handleRequestEdit) // Delete video request command .command('request-delete <id>', 'Delete a video recording request', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The request ID to delete' }) .option('yes', { alias: 'y', type: 'boolean', description: 'Skip confirmation prompt' }); }, handleRequestDelete) // Request details command - show items in a request .command('request-details <id>', 'Show details and items for a video request', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The request ID to view' }) .option('verbose', { alias: 'v', type: 'boolean', description: 'Show download URLs for each item' }); }, handleRequestDetails) // Request download command - download all items from a request .command('request-download <id>', 'Download all items from a video request', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The request ID to download items from' }) .option('out', { alias: 'o', type: 'string', description: 'Output directory', default: '.' }) .option('timeout', { alias: 't', type: 'number', description: 'Delay between downloads in ms', default: 2000 }); }, handleRequestDownload) // Upload a single file .command('upload <file>', 'Upload a file to Zight', (yargs) => { return yargs .positional('file', { type: 'string', description: 'Path to the file to upload' }); }, handleUpload) // Bulk upload files .command('bulk-upload <path>', 'Upload multiple files from a directory', (yargs) => { return yargs .positional('path', { type: 'string', description: 'Path to file or directory to upload' }) .option('timeout', { alias: 't', type: 'number', description: 'Delay between uploads in ms', default: 2000 }); }, handleBulkUpload) // Delete a file .command('delete <id>', 'Delete a file (move to trash)', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The item ID to delete' }) .option('permanent', { type: 'boolean', description: 'Permanently delete (no recovery)', default: false }) .option('yes', { alias: 'y', type: 'boolean', description: 'Skip confirmation prompt' }); }, handleDelete) // List trash .command('trash', 'List items in trash', () => {}, handleTrash) // Restore from trash .command('restore <id>', 'Restore a file from trash', (yargs) => { return yargs .positional('id', { type: 'string', description: 'The item ID to restore' }); }, handleRestore) // Empty trash .command('empty-trash', 'Permanently delete all items in trash', (yargs) => { return yargs .option('yes', { alias: 'y', type: 'boolean', description: 'Skip confirmation prompt' }); }, handleEmptyTrash) // Notifications .command('notifications', 'View your notifications', (yargs) => { return yargs .option('limit', { alias: 'l', type: 'number', description: 'Number of notifications to show', default: 20 }) .option('all', { alias: 'a', type: 'boolean', description: 'Show all notifications (read and unread)' }) .option('unread', { alias: 'u', type: 'boolean', description: 'Show only unread notifications' }) .option('verbose', { alias: 'v', type: 'boolean', description: 'Show action links' }) .option('mark-read', { type: 'boolean', description: 'Mark all notifications as read' }); }, (argv) => { if (argv.markRead) { handleMarkNotificationsRead(argv); } else { handleNotifications(argv); } }) // Help command .command('help', 'Show help information', () => {}, () => { yargs(hideBin(process.argv)).showHelp(); }) .example('$0 login', 'Login to your Zight account') .example('$0 account', 'View your account details') .example('$0 list', 'List your drops/files') .example('$0 list --per-page 48', 'List 48 items per page') .example('$0 export', 'Export ALL items to CSV') .example('$0 export --start-page 1 --end-page 10', 'Export pages 1-10 to CSV') .example('$0 get WnuPyJR5', 'Download a file by ID') .example('$0 download https://share.zight.com/ABC123', 'Download a file by URL') .example('$0 download-list urls.txt', 'Download files from a URL list') .example('$0 download-list urls.txt --out ./videos', 'Download to specific directory') .example('$0 bulk-download', 'Download ALL files from your account') .example('$0 bulk-download --limit 50', 'Download first 50 files') .example('$0 bulk-download --videos-only', 'Download only video files') .example('$0 request', 'Create a video request (interactive)') .example('$0 request-quick', 'Instantly create a request with defaults') .example('$0 requests', 'List all your video requests') .example('$0 request-details wgsX51', 'View request details and submitted items') .example('$0 request-download wgsX51', 'Download all items from a request') .example('$0 request-edit ABC123 --title "New Title"', 'Edit a request') .example('$0 request-delete ABC123', 'Delete a request') .example('$0 upload ./video.mp4', 'Upload a file') .example('$0 bulk-upload ./screenshots/', 'Upload all files in a directory') .example('$0 delete WnuPyJR5', 'Move a file to trash') .example('$0 delete WnuPyJR5 --permanent', 'Permanently delete a file') .example('$0 trash', 'List items in trash') .example('$0 restore WnuPyJR5', 'Restore a file from trash') .example('$0 empty-trash', 'Permanently delete all trash items') .example('$0 notifications', 'View notifications') .example('$0 notifications --unread', 'View only unread notifications') .example('$0 notifications --mark-read', 'Mark all notifications as read') .example('$0 collections', 'List your collections') .help() .alias('help', 'h') .version() .alias('version', 'v') .wrap(100) .argv;