Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process multiple files and other tweaks #9

Closed
wants to merge 2 commits into from
Closed
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
132 changes: 80 additions & 52 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,109 @@
const request = require("request");
const path = require("path");
const colors = require("colors");
const fs = require("fs");
const regex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g
const fs = require("fs").promises;
const regex = /(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g;

// If the user doesn't enter any arguments/filenames, it exits the process
if (process.argv.length === 2) {
console.log("Usage: url-fi [argument(s)] [FILENAME]")
console.log("-v: print the tool name and its version")
console.log("-s: check whether http:// work using https://")
console.log("-h: display the usage of this tool")
process.exit(1)
console.log("Usage: url-fi [argument(s)] [FILENAME]");
console.log("-v: print the tool name and its version");
console.log("-s: check whether http:// work using https://");
console.log("-h: display the usage of this tool");
}

// for option -s, -h, and -v
// If user enter -s, the program checks whether http:// actually work using https://
// If user enter -h, the program prints out the usage of this tool
let sFlag = false;
let files = [];
for (let i = 2; i < process.argv.length; i++) {
let arg = process.argv[i];
if (arg.startsWith('-')) {
if (arg.includes("s")) {
sFlag = true;
}
let arg = process.argv[i];
if (arg.startsWith("-")) {
if (arg.includes("s")) {
sFlag = true;
}

if (arg.includes("h")) {
console.log("Usage: url-fi [FILENAME]")
}
if (arg.includes("h")) {
console.log("Usage: url-fi [FILENAME]");
}

if (arg.includes("v")) {
console.log("Tool Name: url-fi")
console.log("Version: 0.1")
}
if (arg.includes("v")) {
console.log("Tool Name: url-fi");
console.log("Version: 0.1");
}
} else {
if (checkFile(arg)) files.push(arg);
}
}

// Aggregates links from one or multiple files
async function readArgFile() {
try {
console.log(colors.cyan(`${files.length} file/s found`));
let data;
for (let file of files) {
data += await fs.readFile(file, "utf8");
}
return data;
} catch (err) {
console.error(err);
}
}

// If the user enters any arguments/filenames, starts process.
// --version or -v: prints tool name & version
// filename: checks broken links
for (let i = 2; i < process.argv.length; i++) {
let arg = process.argv[i];
if (!arg.startsWith("-")) {
fs.readFile(path.normalize(arg), 'utf8', function (err, data) {
if (err) {
console.log(colors.red(err));
process.exit(1);
}
let links = data.match(regex);
for (let i = 0; i < links.length; i++) {
let link = links[i];
if (link.startsWith("https://")) {
checkUrl(link);
} else {
checkUrl(link);
if (sFlag) {
checkUrl(link.replace(/^http/, "https"));
}
}
}
})
}
async function sendHeadRequests(uList) {
let urlList = uList.toString();
urlList = urlList.match(regex);
console.log(colors.cyan(`${urlList.length} links collected`));

if (sFlag) {
urlList = urlList.map((links) => {
return links.replace(/^http/, "https");
});
console.log(colors.magenta("Testing http links with https"));
}

for (link of urlList) {
checkUrl(link);
}
}

// Main sequence
if (files.length > 0) {
readArgFile()
.then((data) => sendHeadRequests(data))
.catch((err) => {
console.error(err);
});
}

// Checks the link is broken or not
// - status code 200: good
// - status code 400, 404: broken
// - otherwise: unknown
function checkUrl(url) {
request({ method: 'HEAD', uri: url }, function (err, res, body) {
if (err) {
console.log(colors.yellow(`${err} ${url}`));
} else if (res.statusCode == 200) {
console.log(colors.green(`[PASSED] [200] ${url}`));
} else if (res.statusCode == 404 || res.statusCode == 400) {
console.log(colors.red(`[FAILED] [${res.statusCode}] ${url}`));
} else {
console.log(colors.grey(`[UNKNOWN] [${res.statusCode}] ${url}`))
}
})
request({ method: "HEAD", uri: url }, function (err, res, body) {
if (err) {
console.log(colors.yellow(`${err} ${url}`));
} else if (res.statusCode == 200) {
console.log(colors.green(`[PASSED] [200] ${url}`));
} else if (res.statusCode == 404 || res.statusCode == 400) {
console.log(colors.red(`[FAILED] [${res.statusCode}] ${url}`));
} else {
console.log(colors.grey(`[UNKNOWN] [${res.statusCode}] ${url}`));
}
});
}

// Checks if argument provided is a file
async function checkFile(arg) {
try {
const stat = await fs.lstat(arg);
return stat.isFile();
} catch (err) {
console.error(err);
}
}