diff --git a/.classpath b/.classpath new file mode 100644 index 00000000..b79fc0c5 --- /dev/null +++ b/.classpath @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index 99712178..723267e3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ /.gradle/ /build/ src/main/resources/docs/ - +src/main/java/tasks.txt # MacOS custom attributes files created by Finder .DS_Store *.iml diff --git a/.project b/.project new file mode 100644 index 00000000..6fb94a8c --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + duke + Project duke created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..e8895216 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..afafa9f1 --- /dev/null +++ b/build.gradle @@ -0,0 +1,37 @@ +plugins { + id 'java' + id 'application' + id 'checkstyle' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} +checkstyle{ + toolVersion = '8.23' +} +shadowJar { + archiveBaseName = "duke" + archiveVersion = "0.1.3" + archiveClassifier = null + archiveAppendix = null +} +group 'seedu.duke' +version '0.1.0' + +repositories { + mavenCentral() +} + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter:5.5.0' +} + +test { + useJUnitPlatform() +} +application { + // Change this to your main class. + mainClassName = "Duke" +} + +run { + standardInput = System.in +} diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 00000000..b1a57ba6 --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..87b738cb Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..4b7e1f3d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..af6708ff --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..6d57edc7 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..d1e92fe5 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'duke' diff --git a/src/main/java/DatePattern.java b/src/main/java/DatePattern.java new file mode 100644 index 00000000..d6a73974 --- /dev/null +++ b/src/main/java/DatePattern.java @@ -0,0 +1,17 @@ +class DatePattern { + enum TimePatternType { + DAY_OF_WEEK,DATE_TIME,DATE, TIME + } + private String pattern; + private ParseTime.TimePatternType type; + DatePattern(String Pattern, ParseTime.TimePatternType type_date ) { + pattern = Pattern; + type = type_date; + } + public ParseTime.TimePatternType get_type(){ + return type; + } + public String get_pattern(){ + return pattern; + } +} \ No newline at end of file diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 00000000..8e7a8b32 --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,37 @@ +import java.time.LocalDateTime; + +public class Deadline extends Task { + + protected String by; + protected LocalDateTime date_1; + protected boolean date = false; + + public Deadline(boolean to_add_status,String description, LocalDateTime by,String command) { + super(to_add_status,description); + date_1 = by; + date = true; + this.by = command.trim(); + } + public Deadline(boolean to_add_status,String description, String by) { + super(to_add_status,description); + this.by = by; + } + @Override + public String get_type() { + return "D"; + } + @Override + public String toString() { + if(date == false){ + return "[D]" + super.toString() + " (by: " + by + ")"; + } + else{ + return "[D]" + super.toString() + " (by: " + date_1 + ")"; + } + //return "[D]" + super.toString().trim() + " (by: " + by.trim() + ")"; + } + @Override + public String get_attrib(){ + return "D" + super.get_attrib()+"^"+by.trim(); + } +} \ No newline at end of file diff --git a/src/main/java/Duke.java b/src/main/java/Duke.java index 5d313334..ac95eec5 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Duke.java @@ -1,10 +1,121 @@ +import java.util.Scanner; +import java.util.*; +import java.io.FileOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + public class Duke { - public static void main(String[] args) { + private Storage storage; + private TaskList tasks; + private Ui ui; + public static void print_list(List list1){ + int i = 0; + for (Task temp : list1) { + System.out.print(i+1); + System.out.print("."); + System.out.println(temp); + i +=1; + } + } + public Duke(String filePath) { + ui = new Ui(); + storage = new Storage(filePath); + try { + + tasks = new TaskList(storage.load()); + //System.out.println(storage.load().get(0)); + + } catch (DukeException e) { + System.out.println("error for loading file"); + ui.showLoadingError(); + tasks = new TaskList(); + } + catch (FileNotFoundException e){ + System.out.println("error for loading file"); + ui.showLoadingError(); + tasks = new TaskList(); + } + catch(Exception e){ + System.out.println(e); + ui.showLoadingError(); + tasks = new TaskList(); + } + } + public void run(){ String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; + + "| _ \\ _ _| | _____ \n" + + "| | | | | | | |/ / _ \\\n" + + "| |_| | |_| | < __/\n" + + "|____/ \\__,_|_|\\_\\___|\n"; System.out.println("Hello from\n" + logo); + System.out.println("Hello! I'm Duke\nWhat can I do for you?"); + //List l1 = new ArrayList(); + try{ + Parser analyser = new Parser(tasks,storage); + StringParser parse_string = new StringParser(analyser,storage,tasks); + Scanner input = new Scanner(System.in); + while(true){ + if(input.hasNextLine()){ + String command = input.nextLine(); + + String end = "bye"; + if(end.equals(command)){ + try { + storage.serial(tasks.get_list()); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + catch (Exception e) { + System.out.println(e); + } + analyser.bye(); + input.close(); + return; + } + else{ + //System.out.println("hello1221"); + parse_string.get_info(command); + } + } + else{ + //System.out.println("hdahhda"); + try { + storage.serial(tasks.get_list()); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + catch (Exception e) { + System.out.println(e); + } + input.close(); + return; + } + } + + } + + catch(Exception e){ + System.out.println("error"); + System.out.println(e.getMessage()); + } + + + } + public static void main(String[] args) { + new Duke("tasks.txt").run(); } } diff --git a/src/main/java/DukeException.java b/src/main/java/DukeException.java new file mode 100644 index 00000000..f55848b7 --- /dev/null +++ b/src/main/java/DukeException.java @@ -0,0 +1,6 @@ +public class DukeException extends Exception{ + public DukeException(String message){ + super(message); + } + +} \ No newline at end of file diff --git a/src/main/java/DukeTimeException.java b/src/main/java/DukeTimeException.java new file mode 100644 index 00000000..45aa1aa9 --- /dev/null +++ b/src/main/java/DukeTimeException.java @@ -0,0 +1,5 @@ +public class DukeTimeException extends DukeException { + public DukeTimeException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/src/main/java/Events.java b/src/main/java/Events.java new file mode 100644 index 00000000..0b95d7a3 --- /dev/null +++ b/src/main/java/Events.java @@ -0,0 +1,43 @@ +import java.time.LocalDateTime; + +public class Events extends Task { + + protected String end; + protected LocalDateTime end_date; + protected boolean date = false; + protected String start; + protected LocalDateTime start_date; + @Override + public String get_type() { + return "E"; + } + public Events(boolean to_add_status,String description, LocalDateTime start_d,LocalDateTime end_d, String command_start, String command_end) { + super(to_add_status,description); + end_date = end_d; + start_date = start_d; + date = true; + this.end = command_end.trim(); + this.start = command_start.trim(); + } + public Events(boolean to_add_status,String description, String start, String end) { + super(to_add_status,description); + this.end = end; + this.start = start; + } + @Override + public String toString() { + if(date == false){ + return "[E]" + super.toString() + " (at: " + start.trim() + " to " + end.trim() + ")"; + } + else{ + return "[E]" + super.toString() + " (at: " + start_date + " to "+end_date+ ")"; + } + + } + @Override + public String get_attrib(){ + //System.out.println(super.get_attrib()); + return "E" + super.get_attrib()+"^"+start.trim()+"^"+end.trim(); + } + +} \ No newline at end of file diff --git a/src/main/java/ParseTime.java b/src/main/java/ParseTime.java new file mode 100644 index 00000000..e538bfa1 --- /dev/null +++ b/src/main/java/ParseTime.java @@ -0,0 +1,50 @@ +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAdjusters; +class ParseTime { + enum TimePatternType { + DAY_OF_WEEK,DATE_TIME,DATE, TIME + } + LocalDateTime parseStringToDate(String line) throws DukeTimeException { + Task[] j = {new Task(false, "hello")}; + //String[] patterns = { new DatePattern("['next ']['this ']E",TimePatternType.DAY_OF_WEEK ), "['this ']['next ']EEEE", "dd/MM/yyyy HHmm", + // "dd/MM/yy HHmm","d/MM/yyyy HHmm", "HHmm", + // "dd/MM/yy", "yyyy-MM-dd'T'HH:mm[:ss.n]"}; + DatePattern[] patterns = { new DatePattern("['next ']['this ']E",TimePatternType.DAY_OF_WEEK ), new DatePattern("['this ']['next ']EEEE",TimePatternType.DAY_OF_WEEK ),new DatePattern("dd/MM/yyyy HHmm",TimePatternType.DATE_TIME) , + new DatePattern("dd/MM/yy HHmm",TimePatternType.DATE_TIME ),new DatePattern("d/MM/yyyy HHmm",TimePatternType.DATE_TIME ),new DatePattern( "HHmm",TimePatternType.TIME ), + new DatePattern("dd/MM/yy",TimePatternType.DATE ), new DatePattern("yyyy-MM-dd'T'HH:mm[:ss.n]",TimePatternType.DATE_TIME )}; + /*TimePatternType[] types = {TimePatternType.DAY_OF_WEEK, TimePatternType.DAY_OF_WEEK, + TimePatternType.DATE_TIME, TimePatternType.DATE_TIME, TimePatternType.DATE_TIME, TimePatternType.TIME, TimePatternType.DATE, + TimePatternType.DATE_TIME};*/ + + for (int i = 0; i < patterns.length;) { + try { + TemporalAccessor accessor = DateTimeFormatter.ofPattern(patterns[i].get_pattern()).parse(line); + if(patterns[i].get_type()== TimePatternType.DAY_OF_WEEK){ + LocalDateTime localDateTime = LocalDateTime.now(); + return localDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.from(accessor))); + } + else if(patterns[i].get_type() == TimePatternType.DATE_TIME){ + return LocalDateTime.from(accessor); + } + else if(patterns[i].get_type()==TimePatternType.TIME){ + LocalDate localDate = LocalDate.now(); + return localDate.atTime(LocalTime.from(accessor)); + } + else if(patterns[i].get_type() == TimePatternType.DATE){ + LocalTime localTime = LocalTime.now(); + return localTime.atDate(LocalDate.from(accessor)); + } + + } catch (DateTimeParseException e) { + i+=1; + } + } + throw new DukeTimeException("invalid format!"); + } +} \ No newline at end of file diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 00000000..737196a4 --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,196 @@ +import java.util.*; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.time.LocalDateTime; + +public class Parser { + //private ArrayList l1; + private ArrayList temp; + private TaskList task_1; + private Storage writer; + public String delete(int index) throws DukeException, Exception{ + if(index >= 1 && index <= task_1.get_size()){ + Task deleted = task_1.get_index(index-1); + task_1.delete(index); + String message = "Noted. I've removed this task: \n "+ deleted +"\n"+get_end_message(task_1.get_size()); + + + serial(); + return message; + } + else{ + throw new DukeException("Please give a valid task index to delete!"); + } + } + + public Parser(TaskList t1,Storage writer1) throws FileNotFoundException,IOException,DukeException{ + task_1 = t1; + writer = writer1; + //deserial(); + //System.out.println("jjdaj"); + } + public static String get_end_message(Integer num){ + String task_num; + if(num==1){ + task_num = "task"; + } + else{ + task_num = "tasks"; + } + return "Now you have " + Integer.toString(num)+ " " + task_num+ " in the list."; + } + public void print_list(){ + task_1.print_list(); + } + public String find(String keyword){ + return task_1.find(keyword); + } + public void bye(){ + System.out.println("Bye. Hope to see you again soon!"); + return; + } + public void done(int index) throws DukeException{ + System.out.println("Nice! I've marked this task as done: "); + if(index <= 0 || index > task_1.get_size()){ + String message = "☹ OOPS!!! The index doesnt exists! Please check again!:("; + throw new DukeException(message); + } + else{ + System.out.println(" [✓] "+task_1.get_index(index-1).get_name()); + task_1.change_status(index-1,true); + } + } + /** + * Creates a end message for the number items in the list. + * @param int num, the number of items in the list. + * @return String + */ + public static String get_end_message(int num){ + String task_num; + if(num==1){ + task_num = "task"; + } + else{ + task_num = "tasks"; + } + return "Now you have " + Integer.toString(num)+ " " + task_num+ " in the list."; + } + /** + * Creates a new todo object and adds it to the array list through task_1. + * @param s String command + * @return void + */ + public void create_todo(String command) throws DukeException{ + String[] command_list = command.split(" ",2); + //System.out.println("inside create todo"); + if(command.split(" ",2).length>= 2 && !(command_list[1].trim().equals("")) ){ + command = command.split(" ",2)[1]; + + Task c1 = new Todo(false,command); + task_1.add_items(c1); + //System.out.println("inside create todo after splitting"); + System.out.println("Got it. I've added this task: \n"+" "+c1.toString()); + System.out.println(get_end_message(task_1.get_size())); + } + else{ + String message = "☹ OOPS!!! The description of a todo cannot be empty."; + throw new DukeException(message); + } + } + /** + * Creates a new event object and adds it to the array list through task_1. + * @param s String work + * @return void + */ + public void create_events(String work) throws DukeException{ + String[] tasks = work.split("\\/at"); + if(tasks.length >=2 && !(tasks[1].trim().equals("")) ){ + String task_to_be_done = tasks[0]; + String deadline_time = tasks[1]; + Task c1; + try{ + //LocalDateTime date_type = new ParseTime().parseStringToDate(deadline_time.trim()); + //System.out.println("Before : " + date_type); + String [] timing_list= deadline_time.split("-"); + + if(timing_list.length >= 2 && !(timing_list[1].trim().equals(""))){ + + //System.out.println(Arrays.toString(timing_list)); + + // System.out.println(Arrays.toString(timing_list)); + String[] string_list = {task_to_be_done,task_to_be_done,deadline_time}; + c1 = writer.get_first_e(string_list, false); + task_1.add_items(c1); + //System.out.println(c1); + } + else{ + + throw new DukeException("Please enter the start and end time"); + } + + } + catch (DukeTimeException e){ + System.out.println(e.getMessage()); + throw e; + } + //DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HHmm"); + //LocalDateTime dt = LocalDateTime.parse(deadline_time.trim(),formatter); + //System.out.println("Before : " + dt); + + System.out.println("Got it. I've added this task: \n"+" "+c1.toString()); + System.out.println(get_end_message(task_1.get_size())); + } + else{ + String message = "☹ OOPS!!! The description of a events should have a time! "; + throw new DukeException(message); + } + + } + /** + * Creates a new deadline and adds it to the array list through task_1. + * @param s String work + * @return void + */ + public void create_deadline(String work) throws DukeException{ + String[] tasks = work.split("\\/by"); + //System.out.println(Arrays.toString(tasks)+tasks[1].trim()); + if(tasks.length>= 2 && !(tasks[1].trim().equals(""))){ + //System.out.println("hello1"); + String task_to_be_done = tasks[0]; + String deadline_time = tasks[1]; + //Task c1 = new Deadline(false,task_to_be_done,deadline_time); + Task c1; + try{ + LocalDateTime date_type = new ParseTime().parseStringToDate(deadline_time.trim()); + //System.out.println("Before : " + date_type); + c1 = new Deadline(false,task_to_be_done,date_type,deadline_time.trim()); + } + catch (DukeTimeException e){ + c1 = new Deadline(false,task_to_be_done,deadline_time); + } + task_1.add_items(c1); + System.out.println("Got it. I've added this task: \n"+" "+c1.toString()); + System.out.println(get_end_message(task_1.get_size())); + } + else{ + String message = "☹ OOPS!!! The description of a deadline should have a deadline timing! "; + throw new DukeException(message); + } + + } + /** + * Writes the data to the file + */ + public void serial(){ + try{ + writer.serial(task_1.get_list()); + } + catch(Exception e){ + System.out.println(e); + } + } +} \ No newline at end of file diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 00000000..d13d596b --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,143 @@ +import java.util.*; +import java.io.IOException; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.time.LocalDateTime; + +public class Storage { + private String file_path; + private ArrayList l1 = new ArrayList(); + public Task get_first_e(String[] string_list,boolean t) throws DukeException{ + Task c1; + //System.out.println("help me"); + //System.out.println("here "+Arrays.toString(string_list)); + try{ + String[] timing = string_list[2].split("-"); + if(timing.length>= 2 && !(timing[1].trim().equals("")) ){ + //System.out.println(Arrays.toString(timing)); + LocalDateTime start_date = new ParseTime().parseStringToDate(timing[0].trim()); + LocalDateTime end_date = new ParseTime().parseStringToDate(timing[1].trim()); + //System.out.println("Before : " + date_type); + c1 = new Events(t,string_list[1],start_date,end_date,timing[0],timing[1]); + } + else{ + throw new DukeException("Please give a starting and ending time!"); + } + } + catch (DukeTimeException e){ + String[] timing = string_list[2].split("-"); + if(timing.length>= 2 && !(timing[1].trim().equals("")) ){ + c1 = new Events(t,string_list[1],timing[0],timing[1]); + } + else{ + throw new DukeException("Please give a starting and ending time!"); + } + } + return c1; + } + public void deserial() throws FileNotFoundException,IOException,DukeException{ + try{ + FileInputStream fstream = new FileInputStream(file_path); + + BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); + String strLine; + while ((strLine = br.readLine()) != null) { + //System.out.println(strLine); + String[] string_list = strLine.split("\\^"); + //System.out.println(Arrays.toString(string_list)); + if(string_list[0].equals("T")){ + boolean t; + if(string_list[1].equals("1")){ + t= true; + } + else{ + t = false; + } + //System.out.println("hello"); + Task temp = new Todo(t,string_list[2]); + l1.add(temp); + } + else if(string_list[0].equals("E")){ + boolean t; + if(string_list[1].equals("1")){ + t= true; + } + else{ + t = false; + } + Task c1; + try{ + String[] name_list = {string_list[1],string_list[2],string_list[3]+"-"+string_list[4]}; + l1.add(get_first_e(name_list,t)); + } + catch (DukeException e) { + throw e; + } + + //Task temp = new Events(t,string_list[2],string_list[3]); + //l1.add(c1); + } + else if(string_list[0].equals("D")){ + boolean t; + if(string_list[1].equals("1")){ + t= true; + } + else{ + t = false; + } + Task c1; + try{ + LocalDateTime date_type = new ParseTime().parseStringToDate(string_list[3].trim()); + //System.out.println("Before : " + date_type); + c1 = new Deadline(t,string_list[2],date_type,string_list[3]); + } + catch (DukeTimeException e){ + c1 = new Deadline(t,string_list[2],string_list[3]); + } + //Task temp = new Events(t,string_list[2],string_list[3]); + l1.add(c1); + + } + } + fstream.close(); + } + catch (FileNotFoundException e){ + System.out.println("no file found"); + + } + } + + public Storage(String file_path_1) { + file_path = file_path_1; + } + public ArrayList load() throws FileNotFoundException,IOException,DukeException{ + deserial(); + //System.out.println(file_path); + //System.out.println(l1.get(0)); + return l1; + } + public void serial(ArrayList l1) throws Exception{ + try{ + PrintWriter out = new PrintWriter("tasks.txt"); + String serialized = ""; + + for (Task temp : l1) { + //System.out.println("PRINTING " ); + //System.out.println(temp.get_attrib()); + serialized += temp.get_attrib() +"\n"; + } + //System.out.println(serialized); + out.println(serialized); + out.close (); + } + catch (Exception e){ + throw e; + } + } +} + + + \ No newline at end of file diff --git a/src/main/java/StringParser.java b/src/main/java/StringParser.java new file mode 100644 index 00000000..7f447e57 --- /dev/null +++ b/src/main/java/StringParser.java @@ -0,0 +1,161 @@ +import java.util.ArrayList; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class StringParser { + private Parser analyser; + private Storage storage; + private TaskList tasks; + public StringParser(Parser analyser_1,Storage storage_1,TaskList tasks_1){ + analyser = analyser_1; + storage = storage_1; + tasks = tasks_1; + } + public void get_info(String command){ + String end = "bye"; + String show_data = "list"; + String done = "done"; + String deadline = "deadline"; + String todo = "todo"; + String events = "event"; + String remove = "delete"; + String find = "find"; + if(show_data.equals(command.trim())){ + analyser.print_list(); + //System.out.println(l1); + } + + else{ + String[] values = command.trim().split(" ",2); + //marking as done + //System.out.println(Arrays.toString(values)); + + if(remove.equals(values[0])){ + try{ + System.out.println(analyser.delete( Integer.parseInt(values[1].trim()))); + } + catch (NumberFormatException e){ + System.out.println("please enter a valid number"); + } + catch (ArrayIndexOutOfBoundsException e){ + System.out.println("please give a second value!"); + } + catch(DukeException e){ + System.out.println(e.getMessage()); + } + catch(Exception e){ + System.out.println(e.getMessage()); + } + } + + else if(find.equals(values[0])){ + try{ + System.out.println(analyser.find(values[1])); + } + catch(ArrayIndexOutOfBoundsException e){ + System.out.println("Please enter a keyword"); + } + + } + else if(done.equals(values[0])){ + int index; + try{ + index = Integer.parseInt(values[1]); + analyser.done(index); + storage.serial(tasks.get_list()); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + catch(NumberFormatException nfe){ + System.out.println("Sorry, you dint enter a valid index number!"); + } + catch (Exception e) { + System.out.println(e); + } + + } + + else if(todo.equals(values[0])){ + try{ + //System.out.println("todo caaled"); + analyser.create_todo(command); + //System.out.println("todo caaled after create"); + storage.serial(tasks.get_list()); + } + catch (DukeException e){ + System.out.println(e.getMessage()); + } + + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + catch (Exception e) { + System.out.println(e); + } + } + + else if(events.equals(values[0])){ + try{ + analyser.create_events(values[1]); + storage.serial(tasks.get_list()); + } + catch (DukeException e){ + System.out.println(e.getMessage()); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + catch (Exception e){ + System.out.println(e.getMessage()); + } + } + + else if(deadline.equals(values[0])){ + String work = values[1]; + try{ + analyser.create_deadline(work); + storage.serial(tasks.get_list()); + } + catch (DukeException e){ + System.out.println(e.getMessage()); + } + catch (FileNotFoundException e) { + e.printStackTrace(); + } + catch (IOException e) { + e.printStackTrace(); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + catch (Exception e){ + System.out.println(e.getMessage()); + } + } + + else{ + System.out.println("☹ OOPS!!! I'm sorry, but I don't know what that means :-("); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 00000000..51605613 --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,48 @@ +import java.io.Serializable; + +//this is the Task class +public class Task implements Serializable{ + private boolean status; + private String name; + private static final long serialVersionUID = 1L; + public Task(boolean to_add_status, String name_to_add){ + status = to_add_status; + name = name_to_add; + } + public void change_status(boolean to_change_status){ + status = to_change_status; + } + public void change_task(String to_change_task){ + name = to_change_task; + } + public boolean get_status(){ + return status; + } + public String get_name(){ + return name; + } + public String get_type(){ + return "T"; + } + public String toString() { + + if(status == true){ + String name_1 = "[✓] "+get_name().trim(); + return name_1; + } + else{ + String name_1 = "[✗] "+get_name().trim(); + return name_1; + } + } + public String get_attrib(){ + String type; + if(status==true){ + type = "1"; + } + else{ + type = "0"; + } + return "^"+type+"^"+name ; + } +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 00000000..c7931864 --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,72 @@ +import java.util.ArrayList; + +public class TaskList { + private ArrayList l1 ; + + public TaskList(){ + l1 = new ArrayList(); + } + public TaskList(ArrayList temp ){ + //System.out.println("tasklist temp"); + l1 = temp; + } + public void add_items(Task temp){ + //System.out.println("added items to list sucessfully"); + l1.add(temp); + } + public ArrayList get_list(){ + return l1; + } + public Task get_index(int num){ + return l1.get(num); + } + public int get_size(){ + return l1.size(); + } + public void print_list(){ + int i = 0; + for (Task temp : l1) { + System.out.print(i+1); + System.out.print("."); + //boolean status = temp.get_status(); + System.out.println(temp); + i +=1; + } + } + public String find(String keyword){ + String message = ""; + int num = 1; + for (Task temp : l1) { + //System.out.println("PRINTING " ); + //System.out.println(temp.get_attrib()); + + if(temp.get_name().contains(keyword)){ + if(num==1){ + message +="Here are the matching tasks in your list:\n"; + } + message +=String.valueOf(num)+"."+ temp+"\n"; + num+=1; + } + } + if(message == ""){ + return "No such keyword found!"; + } + else{ + return message; + } + } + public void delete(int index) throws DukeException, Exception{ + if(index >= 1 && index <= l1.size()){ + + l1.remove(index-1); + + } + else{ + throw new DukeException("Please give a valid task index to delete!"); + } + } + public void change_status(int index,boolean val){ + l1.get(index-1).change_status(val); + } + +} \ No newline at end of file diff --git a/src/main/java/Todo.java b/src/main/java/Todo.java new file mode 100644 index 00000000..fad6da7b --- /dev/null +++ b/src/main/java/Todo.java @@ -0,0 +1,15 @@ +public class Todo extends Task { + + public Todo(boolean to_add_status,String description) { + super(to_add_status,description); + } + + @Override + public String toString() { + return "[T]" + super.toString().trim() ; + } + @Override + public String get_attrib(){ + return "T" + super.get_attrib(); + } +} \ No newline at end of file diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 00000000..aeada8e2 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,8 @@ +public class Ui { + public Ui(){ + } + public void showLoadingError(){ + System.out.println("Error in Loading of file"); + } + +} \ No newline at end of file diff --git a/src/test/java/DukeTest.java b/src/test/java/DukeTest.java new file mode 100644 index 00000000..c09b85c0 --- /dev/null +++ b/src/test/java/DukeTest.java @@ -0,0 +1,12 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DukeTest { + @Test + public void dummyTest(){ + Task todo = new Deadline(false,"assignment","monday 2359"); + System.out.println(todo.toString()); + assertEquals(todo.toString(), "[D][✗] assignment (by: monday 2359)"); + } +} \ No newline at end of file diff --git a/src/test/java/TodoTest.java b/src/test/java/TodoTest.java new file mode 100644 index 00000000..2103158d --- /dev/null +++ b/src/test/java/TodoTest.java @@ -0,0 +1,11 @@ +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TodoTest { + @Test + public void dummyTest(){ + Task todo = new Todo(false,"Buy Eggs"); + assertEquals(todo.toString(), "[T][✗] Buy Eggs"); + } +} \ No newline at end of file diff --git a/text-ui-test/ACTUAL.TXT b/text-ui-test/ACTUAL.TXT new file mode 100644 index 00000000..d784fdf0 --- /dev/null +++ b/text-ui-test/ACTUAL.TXT @@ -0,0 +1,13 @@ +Hello from + ____ _ +| _ \ _ _| | _____ +| | | | | | | |/ / _ \ +| |_| | |_| | < __/ +|____/ \__,_|_|\_\___| + +Hello! I'm Duke +What can I do for you? +1.[T][✗] hello +2.[T][✗] cs assignment +3.[T][✗] cs assignment +Bye. Hope to see you again soon! diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT new file mode 100644 index 00000000..d784fdf0 --- /dev/null +++ b/text-ui-test/EXPECTED.TXT @@ -0,0 +1,13 @@ +Hello from + ____ _ +| _ \ _ _| | _____ +| | | | | | | |/ / _ \ +| |_| | |_| | < __/ +|____/ \__,_|_|\_\___| + +Hello! I'm Duke +What can I do for you? +1.[T][✗] hello +2.[T][✗] cs assignment +3.[T][✗] cs assignment +Bye. Hope to see you again soon! diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt new file mode 100644 index 00000000..80216cfd --- /dev/null +++ b/text-ui-test/input.txt @@ -0,0 +1,2 @@ +list +bye diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh new file mode 100755 index 00000000..e173f837 --- /dev/null +++ b/text-ui-test/runtest.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# create bin directory if it doesn't exist +if [ ! -d "../bin" ] +then + mkdir ../bin +fi + +# delete output from previous run +if [ -e "./ACTUAL.TXT" ] +then + rm ACTUAL.TXT +fi + +# compile the code into the bin folder, terminates if error occurred +if ! javac -cp ../src -Xlint:none -d ../src/main/java ../src/main/java/*.java +then + echo "********** BUILD FAILURE **********" + exit 1 +fi + +# run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT +java -classpath ../src/main/java Duke < input.txt > ACTUAL.TXT + +# compare the output to the expected output +diff ACTUAL.TXT EXPECTED.TXT +if [ $? -eq 0 ] +then + echo "Test result: PASSED" + exit 0 +else + echo "Test result: FAILED" + exit 1 +fi \ No newline at end of file diff --git a/text-ui-test/tasks.txt b/text-ui-test/tasks.txt new file mode 100644 index 00000000..8f04cfba --- /dev/null +++ b/text-ui-test/tasks.txt @@ -0,0 +1,4 @@ +T^0^hello +T^0^cs assignment +T^0^cs assignment +