diff --git a/README.md b/README.md index 8388f4e..123e4b6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -`#node.js` `#master-in-software-engineering` +`#node.js` `#master-in-software-engineering` `CLI` @@ -8,156 +8,62 @@ # Assembler School: Node.js MovieDB CLI App -In this project you will learn how to create a cli app with Node.js. +In this project we have developed a CLI program with node.js that is able to run using a terminal application. +The program is connecting to a third-party API to show the data returned and store it in the local system. -## Table of Contents - -- [Getting Started](#getting-started) -- [The Project](#the-project) -- [Project requirements](#project-requirements) -- [Project delivery](#project-delivery) -- [Resources](#resources) - -## Getting Started - -These instructions will get you a copy of the project up and running on your -local machine for development and testing purposes. - -See deployment for notes on how to deploy the project on a live system. - -### The repository - -First, you will need to `clone` or `fork` the repository into your Github -account: - -Fork on GitHub - -``` -$ git clone https://github.com/assembler-school/node-moviedb-cli.git -``` +## Repository -## Contents and Branches Naming Strategy +Project created from the Assembler School repository _node-moviedb-cli.git_: -The repository is made up of several branches that include the contents of each -section. +https://github.com/assembler-school/node-moviedb-cli.git -The branches follow a naming strategy like the following: - -- `main`: includes the main contents and the instructions -- `assembler-solution`: includes the solution - -### Fetching All the Branches - -In order to fetch all the remote branches in the repository, you can use the -following command: - -```sh -$ git fetch --all -``` +## Technologies used -### List Both Remote Tracking Branches and Local Branches +\* JavaScript +\* NodeJS -```sh -$ git branch --all -``` +## Table of Contents -Then, you can create a local branch based on a remote branch with the following -command: +- [Main objectives](#main-objectives) +- [Installing](#installing) +- [Resources](#resources) +- [Authors](#authors) -```sh -$ git checkout -b -``` +## Main objectives -### Installing +* Learn how to connect to a third party API using node.js +* Learn how to implement a CLI program using node.js +* Learn how to work with the filesystem apis of node.js +* Learn how to interact with a CLI program and develop a menu that users can use to know how to execute the program -First, you will need to install the dependencies with: `npm install`. +## Installing +First, you will need to install the dependencies with: npm install. Run the following command in your terminal after cloning the main repo: -```sh +``` $ npm install ``` -### Running the Tests - -The tests that validate your solution can be executed by runing the following -command: +Next you can install the general command _moviedb_ so you can use it: ``` -$ npm run test +$ npm install -g ``` -### Git `precommit` and `prepush` Hooks - -In the `assembler-solution` branch you can see an implementation of these tools -if you'd like to use them. - -## Deployment - -In this pill we won't deploy the app. - -## Technologies used - -- `Node.js` -- `eslint` -- `prettier` -- `lint-staged` -- `husky` - -## The Project - -In this project you will build a cli app similar to the following screenshot. - - - -## Project requirements - -This is an overview of the main requirements of this project. The exact ones are -found in the doc that the academic team will provide you. - -- You must follow all the instructions of the project step-by-step -- You should always try to solve them by yourself before asking for help -- You should always help your team members and fellow students of the master so - that you can all learn together and become better software developers and team - members -- You must finish all the steps that are marked as `Required` -- Once you are done, you can move on to the optional ones that are marked as - `Extra 💯` - -## Project delivery - -To deliver this project you must follow the steps indicated in the document: - -- [Submitting a solution](https://www.notion.so/Submitting-a-solution-524dab1a71dd4b96903f26385e24cdb6) +The project is ready for you to play with it! ## Resources -- See the document we provide - -## License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file -for details - -## Contributors ✨ - -Thanks goes to these wonderful people -([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - - - - -

Dani Lucaci

💻 📖 💡 🔧
- - - +\* [Build a CLI with Node.js](https://dev.to/rushankhan1/build-a-cli-with-node-js-4jbi) +\* [How to http request with Node.js and https.request](https://www.twilio.com/blog/2017/08/http-requests-in-node-js.html) +\* [Understanding module export in Node.js](https://www.sitepoint.com/understanding-module-exports-exports-node-js/) +\* [The MoviDB API](https://www.themoviedb.org/documentation/api) +\* [Ora Module](https://www.npmjs.com/package/ora) +\* [Commander Module](https://www.npmjs.com/package/commander) - +## Authors -This project follows the -[all-contributors](https://github.com/all-contributors/all-contributors) -specification. Contributions of any kind welcome! +- [@Ethan-Alfaro](https://github.com/Ethan-Alfaro) +- [@Ernest-DT](https://github.com/Ernest-DT) +- [@JordixArnau](https://github.com/JordixArnau) diff --git a/documentation/moviedb.postman_collection.json b/documentation/moviedb.postman_collection.json new file mode 100644 index 0000000..120009f --- /dev/null +++ b/documentation/moviedb.postman_collection.json @@ -0,0 +1,220 @@ +{ + "info": { + "_postman_id": "13bbfa29-c3ac-4a55-8c0d-e140289c2316", + "name": "moviedb", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Persons popular", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/person/popular?api_key=c15aef2e35d1752562aec3685f62834e&page=1", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "person", + "popular" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + }, + { + "key": "page", + "value": "1" + } + ] + } + }, + "response": [] + }, + { + "name": "Person", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/person/:id?api_key=c15aef2e35d1752562aec3685f62834e", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "person", + ":id" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + } + ], + "variable": [ + { + "key": "id", + "value": "91606" + } + ] + } + }, + "response": [] + }, + { + "name": "Movies now playing", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/movie/:state?api_key=c15aef2e35d1752562aec3685f62834e&page=2", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "movie", + ":state" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + }, + { + "key": "page", + "value": "2" + } + ], + "variable": [ + { + "key": "state", + "value": "now_playing" + } + ] + } + }, + "response": [] + }, + { + "name": "Movies popular", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/movie/:state?api_key=c15aef2e35d1752562aec3685f62834e&page=2", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "movie", + ":state" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + }, + { + "key": "page", + "value": "2" + } + ], + "variable": [ + { + "key": "state", + "value": "popular" + } + ] + } + }, + "response": [] + }, + { + "name": "Movie", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/movie/:id?api_key=c15aef2e35d1752562aec3685f62834e", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "movie", + ":id" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + } + ], + "variable": [ + { + "key": "id", + "value": "70" + } + ] + } + }, + "response": [] + }, + { + "name": "Movie review", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://api.themoviedb.org/3/movie/:id/reviews?api_key=c15aef2e35d1752562aec3685f62834e", + "protocol": "https", + "host": [ + "api", + "themoviedb", + "org" + ], + "path": [ + "3", + "movie", + ":id", + "reviews" + ], + "query": [ + { + "key": "api_key", + "value": "c15aef2e35d1752562aec3685f62834e" + } + ], + "variable": [ + { + "key": "id", + "value": "70" + } + ] + } + }, + "response": [] + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index fcf3619..5979412 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,391 @@ { "name": "node-moviedb-cli", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "commander": "^6.1.0", + "dotenv": "^8.2.0", + "node-notifier": "^8.0.0", + "ora": "^5.1.0" + }, + "bin": { + "moviedb": "src/moviedb.js" + } + }, + "node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/chalk/node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/chalk/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/commander": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.1.0.tgz", + "integrity": "sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/dotenv": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "node_modules/is-docker": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", + "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/node-notifier": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", + "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node_modules/ora": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.1.0.tgz", + "integrity": "sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w==", + "dependencies": { + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.4.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "mute-stream": "0.0.8", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ora/node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/cli-spinners": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.4.0.tgz", + "integrity": "sha512-sJAofoarcm76ZGpuooaO0eDy8saEy+YoZBLjC4h8srt4jeBnkYeOgqxgsJQTpyt2LjI5PTfLJHSL+41Yu4fEJA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/ora/node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ora/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "node_modules/uuid": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + } + }, "dependencies": { "chalk": { "version": "4.1.0", diff --git a/package.json b/package.json index f20c9c6..e5f59d3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,9 @@ "type": "git", "url": "https://github.com/assembler-school/node-moviedb-cli.git" }, + "bin": { + "moviedb": "./src/moviedb.js" + }, "scripts": {}, "dependencies": { "chalk": "^4.1.0", diff --git a/src/moviedb.js b/src/moviedb.js index dd5591a..0f77915 100755 --- a/src/moviedb.js +++ b/src/moviedb.js @@ -1,6 +1,8 @@ #!/usr/bin/env node const { Command } = require("commander"); +const req = require("./utils/httprequest"); +require("dotenv/config"); const program = new Command(); program.version("0.0.1"); @@ -8,29 +10,51 @@ program.version("0.0.1"); program .command("get-persons") .description("Make a network request to fetch most popular persons") - .action(function handleAction() { - console.log("hello-world"); + .requiredOption("-p, --popular", "Fetch the popular persons") + .requiredOption( + "--page ", + "The page of persons data results to fetch" + ) + .action(function handleAction(options) { + req.httpRequest("person/popular", `page=${options.page}`); }); program .command("get-person") .description("Make a network request to fetch the data of a single person") - .action(function handleAction() { - console.log("hello-world"); + .requiredOption("-i, --id ", "The id of the person") + .action(function handleAction(options) { + req.httpRequest(`person/${options.id}`); }); program .command("get-movies") .description("Make a network request to fetch movies") - .action(function handleAction() { - console.log("hello-world"); + .requiredOption( + "--page ", + "The page of movies data results to fetch" + ) + .option("-p, --popular", "Fetch the popular movies") + .option("-n, --now-playing", "Fetch the movies that are playing now") + .action(function handleAction(options) { + const endPoint = options.nowPlaying ? "movie/now_playing" : "movie/popular"; + req.httpRequest(endPoint, `page=${options.page}`); }); program .command("get-movie") .description("Make a network request to fetch the data of a single person") - .action(function handleAction() { - console.log("hello-world"); + .requiredOption("-i, --id ", "The id of the movie") + .option("-r, --review", "Fetch the reviews of the movie") + + .action(function handleAction(options) { + let movieId = options.id; + let movieReview = options.review; + if (movieReview) { + req.httpRequest("movie/" + movieId + "/reviews"); + } else { + req.httpRequest("movie/" + movieId); + } }); // error on unknown commands diff --git a/src/utils/httprequest.js b/src/utils/httprequest.js new file mode 100644 index 0000000..a9bb50a --- /dev/null +++ b/src/utils/httprequest.js @@ -0,0 +1,53 @@ +const https = require("https"); +const fs = require("fs"); +const { movie_render, person_render } = require("./render_movie"); +const spin = require("./spinner"); +const render = require("./render_globals"); +require("dotenv/config"); + +exports.httpRequest = function (endPoint, option1 = "", option2 = "") { + const spinner = spin.start(endPoint); + https + .get( + `https://api.themoviedb.org/3/${endPoint}?api_key=${process.env.API_KEY}&${option1}&${option2}`, + (response) => { + let result = ""; + response.on("data", (d) => { + result += d; + }); + + response.on("end", () => { + if (result === "") { + spinner.fail("Error: can't find your request"); + return; + } + + if (endPoint === "person/popular") { + render.persons(JSON.parse(result)); + spinner.succeed("Popular Persons data loaded"); + return; + } else if (endPoint === "movie/popular") { + render.movies(JSON.parse(result)); + spinner.succeed("Popular movies data loaded"); + return; + } else if (endPoint === "movie/now_playing") { + render.movies(JSON.parse(result)); + spinner.succeed("Movies playing now data loaded"); + return; + } else if (endPoint.includes("movie/")) { + movie_render(JSON.parse(result)); + spinner.succeed("Film loaded successfully"); + return; + } else if (endPoint.includes("person/")) { + person_render(JSON.parse(result)); + spinner.succeed("Person loaded successfully"); + return; + } + }); + } + ) + .on("error", (err) => { + spinner.fail("Error: " + err.message); + }); + spinner.stop(); +}; diff --git a/src/utils/render_globals.js b/src/utils/render_globals.js new file mode 100644 index 0000000..236c6cc --- /dev/null +++ b/src/utils/render_globals.js @@ -0,0 +1,69 @@ +const chalk = require("chalk"); + +function renderPersons(data) { + if (data.total_pages > data.page) { + console.log(chalk.white("\n")); + console.log(chalk.white("-".repeat(100))); + console.log(chalk.white("Page " + data.page + " of " + data.total_pages)); + } + const persons = data.results; + persons.map((person) => { + console.log(chalk.white("-".repeat(100))); + console.log(chalk.white("\n")); + console.log(chalk.white("Person:")); + console.log(chalk.white("\n")); + console.log(chalk.white("ID: " + person.id)); + console.log(chalk.white("Name: ") + chalk.blue.bold(person.name)); + if (person.known_for_department === "Acting") { + console.log( + chalk.white("Department: ") + chalk.magenta(person.known_for_department) + ); + console.log(chalk.white("\n")); + } + let definedMovies = 0; + person.known_for.map((film) => { + if (film.title !== undefined) { + definedMovies += 1; + } + }); + if (definedMovies > 0) { + console.log(chalk.white("Know for movies:")); + console.log(chalk.white("\n")); + person.known_for.map((movie) => { + if (movie.title !== undefined) { + console.log("\t" + chalk.white("Movie:")); + console.log("\t" + chalk.white("ID: " + movie.id)); + console.log( + "\t" + chalk.white("Release date: " + movie.release_date) + ); + console.log("\t" + chalk.white("Title: " + movie.title)); + console.log(chalk.white("\n")); + } + }); + } else { + console.log( + chalk.yellow(person.name + " doesn’t appear in any movie \n") + ); + } + }); +} + +function renderMovies(data) { + if (data.total_pages > data.page) { + console.log(chalk.white("\n")); + console.log(chalk.white("-".repeat(100))); + console.log(chalk.white("Page " + data.page + " of " + data.total_pages)); + } + const movies = data.results; + movies.map((movie) => { + console.log(chalk.white("-".repeat(100))); + console.log(chalk.white("\n")); + console.log(chalk.white("Movie:\n")); + console.log(chalk.white("ID: " + movie.id)); + console.log(chalk.white("Title: ") + chalk.blue(movie.title)); + console.log(chalk.white("Release Date: " + movie.release_date + "\n")); + }); +} + +exports.persons = renderPersons; +exports.movies = renderMovies; diff --git a/src/utils/render_movie.js b/src/utils/render_movie.js new file mode 100644 index 0000000..5d27fb2 --- /dev/null +++ b/src/utils/render_movie.js @@ -0,0 +1,94 @@ +const chalk = require("chalk"); + +exports.movie_render = function (obj) { + if (obj.title != undefined) { + console.log( + chalk.white("---------------------" + obj.title + "------------------\n") + ); + console.log(chalk.blue("Movie ID: " + obj.id + "\n")); + console.log(chalk.bold.blue("Movie TITLE: " + obj.title + "\n")); + console.log(chalk.white("RELEASE DATE: " + obj.release_date + "\n")); + console.log(chalk.white("RUNTIME: " + obj.runtime + "\n")); + console.log(chalk.white("VOTE COUNT: " + obj.vote_count + "\n")); + console.log(chalk.white("OVERVIEW: " + obj.overview + "\n")); + console.log(chalk.white("\n")); + if (obj.genre != "") { + console.log(chalk.white("GENRE: " + obj.genres[0].name + "\n")); + } else { + console.log(chalk.yellow("The movie doesn’t have a declared genre \n")); + } + console.log(chalk.white("\n")); + + if (obj.spoken_lenguages != "") { + const len = obj.spoken_languages; + len.forEach((name) => { + console.log(chalk.white("LENGUAGES: " + name.name + "\n")); + }); + } else { + console.log( + chalk.yellow( + `The movie: ${obj.id} doesn’t have any declared languages \n` + ) + ); + } + } else { + const res = obj.results; + if (res.length > 0) { + let totalPages = obj.total_pages; + let pages = obj.page; + if (totalPages > pages) { + console.log(chalk.white("--------------------------\n")); + console.log( + chalk.white("PAGE : " + pages + " OF " + totalPages + "\n") + ); + console.log(chalk.white("--------------------------\n")); + } + console.log("\n"); + res.forEach((resu) => { + console.log(chalk.bold.blue("AUTHOR: " + resu.author)); + let cont = resu.content; + if (cont.length > 400) { + cont.slice(0, 399); + console.log(chalk.white("CONTENT: " + cont + "...")); + } else { + console.log(chalk.white(resu.content + "\n")); + } + }); + } else { + console.log( + chalk.yellow(`The movie: ${obj.id} doesn’t have any reviews`) + ); + } + } +}; + +exports.person_render = function (data) { + console.log(chalk.white("-".repeat(100))); + console.log(chalk.white("\n")); + console.log(chalk.white("Person:\n")); + console.log(chalk.white("ID: " + data.id)); + console.log(chalk.white("Name: ") + chalk.blue(data.name)); + console.log( + chalk.white("Birthday: " + data.birthday) + + chalk.gray(" | ") + + chalk.white(data.place_of_birth) + ); + if (data.known_for_department === "Acting") { + console.log( + chalk.white("Department: ") + chalk.magenta(data.known_for_department) + ); + } + console.log(chalk.white("Biography: ") + chalk.blue.bold(data.biography)); + if (data.also_known_as.length > 0) { + console.log(chalk.white("\n")); + console.log(chalk.white("Also known as:\n")); + data.also_known_as.map((aka) => { + console.log(chalk.white(aka + "\n")); + }); + } else { + console.log(chalk.white("\n")); + console.log( + chalk.yellow(data.name + " doesn't have any alternate names\n") + ); + } +}; diff --git a/src/utils/spinner.js b/src/utils/spinner.js new file mode 100644 index 0000000..8ff607c --- /dev/null +++ b/src/utils/spinner.js @@ -0,0 +1,24 @@ +const ora = require("ora"); + +function spinnerStart(endPoint) { + let spinner = ""; + + if (endPoint === "person/popular") { + spinner = ora("Fetching the popular person's data...").start(); + return spinner; + } else if (endPoint === "movie/popular") { + spinner = ora("Fetching the movies data...").start(); + return spinner; + } else if (endPoint === "movie/now_playing") { + spinner = ora("Fetching the movies data...").start(); + return spinner; + } else if (endPoint.includes("movie/")) { + spinner = ora("Fetching the movie data...").start(); + return spinner; + } else if (endPoint.includes("person/")) { + spinner = ora("Fetching the person data...").start(); + return spinner; + } +} + +exports.start = spinnerStart;