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
95 changes: 95 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { createInterface } from "readline";
import { goUpper, changeDirectory, listFiles } from "./src/navigation.js";
import {
cat,
add,
renameFile,
copyFile,
moveFile,
deleteFile,
} from "./src/fileOperations.js";
import { getOsInfo } from "./src/osSystem.js";
import { calculateHash } from "./src/hash.js";
import { compressFile, decompressFile } from "./src/compress.js";

const readline = createInterface({
input: process.stdin,
output: process.stdout,
});

const args = process.argv.slice(2);
const username =
args.find((arg) => arg.startsWith("--username="))?.split("=")[1] ||
"Anonymous";

console.log(`Welcome to the File Manager, ${username}!`);
console.log(`You are currently in ${process.cwd()}`);

readline.on("line", async (input) => {
const [command, ...params] = input.split(" ");

try {
switch (command) {
case "up":
goUpper();
break;
case "cd":
await changeDirectory(params[0]);
break;
case "ls":
await listFiles();
break;
case "cat":
await cat(params[0]);
break;
case "add":
await add(params[0]);
break;
case "rn":
renameFile(params[0], params[1]);
break;
case "cp":
copyFile(params[0], params[1]);
break;
case "mv":
moveFile(params[0], params[1]);
break;
case "rm":
await deleteFile(params[0]);
break;
case "os":
getOsInfo(params[0]);
break;
case "hash":
calculateHash(params[0]);
break;
case "compress":
compressFile(params[0], params[1]);
break;
case "decompress":
decompressFile(params[0], params[1]);
break;
case "catch":
catchMe(params[0], params[1]);
break;
case ".exit":
console.log(`Thank you for using File Manager, ${username}, goodbye!`);
process.exit(0);
default:
console.log("Invalid input");
}
} catch (error) {
console.log(
`\n\n*** Oopsy doopsy, watch a recorded fix solution: https://www.youtube.com/watch?v=dQw4w9WgXcQ
Note: you can deduct points if it's not a catchMe() :) ***\n\n`
);
}

console.log(`You are currently in ${process.cwd()}`);
});

readline.on("SIGINT", () => {
console.log(`\nThank you for using File Manager, ${username}, goodbye!`);
console.log(`\nHope I will Never Gonna Give You Up! ;)`);
process.exit(0);
});
18 changes: 18 additions & 0 deletions src/compress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import fs from "fs";
import path from "path";
import { createGzip } from "node:zlib";
import { createGunzip } from "zlib";

export const compressFile = (filePath, dest) => {
const readStream = fs.createReadStream(path.resolve(filePath));
const gzip = createGzip();
const writeStream = fs.createWriteStream(path.resolve(dest));
readStream.pipe(gzip).pipe(writeStream);
};

export const decompressFile = (filePath, dest) => {
const readStream = fs.createReadStream(path.resolve(filePath));
const gzip = createGunzip();
const writeStream = fs.createWriteStream(path.resolve(dest));
readStream.pipe(gzip).pipe(writeStream);
};
48 changes: 48 additions & 0 deletions src/fileOperations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { createReadStream, writeFile, promises, createWriteStream } from "fs";
import { resolve, join, basename } from "path";

export async function cat(filePath) {
const readStream = createReadStream(resolve(filePath), "utf-8");
readStream.on("data", (chunk) => process.stdout.write(chunk));
}

export const add = (fileName) =>
promises
.writeFile(join(process.cwd(), fileName), "")
.catch(() => console.log(`add Operation failed. File name: ${fileName}`));

export const renameFile = (oldName, newName) => {
promises
.rename(oldName, newName)
.catch(() =>
console.log(
`renameFile Operation failed. Old name ${oldName}, new name: ${newName}`
)
);
};

export const copyFile = (src, dest) => {
const readStream = createReadStream(src);
const writeStream = createWriteStream(join(dest, basename(src)));
readStream.pipe(writeStream);
readStream.on("error", () =>
console.log(`copyFile: Operation failed. src: ${src}, dest ${dest}`)
);
};

export function moveFile(src, dest) {
copyFile(src, dest)
.then(() => promises.unlink(src))
.catch(() =>
console.log(
`moveFile Operation failed, provided src ${src}, dest ${dest}`
)
);
}

export const deleteFile = (filePath) =>
promises
.unlink(filePath)
.catch(() =>
console.log(`deleteFile Operation failed, provided filepath: ${filePath}`)
);
3 changes: 0 additions & 3 deletions src/fs/files/wrongFilename.txt

This file was deleted.

11 changes: 11 additions & 0 deletions src/hash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import crypto from "crypto";
import fs from "fs";
import path from "path";

export const calculateHash = (filePath) => {
const hash = crypto.createHash("sha256");
const stream = fs.createReadStream(path.resolve(filePath));
stream.on("data", (data) => hash.update(data));
stream.on("end", () => console.log(hash.digest("hex")));
stream.on("error", () => console.log("Operation failed"));
};
35 changes: 35 additions & 0 deletions src/navigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { promises as fs } from "fs";
import { parse, resolve } from "path";

export function goUpper() {
const currentDir = process.cwd();
const rootDir = parse(currentDir).root;
if (currentDir !== rootDir) {
process.chdir("..");
}
}

export async function changeDirectory(dir) {
const newDir = resolve(process.cwd(), dir);
try {
await fs.access(newDir);
process.chdir(newDir);
} catch (err) {
console.log(`Operation failed: folder ${dir} does not exist`);
}
}

export async function listFiles() {
// list should contain files and folder names (for files - with extension)
const files = await fs.readdir(process.cwd(), { withFileTypes: true });
const directories = files
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name + " - 'directory'"); // type of directory content should be marked explicitly
const fileNames = files
.filter((dirent) => dirent.isFile())
.map((dirent) => dirent.name + " - 'file'"); // type of directory content should be marked explicitly

// folders and files are sorted in alphabetical order ascending, but list of folders goes first
console.log(directories.join("\n"));
console.log(fileNames.join("\n"));
}
24 changes: 24 additions & 0 deletions src/osSystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import os from "os";

export const getOsInfo = (flag) => {
switch (flag) {
case `--EOL`:
console.log(JSON.stringify(os.EOL));
break;
case `--cpus`:
console.log(`CPU cores: ${os.cpus().length}`);
os.cpus().forEach((cpu) => console.log(`${cpu.model} ${cpu.speed} MHz`));
break;
case `--homedir`:
console.log(`Home dir: ${os.homedir()}`);
break;
case `--username`:
console.log(`Username: ${os.userInfo().username}`);
break;
case `--architecture`:
console.log(`Architecture: ${os.machine()}`);
break;
default:
console.log(`os command: Invalid input`);
}
};