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
21 changes: 21 additions & 0 deletions compress_decompress/compress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createReadStream, createWriteStream } from "node:fs"
import path from "node:path"
import { createBrotliCompress } from "node:zlib"
import { getFileFromPath } from "../utils/getFileFromPath.js"
import { printCWD } from "../utils/printCWD.js"

export function compressFile(paths) {
const fileToCompress = getFileFromPath(paths[0])

const input = createReadStream(paths[0])

const brotli = createBrotliCompress()

input.on("error", error => {console.error("Operation failed"); printCWD()})
.pipe(brotli.on("error", error => {console.error("Operation failed"); printCWD()}))
.on("data", data => createWriteStream(path.join(paths[1], `${fileToCompress}.br`))
.on("error", error => {console.error("Operation failed"); printCWD()})
.on("open", () => printCWD())
.write(data)
)
}
23 changes: 23 additions & 0 deletions compress_decompress/decompress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createReadStream, createWriteStream } from "node:fs"
import { createBrotliDecompress } from "node:zlib"
import path from "node:path"
import { getFileFromPath } from "../utils/getFileFromPath.js"
import { printCWD } from "../utils/printCWD.js"

export function decompressFile(paths) {

const fileToDecompress = getFileFromPath(paths[0]).split(".")
fileToDecompress.pop() // Remove .br extension

const input = createReadStream(paths[0])

const brotli = createBrotliDecompress()

input.on("error", error => {console.error("Operation failed"); printCWD()})
.pipe(brotli.on("error", error => {console.error("Operation failed"); printCWD()}))
.on("data", data => createWriteStream(path.join(paths[1], fileToDecompress.join(".")))
.on("error", error => console.error("Operation failed"))
.on("open", () => printCWD())
.write(data)
)
}
16 changes: 16 additions & 0 deletions compress_decompress/handleCompDecomp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { compressFile } from "./compress.js";
import { decompressFile } from "./decompress.js";

export function handleCompDecomp(command, paths) {
switch (command) {
case "compress":
compressFile(paths)
break;
case "decompress":
decompressFile(paths)
break;
default:
console.error("Invalid input")
break;
}
}
11 changes: 11 additions & 0 deletions file_operations/add.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { writeFile} from "node:fs/promises"
import { printCWD } from "../utils/printCWD.js"

export async function addFile(path) {
try {
await writeFile(path, "", {encoding: "utf8"})
} catch (error) {
console.error("Operation failed")
}
printCWD()
}
8 changes: 8 additions & 0 deletions file_operations/cat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { createReadStream } from "node:fs"
import { printCWD } from "../utils/printCWD.js"

export function readContent(path) {
createReadStream(path)
.on("error", error => console.error("Operation failed"))
.on("data", data => {console.log(data.toString()); printCWD()})
}
33 changes: 33 additions & 0 deletions file_operations/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createReadStream, createWriteStream, existsSync } from "node:fs"
import { printCWD } from "../utils/printCWD.js"
import path from "node:path"
import { mkdir } from "node:fs/promises"
import { getFileFromPath } from "../utils/getFileFromPath.js"
import { rm } from "node:fs/promises"

export async function copyFile(paths, withRemove = false) {
try {
if (!existsSync(paths[1])) {
await mkdir(paths[1], { recursive: true })
}

const fileToCopy = getFileFromPath(paths[0])

const dest = path.join(paths[1], fileToCopy)

createReadStream(paths[0], { encoding: "utf8" })
.on("error", error => {console.error("Operation failed"); printCWD()})
.on("data", data => {
createWriteStream(dest)
.on("error", error => console.error("Operation failed"))
.on("open", async () => withRemove
? (await rm(paths[0]).catch(error => console.error("Operation failed")), printCWD())
: printCWD()
)
.write(data)
})
} catch (error) {
console.error("Operation failed")
}

}
31 changes: 31 additions & 0 deletions file_operations/handleOperations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { readContent } from "./cat.js";
import { addFile } from "./add.js";
import { renameFile } from "./rename.js";
import { copyFile } from "./copy.js";
import { removeFile } from "./remove.js";

export async function handleFileOperation(operation, paths) {
switch (operation) {
case "cat":
readContent(paths[0])
break;
case "add":
await addFile(paths[0])
break;
case "rn":
await renameFile(paths)
break;
case "cp":
await copyFile(paths)
break;
case "mv":
await copyFile(paths, true)
break;
case "rm":
await removeFile(paths[0])
break;
default:
console.error("Invalid input")
break;
}
}
7 changes: 7 additions & 0 deletions file_operations/remove.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { rm } from "node:fs/promises"
import { printCWD } from "../utils/printCWD.js"

export async function removeFile(path) {
await rm(path).catch(error => console.error("Operation failed"))
printCWD()
}
12 changes: 12 additions & 0 deletions file_operations/rename.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { rename } from "node:fs/promises"
import { printCWD } from "../utils/printCWD.js"
import { getFileFromPath } from "../utils/getFileFromPath.js"
import path from "node:path"

export async function renameFile(paths) {
const fileNameLength = getFileFromPath(paths[0]).length
const pathToFile = paths[0].slice(0, paths[0].length - fileNameLength)
await rename(paths[0], path.join(pathToFile, paths[1]))
.catch(error => console.error("Operation failed"))
printCWD()
}
12 changes: 12 additions & 0 deletions hash/handleHashCommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createHash } from "node:crypto"
import { readFile } from "node:fs/promises"
import { printCWD } from "../utils/printCWD.js"

export async function hashFile(path) {
try {
console.log(createHash("sha256").update(await readFile(path)).digest("hex"))
} catch (error) {
console.error("Operation failed")
}
printCWD()
}
15 changes: 12 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import process from "node:process"
import readline from "node:readline/promises"
import { handleUserInput } from "./user_input/handleUserInput.js"

export const printCWD = () => console.log(`You are currently in ${process.cwd()}`)
import { homedir } from "node:os"
import { printCWD } from "./utils/printCWD.js"

async function fileManager() {
const rl = readline.createInterface({ input: process.stdin, output: process.stdout })
Expand All @@ -11,9 +11,18 @@ async function fileManager() {
|| await rl.question("Please, provide your username: ")

console.log(`Welcome to the File Manager, ${username}!`)

process.chdir(homedir())

printCWD()

rl.on("line", async (line) => await handleUserInput(line))
rl.on("line",
(line) => line === ".exit" || line === "CLOSE"
? process.exit()
: handleUserInput(line.trim())
)

process.on("exit", () => console.log(`Thank you for using File Manager, ${username}, goodbye!`))
}

await fileManager()
24 changes: 24 additions & 0 deletions os/handleOSCommands.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { EOL, cpus, homedir, userInfo } from "node:os"

export function handleOSCommands(command) {
switch (command) {
case "--EOL":
console.log(`End of line: ${JSON.stringify(EOL)}`)
break;
case "--cpus":
console.log("Machine CPUs: ", cpus().map(cpu => cpu.model))
break;
case "--homedir":
console.log(`Home directory: ${homedir}`)
break;
case "--username":
console.log(`System username: ${userInfo().username}`)
break;
case "--architecture":
console.log(`CPU architecture: ${process.arch}`)
break;
default:
console.error("Invalid input")
break;
}
}
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "file-manager",
"version": "1.0.0",
"description": "RS school file manager task",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"repository": {
"type": "git",
"url": ""
},
"author": "bulbex",
"license": "ISC"
}
77 changes: 77 additions & 0 deletions user_input/handleUserInput.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { handleFileOperation } from "../file_operations/handleOperations.js"
import { handleOSCommands } from "../os/handleOSCommands.js"
import { printCWD } from "../utils/printCWD.js"
import { readdir } from "node:fs"
import { hashFile } from "../hash/handleHashCommand.js"
import { handleCompDecomp } from "../compress_decompress/handleCompDecomp.js"

export async function handleUserInput(line) {
try {
if (line === "") {
printCWD()
return
}

if (line === "up") {
process.chdir("..")
printCWD()
return
}

if (line === "ls") {
readdir(process.cwd(), {withFileTypes: true},
(err, files) => {
if (err) {
console.error("Operation failed")
return
}
console.table(
files.sort((a, b) => {
return a.isDirectory()
? b.isDirectory()
? a.name - b.name
: -1
: b.isDirectory()
? 1
: a.name - b.name
}).map(file => Object.assign({ name: file.name, type: file.isDirectory() ? 'directory' : 'file' })))
printCWD()
})
return
}

if (line.startsWith("cd ")) {
process.chdir(line.split(" ").slice(1).join(" "))
printCWD()
return
}

if (line.startsWith("os ")) {
handleOSCommands(line.split(" ")[1])
printCWD()
return
}

const command = line.split(" ")[0]
const filePaths = command.startsWith("cp") && line.split(" ").slice(1).length === 2
? line.split(" ").slice(1)
: line.slice(command.length).match(/[^ (\"|\')][\:*\w+ \/\.]+[^ (\"|\')]/g)

if (line.startsWith("hash ")) {
await hashFile(filePaths[0])
return
}


if (line.startsWith("compress ") || line.startsWith("decompress ")) {
handleCompDecomp(command, filePaths)
return
}

await handleFileOperation(command, filePaths)

} catch (error) {
console.error(error)
printCWD()
}
}
5 changes: 5 additions & 0 deletions utils/getFileFromPath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function getFileFromPath(path) {
return path.includes("/")
? `${path.split("/").slice(-1)}`
: `${path.split("\\").slice(-1)}`
}
1 change: 1 addition & 0 deletions utils/printCWD.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const printCWD = () => console.log(`You are currently in ${process.cwd()}`)