Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A possible solution for the CoronaSafe Fellowship Todo CLI application
/*
https://fullstack.pupilfirst.org
https://github.com/nseadlc-2020/package-todo-cli-task/tree/master/shared
*/
const EOL = require('os').EOL
const fs = require('fs')
const PENDING_TODOS_FILE = 'todo.txt'
const COMPLETED_TODOS_FILE = 'done.txt'
const HELP_STRING = `Usage :-
$ ./todo add \"todo item\" # Add a new todo
$ ./todo ls # Show remaining todos
$ ./todo del NUMBER # Delete a todo
$ ./todo done NUMBER # Complete a todo
$ ./todo help # Show usage
$ ./todo report # Statistics`;
/* https://stackoverflow.com/a/57163283 */
let isEmpty = x => !Boolean(x);
/* https://stackoverflow.com/a/50130338 */
let getToday = () => {
let date = new Date();
return new Date(date.getTime() - (date.getTimezoneOffset() * 60000))
.toISOString()
.split("T")[0];
}
let readFile = (filename) => {
if (!fs.existsSync(filename)) {
return []
}
let text = fs.readFileSync(filename, {encoding: 'utf8', flag: 'r'})
lines = text.split(EOL)
return lines
}
let appendToFile = (filename, text) => {
fs.appendFileSync(filename, text, {encoding: 'utf8', flag: 'a+'});
}
let writeFile = (filename, lines) => {
let text = lines.join(EOL)
fs.writeFileSync(filename, text, {encoding: 'utf8'});
}
let updateFile = (filename, updaterFn) => {
let contents = readFile(filename)
contents = updaterFn(contents)
writeFile(filename, contents)
}
let cmdHelp = () => {
console.log(HELP_STRING);
}
let cmdLs = () => {
let todos = readFile(PENDING_TODOS_FILE)
if (todos.length == 0) {
console.log("There are no pending todos!")
return
}
let length = todos.length
todos = todos.reverse().map((todo, index) => `[${length - index}] ${todo}`)
console.log(todos.join("\n"))
}
let cmdAddTodo = (text) => {
if (isEmpty(text)) {
console.log("Error: Missing todo string. Nothing added!")
return
}
updateFile(PENDING_TODOS_FILE, todos => {
return todos.concat([text])
})
console.log(`Added todo: "${text}"`)
}
let cmdDelTodo = (number) => {
if (isEmpty(number)) {
console.log(`Error: Missing NUMBER for deleting todo.`)
return
}
number = Number(number)
updateFile(PENDING_TODOS_FILE, todos => {
if (number < 1 || number > todos.length) {
console.log(`Error: todo #${number} does not exist. Nothing deleted.`)
} else {
todos.splice(number, 1)
console.log(`Deleted todo #${number}`)
}
return todos
});
}
let cmdMarkDone = (number) => {
if (isEmpty(number)) {
console.log(`Error: Missing NUMBER for marking todo as done.`)
return
}
number = Number(number)
let todos = readFile(PENDING_TODOS_FILE)
if (number < 1 || number > todos.length) {
console.log(`Error: todo #${number} does not exist.`)
return
}
let completedTodo = todos.splice(number, 1)
writeFile(PENDING_TODOS_FILE, todos)
completedTodo = completedTodo[0] + EOL
appendToFile(COMPLETED_TODOS_FILE, completedTodo)
console.log(`Marked todo #${number} as done.`)
}
let cmdReport = () => {
let pending = readFile(PENDING_TODOS_FILE).length - 1
let completed = readFile(COMPLETED_TODOS_FILE).length - 1
console.log(`${getToday()} Pending : ${pending} Completed : ${completed}`)
}
let argv = process.argv
let command = argv[2];
let arg = argv[3];
if (isEmpty(command)) {
cmdHelp();
} else {
switch (command.trim().toLowerCase()) {
case 'help':
cmdHelp()
break;
case 'ls':
cmdLs()
break
case 'add':
cmdAddTodo(arg)
break
case 'del':
cmdDelTodo(arg)
break
case 'done':
cmdMarkDone(arg)
break
case 'report':
cmdReport()
break
default:
cmdHelp()
}
}
@mohamedhazzali3
Copy link

mohamedhazzali3 commented Feb 2, 2021

Good Morning Sir,
Iam beginner for this programming Language,Could you Please post the above program in C language for better understanding to me .
Thank you sir

@jasim
Copy link
Author

jasim commented Feb 2, 2021

@mohamedhazzali3 Sorry, we won't be able to port this to other languages.

@gex7777
Copy link

gex7777 commented Feb 2, 2021

impressive way of handling the io operations, I used js too and found it hard to keep the code clean, thank you for this

@arnabsen1729
Copy link

arnabsen1729 commented Feb 16, 2021

@mohamedhazzali3 You can see my approach todo-cli-c. I have divided the program into separate modules.

  • fileHandling.c : to handle file operations
  • commands.c: to handle the commands
  • main.c: main entrypoint for the program
    It passed all the tests as well.
    Tried to follow the good practices in C. See if you can find some room for improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment