diff --git a/README.md b/README.md index a5dcc3b..980ed22 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ https://user-images.githubusercontent.com/56788883/181006153-f1d41833-fc60-43e0- - Debian based distributions `sudo add-apt-repository ppa:mc3man/mpv-tests` `sudo apt update && sudo apt install mpv` + - [Update] For Ubuntu 22.04 +`sudo apt install mpv` - Windows [Follow This link](https://mpv.io/installation/#:~:text=master%20is%20recommended.-,Windows,-All%20binary%20packages) @@ -36,6 +38,8 @@ https://user-images.githubusercontent.com/56788883/181006153-f1d41833-fc60-43e0- Quran-CLI Listen to the Quran from your terminal + While listening press P to toggle between pause and resume + Press q to exit Options @@ -67,4 +71,4 @@ Options - Install typescript using: `npm install -g typescript` if you do not have typescript globally - Install dependencies: `npm install` - Build the source files: `npm run build` -- Run the index: `node src/index.js [options]` +- Run the index: `node bin/index.js [options]` diff --git a/lib/modes/radioMode/radioMode.js b/lib/modes/radioMode/radioMode.js index 0834470..1b55ee0 100644 --- a/lib/modes/radioMode/radioMode.js +++ b/lib/modes/radioMode/radioMode.js @@ -14,7 +14,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -36,20 +36,21 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.runRadio = exports.showAllRadios = void 0; var node_fetch_1 = require("node-fetch"); var helperFunctions_1 = require("../../utilities/helperFunctions"); var url = "https://api.mp3quran.net/radios/radio_english.json"; function getData() { try { - helperFunctions_1.print("Fetching data...", "cyan"); - return node_fetch_1.default(url) + (0, helperFunctions_1.print)("Fetching data...", "cyan"); + return (0, node_fetch_1.default)(url) .then(function (res) { return res.json(); }) .then(function (res) { return res['radios']; }); } catch (err) { - helperFunctions_1.print("No available Internet connection", "red"); + (0, helperFunctions_1.print)("No available Internet connection", "red"); process.exit(1); } } @@ -85,9 +86,9 @@ function getSpecificRadioData(radioIndex) { } function showAllRadios() { getRadioNamesList().then(function (res) { - helperFunctions_1.showListIndex(res, 'Radio Index', 'Name'); + (0, helperFunctions_1.showListIndex)(res, 'Radio Index', 'Name'); }).catch(function (err) { - helperFunctions_1.raiseError("SHOW_ALL_RADIOS", "Error while showing all the radios"); + (0, helperFunctions_1.raiseError)("SHOW_ALL_RADIOS", "Error while showing all the radios"); }); } exports.showAllRadios = showAllRadios; @@ -104,7 +105,7 @@ function runRadio(radioIndex) { return [4, data['name']]; case 2: radioName = _b.sent(); - helperFunctions_1.print("Radio Channel: " + radioName, "green"); + (0, helperFunctions_1.print)("Radio Channel: ".concat(radioName), "green"); _a = helperFunctions_1.runFromURL; return [4, data['radio_url']]; case 3: @@ -116,7 +117,7 @@ function runRadio(radioIndex) { case 5: list = _b.sent(); errMsg = "Please, enter an index from 0 to " + (list.length - 1) + "\nYou can list all the radio channels using the '-n' option."; - helperFunctions_1.raiseError("INVALID_VALUE", errMsg); + (0, helperFunctions_1.raiseError)("INVALID_VALUE", errMsg); return [3, 6]; case 6: return [2]; } diff --git a/lib/modes/reciterMode/reciterMode.js b/lib/modes/reciterMode/reciterMode.js index 6271930..bb3220b 100644 --- a/lib/modes/reciterMode/reciterMode.js +++ b/lib/modes/reciterMode/reciterMode.js @@ -14,7 +14,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -36,6 +36,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { } }; Object.defineProperty(exports, "__esModule", { value: true }); +exports.runSurah = exports.showReciterAvailableSuras = exports.getReciterAvailableSuras = exports.showAllReciters = void 0; var node_fetch_1 = require("node-fetch"); var helperFunctions_1 = require("../../utilities/helperFunctions"); var data_2 = require("../../utilities/data"); @@ -47,8 +48,8 @@ function getData() { switch (_a.label) { case 0: _a.trys.push([0, 3, , 4]); - helperFunctions_1.print("Fetching data...", "cyan"); - return [4, node_fetch_1.default(url)]; + (0, helperFunctions_1.print)("Fetching data...", "cyan"); + return [4, (0, node_fetch_1.default)(url)]; case 1: data = _a.sent(); return [4, data.json()]; @@ -57,7 +58,7 @@ function getData() { return [2, data_1['reciters']]; case 3: err_1 = _a.sent(); - helperFunctions_1.print("No available Internet connection", "red"); + (0, helperFunctions_1.print)("No available Internet connection", "red"); process.exit(1); return [3, 4]; case 4: return [2]; @@ -98,10 +99,10 @@ function getSpecificReciterData(reciterIndex) { function showAllReciters() { getReciterNamesList() .then(function (res) { - helperFunctions_1.showListIndex(res, 'Reciter Index', 'Name'); + (0, helperFunctions_1.showListIndex)(res, 'Reciter Index', 'Name'); }) .catch(function (err) { - helperFunctions_1.raiseError("SHOW_ALL_RECITERS", "Error while showing all the reciters"); + (0, helperFunctions_1.raiseError)("SHOW_ALL_RECITERS", "Error while showing all the reciters"); }); } exports.showAllReciters = showAllReciters; @@ -144,11 +145,11 @@ function showReciterAvailableSuras(reciterIndex) { return [4, getReciterAvailableSuras(reciterIndex)]; case 1: availableSuras = _a.sent(); - helperFunctions_1.showListIndex(availableSuras, 'Surah Index', 'Name', true); + (0, helperFunctions_1.showListIndex)(availableSuras, 'Surah Index', 'Name', true); return [3, 3]; case 2: err_2 = _a.sent(); - helperFunctions_1.raiseError("INVALID_VALUE", "Reciter not available, you can list the available reciters using the '-r' option."); + (0, helperFunctions_1.raiseError)("INVALID_VALUE", "Reciter not available, you can list the available reciters using the '-r' option."); return [3, 3]; case 3: return [2]; } @@ -172,7 +173,7 @@ function runSurah(reciterIndex, surahIndex) { if (surahIndex > reciterData['suras'].split(",").length) { throw new Error("Surah not available, you can check the available suras for the specified reciter by passing the reciter index only to the '-c' option."); } - helperFunctions_1.print("Reciter: " + reciterName + ", Surah: " + data_2.surasDictionary[surahIndex], "green"); + (0, helperFunctions_1.print)("Reciter: ".concat(reciterName, ", Surah: ").concat(data_2.surasDictionary[surahIndex]), "green"); _a = helperFunctions_1.runFromURL; return [4, getSurahURL(reciterIndex, surahIndex)]; case 3: @@ -181,9 +182,9 @@ function runSurah(reciterIndex, surahIndex) { case 4: err_3 = _b.sent(); if (data_2.surasDictionary[surahIndex] === undefined) - helperFunctions_1.raiseError("INVALID_VALUE", "Surah not available, you can check the available suras for the specified reciter by passing the reciter index only to the '-c' option."); + (0, helperFunctions_1.raiseError)("INVALID_VALUE", "Surah not available, you can check the available suras for the specified reciter by passing the reciter index only to the '-c' option."); else - helperFunctions_1.raiseError("INVALID_VALUE", "Reciter not available, you can list the available reciters using the '-r' option."); + (0, helperFunctions_1.raiseError)("INVALID_VALUE", "Reciter not available, you can list the available reciters using the '-r' option."); return [3, 5]; case 5: return [2]; } diff --git a/lib/utilities/data.js b/lib/utilities/data.js index dc6ba3d..cbf7699 100644 --- a/lib/utilities/data.js +++ b/lib/utilities/data.js @@ -1,3 +1,4 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.surasDictionary = void 0; exports.surasDictionary = { 1: 'Al-Faatiha', 2: 'Al-Baqara', 3: 'Aal-i-Imraan', 4: 'An-Nisaa', 5: 'Al-Maaida', 6: "Al-An'aam", 7: "Al-A'raaf", 8: 'Al-Anfaal', 9: 'At-Tawba', 10: 'Yunus', 11: 'Hud', 12: 'Yusuf', 13: "Ar-Ra'd", 14: 'Ibrahim', 15: 'Al-Hijr', 16: 'An-Nahl', 17: 'Al-Israa', 18: 'Al-Kahf', 19: 'Maryam', 20: 'Taa-Haa', 21: 'Al-Anbiyaa', 22: 'Al-Hajj', 23: 'Al-Muminoon', 24: 'An-Noor', 25: 'Al-Furqaan', 26: "Ash-Shu'araa", 27: 'An-Naml', 28: 'Al-Qasas', 29: 'Al-Ankaboot', 30: 'Ar-Room', 31: 'Luqman', 32: 'As-Sajda', 33: 'Al-Ahzaab', 34: 'Saba', 35: 'Faatir', 36: 'Yaseen', 37: 'As-Saaffaat', 38: 'Saad', 39: 'Az-Zumar', 40: 'Al-Ghaafir', 41: 'Fussilat', 42: 'Ash-Shura', 43: 'Az-Zukhruf', 44: 'Ad-Dukhaan', 45: 'Al-Jaathiya', 46: 'Al-Ahqaf', 47: 'Muhammad', 48: 'Al-Fath', 49: 'Al-Hujuraat', 50: 'Qaaf', 51: 'Adh-Dhaariyat', 52: 'At-Tur', 53: 'An-Najm', 54: 'Al-Qamar', 55: 'Ar-Rahmaan', 56: 'Al-Waaqia', 57: 'Al-Hadid', 58: 'Al-Mujaadila', 59: 'Al-Hashr', 60: 'Al-Mumtahana', 61: 'As-Saff', 62: "Al-Jumu'a", 63: 'Al-Munaafiqoon', 64: 'At-Taghaabun', 65: 'At-Talaaq', 66: 'At-Tahrim', 67: 'Al-Mulk', 68: 'Al-Qalam', 69: 'Al-Haaqqa', 70: "Al-Ma'aarij", 71: 'Nooh', 72: 'Al-Jinn', 73: 'Al-Muzzammil', 74: 'Al-Muddaththir', 75: 'Al-Qiyaama', 76: 'Al-Insaan', 77: 'Al-Mursalaat', 78: 'An-Naba', 79: "An-Naazi'aat", 80: 'Abasa', 81: 'At-Takwir', 82: 'Al-Infitaar', 83: 'Al-Mutaffifin', 84: 'Al-Inshiqaaq', 85: 'Al-Burooj', 86: 'At-Taariq', 87: "Al-A'laa", 88: 'Al-Ghaashiya', 89: 'Al-Fajr', 90: 'Al-Balad', 91: 'Ash-Shams', 92: 'Al-Lail', 93: 'Ad-Dhuhaa', 94: 'Ash-Sharh', 95: 'At-Tin', 96: 'Al-Alaq', 97: 'Al-Qadr', 98: 'Al-Bayyina', 99: 'Az-Zalzala', 100: 'Al-Aadiyaat', 101: "Al-Qaari'a", 102: 'At-Takaathur', 103: 'Al-Asr', 104: 'Al-Humaza', 105: 'Al-Fil', 106: 'Quraish', 107: "Al-Maa'un", 108: 'Al-Kawthar', 109: 'Al-Kaafiroon', 110: 'An-Nasr', 111: 'Al-Masad', 112: 'Al-Ikhlaas', 113: 'Al-Falaq', 114: 'An-Naas' }; diff --git a/lib/utilities/helperFunctions.js b/lib/utilities/helperFunctions.js index 29edc16..c6d3b16 100644 --- a/lib/utilities/helperFunctions.js +++ b/lib/utilities/helperFunctions.js @@ -1,9 +1,11 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.raiseError = exports.runFromURL = exports.showListIndex = exports.print = void 0; var data_1 = require("./data"); var colors = require("colors"); var Table = require("../custom_node_modules/cli-table3"); var mpv = require("node-mpv"); +var readline = require('readline'); function print(str, color) { if (color === void 0) { color = "white"; } console.log(colors[color](str)); @@ -25,16 +27,39 @@ function showListIndex(arr, header1, header2, suras) { exports.showListIndex = showListIndex; function runFromURL(url) { try { - var mpvPlayer = new mpv({ + var mpvPlayer_1 = new mpv({ "verbose": false, "audio_only": true }); - mpvPlayer.load(url); - mpvPlayer.play(); - mpvPlayer.on('stopped', function () { + mpvPlayer_1.addProperty('pause', 'no'); + var rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + mpvPlayer_1.load(url); + mpvPlayer_1.play(); + mpvPlayer_1.on('stopped', function () { print("Finished playing", "green"); process.exit(1); }); + rl.input.on('keypress', function (key, data) { + if (data.name === 'p') { + mpvPlayer_1.togglePause(); + mpvPlayer_1.getProperty('pause').then(function (val) { + if (val) { + mpvPlayer_1.setProperty('pause', 'yes'); + print("\nPaused", "yellow"); + } + else { + mpvPlayer_1.setProperty('pause', 'no'); + print("\nResumed", "green"); + } + }); + } + else if (data.name === 'q') { + mpvPlayer_1.stop(); + } + }); } catch (err) { print("You don't have MPV installed", "red"); diff --git a/lib/utilities/helperFunctions.ts b/lib/utilities/helperFunctions.ts index a13a95d..7cf5a96 100644 --- a/lib/utilities/helperFunctions.ts +++ b/lib/utilities/helperFunctions.ts @@ -2,6 +2,8 @@ import { surasDictionary } from "./data"; import colors = require('colors'); import Table = require('../custom_node_modules/cli-table3'); import mpv = require('node-mpv'); +const readline = require('readline'); + export function print(str: string, color: string = "white") { console.log(colors[color](str)); @@ -28,12 +30,38 @@ export function runFromURL(url: string) { "verbose": false, "audio_only": true }); + // set property + mpvPlayer.addProperty('pause', 'no'); + // Handle keypress events + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); mpvPlayer.load(url); mpvPlayer.play(); mpvPlayer.on('stopped', function () { print("Finished playing", "green"); process.exit(1); // close the program }); + rl.input.on('keypress', (key, data) => { + if (data.name === 'p') { + // Toggle pause and resume + mpvPlayer.togglePause(); + mpvPlayer.getProperty('pause').then(function (val) { + if (val) { + mpvPlayer.setProperty('pause', 'yes'); + print("\nPaused", "yellow"); + } else { + mpvPlayer.setProperty('pause', 'no'); + print("\nResumed", "green"); + } + } + ); + } + else if (data.name === 'q') { + mpvPlayer.stop(); + } + }); } catch (err) { print("You don't have MPV installed", "red"); diff --git a/lib/utilities/parser.js b/lib/utilities/parser.js index af71829..2b8dbed 100644 --- a/lib/utilities/parser.js +++ b/lib/utilities/parser.js @@ -1,11 +1,12 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.CommandLine = void 0; var ts_command_line_args_1 = require("ts-command-line-args"); var CommandLine = (function () { function CommandLine() { } CommandLine.getArgs = function () { - var args = ts_command_line_args_1.parse({ + var args = (0, ts_command_line_args_1.parse)({ showRadios: { type: Boolean, optional: true, alias: 'n', description: 'Shows all available radio channels' }, radio: { type: Number, optional: true, alias: 'd', description: 'Play specific radio' }, reciterSurah: { type: Number, multiple: true, optional: true, alias: 'c', description: 'lay specific surah by a specific reciter. \nIf no surah specified, it will shows the available suras for the specified reciter.' }, @@ -15,7 +16,7 @@ var CommandLine = (function () { help: { type: Boolean, optional: true, alias: 'h', description: 'Prints this usage guide' }, }, { helpArg: 'help', - headerContentSections: [{ header: 'Quran-CLI', content: 'Listen to the Quran from your terminal' }], + headerContentSections: [{ header: 'Quran-CLI', content: 'Listen to the Quran from your terminal \n While listening press P to toggle between pause and resume \n Press q to exit' }], footerContentSections: [{ header: '^_^', content: "Recall us in your doa'!" }], }); if (args.reciterSurah == undefined) { diff --git a/lib/utilities/parser.ts b/lib/utilities/parser.ts index 9b83501..91f7ab2 100644 --- a/lib/utilities/parser.ts +++ b/lib/utilities/parser.ts @@ -25,7 +25,7 @@ export class CommandLine { }, { helpArg: 'help', - headerContentSections: [{ header: 'Quran-CLI', content: 'Listen to the Quran from your terminal' }], + headerContentSections: [{ header: 'Quran-CLI', content: 'Listen to the Quran from your terminal \n While listening press P to toggle between pause and resume \n Press q to exit' }], footerContentSections: [{ header: '^_^', content: `Recall us in your doa'!` }], }, ); diff --git a/package.json b/package.json index 0dc7941..b25447c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "name": "@quran-cli/q-cli", "description": "A simple command line interface for listening to Quran. ## Used API [mp3quran](https://mp3quran.net/eng/api) ## Installation - `npm install` - Install **mpv** as it is required for playing the audio. - Debian based distributions `sudo add-apt-repository ppa:mc3man/mpv-tests` `sudo apt update && sudo apt install mpv` - Windows [Follow This link](https://mpv.io/installation/#:~:text=master%20is%20recommended.-,Windows,-All%20binary%20packages)", - "version": "1.1.2", + "version": "1.1.3", "main": "src/index.js", "scripts": { "test": "echo \"Error: no test specified",