Skip to content

Commit

Permalink
Merge pull request AY2324S1-CS2103-F13-4#42 from junhonglow/branch-Ad…
Browse files Browse the repository at this point in the history
…d-Calendar-Storage

Add calendar storage functionality
  • Loading branch information
junhonglow authored Oct 20, 2023
2 parents af3905b + c5688b0 commit fb90d92
Show file tree
Hide file tree
Showing 44 changed files with 1,011 additions and 54 deletions.
4 changes: 2 additions & 2 deletions docs/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,14 @@ Priorities: High (must have) - `* * *`, Medium (nice to have) - `* *`, Low (unli
| `* * *` | NUS student | search for a name in the contact | easily find the person’s contact |
| `* * *` | NUS student | add contacts into my address book easily | retrieve the saved contact |
| `* * *` | NUS student living on campus | save the contacts of my neighbors | contact them in case of any emergencies |
| `* * *` | NUS student living on campus | save the addresses of my neighbours | locate them easily when necessary |
| `* * *` | NUS student living on campus | save the addresses of my neighbours | locate them easily when necessary |
| `* * *` | NUS student in multiple CCAs | filter my contacts by tags to identify all people in a group | find the relevant contacts in a certain group quickly |
| `* * *` | student staying on campus | label multiple tags to my contacts | locate my friends taking the same module and staying in the same campus residence as me |
| `* * *` | user that is familiar with the keyboard | use the keyboard to type commands in the applications | access the features of the application |
| `* * *` | user with bad memory | save a short description of my contact | identify my contacts better |
| `* * *` | visual-reliant user | save a photo of the person into my contacts | quickly recognise and find them |
| `* * *` | non-tech-savvy user | use the help feature of the app | navigate about the app easily |
| `* *` | NUS student | import the NUS calendar into the application | view all academic commitments more conveniently |
| `* *` | NUS student | import the NUS calendar into the application | view all academic commitments more conveniently |
| `* *` | NUS Student | compare timetables/calendars with my peers easily | plan meetings more conveniently |
| `* *` | NUS student | allocate tasks and responsibilities within a project or CCA group | tasks can be done efficiently |
| `* *` | NUS Student in multiple CCAs | group my contacts | identify which group my contacts belong to |
Expand Down
4 changes: 0 additions & 4 deletions docs/UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@

UniMate is a desktop app for students to **manage contacts** and **manage schedules** optimized for use via a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, UniMate can get your contact management tasks done faster than traditional GUI apps.

AddressBook Level 3 (AB3) is a **desktop app for managing contacts, optimized for use via a Line Interface** (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB3 can get your contact management tasks done faster than traditional GUI apps.

<!-- * Table of Contents -->
<page-nav-print />
<!-- * Table of Contents -->
<page-nav-print />

Expand Down
32 changes: 27 additions & 5 deletions src/main/java/seedu/address/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.ReadOnlyUserPrefs;
import seedu.address.model.UserPrefs;
import seedu.address.model.calendar.Calendar;
import seedu.address.model.calendar.ReadOnlyCalendar;
import seedu.address.model.util.SampleCalendarUtil;
import seedu.address.model.util.SampleDataUtil;
import seedu.address.storage.AddressBookStorage;
import seedu.address.storage.CalendarStorage;
import seedu.address.storage.JsonAddressBookStorage;
import seedu.address.storage.JsonCalendarStorage;
import seedu.address.storage.JsonUserPrefsStorage;
import seedu.address.storage.Storage;
import seedu.address.storage.StorageManager;
Expand Down Expand Up @@ -58,7 +63,8 @@ public void init() throws Exception {
UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath());
UserPrefs userPrefs = initPrefs(userPrefsStorage);
AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath());
storage = new StorageManager(addressBookStorage, userPrefsStorage);
CalendarStorage calendarStorage = new JsonCalendarStorage(userPrefs.getCalendarFilePath());
storage = new StorageManager(addressBookStorage, calendarStorage, userPrefsStorage);

model = initModelManager(storage, userPrefs);

Expand All @@ -76,21 +82,37 @@ private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
logger.info("Using data file : " + storage.getAddressBookFilePath());

Optional<ReadOnlyAddressBook> addressBookOptional;
ReadOnlyAddressBook initialData;
ReadOnlyAddressBook addressBookInitialData;
Optional<ReadOnlyCalendar> calendarOptional;
ReadOnlyCalendar calendarInitialData;

try {
addressBookOptional = storage.readAddressBook();
if (!addressBookOptional.isPresent()) {
logger.info("Creating a new data file " + storage.getAddressBookFilePath()
+ " populated with a sample AddressBook.");
}
initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook);
addressBookInitialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook);
} catch (DataLoadingException e) {
logger.warning("Data file at " + storage.getAddressBookFilePath() + " could not be loaded."
+ " Will be starting with an empty AddressBook.");
addressBookInitialData = new AddressBook();
}

try {
calendarOptional = storage.readCalendar();
if (!calendarOptional.isPresent()) {
logger.info("Creating a new data file " + storage.getCalendarFilePath()
+ " populated with a sample Calendar.");
}
calendarInitialData = calendarOptional.orElseGet(SampleCalendarUtil::getSampleCalendar);
} catch (DataLoadingException e) {
logger.warning("Data file at " + storage.getAddressBookFilePath() + " could not be loaded."
+ " Will be starting with an empty AddressBook.");
initialData = new AddressBook();
calendarInitialData = new Calendar();
}

return new ModelManager(initialData, userPrefs);
return new ModelManager(addressBookInitialData, calendarInitialData, userPrefs);
}

private void initLogging(Config config) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public CommandResult execute(String commandText) throws CommandException, ParseE

try {
storage.saveAddressBook(model.getAddressBook());
storage.saveCalendar(model.getCalendar());
} catch (AccessDeniedException e) {
throw new CommandException(String.format(FILE_OPS_PERMISSION_ERROR_FORMAT, e.getMessage()), e);
} catch (IOException ioe) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.calendar.ReadOnlyCalendar;
import seedu.address.model.event.Event;
import seedu.address.model.event.exceptions.EventNotFoundException;
import seedu.address.model.person.Person;
Expand Down Expand Up @@ -56,6 +57,24 @@ public interface Model {
/** Returns the AddressBook */
ReadOnlyAddressBook getAddressBook();

/**
* Returns the user prefs' calendar file path.
*/
Path getCalendarFilePath();

/**
* Sets the user prefs' calendar file path.
*/
void setCalendarFilePath(Path calendarFilePath);

/**
* Replaces calendar data with the data in {@code calendar}.
*/
void setCalendar(ReadOnlyCalendar calendar);

/** Returns the Calendar */
ReadOnlyCalendar getCalendar();

/**
* Returns true if a person with the same identity as {@code person} exists in the address book.
*/
Expand Down
34 changes: 28 additions & 6 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.calendar.Calendar;
import seedu.address.model.calendar.ReadOnlyCalendar;
import seedu.address.model.event.Event;
import seedu.address.model.event.exceptions.EventNotFoundException;
import seedu.address.model.person.Person;
Expand All @@ -26,27 +27,26 @@ public class ModelManager implements Model {
private static final Logger logger = LogsCenter.getLogger(ModelManager.class);

private final AddressBook addressBook;
private final Calendar calendar;
private final UserPrefs userPrefs;
private final FilteredList<Person> filteredPersons;

private final Calendar calendar;

/**
* Initializes a ModelManager with the given addressBook and userPrefs.
* Initializes a ModelManager with the given addressBook, calendar and userPrefs.
*/
public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyUserPrefs userPrefs) {
public ModelManager(ReadOnlyAddressBook addressBook, ReadOnlyCalendar calendar, ReadOnlyUserPrefs userPrefs) {
requireAllNonNull(addressBook, userPrefs);

logger.fine("Initializing with address book: " + addressBook + " and user prefs " + userPrefs);

this.addressBook = new AddressBook(addressBook);
this.calendar = new Calendar(calendar);
this.userPrefs = new UserPrefs(userPrefs);
filteredPersons = new FilteredList<>(this.addressBook.getPersonList());
calendar = new Calendar();
}

public ModelManager() {
this(new AddressBook(), new UserPrefs());
this(new AddressBook(), new Calendar(), new UserPrefs());
}

//=========== UserPrefs ==================================================================================
Expand Down Expand Up @@ -84,6 +84,16 @@ public void setAddressBookFilePath(Path addressBookFilePath) {
userPrefs.setAddressBookFilePath(addressBookFilePath);
}

@Override
public Path getCalendarFilePath() {
return userPrefs.getCalendarFilePath();
}

@Override
public void setCalendarFilePath(Path calendarFilePath) {
requireNonNull(calendarFilePath);
userPrefs.setCalendarFilePath(calendarFilePath);
}


//=========== AddressBook ================================================================================
Expand Down Expand Up @@ -129,6 +139,17 @@ public void sortPersonList(Comparator<Person> personComparator) {
}

//=========== Calendar ===================================================================================

@Override
public void setCalendar(ReadOnlyCalendar calendar) {
this.calendar.resetData(calendar);
}

@Override
public ReadOnlyCalendar getCalendar() {
return calendar;
}

@Override
public boolean canAddEvent(Event event) {
return calendar.canAddEvent(event);
Expand Down Expand Up @@ -195,6 +216,7 @@ public boolean equals(Object other) {

ModelManager otherModelManager = (ModelManager) other;
return addressBook.equals(otherModelManager.addressBook)
&& calendar.equals(otherModelManager.calendar)
&& userPrefs.equals(otherModelManager.userPrefs)
&& filteredPersons.equals(otherModelManager.filteredPersons);
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/model/UserPrefs.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class UserPrefs implements ReadOnlyUserPrefs {

private GuiSettings guiSettings = new GuiSettings();
private Path addressBookFilePath = Paths.get("data" , "addressbook.json");
private Path calendarFilePath = Paths.get("data", "calendar.json");

/**
* Creates a {@code UserPrefs} with default values.
Expand Down Expand Up @@ -56,6 +57,15 @@ public void setAddressBookFilePath(Path addressBookFilePath) {
this.addressBookFilePath = addressBookFilePath;
}

public Path getCalendarFilePath() {
return calendarFilePath;
}

public void setCalendarFilePath(Path calendarFilePath) {
requireNonNull(calendarFilePath);
this.calendarFilePath = calendarFilePath;
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
36 changes: 35 additions & 1 deletion src/main/java/seedu/address/model/calendar/Calendar.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

import javafx.collections.ObservableList;
import seedu.address.model.event.AllDaysEventListManager;
import seedu.address.model.event.Event;

/**
* Represents a calendar that stores and manages events.
*/
public class Calendar {
public class Calendar implements ReadOnlyCalendar {
private final AllDaysEventListManager eventManager;

/**
Expand All @@ -21,6 +23,33 @@ public Calendar() {
this.eventManager = new AllDaysEventListManager();
}

/**
* Creates a Calendar using the Events in the {@code toBeCopied}
*/
public Calendar(ReadOnlyCalendar toBeCopied) {
this();
resetData(toBeCopied);
}

//// overwrite operations

/**
* Replaces the contents of the Calendar with {@code events}.
* {@code events} must not contain duplicate events.
*/
public void setEvents(List<Event> events) {
events.forEach(this::addEvent);
}

/**
* Resets the existing data of this {@code Calendar} with {@code newData}.
*/
public void resetData(ReadOnlyCalendar newData) {
requireNonNull(newData);

setEvents(newData.getEventList());
}

/**
* Return the AllDaysEventListManager managing the events for this calendar.
*
Expand Down Expand Up @@ -107,6 +136,11 @@ public boolean hasEvents() {
return false;
}

@Override
public ObservableList<Event> getEventList() {
return eventManager.asUnmodifiableObservableList();
}

@Override
public boolean equals(Object other) {
if (this == other) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package seedu.address.model;
package seedu.address.model.calendar;

import javafx.collections.ObservableList;
import seedu.address.model.event.Event;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.TreeMap;
import java.util.stream.Collectors;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import seedu.address.model.event.exceptions.EventNotFoundException;

/**
Expand Down Expand Up @@ -128,6 +131,17 @@ public boolean isEmpty() {
return this.dayToEventListMap.isEmpty();
}

/**
* Returns the event list as an unmodifiable {@code ObservableList}.
*/
public ObservableList<Event> asUnmodifiableObservableList() {
List<Event> list = dayToEventListMap.values().stream()
.flatMap(singleDayEventList -> singleDayEventList.getDayEventList().stream())
.collect(Collectors.toList());

return FXCollections.observableList(list);
}

/**
* Checks if there are any events at all in the manager.
*
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/seedu/address/model/event/EventPeriod.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@ public List<LocalDate> getDates() {
return listOfDates;
}

/**
* Get the string representation of the EventPeriod.
*
* @return string representation of the period the eventPeriod spans.
*/
public String getFormattedPeriod() {
String startString = start.format(DATE_TIME_STRING_FORMATTER);
String endString = end.format(DATE_TIME_STRING_FORMATTER);
return startString + " - " + endString;
}

@Override
public boolean equals(Object other) {
requireNonNull(other);
Expand Down
32 changes: 32 additions & 0 deletions src/main/java/seedu/address/model/util/SampleCalendarUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package seedu.address.model.util;

import seedu.address.model.calendar.Calendar;
import seedu.address.model.calendar.ReadOnlyCalendar;
import seedu.address.model.event.Event;
import seedu.address.model.event.EventDescription;
import seedu.address.model.event.EventPeriod;

/**
* Contains utility methods for populating {@code Calendar} with sample data.
*/
public class SampleCalendarUtil {
public static Event[] getSampleEvents() {
return new Event[] {
new Event(new EventDescription("Weekly team meeting"),
new EventPeriod("2023-10-25 09:00", "2023-10-25 10:30")),
new Event(new EventDescription(" Annual health checkup"),
new EventPeriod("2023-11-10 15:15", "2023-11-10 16:00")),
new Event(new EventDescription(" Birthday celebration"),
new EventPeriod("2023-11-15 18:00", "2023-11-15 22:00"))
};
}

public static ReadOnlyCalendar getSampleCalendar() {
Calendar sampleCalendar = new Calendar();
for (Event sampleEvent : getSampleEvents()) {
sampleCalendar.addEvent(sampleEvent);
}
return sampleCalendar;
}

}
Loading

0 comments on commit fb90d92

Please sign in to comment.