Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FileIO function to restore saved goal record #90

Merged
merged 4 commits into from
Nov 11, 2023
Merged
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
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
Loading