UNPKG

yts-commandline

Version:

CLI (command line interface) client for YTS

266 lines (240 loc) 7.72 kB
#!/usr/bin/env node const program = require('commander') const opn = require('open') const Table = require('cli-table3') const Ora = require('ora') const querystring = require('querystring'); const colors = require('colors'); const isOnline = require('is-online'); const { movies, getMovie, getSuggestions, magnetURI } = require('./index.js') const { getTorrentLinks, getTorrentHash, availableQualities, mapTable } = require('./utils.js') // Ora default spinner const spinner = new Ora({ text: 'Loading ' }) // Init commander program program .version('1.3.0') .name('yts') .usage("[command] [option]") .description('YTS Movies CLI Client') // Default table style let tableConfig = { head: ['ID', 'Rating', 'Title', 'Available In'], colWidths: [7, 8, 35, 25], wordWrap: true, style: { 'padding-left': 1 } } let tableConfigForM = { colWidths: [15, 45], compact: true, wordWrap: true, style: { 'padding-left': 1 } } /** * listMovies * @param query String * @return Promise */ const listMovies = async (query, options) => { spinner.start(); if (!await isOnline()) { spinner.fail(' Sorry I can\'t work offline. Please enable network connectivity.'); process.exit(); } try { let queryObj = {}; if (query) { queryObj.query_term = query; } if (options.quality) { switch (options.quality) { case 'HD': queryObj.quality = '720p'; break; case 'FHD': queryObj.quality = '1080p'; break; case '4K': queryObj.quality = '2160p'; break; case '3D': queryObj.quality = '3D'; break; default: spinner.fail(" Invalid quality value."); process.exit(); //break; } } if (options.genre) { queryObj.genre = options.genre; } if (options.sort) { queryObj.sort_by = options.sort; } if (options.order) { queryObj.order_by = options.order; } if (options.minrating) { queryObj.minimum_rating = options.minrating; } if (process.stdout.columns < 100) { tableConfig.colWidths = [7, 8, process.stdout.columns - 31, 11]; } else if (process.stdout.columns > 100) { tableConfig.colWidths = [7, 8, 60, 25]; } const table = new Table(tableConfig); const qs = querystring.stringify(queryObj); const data = await movies(qs); if (!data) { spinner.fail(' No movie found.') process.exit() } if (data.length > 1) { await data.map(movie => movie.torrents ? table.push(mapTable(movie)) : null); } else { table.push(mapTable(data)) } return spinner.succeed('Done!\n' + table.toString()); } catch (error) { spinner.fail(' Something went wrong, please check your network connection and try again.\n If problem persists, please contact author.'); } } /** * movieAction * @param id Number * @return Promise */ const movieAction = async (id, options) => { spinner.start() if (!await isOnline()) { spinner.fail(' Sorry I can\'t work offline. Please enable network connectivity.'); process.exit(); } try { if (id.toString().match('^[0-9]*$') == null) { spinner.fail(' ID can be numeric value only.'); process.exit(); } if (id) { let data = await getMovie(id); if (data.id == 0) { spinner.fail(' No movie found, please verify that correct ID was passed.'); process.exit(); } const { torrents } = data; if (options.open) { await opn(data.url, { wait: true }); spinner.succeed('Done'); process.exit() } if (options.trailer) { await opn(`https://youtu.be/${data.yt_trailer_code}`, { wait: true }); spinner.succeed('Done'); process.exit() } if (options.imdb) { await opn(`http://imdb.com/title/${data.imdb_code}`, { wait: true }); spinner.succeed('Done'); process.exit() } if (options.suggest) { if (process.stdout.columns < 100) { tableConfig.colWidths = [7, 8, process.stdout.columns - 31, 11]; } else if (process.stdout.columns > 100) { tableConfig.colWidths = [7, 8, 60, 25]; } let table = new Table(tableConfig); data = await getSuggestions(id); if (data.length > 1) { await data.map(movie => movie.torrents ? table.push(mapTable(movie)) : null); } else { table.push(mapTable(data)) } return spinner.succeed('Done!\n' + table.toString()); } else if (options.download) { if (typeof options.download != "string") { spinner.info("Using default quality - 1080p"); options.download = "1080p"; } const hash = getTorrentHash(options.download, torrents); if (hash.length === 0) { spinner.fail('Could not generate a magnet link with that quality') process.exit(1); } const hashLink = magnetURI(hash, data.title_long) console.info("Magnet Link:") console.info(hashLink) await opn(hashLink, { wait: true }); spinner.succeed('Done'); process.exit() } else { tableConfigForM.colWidths = [13, process.stdout.columns - 16 > 65 ? 65 : process.stdout.columns - 16]; let table = new Table(tableConfigForM); table.push([colors.red('Title'), data.title_long]); table.push([colors.red('Rating'), data.rating]); table.push([colors.red('Genre'), data.genres.join(', ')]); data.cast ? table.push([colors.red('Cast'), data.cast.map(c => c.name).join(', ')]) : null; table.push([colors.red('Description'), data.description_full]); data.torrents ? table.push([colors.red('Available In'), data.torrents.map(t => (t.quality + ' ' + t.type).padEnd(13) + ' | ' + t.size.padEnd(10) + ' | Seeds - ' + t.seeds).join('\n')]) : null; return spinner.succeed('Done!\n' + table.toString()); } } } catch (error) { spinner.fail(' Something went wrong, please check your network connection and try again.\n If problem persists, please contact author.'); // console.error(error); } } program .command('search [query] [option]') .usage("[query] [option]") .option('-q, --quality <quality>', 'find using below supported qualities\n(HD, FHD, 4K, 3D)') .option('-g, --genre <genre>', 'find using genre, see https://www.imdb.com/feature/genre') .option('-s, --sort <sorting>', 'sorts the results by choosen value,\n(title, year, rating, peers, seeds, download_count, like_count, date_added)') .option('-o, --order <order>', 'orders the results by either ascending or descending order\n(desc, asc)') .option('-m, --minrating <rating>', 'filter movies by a given minimum IMDb rating\n(integer between 0 - 9)') .description('search movies') .alias('s') .action((id, arg, options) => listMovies(id, options)) program .command('movie <id>') .usage('<id> [option]') .option('-d, --download [quality]', 'download torrent') .option('-o, --open', 'view on YTS') .option('-t, --trailer', 'open trailer') .option('-i, --imdb', 'view movie on IMDB') .option('-s, --suggest', 'suggest 4 related movies') .description('fetch movie and perform operations like download, view trailer etc, \nuse search command to get id') .alias('m') .action((id, options) => movieAction(id, options)) // Assert that a VALID command is provided if (!process.argv.slice(2).length) { program.outputHelp(); process.exit(); } program.parse(process.argv)