Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
459 changes: 247 additions & 212 deletions package-lock.json

Large diffs are not rendered by default.

49 changes: 25 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{
"name": "node-moviedb-cli",
"version": "1.0.0",
"description": "Assembler School: Node.js MovieDB CLI",
"keywords": [
"node.js",
"cli app",
"assembler school"
],
"author": "Dani Lucaci <dani@assemblerschool.com>",
"license": "MIT",
"private": true,
"main": "src/moviedb.js",
"repository": {
"type": "git",
"url": "https://github.com/assembler-school/node-moviedb-cli.git"
},
"scripts": {},
"dependencies": {
"chalk": "^4.1.0",
"commander": "^6.1.0",
"dotenv": "^8.2.0",
"node-notifier": "^8.0.0",
"ora": "^5.1.0"
}
"type": "module",
"name": "node-moviedb-cli",
"version": "1.0.0",
"description": "Assembler School: Node.js MovieDB CLI",
"keywords": [
"node.js",
"cli app",
"assembler school"
],
"author": "Dani Lucaci <dani@assemblerschool.com>",
"license": "MIT",
"private": true,
"main": "src/app.js",
"repository": {
"type": "git",
"url": "https://github.com/assembler-school/node-moviedb-cli.git"
},
"scripts": {},
"dependencies": {
"chalk": "^5.0.0",
"commander": "^8.3.0",
"dotenv": "^10.0.0",
"node-notifier": "^10.0.0",
"ora": "^6.0.1"
}
}
138 changes: 138 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { config } from "dotenv";

config();

import { Command } from "commander";
import { default as ora } from "ora";
import { getPerson, getPersons } from "./models/personModel.js";
import { getMovie, getMovieReviews, getPlayingMovies, getPopularMovies } from "./models/movieModel.js";
import { showPerson, showPersons } from "./views/personView.js";
import { showMovie, showMovieReviews, showMovies } from "./views/movieView.js";
import { optionParseInteger } from "./utils/option.js";

const program = new Command();

program.version("0.0.1", "-v, --version", "Display the current version");

program
.command("get-person")
.description("Make a network request to fetch most popular persons")
.requiredOption("-i, --id <number>", "The id of the person", optionParseInteger)
.action(async (options) => {
const { id } = options;
const loader = ora({
text: "Fetching person details...",
spinner: "dots",
});

try {
loader.start();

const data = await getPerson(id);

if (data.status_message) throw new Error(data.status_message);

showPerson(data);

loader.succeed("Person details loaded successfully");
} catch (error) {
loader.fail(error.message);
}
});

program
.command("get-persons")
.description("Make a network request to fetch most popular persons")
.requiredOption("-p, --popular", "Fetch the popular persons")
.requiredOption("--page <number>", "The page of persons data results to fetch", optionParseInteger)
.action(async (options) => {
const { page } = options;
const loader = ora({
text: "Fetching popular persons' data...",
spinner: "dots",
});

try {
loader.start();

const data = await getPersons(page);

if (data.status_message) throw new Error(data.status_message);

showPersons(data);

loader.succeed("Popular persons' data loaded successfully");
} catch (error) {
loader.fail(error.message);
}
});

program
.command("get-movies")
.description("Make a network request to fetch movies")
.requiredOption("--page <number>", "The page of movies data results to fetch", optionParseInteger)
.option("-p, --popular", "Fetch the popular movies")
.option("-n, --now-playing", "Fetch the movies that are playing now")
.action(async (options) => {
const { page, nowPlaying } = options;
const loader = ora({
text: "Fetching the movies data...",
spinner: "dots",
});

try {
loader.start();

const data = nowPlaying ? await getPlayingMovies(page) : await getPopularMovies(page);

if (data.status_message) throw new Error(data.status_message);

showMovies(data);

loader.succeed(
nowPlaying ? " Movies playing now data loaded successfully" : "Popular movies data loaded successfully"
);
} catch (error) {
loader.fail(error.message);
}
});

program
.command("get-movie")
.description("Make a network request to fetch movie details")
.requiredOption("-i, --id <number>", "The id of the person", optionParseInteger)
.option("--page <number>", "Fetch the movie reviews", optionParseInteger, 1)
.option("--reviews", "Fetch the movie reviews")
.action(async (options) => {
const { id, reviews, page } = options;
const loader = ora({
text: "Fetching the movie data...",
spinner: "dots",
});

try {
loader.start();

if (reviews) {
const data = await getMovieReviews(id, page);

if (data.status_message) throw new Error(data.status_message);

showMovieReviews(data);

loader.succeed("Movie reviews loaded successfully");
} else {
const data = await getMovie(id);

if (data.status_message) throw new Error(data.status_message);

showMovie(data);

loader.succeed("Movie details loaded successfully");
}
} catch (error) {
loader.fail(error.message);
}
});

program.parse(process.argv);
Binary file removed src/img/app-view.png
Binary file not shown.
47 changes: 47 additions & 0 deletions src/models/movieModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import request from "../utils/request.js";

async function getMovie(id) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/movie/${id}?api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

async function getMovieReviews(id, page) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/movie/${id}/reviews?page=${page}&api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

async function getPopularMovies(page) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/movie/popular?page=${page}&api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

async function getPlayingMovies(page) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/movie/now_playing?page=${page}&api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

export { getMovie, getMovieReviews, getPopularMovies, getPlayingMovies };
25 changes: 25 additions & 0 deletions src/models/personModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import request from "../utils/request.js";

async function getPerson(id) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/person/${id}?api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

async function getPersons(page) {
const options = {
method: "GET",
hostname: process.env.API_BASE_URL,
path: `/${process.env.API_VERSION}/person/popular?page=${page}&api_key=${process.env.API_KEY}`,
maxRedirects: 20,
};

return await request(options);
}

export { getPerson, getPersons };
38 changes: 0 additions & 38 deletions src/moviedb.js

This file was deleted.

11 changes: 11 additions & 0 deletions src/utils/option.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { InvalidArgumentError } from "commander";

function optionParseInteger(value) {
const number = parseInt(value);

if (isNaN(number)) throw new InvalidArgumentError("Not an integer value.");

return number;
}

export { optionParseInteger };
25 changes: 25 additions & 0 deletions src/utils/request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import https from "https";

function request(options) {
return new Promise((resolve, reject) => {
let data = "";

const req = https.request(options, (res) => {
res.on("data", function (chunk) {
data += chunk;
});

res.on("end", function () {
resolve(JSON.parse(data));
});

res.on("error", function (error) {
reject(error);
});
});

req.end();
});
}

export default request;
Loading