Skip to content

Commit 635ebc5

Browse files
committed
working demo complete
1 parent b835d05 commit 635ebc5

8 files changed

Lines changed: 290 additions & 112 deletions

File tree

build.sbt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ name := "alist"
22
organization := "com.shiftio"
33
version := "1.0-SNAPSHOT"
44
scalaVersion := "2.13.1"
5+
lazy val circeVersion = "0.12.3"
56
libraryDependencies ++= Seq(
67
"com.github.pathikrit" %% "better-files" % "3.9.1",
78
"com.colofabrix.scala" %% "figlet4s-core" % "0.3.0",
89
"org.scalatest" %% "scalatest" % "3.1.0" % Test,
9-
"com.github.nscala-time" %% "nscala-time" % "2.28.0",
10-
"com.lihaoyi" %% "upickle" % "1.3.8",
11-
"com.lihaoyi" %% "fansi" % "0.2.14"
12-
)
10+
"com.lihaoyi" %% "fansi" % "0.2.14",
11+
"com.github.tototoshi" %% "scala-csv" % "1.3.8"
12+
13+
)

db.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2,Play some games,Play COD,N/A,false
2+
3,Add a new test,Pick some tests to run and add them,N/A,true

res/db.json

Whitespace-only changes.

src/main/scala/Api.scala

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import DB.inMemory
2+
import commons.OS._
3+
import commons._
4+
5+
import java.time.LocalDate
6+
import java.time.format.DateTimeFormatter
7+
import scala.io.StdIn.readLine
8+
import scala.language.postfixOps
9+
import scala.sys.process._
10+
11+
12+
object Api {
13+
14+
val listHeading: String =
15+
" ID | NAME | DESCRIPTION | DUE DATE | REMINDER " +
16+
"\n ------------------------------------------------------------"
17+
18+
def parse(string: String, limit: Int = 10): String =
19+
s"$string...${" " * ((limit - 3) - string.length)}"
20+
21+
def listTodoItem(x: TodoItem): Unit =
22+
println(s" ${x.id} | ${parse(x.name.take(7))} | ${parse(x.desc.take(10))} | ${parse(x.dueBy.getOrElse("N/A").toString.take(5))} | ${if (x.remind) " Yes" else " No"}")
23+
24+
def viewTodoItem(x: TodoItem): Unit =
25+
println(
26+
s""" ID: ${x.id}
27+
| Name: ${x.name}
28+
| Description: ${x.desc}
29+
| Due Date: ${x.dueBy.getOrElse("N/A")}
30+
| Remind Me: ${if (x.remind) "Yes" else "No"} """.stripMargin
31+
)
32+
33+
def cls(): Unit = _OS_NAME_ match {
34+
case LINUX => "clear".!
35+
case MAC_OS_X => "clear".!
36+
case WINDOWS => "cmd.exe -c cls".!
37+
case SUN_OS => "clear".!
38+
case FREEBSD => "clear".!
39+
case UNKNOWN =>
40+
println("Unrecognized OS\nExiting...")
41+
System.exit(0)
42+
}
43+
44+
def readVar(identifier: String): String = {
45+
print(identifier)
46+
readLine
47+
}
48+
49+
def add(): Unit = {
50+
println(" Add a new todo list item")
51+
val name = readVar("\tName: ")
52+
val desc = readVar("\tDescription: ")
53+
val dueBy = readVar("\tDue Date[yyyy-MM-dd][Press Enter to skip]: ") match {
54+
case "" => None
55+
case date => Some(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
56+
}
57+
val remind = readVar("\tRemind[y/n]: ") match {
58+
case "y" => true
59+
case _ => false
60+
}
61+
inMemory = inMemory.appended(TodoItem(if (inMemory.isEmpty) 1 else inMemory.maxBy(_.id).id + 1, name, desc, dueBy, remind = remind))
62+
}
63+
64+
def list(): Unit = {
65+
if (inMemory.isEmpty) {
66+
println(" You've not added any items yet!")
67+
} else {
68+
println(listHeading)
69+
inMemory foreach listTodoItem
70+
}
71+
}
72+
73+
def edit(id: Int): Unit = {
74+
if (inMemory.isEmpty) {
75+
println(" No todo list item matches id " + id)
76+
} else {
77+
println("\tPress enter to leave unchanged")
78+
inMemory = inMemory.filterNot(_.id == id) ::: inMemory.filter(_.id == id).map(x => {
79+
println(s"\tOld Name: ${x.name}")
80+
val newName = readVar("\tNew Name: ")
81+
println(s"\tOld Description: ${x.desc}")
82+
val newDesc = readVar("\tNew Description: ")
83+
println(s"\tOld Due Date: ${x.dueBy}")
84+
val newDueBy = readVar("\tNew Due Date[yyyy-MM-dd]: ")
85+
println(s"\tOld Remind: ${x.remind}")
86+
val newRemind = readVar("\tRemind[y/n]: ")
87+
x.copy(
88+
x.id,
89+
{
90+
if (newName == "") {
91+
x.name
92+
} else {
93+
newName
94+
}
95+
},
96+
{
97+
if (newDesc == "") {
98+
x.desc
99+
} else {
100+
newDesc
101+
}
102+
},
103+
{
104+
if (newDueBy == "") {
105+
x.dueBy
106+
} else {
107+
Some(LocalDate.parse(newDueBy, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
108+
}
109+
},
110+
{
111+
if (newRemind == "") {
112+
x.remind
113+
} else if (newRemind == "y") {
114+
true
115+
} else {
116+
false
117+
}
118+
}
119+
)
120+
})
121+
}
122+
}
123+
}

src/main/scala/DB.scala

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import better.files.Dsl.pwd
2+
import better.files.File
3+
import commons.TodoItem
4+
5+
import java.time.LocalDate
6+
import java.time.format.DateTimeFormatter
7+
8+
object DB {
9+
10+
val db: File = pwd / "db.csv"
11+
12+
var inMemory: List[TodoItem] = selectAll
13+
14+
def selectAll: List[TodoItem] = {
15+
if (!db.exists) {
16+
println("[INFO] DB file not found!\n[INFO] Creating new db in present working directory")
17+
db.createFile()
18+
}
19+
read()
20+
}
21+
22+
def read(): List[TodoItem] = {
23+
val data = db.contentAsString
24+
if (data == "") {
25+
List()
26+
} else {
27+
data.split("\n").map(_.split(",")).map(
28+
item => {
29+
val n = item(3) match {
30+
case "N/A" => None
31+
case _ => Some(LocalDate.parse(item(3), DateTimeFormatter.ofPattern("yyyy-MM-dd")))
32+
}
33+
TodoItem(item.head.toInt, item(1), item(2), n, if (item(4).last.toInt == 1) true else false)
34+
}
35+
).toList
36+
}
37+
}
38+
39+
def commit(): Unit = {
40+
db.write(
41+
inMemory.map(item => {
42+
List(item.id, item.name, item.desc, item.dueBy.getOrElse("N/A"), item.remind).mkString(",")
43+
}).mkString("\n"))
44+
}
45+
}

src/main/scala/Main.scala

Lines changed: 46 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,88 @@
1-
import OS._OS_NAME_
2-
import com.colofabrix.scala.figlet4s.unsafe.{FIGureOps, Figlet4s, OptionsBuilderOps}
1+
//import Api.nextID
2+
3+
import Api._
4+
import DB.{commit, inMemory}
5+
import commons._
36

4-
import java.time.LocalDateTime
57
import scala.annotation.tailrec
68
import scala.io.StdIn._
79
import scala.language.postfixOps
8-
import scala.sys.process._
9-
import scala.util.{Failure, Random, Success, Try}
10+
import scala.util.{Failure, Success, Try}
1011

1112
object Main extends App {
1213

13-
case class TodoItem(id: Int, name: String, desc: String, dueBy: Option[LocalDateTime], remind: Boolean)
14-
15-
val asciiStyle = fansi.Bold.On ++ Random.shuffle(fansi.Color.all).head
16-
val captionStyle = fansi.Bold.On ++ Random.shuffle(fansi.Color.all).head
17-
val helpStyle = fansi.Underlined.On ++ fansi.Bold.On ++ Random.shuffle(fansi.Color.all).head
18-
val promptText = "> "
19-
val listHeading =
20-
"\tID | NAME | DESCRIPTION | DUE BY | REMINDER SET" +
21-
"\n\t------------------------------------------------------------"
22-
23-
val helpText =
24-
""" add: Add a new todo list item
25-
| list: Lists all available todo list items
26-
| view [x]: View todo list item with id x
27-
| edit [x]: Edit todo list item with id x
28-
| del [x]: Delete todo list item with id x
29-
| help: Prints this message
30-
""" stripMargin
31-
32-
def todoList: List[TodoItem] =
33-
List(
34-
TodoItem(1, "Dishes", "Remember to wash the dishes", None, remind = false),
35-
TodoItem(2, "Sweep", "Sweep the living room and kitchen", None, remind = false),
36-
TodoItem(3, "Wash", "Wash all the dirty clothes available", None, remind = true),
37-
TodoItem(4, "Homework", "Do PHY101 homework with the internet", Some(LocalDateTime.now()), remind = true),
38-
TodoItem(5, "Submit", "Submit PHY101 homework", Some(LocalDateTime.now()), remind = true)
39-
)
40-
41-
def parse(string: String, limit: Int = 10): String =
42-
s"$string...${" " * ((limit - 3) - string.length)}"
43-
44-
def listTodoItem(x: TodoItem): Unit =
45-
println(s"\t${x.id} | ${parse(x.name.take(7))} | ${parse(x.desc.take(10))} | ${parse(x.dueBy.getOrElse("N/A").toString.take(5))} | ${if (x.remind) " Yes" else " No"}")
46-
47-
def viewTodoItem(x: TodoItem): Unit =
48-
println(
49-
s""" ID: ${x.id}
50-
| Name: ${x.name}
51-
| Description: ${x.desc}
52-
| Due By: ${x.dueBy.getOrElse("N/A")}
53-
| Remind Me: ${if (x.remind) "Yes" else "No"} """.stripMargin
54-
)
55-
56-
def cls(): Unit =
57-
_OS_NAME_ match {
58-
case OS.LINUX => "clear".!
59-
case OS.MAC_OS_X => "clear".!
60-
case OS.WINDOWS => "cmd.exe -c cls".!
61-
case OS.SUN_OS => "clear".!
62-
case OS.FREEBSD => "clear".!
63-
case OS.UNKNOWN =>
64-
println("Unrecognized OS\nExiting...")
65-
System.exit(0)
66-
}
67-
68-
69-
def handle(input: String): Unit = {
14+
def run(input: String): Unit = {
7015
cls()
7116

72-
println(
73-
asciiStyle(Figlet4s
74-
.builder("AList 1 . 0 !")
75-
.render
76-
.asSeq
77-
.mkString("\n"))
78-
++ captionStyle("\nGet your life organized!")
79-
++ helpStyle("\nType help to view options\n")
80-
)
17+
println(header)
8118

8219
input match {
8320
case h if h take 4 equalsIgnoreCase "help" => println(helpText)
8421

85-
case v if v take 4 equalsIgnoreCase "add" => ???
22+
case v if v take 4 equalsIgnoreCase "add" => add()
8623

87-
case x if x take 4 equalsIgnoreCase "list" =>
88-
println(listHeading)
89-
todoList foreach listTodoItem
24+
case x if x take 4 equalsIgnoreCase "list" => list()
9025

9126
case v if v take 4 equalsIgnoreCase "view" =>
9227
Try(
93-
v.last.toString.toInt
28+
v.split(" ").last.toInt
9429
) match {
9530
case Failure(err) => println(s"View process failed with exception: ${err.getCause}")
9631
case Success(id) =>
97-
todoList filter (_.id == id) foreach viewTodoItem
32+
inMemory filter (_.id == id) match {
33+
case x if x.isEmpty =>
34+
println(" No todo list item matches id " + id)
35+
case x =>
36+
x foreach viewTodoItem
37+
}
9838
}
9939

100-
case v if v take 4 equalsIgnoreCase "edit" => ???
40+
case v if v take 4 equalsIgnoreCase "edit" =>
41+
Try(
42+
v.split(" ").last.toInt
43+
) match {
44+
case Failure(err) => println(s"Edit process failed with exception: ${err.getCause}")
45+
case Success(id) =>
46+
edit(id)
47+
}
10148

102-
case v if v take 4 equalsIgnoreCase "del" => ???
49+
case v if v take 3 equalsIgnoreCase "drop" =>
50+
Try(
51+
v.split(" ").last.toInt
52+
) match {
53+
case Failure(err) => println(s"View process failed with exception: ${err.getCause}")
54+
case Success(id) =>
55+
if (inMemory.isEmpty) {
56+
println(" No todo list item matches id " + id)
57+
} else {
58+
inMemory = inMemory.filterNot(_.id == id)
59+
}
60+
}
61+
list()
62+
63+
case q if q take 4 equalsIgnoreCase "quit" =>
64+
println("Goodbye!")
65+
System.exit(0)
10366

10467
case _ => println("Unrecognized Input!")
10568

10669
}
70+
commit()
10771
}
10872

10973
@tailrec
11074
def prompt(): Unit = {
11175
print(promptText)
11276

113-
handle(readLine)
77+
run(readLine)
11478

11579
prompt()
11680
}
11781

11882
cls()
83+
11984
println(
120-
asciiStyle(Figlet4s
121-
.builder("AList 1 . 0 !")
122-
.render
123-
.asSeq
124-
.mkString("\n"))
125-
++ captionStyle("\nGet your life organized!")
126-
++ helpStyle("\nType help to view options\n")
85+
header
12786
)
12887
prompt()
12988
}

src/main/scala/OS.scala

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)