const {log, biglog, errorlog, colorize} = require("./out"); const model = require('./model'); /** * Muestra la ayuda. * * @param rl Objeto readline usado para implementar el CLI. */ exports.helpCmd = rl => { log("Commandos:"); log(" h|help - Muestra esta ayuda."); log(" list - Listar los quizzes existentes."); log(" show - Muestra la pregunta y la respuesta el quiz indicado."); log(" add - Añadir un nuevo quiz interactivamente."); log(" delete - Borrar el quiz indicado."); log(" edit - Editar el quiz indicado."); log(" test - Probar el quiz indicado."); log(" p|play - Jugar a preguntar aleatoriamente todos los quizzes."); log(" credits - Créditos."); log(" q|quit - Salir del programa."); rl.prompt(); }; /** * Lista todos los quizzes existentes en el modelo. * * @param rl Objeto readline usado para implementar el CLI. */ exports.listCmd = rl => { model.getAll().forEach((quiz, id) => { log(` [${colorize(id, 'magenta')}]: ${quiz.question}`); }); rl.prompt(); }; /** * Muestra el quiz indicado en el parámetro: la pregunta y la respuesta. * * @param rl Objeto readline usado para implementar el CLI. * @param id Clave del quiz a mostrar. */ exports.showCmd = (rl, id) => { if (typeof id === "undefined") { errorlog(`Falta el parámetro id.`); } else { try { const quiz = model.getByIndex(id); log(` [${colorize(id, 'magenta')}]: ${quiz.question} ${colorize('=>', 'magenta')} ${quiz.answer}`); } catch(error) { errorlog(error.message); } } rl.prompt(); }; /** * Añade un nuevo quiz al módelo. * Pregunta interactivamente por la pregunta y por la respuesta. * * Hay que recordar que el funcionamiento de la funcion rl.question es asíncrono. * El prompt hay que sacarlo cuando ya se ha terminado la interacción con el usuario, * es decir, la llamada a rl.prompt() se debe hacer en la callback de la segunda * llamada a rl.question. * * @param rl Objeto readline usado para implementar el CLI. */ exports.addCmd = rl => { rl.question(colorize(' Introduzca una pregunta: ', 'red'), question => { rl.question(colorize(' Introduzca la respuesta ', 'red'), answer => { model.add(question, answer); log(` ${colorize('Se ha añadido', 'magenta')}: ${question} ${colorize('=>', 'magenta')} ${answer}`); rl.prompt(); }); }); }; /** * Borra un quiz del modelo. * * @param rl Objeto readline usado para implementar el CLI. * @param id Clave del quiz a borrar en el modelo. */ exports.deleteCmd = (rl, id) => { if (typeof id === "undefined") { errorlog(`Falta el parámetro id.`); } else { try { model.deleteByIndex(id); } catch(error) { errorlog(error.message); } } rl.prompt(); }; /** * Edita un quiz del modelo. * * Hay que recordar que el funcionamiento de la funcion rl.question es asíncrono. * El prompt hay que sacarlo cuando ya se ha terminado la interacción con el usuario, * es decir, la llamada a rl.prompt() se debe hacer en la callback de la segunda * llamada a rl.question. * * @param rl Objeto readline usado para implementar el CLI. * @param id Clave del quiz a editar en el modelo. */ exports.editCmd = (rl, id) => { if (typeof id === "undefined") { errorlog(`Falta el parámetro id.`); rl.prompt(); } else { try { const quiz = model.getByIndex(id); process.stdout.isTTY && setTimeout(() => {rl.write(quiz.question)},0); rl.question(colorize(' Introduzca una pregunta: ', 'red'), question => { process.stdout.isTTY && setTimeout(() => {rl.write(quiz.answer)},0); rl.question(colorize(' Introduzca la respuesta ', 'red'), answer => { model.update(id, question, answer); log(` Se ha cambiado el quiz ${colorize(id, 'magenta')} por: ${question} ${colorize('=>', 'magenta')} ${answer}`); rl.prompt(); }); }); } catch (error) { errorlog(error.message); rl.prompt(); } } }; /** * Prueba un quiz, es decir, hace una pregunta del modelo a la que debemos contestar. * * @param rl Objeto readline usado para implementar el CLI. * @param id Clave del quiz a probar. */ exports.testCmd = (rl, id) => { if (typeof id === "undefined") { errorlog(`Falta el parámetro id.`); rl.prompt(); } else { try { const quiz = model.getByIndex(id); rl.question(colorize(quiz.question + " ", 'red'), answer => { if ( quiz.answer == answer ) { biglog("correct", "green"); } else { biglog("incorrect", "red"); } rl.prompt(); }); } catch (error) { errorlog(error.message); rl.prompt(); } } }; /** * Shuffles array in place. ES6 version * @param {Array} a items An array containing the items. */ function shuffle(a) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } /** * Pregunta todos los quizzes existentes en el modelo en orden aleatorio. * Se gana si se contesta a todos satisfactoriamente. * * @param rl Objeto readline usado para implementar el CLI. */ exports.playCmd = rl => { let aciertos = 0; let questions = shuffle(model.getAll()); const keepAsking = () => { if (questions.length<1){ log(`Fin del juego - Aciertos: ${aciertos}`, "red"); rl.prompt(); return } try { let quiz = questions.pop(); rl.question(colorize(quiz.question + " ", 'red'), answer => { if ( quiz.answer == answer ) { aciertos += 1; log(`CORRECTO - lleva ${aciertos} aciertos`, "green"); } else { log("INCORRECTO", "red"); questions = []; } keepAsking() }); } catch (error) { errorlog(error.message); rl.prompt(); } } keepAsking(); }; /** * Muestra los nombres de los autores de la práctica. * * @param rl Objeto readline usado para implementar el CLI. */ exports.creditsCmd = rl => { log('Autores de la práctica:'); log('Nombre 1', 'green'); log('Nombre 2', 'green'); rl.prompt(); }; /** * Terminar el programa. * * @param rl Objeto readline usado para implementar el CLI. */ exports.quitCmd = rl => { rl.close(); };