Skip to content

Commit

Permalink
Merge pull request #90 from AY2324S1-CS2113-F11-1/goalStorage
Browse files Browse the repository at this point in the history
Add FileIO function to restore saved goal record
  • Loading branch information
J-Y-Yan authored Nov 11, 2023
2 parents 0192df9 + 9b4a10e commit 64b2a2a
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 48 deletions.
7 changes: 6 additions & 1 deletion src/main/java/seedu/duke/Duke.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import seedu.duke.data.meal.Meal;
import seedu.duke.parser.Parser;
import seedu.duke.exerciselog.Log;
import seedu.duke.storagefile.GoalStorage;
import seedu.duke.ui.TextUi;
import seedu.duke.storagefile.StorageFile;

Expand All @@ -27,10 +28,12 @@ public class Duke {
public static GoalList achievedGoals = new GoalList();
public static Log exerciseLog = new Log();
public static StorageFile exerciseLogStorage;
public static GoalStorage goalStorage;
static ArrayList<Meal> meals = new ArrayList<Meal>();
private TextUi ui;
private String dirPath = "data";
private String exerciseLogFilePath = "./data/ExerciseLog.txt";
private String goalFilePath = "./data/GoalRecord.txt";
public static void main(String... launchArgs) {
new Duke().run(launchArgs);
}
Expand All @@ -55,7 +58,9 @@ private void start(String[] launchArgs) {
try {
this.ui = new TextUi();
this.exerciseLogStorage = StorageFile.initializeStorage(dirPath, exerciseLogFilePath);
exerciseLogStorage.checkForTextFile(exerciseLog);
exerciseLogStorage.checkForLogTextFile(exerciseLog);
this.goalStorage = GoalStorage.initializeGoalStorage(dirPath, goalFilePath);
goalStorage.restoreGoalRecord();
ui.showWelcomeMessage(VERSION, "storage.getPath()");
MealCommand.setMeals(meals);
} catch (Exception e) { // TODO: change to specific storage exceptions later
Expand Down
22 changes: 10 additions & 12 deletions src/main/java/seedu/duke/commands/HelpCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,18 @@ public class HelpCommand extends Command {

@Override
public CommandResult execute() {
String HelpMsg = HelpCommand.MESSAGE_USAGE + "\n";
HelpMsg += LogCommand.MESSAGE_USAGE + "\n";
HelpMsg += DeleteLogCommand.MESSAGE_USAGE + "\n";
HelpMsg += UpdateLogCommand.MESSAGE_USAGE + "\n";
HelpMsg += ViewLogCommand.MESSAGE_USAGE + "\n";
HelpMsg += GoalCommand.MESSAGE_USAGE + "\n";
HelpMsg += GoalCommand.MESSAGE_USAGE + "\n";
HelpMsg += DeleteLogCommand.MESSAGE_USAGE + "\n";
HelpMsg += ViewGoalCommand.MESSAGE_USAGE + "\n";
HelpMsg += AchieveGoalCommand.MESSAGE_USAGE + "\n";
HelpMsg += AchievementCommand.MESSAGE_USAGE;

return new CommandResult(
HelpMsg
HelpCommand.MESSAGE_USAGE
+ " \n" + LogCommand.MESSAGE_USAGE
+ "\n" + DeleteLogCommand.MESSAGE_USAGE
+ "\n" + UpdateLogCommand.MESSAGE_USAGE
+ "\n" + ViewLogCommand.MESSAGE_USAGE
+ "\n" + GoalCommand.MESSAGE_USAGE
+ "\n" + DeleteLogCommand.MESSAGE_USAGE
+ "\n" + ViewGoalCommand.MESSAGE_USAGE
+ "\n" + AchieveGoalCommand.MESSAGE_USAGE
+ "\n" + AchievementCommand.MESSAGE_USAGE

// + "\n" + DeleteCommand.MESSAGE_USAGE
// + "\n" + ClearCommand.MESSAGE_USAGE
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/seedu/duke/commands/goal/DeleteGoalCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import seedu.duke.data.GoalList;
import seedu.duke.data.exception.IncorrectFormatException;

import java.io.IOException;

public class DeleteGoalCommand extends Command {
public static final String COMMAND_WORD = "deleteg";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Delete an goal from the current goal list.\n"
Expand All @@ -29,10 +31,13 @@ public CommandResult execute() {
feedbackToUser = "Please input a valid number for delete index.";
} catch (IncorrectFormatException ife) {
feedbackToUser = ife.getMessage();
} catch (IOException io) {
feedbackToUser = "Failed to save data. Please check the output file and restart the app.";
} catch (Exception e) {
feedbackToUser = "Something went wrong, please try again.";
}


return new CommandResult(feedbackToUser);
}

Expand Down
7 changes: 7 additions & 0 deletions src/main/java/seedu/duke/commands/goal/GoalCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import seedu.duke.data.exception.IncorrectFormatException;
import seedu.duke.data.exception.InvalidDateException;

import java.io.IOException;


public class GoalCommand extends Command {

Expand Down Expand Up @@ -35,10 +37,15 @@ public CommandResult execute() {
feedbackToUser = "Please input a valid number for calories.";
} catch (InvalidDateException ide) {
feedbackToUser = ide.getMessage();
} catch (IOException io) {
feedbackToUser = "Failed to save data. Please check the output file and restart the app.";
} catch (Exception e) {
feedbackToUser = "Something went wrong, please try again.";
}




return new CommandResult(feedbackToUser);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ public CommandResult execute() throws IncorrectFormatException, IOException {
feedbackToUser = Duke.exerciseLog.updateExercise(month, day, oldExerciseName.trim(), oldCaloriesBurned,
newExerciseName.trim(), newCaloriesBurned) ? "Exercise successfully updated!" :
"Could not find exercise to update.";
Duke.exerciseLogStorage.updateExerciseInFile(month, day, oldExerciseName.trim().split(" "), oldCaloriesBurned,
Duke.exerciseLogStorage.updateExerciseInFile(month, day,
oldExerciseName.trim().split(" "), oldCaloriesBurned,
newExerciseName.trim().split(" "), newCaloriesBurned);

return new CommandResult(feedbackToUser);
Expand Down
24 changes: 6 additions & 18 deletions src/main/java/seedu/duke/data/Date.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,19 @@ public class Date {
public String standardString;
transient LocalDate date;

// @SerializedName("rawData")

/**
* Create a new date.
*
* @param rawData A String that needs to comply with a supported format and
* indicates a correct date that will be recorded by this Date
* instance.
* @throws TipsException Any excption will be throw in this type, which contains
* information about this exception and the possible
* solution.
* @param rawData refers to the date String
* @throws InvalidDateException if failed to parse date string input
*/
public Date(String rawData) throws InvalidDateException {
setRawData(rawData);
}

/**
* Modifying an existing date with a rawData String.
*
* @param rawData A String that needs to comply with a supported format and
* indicates a correct date that will be recorded by this Date
* instance.
* @throws TipsException Any excption will be throw in this type, which contains
* information about this exception and the possible
* solution.
* The method is used to set up the date field of a Date object
* It contains the actual implementation to parse date information from a string
* @param rawData refers to a date string
* @throws InvalidDateException if failed to parse date string input
*/
public void setRawData(String rawData) throws InvalidDateException {
for (DateTimeFormatter formatter : formatters) {
Expand Down
1 change: 0 additions & 1 deletion src/main/java/seedu/duke/data/Goal.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package seedu.duke.data;

import seedu.duke.data.Date;
import seedu.duke.data.exception.InvalidDateException;


Expand Down
10 changes: 7 additions & 3 deletions src/main/java/seedu/duke/data/GoalList.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import seedu.duke.data.exception.IncorrectFormatException;
import seedu.duke.data.exception.InvalidDateException;
import seedu.duke.ui.TextUi;
import seedu.duke.data.DateTime;

import java.io.IOException;
import java.util.ArrayList;

public class GoalList extends ArrayList<Goal> {
Expand Down Expand Up @@ -39,12 +39,15 @@ public int getGoalCount() {
* @param cmd Raw user Command
* @return message of succeeding to delete goal and tell user the updated total number of goals
*/
public static String deleteGoal(String cmd) throws IncorrectFormatException, NumberFormatException {
public static String deleteGoal(String cmd) throws IncorrectFormatException,
NumberFormatException, IOException {
verifyDeleteGoalInput(cmd);
String[] cmdSplit = cmd.toLowerCase().trim().split(" ");
int index = Integer.parseInt(cmdSplit[1]);
Goal targetGoal = Duke.goalList.goals.remove(index - 1);
Duke.goalList.goalCount--;
Duke.goalStorage.overwriteGoalToFile();

return TextUi.deleteGoalMsg(targetGoal) + TextUi.noOfGoalMsg(Duke.goalList.goalCount);
}

Expand Down Expand Up @@ -142,7 +145,7 @@ private static void verifyAchieveGoalInput(String cmd) throws IncorrectFormatExc
* @throws NumberFormatException if the user does not input a valid number
*/
public static String addGoal(String userCmd) throws IncorrectFormatException, NumberFormatException,
InvalidDateException {
InvalidDateException, IOException {
verifyGoalInput(userCmd); //if invalid, exceptions is thrown

String[] cmdSplit = userCmd.split(" ");
Expand All @@ -151,6 +154,7 @@ public static String addGoal(String userCmd) throws IncorrectFormatException, Nu

Duke.goalList.goals.add(new Goal(calories, date));
Duke.goalList.goalCount++;
Duke.goalStorage.overwriteGoalToFile();

return TextUi.addGoalSuccessMessage();
}
Expand Down
107 changes: 107 additions & 0 deletions src/main/java/seedu/duke/storagefile/GoalStorage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package seedu.duke.storagefile;

import seedu.duke.Duke;
import seedu.duke.data.GoalList;
import seedu.duke.ui.TextUi;

import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class GoalStorage extends StorageFile {

public GoalStorage(String dirName, String textFileName) {
super(dirName, textFileName);
}

public static GoalStorage initializeGoalStorage(String dirName, String textFilePath) {
return new GoalStorage(dirName, textFilePath);
}

/**
* This method restore any saved goal into goal list at the beginning to start the app.
* Both directory or save file not found will cause the app to start with an empty goal list
* if error occurs in loading saved date, the app will start with empty list immediately
* without loading part of data
* Note that this method also set up the file writer into overwrite mode
*/
public void restoreGoalRecord() throws IOException {
if (dir.exists() && textFile.exists()) {
try {
Scanner s = new Scanner(textFile);
while (s.hasNextLine()) {
String line = s.nextLine();
if (!line.trim().isEmpty()) {
textToGoalObject(line);
}
}
s.close();
} catch (FileNotFoundException fnf) {
System.out.println("Saved file cannot be found! FItNus will start with empty goal records.");
System.out.println(TextUi.buildingFileMsg());
Duke.goalList = new GoalList();
} catch (Exception e) {
System.out.println("Saved goal file is corrupted! FitNus will start with empty goal records.");
System.out.println(TextUi.buildingFileMsg());
Duke.goalList = new GoalList(); //start with an empty goal list
}
}

if (!dir.exists()) {
dir.mkdir();
}
if (!textFile.exists()) {
textFile.createNewFile();
Duke.goalList = new GoalList(); //start with an empty goal list
}

}

/**
* This method update the content of output Goal File by overwriting the file
* with all data saved in the current goalList
* Note that in the following implementation, the field writeFile in not used
* Instead, everytime a new file writer is created to update content of file
* @throws IOException if failed to access file
*/
public void overwriteGoalToFile() throws IOException {
String content = TextUi.contentOfGoalList(Duke.goalList);
if (content == null) {
return;
}
FileWriter fw = new FileWriter(textFile.toPath().toString(), false);
fw.write(content);
fw.close();
}

private static void textToGoalObject(String goalRecord) throws Exception {
String[] goalRecordParts = goalRecord.split(" ", 5);
//example of saved record: Consume 1230 kcal on Nov 11, 2023
int amount =Integer.parseInt(goalRecordParts[1]);
String savedDateString = goalRecordParts[4];
String date = convertDateFormat(savedDateString);
String restoredCommand = "set " + amount + " on " + date;
GoalList.addGoal(restoredCommand);
}


/**
* This method is used to convert a date String with format MMM d, yyyy into a date String with format dd/MM/yyyy
* @param originalDateString date String with format MMM d, yyyy, e.g. 11 Nov, 2023
* @return date String with format dd/MM/yyyy, e.g. 11/11/2023
*/
private static String convertDateFormat(String originalDateString) {
DateTimeFormatter originalFormatter = DateTimeFormatter.ofPattern("MMM d, yyyy", Locale.ENGLISH);
LocalDate originalDate = LocalDate.parse(originalDateString, originalFormatter);
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("dd/M/yyyy");
return originalDate.format(newFormatter);
}


}


9 changes: 5 additions & 4 deletions src/main/java/seedu/duke/storagefile/StorageFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import seedu.duke.exerciselog.Log;

public class StorageFile {
private static File dir;
private static File textFile;
private static FileWriter writeFile;
protected File dir;
protected File textFile;
protected FileWriter writeFile;

public StorageFile(String dirName, String textFileName) {
dir = new File(dirName);
Expand All @@ -22,7 +22,7 @@ public static StorageFile initializeStorage(String dirName, String textFilePath)
return new StorageFile(dirName, textFilePath);
}

public void checkForTextFile(Log exerciseLog) throws IOException {
public void checkForLogTextFile(Log exerciseLog) throws IOException {
if (dir.exists() && textFile.exists()) {
try {
Scanner s = new Scanner(textFile);
Expand Down Expand Up @@ -64,6 +64,7 @@ public void writeExerciseToFile(int month, int day, String[] exerciseName, int c

public void removeExerciseFromFile(int month, int day, String[] exerciseName, int caloriesBurned)
throws IOException {
//duplicated code
Scanner readFile = new Scanner(textFile);
File tempFile = new File("./data/temp.txt");
FileWriter tempWriter = new FileWriter(tempFile.toPath().toString());
Expand Down
Loading

0 comments on commit 64b2a2a

Please sign in to comment.