From a437236788ccadc5fd3bd56b3fdb5d6e5acfb553 Mon Sep 17 00:00:00 2001 From: schrom01 Date: Thu, 24 Nov 2022 23:45:33 +0100 Subject: [PATCH 1/5] created Class Notifier --- .../gartenverwaltung/notifier/Notifier.java | 38 +++++++++++++++++++ .../ch/zhaw/gartenverwaltung/types/Task.java | 2 + src/main/java/module-info.java | 2 + .../gartenverwaltung/io/template-taskdb.json | 12 ++++++ .../gartenverwaltung/io/test-plantdb.json | 27 +++++-------- 5 files changed, 63 insertions(+), 18 deletions(-) create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java diff --git a/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java b/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java new file mode 100644 index 0000000..857fa1d --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java @@ -0,0 +1,38 @@ +package ch.zhaw.gartenverwaltung.notifier; + +import ch.zhaw.gartenverwaltung.models.GardenSchedule; +import ch.zhaw.gartenverwaltung.types.Task; + +import java.io.IOException; +import java.time.LocalDate; +import java.util.function.Consumer; + +public class Notifier implements Runnable{ + private final GardenSchedule gardenSchedule; + + public Notifier(GardenSchedule gardenSchedule) { + this.gardenSchedule = gardenSchedule; + } + + private void sendNotification(Task task){ + // TODO implement + } + + @Override + public void run() { + try { + gardenSchedule.getTaskList().forEach(new Consumer() { + @Override + public void accept(Task task) { + if(task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))){ + sendNotification(task); + task.setNextNotification(task.getNextExecution()); + } + } + }); + } catch (IOException e) { + // TODO Logger + e.printStackTrace(); + } + } +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java index dab4d39..509eb7a 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/types/Task.java @@ -69,8 +69,10 @@ public class Task { public void done(){ if(interval != null && !nextExecution.plusDays(interval).isAfter(endDate)){ nextExecution = nextExecution.plusDays(interval); + nextNotification = nextExecution; } else { nextExecution = null; + nextNotification = null; } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 44103dd..38607ea 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -13,4 +13,6 @@ module ch.zhaw.gartenverwaltung { exports ch.zhaw.gartenverwaltung.types; exports ch.zhaw.gartenverwaltung.models; exports ch.zhaw.gartenverwaltung.json; + exports ch.zhaw.gartenverwaltung.notifier; + opens ch.zhaw.gartenverwaltung.notifier to javafx.fxml; } \ No newline at end of file diff --git a/src/test/resources/ch/zhaw/gartenverwaltung/io/template-taskdb.json b/src/test/resources/ch/zhaw/gartenverwaltung/io/template-taskdb.json index 7728bb0..b10124d 100644 --- a/src/test/resources/ch/zhaw/gartenverwaltung/io/template-taskdb.json +++ b/src/test/resources/ch/zhaw/gartenverwaltung/io/template-taskdb.json @@ -4,6 +4,8 @@ "name" : "sow plant", "description": "Plant the seeds, crops in de bed.", "startDate" : "2022-05-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-05-01", "interval" : 0, "cropId" : 0 @@ -13,6 +15,8 @@ "name" : "water plant", "description": "water the plant, so that the soil is wet around the plant.", "startDate" : "2022-05-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-09-01", "interval" : 2, "cropId" : 0 @@ -22,6 +26,8 @@ "name" : "fertilize plant", "description": "The fertilizer has to be mixed with water. Then fertilize the plants soil with the mixture", "startDate" : "2022-06-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-08-01", "interval" : 28, "cropId" : 0 @@ -31,6 +37,8 @@ "name" : "covering plant", "description": "Take a big enough coverage for the plants. Cover the whole plant with a bit space between the plant and the coverage", "startDate" : "2022-07-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-07-01", "interval" : 0, "cropId" : 0 @@ -40,6 +48,8 @@ "name" : "look after plant", "description": "Look for pest or illness at the leaves of the plant. Check the soil around the plant, if the roots are enough covered with soil", "startDate" : "2022-05-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-09-01", "interval" : 5, "cropId" : 0 @@ -49,6 +59,8 @@ "name" : "harvest plant", "description": "Pull the ripe vegetables out from the soil. Clean them with clear, fresh water. ", "startDate" : "2022-09-01", + "nextExecution": "2022-05-01", + "nextNotification": "2022-05-01", "endDate" : "2022-09-01", "interval" : 0, "cropId" : 0 diff --git a/src/test/resources/ch/zhaw/gartenverwaltung/io/test-plantdb.json b/src/test/resources/ch/zhaw/gartenverwaltung/io/test-plantdb.json index 5440e42..4268df1 100644 --- a/src/test/resources/ch/zhaw/gartenverwaltung/io/test-plantdb.json +++ b/src/test/resources/ch/zhaw/gartenverwaltung/io/test-plantdb.json @@ -32,8 +32,7 @@ "relativeStartDate": -14, "relativeEndDate": null, "description": "Take an egg carton and fill it with soil. Put the seedling deep enough so its half covered with soil. Keep it in 10-15 * Celsius with lots of light.", - "interval": null, - "isOptional": false + "interval": null } ] }, @@ -54,8 +53,7 @@ "relativeStartDate": 0, "relativeEndDate": null, "description": "When the plants are 20 cm tall, begin hilling the potatoes by gently mounding the soil from the center of your rows around the stems of the plant. Mound up the soil around the plant until just the top few leaves show above the soil. Two weeks later, hill up the soil again when the plants grow another 20 cm.", - "interval": 21, - "isOptional": false + "interval": 21 } ] }, @@ -76,8 +74,7 @@ "relativeStartDate": 0, "relativeEndDate": null, "description": "Once the foliage has wilted and dried completely, harvest on a dry day. Store in a dark and cool location.", - "interval": null, - "isOptional": false + "interval": null } ] } @@ -106,8 +103,7 @@ "relativeStartDate": 0, "relativeEndDate": 0, "description": "Mound up the soil around the plant until just the top few leaves show above the soil. ", - "interval": null, - "isOptional": false + "interval": null } ] }, @@ -130,8 +126,7 @@ "relativeStartDate": 0, "relativeEndDate": null, "description": "Mound up the soil around the plant until just the top few leaves show above the soil. ", - "interval": 15, - "isOptional": true + "interval": 15 } ] }, @@ -152,8 +147,7 @@ "relativeStartDate": 0, "relativeEndDate": 14, "description": "When the leaves turn to a yellowish brown. Do not harvest earlier. The plant will show when it's ready.", - "interval": null, - "isOptional": false + "interval": null } ] } @@ -193,8 +187,7 @@ "relativeStartDate": 0, "relativeEndDate": 0, "description": "Mound up the soil around the plant until just the top few leaves show above the soil. ", - "interval": null, - "isOptional": false + "interval": null } ] }, @@ -217,8 +210,7 @@ "relativeStartDate": 0, "relativeEndDate": null, "description": "Mound up the soil around the plant until just the top few leaves show above the soil. ", - "interval": 15, - "isOptional": true + "interval": 15 } ] }, @@ -241,8 +233,7 @@ "relativeStartDate": 0, "relativeEndDate": 14, "description": "When ready for harvest, the leaves on your onion plants will start to flop over. This happens at the \"neck\" of the onion and it signals that the plant has stopped growing and is ready for storage. Onions should be harvested soon thereafter", - "interval": null, - "isOptional": false + "interval": null } ] } From 2d88c9ea9108449d3d60f60285cb5bfec54f2945 Mon Sep 17 00:00:00 2001 From: schrom01 Date: Fri, 25 Nov 2022 12:58:03 +0100 Subject: [PATCH 2/5] implemented multithreading --- .../gartenverwaltung/HelloApplication.java | 7 +++++ .../gartenverwaltung/bootstrap/AppLoader.java | 6 ++++ .../models/GardenSchedule.java | 1 - .../gartenverwaltung/notifier/Notifier.java | 28 +++++++++++++------ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java b/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java index 9018a31..0b8a0a1 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java @@ -1,16 +1,23 @@ package ch.zhaw.gartenverwaltung; import ch.zhaw.gartenverwaltung.bootstrap.AppLoader; +import ch.zhaw.gartenverwaltung.notifier.Notifier; import javafx.application.Application; import javafx.stage.Stage; import java.io.IOException; public class HelloApplication extends Application { + @Override public void start(Stage stage) throws IOException { AppLoader appLoader = new AppLoader(); + Notifier notifier = new Notifier(appLoader.getGardenSchedule()); + Thread notificationThread = new Thread(notifier); + notificationThread.start(); + notificationThread.interrupt(); + appLoader.loadSceneToStage("MainFXML.fxml", stage); stage.setTitle("Gartenverwaltung"); diff --git a/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java b/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java index 59a4f7d..6c660ab 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java @@ -10,6 +10,7 @@ import ch.zhaw.gartenverwaltung.io.TaskList; import ch.zhaw.gartenverwaltung.models.Garden; import ch.zhaw.gartenverwaltung.models.GardenSchedule; import ch.zhaw.gartenverwaltung.models.PlantListModel; +import ch.zhaw.gartenverwaltung.notifier.Notifier; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.DialogPane; @@ -41,6 +42,7 @@ public class AppLoader { public AppLoader() throws IOException { + } @@ -154,4 +156,8 @@ public class AppLoader { default -> null; }; } + + public GardenSchedule getGardenSchedule() { + return gardenSchedule; + } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/models/GardenSchedule.java b/src/main/java/ch/zhaw/gartenverwaltung/models/GardenSchedule.java index f4b2bb3..936eaf6 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/models/GardenSchedule.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/models/GardenSchedule.java @@ -9,7 +9,6 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.function.Consumer; import java.util.stream.Collectors; public class GardenSchedule { diff --git a/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java b/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java index 857fa1d..26e22fc 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java @@ -9,6 +9,7 @@ import java.util.function.Consumer; public class Notifier implements Runnable{ private final GardenSchedule gardenSchedule; + private boolean interrupted = false; public Notifier(GardenSchedule gardenSchedule) { this.gardenSchedule = gardenSchedule; @@ -18,16 +19,13 @@ public class Notifier implements Runnable{ // TODO implement } - @Override - public void run() { + private void sendNotifications(){ + System.out.println("sending Notifications"); try { - gardenSchedule.getTaskList().forEach(new Consumer() { - @Override - public void accept(Task task) { - if(task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))){ - sendNotification(task); - task.setNextNotification(task.getNextExecution()); - } + gardenSchedule.getTaskList().forEach(task -> { + if(task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))){ + sendNotification(task); + task.setNextNotification(task.getNextExecution()); } }); } catch (IOException e) { @@ -35,4 +33,16 @@ public class Notifier implements Runnable{ e.printStackTrace(); } } + + @Override + public void run() { + while(!interrupted){ + try { + sendNotifications(); + Thread.sleep(3000); + } catch (InterruptedException e) { + interrupted = true; + } + } + } } From fbf1700c34d343b2debde0bb324986a1858590ab Mon Sep 17 00:00:00 2001 From: schrom01 Date: Mon, 28 Nov 2022 08:00:31 +0100 Subject: [PATCH 3/5] implemented EMailSender --- build.gradle | 2 + .../gartenverwaltung/HelloApplication.java | 16 +++++-- .../ch/zhaw/gartenverwaltung/Settings.java | 28 ++++++++++- .../backgroundtasks/BackgroundTasks.java | 42 ++++++++++++++++ .../backgroundtasks/Notifier.java | 42 ++++++++++++++++ .../backgroundtasks/email/EMailSender.java | 44 +++++++++++++++++ .../email/SmtpCredentials.java | 41 ++++++++++++++++ .../gartenverwaltung/bootstrap/AppLoader.java | 13 +++-- .../gartenverwaltung/notifier/Notifier.java | 48 ------------------- src/main/java/module-info.java | 8 +++- 10 files changed, 225 insertions(+), 59 deletions(-) create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java create mode 100644 src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/SmtpCredentials.java delete mode 100644 src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java diff --git a/build.gradle b/build.gradle index 35ebaa2..8c3b14a 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,8 @@ dependencies { implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.4' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.13.4' testImplementation 'org.mockito:mockito-core:4.3.+' + implementation 'com.sun.mail:javax.mail:1.6.2' + } test { diff --git a/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java b/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java index 0b8a0a1..1d8ed5a 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/HelloApplication.java @@ -1,22 +1,23 @@ package ch.zhaw.gartenverwaltung; import ch.zhaw.gartenverwaltung.bootstrap.AppLoader; -import ch.zhaw.gartenverwaltung.notifier.Notifier; +import ch.zhaw.gartenverwaltung.backgroundtasks.BackgroundTasks; import javafx.application.Application; import javafx.stage.Stage; import java.io.IOException; +import java.util.Timer; public class HelloApplication extends Application { + Timer backGroundTaskTimer = new Timer(); + BackgroundTasks backgroundTasks; @Override public void start(Stage stage) throws IOException { AppLoader appLoader = new AppLoader(); - Notifier notifier = new Notifier(appLoader.getGardenSchedule()); - Thread notificationThread = new Thread(notifier); - notificationThread.start(); - notificationThread.interrupt(); + backgroundTasks = new BackgroundTasks(appLoader.getTaskList(), appLoader.getGarden(), appLoader.getPlantList()); + backGroundTaskTimer.scheduleAtFixedRate(backgroundTasks, 0, 1000); appLoader.loadSceneToStage("MainFXML.fxml", stage); @@ -24,6 +25,11 @@ public class HelloApplication extends Application { stage.show(); } + @Override + public void stop(){ + backGroundTaskTimer.cancel(); + } + public static void main(String[] args) { launch(); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java index c15454c..63cf6e7 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java @@ -1,13 +1,23 @@ package ch.zhaw.gartenverwaltung; +import ch.zhaw.gartenverwaltung.backgroundtasks.email.SmtpCredentials; import ch.zhaw.gartenverwaltung.types.HardinessZone; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; +import java.util.List; + public class Settings { + private static final Settings instance; private HardinessZone currentHardinessZone = HardinessZone.ZONE_8A; - private static Settings instance; private final BooleanProperty showTutorial = new SimpleBooleanProperty(false); + private SmtpCredentials smtpCredentials = new SmtpCredentials("imap.gmail.com", "587", "pm3.hs22.it21b.win.team1@gmail.com", "pm3.hs22.it21b.win.team1@gmail.com", "bisefhhjtrrhtoqr", true); + // Gmail Address: pm3.hs22.it21b.win.team1@gmail.com + // Gmail Passwort: Gartenverwaltung.PM3.2022 + // E-Mail Inbox: https://www.mailinator.com/v4/public/inboxes.jsp?to=pm3.hs22.it21b.win.team1 + private String mailNotificationReceivers = "pm3.hs22.it21b.win.team1@mailinator.com"; + private String mailNotificationSubjectTemplate = "Task %s is due!"; // {0} = Task Name + private String mailNotificationTextTemplate = "Dear user\nYour gardentask %s is due since %tF. Don't forget to confirm in your application if the task is done.\nTask description:\n%s"; // {0} = Task Name, {1} = nextExecution, {2} = Task description static { instance = new Settings(); @@ -38,4 +48,20 @@ public class Settings { public boolean getShowTutorial() { return this.showTutorial.get(); } + + public SmtpCredentials getSmtpCredentials() { + return smtpCredentials; + } + + public String getMailNotificationReceivers() { + return mailNotificationReceivers; + } + + public String getMailNotificationSubjectTemplate() { + return mailNotificationSubjectTemplate; + } + + public String getMailNotificationTextTemplate() { + return mailNotificationTextTemplate; + } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java new file mode 100644 index 0000000..52e902e --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java @@ -0,0 +1,42 @@ +package ch.zhaw.gartenverwaltung.backgroundtasks; + +import ch.zhaw.gartenverwaltung.io.PlantList; +import ch.zhaw.gartenverwaltung.io.TaskList; +import ch.zhaw.gartenverwaltung.models.Garden; + +import javax.mail.MessagingException; +import java.io.IOException; +import java.util.TimerTask; + +public class BackgroundTasks extends TimerTask { + private final TaskList taskList; + private final Garden garden; + private final PlantList plantList; + private final Notifier notifier; + //TODO uncomment: privat final WeatherGardenTaskPlaner weatherGardenTaskPlaner; + + public BackgroundTasks(TaskList taskList, Garden garden, PlantList plantList) { + this.taskList = taskList; + this.garden = garden; + this.plantList = plantList; + notifier = new Notifier(taskList, garden, plantList); + //TODO uncomment: weatherGardenTaskPlaner = new WeatherGardenTaskPlaner(taskList); + } + + @Override + public void run() { + // TODO uncomment: weatherGardenTaskPlaner.refreshTasks(); + try { + try { + notifier.sendNotifications(); + } catch (MessagingException e) { + e.printStackTrace(); + // TODO logger + } + } catch (IOException e) { + e.printStackTrace(); + // TODO logger + } + } +} + diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java new file mode 100644 index 0000000..f36913f --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java @@ -0,0 +1,42 @@ +package ch.zhaw.gartenverwaltung.backgroundtasks; + +import ch.zhaw.gartenverwaltung.Settings; +import ch.zhaw.gartenverwaltung.backgroundtasks.email.EMailSender; +import ch.zhaw.gartenverwaltung.io.PlantList; +import ch.zhaw.gartenverwaltung.io.TaskList; +import ch.zhaw.gartenverwaltung.models.Garden; +import ch.zhaw.gartenverwaltung.types.Task; + +import javax.mail.MessagingException; +import java.io.IOException; +import java.time.LocalDate; + +public class Notifier { + private final TaskList taskList; + private final Garden garden; + private final PlantList plantList; + private final EMailSender eMailSender = new EMailSender(); + + public Notifier(TaskList taskList, Garden garden, PlantList plantList) { + this.taskList = taskList; + this.garden = garden; + this.plantList = plantList; + } + + private void sendNotification(Task task) throws MessagingException { + String messageSubject = String.format(Settings.getInstance().getMailNotificationSubjectTemplate(), task.getName()); + String messageText = String.format(Settings.getInstance().getMailNotificationTextTemplate(), task.getName(), task.getNextExecution(), task.getDescription()); + //TODO create Exception for email sent fail + eMailSender.sendMails(Settings.getInstance().getMailNotificationReceivers(), messageSubject, messageText); + } + + public void sendNotifications() throws IOException, MessagingException { + System.out.println("sending Notifications"); + for (Task task : taskList.getTaskList(LocalDate.MIN, LocalDate.MAX)) { + if (task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))) { + sendNotification(task); + task.setNextNotification(LocalDate.now().plusDays(1)); + } + } + } +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java new file mode 100644 index 0000000..734967c --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java @@ -0,0 +1,44 @@ +package ch.zhaw.gartenverwaltung.backgroundtasks.email; + +import ch.zhaw.gartenverwaltung.Settings; + +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +public class EMailSender { + + + public EMailSender(){ + + } + + public void sendMails(String recipients, String subject, String text) throws MessagingException { + // TODO replace printMail with implementation + printMail(recipients, subject, text); // TODO Remove Printing E-Mail to console to test it + MimeMessage message = new MimeMessage(Settings.getInstance().getSmtpCredentials().getSession()); + message.addHeader("Content-type", "text/HTML; charset=UTF-8"); + message.addHeader("format", "flowed"); + message.addHeader("Content-Transfer-Encoding", "8bit"); + message.setFrom(new InternetAddress(Settings.getInstance().getSmtpCredentials().fromAddress())); + message.setReplyTo(InternetAddress.parse(Settings.getInstance().getSmtpCredentials().fromAddress(), false)); + message.setSubject(subject); + message.setText(text); + message.setSentDate(new Date()); + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients, false)); + System.out.println("Message is ready: "); + Transport.send(message); + } + + private void printMail(String receiver, String subject, String text){ + System.out.printf("\nSending E-Mail:\nTo: %s\nSubject: %s\nMessage:\n%s\n", receiver, subject, text); + } + +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/SmtpCredentials.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/SmtpCredentials.java new file mode 100644 index 0000000..5e066ec --- /dev/null +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/SmtpCredentials.java @@ -0,0 +1,41 @@ +package ch.zhaw.gartenverwaltung.backgroundtasks.email; + +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import java.net.Authenticator; +import java.util.Properties; + +public record SmtpCredentials( + String host, + String port, + String fromAddress, + String username, + String password, + boolean startTLS + ) { + + private Properties getProperties() { + Properties properties = new Properties(); + properties.put("mail.smtp.host", host); + properties.put("mail.smtp.port", port); + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.starttls.enable", startTLS ? "true" : "false"); + return properties; + } + + private javax.mail.Authenticator getAuthenticator() { + return new javax.mail.Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }; + } + + public Session getSession() { + return Session.getInstance(getProperties(), getAuthenticator()); + } + + + +} diff --git a/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java b/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java index 6c660ab..2065278 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/bootstrap/AppLoader.java @@ -10,7 +10,6 @@ import ch.zhaw.gartenverwaltung.io.TaskList; import ch.zhaw.gartenverwaltung.models.Garden; import ch.zhaw.gartenverwaltung.models.GardenSchedule; import ch.zhaw.gartenverwaltung.models.PlantListModel; -import ch.zhaw.gartenverwaltung.notifier.Notifier; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.control.DialogPane; @@ -157,7 +156,15 @@ public class AppLoader { }; } - public GardenSchedule getGardenSchedule() { - return gardenSchedule; + public PlantList getPlantList() { + return plantList; + } + + public Garden getGarden() { + return garden; + } + + public TaskList getTaskList() { + return taskList; } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java b/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java deleted file mode 100644 index 26e22fc..0000000 --- a/src/main/java/ch/zhaw/gartenverwaltung/notifier/Notifier.java +++ /dev/null @@ -1,48 +0,0 @@ -package ch.zhaw.gartenverwaltung.notifier; - -import ch.zhaw.gartenverwaltung.models.GardenSchedule; -import ch.zhaw.gartenverwaltung.types.Task; - -import java.io.IOException; -import java.time.LocalDate; -import java.util.function.Consumer; - -public class Notifier implements Runnable{ - private final GardenSchedule gardenSchedule; - private boolean interrupted = false; - - public Notifier(GardenSchedule gardenSchedule) { - this.gardenSchedule = gardenSchedule; - } - - private void sendNotification(Task task){ - // TODO implement - } - - private void sendNotifications(){ - System.out.println("sending Notifications"); - try { - gardenSchedule.getTaskList().forEach(task -> { - if(task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))){ - sendNotification(task); - task.setNextNotification(task.getNextExecution()); - } - }); - } catch (IOException e) { - // TODO Logger - e.printStackTrace(); - } - } - - @Override - public void run() { - while(!interrupted){ - try { - sendNotifications(); - Thread.sleep(3000); - } catch (InterruptedException e) { - interrupted = true; - } - } - } -} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 38607ea..159fd0b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -5,6 +5,8 @@ module ch.zhaw.gartenverwaltung { requires com.fasterxml.jackson.datatype.jsr310; requires com.fasterxml.jackson.datatype.jdk8; requires java.logging; + requires java.mail; + opens ch.zhaw.gartenverwaltung to javafx.fxml; opens ch.zhaw.gartenverwaltung.types to com.fasterxml.jackson.databind; @@ -13,6 +15,8 @@ module ch.zhaw.gartenverwaltung { exports ch.zhaw.gartenverwaltung.types; exports ch.zhaw.gartenverwaltung.models; exports ch.zhaw.gartenverwaltung.json; - exports ch.zhaw.gartenverwaltung.notifier; - opens ch.zhaw.gartenverwaltung.notifier to javafx.fxml; + exports ch.zhaw.gartenverwaltung.backgroundtasks; + opens ch.zhaw.gartenverwaltung.backgroundtasks to javafx.fxml; + exports ch.zhaw.gartenverwaltung.backgroundtasks.email; + opens ch.zhaw.gartenverwaltung.backgroundtasks.email to javafx.fxml; } \ No newline at end of file From fd184e1248386bdedf41fa5642a3385dbcb0f56f Mon Sep 17 00:00:00 2001 From: schrom01 Date: Mon, 28 Nov 2022 09:11:37 +0100 Subject: [PATCH 4/5] implemented Exception handling in EMailSender --- .../backgroundtasks/BackgroundTasks.java | 6 ------ .../backgroundtasks/email/EMailSender.java | 13 +++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java index 52e902e..2cb5e2e 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/BackgroundTasks.java @@ -9,16 +9,10 @@ import java.io.IOException; import java.util.TimerTask; public class BackgroundTasks extends TimerTask { - private final TaskList taskList; - private final Garden garden; - private final PlantList plantList; private final Notifier notifier; //TODO uncomment: privat final WeatherGardenTaskPlaner weatherGardenTaskPlaner; public BackgroundTasks(TaskList taskList, Garden garden, PlantList plantList) { - this.taskList = taskList; - this.garden = garden; - this.plantList = plantList; notifier = new Notifier(taskList, garden, plantList); //TODO uncomment: weatherGardenTaskPlaner = new WeatherGardenTaskPlaner(taskList); } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java index 734967c..82f895a 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java @@ -2,10 +2,7 @@ package ch.zhaw.gartenverwaltung.backgroundtasks.email; import ch.zhaw.gartenverwaltung.Settings; -import javax.mail.Address; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Transport; +import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.ArrayList; @@ -33,8 +30,12 @@ public class EMailSender { message.setText(text); message.setSentDate(new Date()); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients, false)); - System.out.println("Message is ready: "); - Transport.send(message); + try{ + Transport.send(message); + } catch (MessagingException e) { + e.printStackTrace(); + // TODO logger + } } private void printMail(String receiver, String subject, String text){ From 220d13818500aec6ffc59069a667bfc542e4ee18 Mon Sep 17 00:00:00 2001 From: schrom01 Date: Mon, 28 Nov 2022 19:31:08 +0100 Subject: [PATCH 5/5] fixed saving Task after editing --- .../ch/zhaw/gartenverwaltung/Settings.java | 2 +- .../backgroundtasks/Notifier.java | 27 ++++++++++++++++--- .../backgroundtasks/email/EMailSender.java | 7 +---- .../META-INF/javamail.default.address.map | 0 4 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 src/main/resources/META-INF/javamail.default.address.map diff --git a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java index 63cf6e7..462237c 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/Settings.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/Settings.java @@ -17,7 +17,7 @@ public class Settings { // E-Mail Inbox: https://www.mailinator.com/v4/public/inboxes.jsp?to=pm3.hs22.it21b.win.team1 private String mailNotificationReceivers = "pm3.hs22.it21b.win.team1@mailinator.com"; private String mailNotificationSubjectTemplate = "Task %s is due!"; // {0} = Task Name - private String mailNotificationTextTemplate = "Dear user\nYour gardentask %s is due since %tF. Don't forget to confirm in your application if the task is done.\nTask description:\n%s"; // {0} = Task Name, {1} = nextExecution, {2} = Task description + private String mailNotificationTextTemplate = "Dear user\nYour gardentask %s for plant %s is due at %tF. Don't forget to confirm in your application if the task is done.\nTask description:\n%s"; // {0} = Task Name, {1} = plantname, {2} = nextExecution, {3} = Task description static { instance = new Settings(); diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java index f36913f..c172e83 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/Notifier.java @@ -2,9 +2,11 @@ package ch.zhaw.gartenverwaltung.backgroundtasks; import ch.zhaw.gartenverwaltung.Settings; import ch.zhaw.gartenverwaltung.backgroundtasks.email.EMailSender; +import ch.zhaw.gartenverwaltung.io.HardinessZoneNotSetException; import ch.zhaw.gartenverwaltung.io.PlantList; import ch.zhaw.gartenverwaltung.io.TaskList; import ch.zhaw.gartenverwaltung.models.Garden; +import ch.zhaw.gartenverwaltung.types.Crop; import ch.zhaw.gartenverwaltung.types.Task; import javax.mail.MessagingException; @@ -23,11 +25,27 @@ public class Notifier { this.plantList = plantList; } - private void sendNotification(Task task) throws MessagingException { + private void sendNotification(Task task) { + String plantName = "unkown plant"; + try { + if(garden.getCrop(task.getCropId()).isPresent()){ + Crop crop = garden.getCrop(task.getCropId()).get(); + if(plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).isPresent()) { + plantName = plantList.getPlantById(Settings.getInstance().getCurrentHardinessZone(), crop.getPlantId()).get().name(); + } + } + } catch (IOException | HardinessZoneNotSetException e) { + e.printStackTrace(); + // TODO logger + } String messageSubject = String.format(Settings.getInstance().getMailNotificationSubjectTemplate(), task.getName()); - String messageText = String.format(Settings.getInstance().getMailNotificationTextTemplate(), task.getName(), task.getNextExecution(), task.getDescription()); - //TODO create Exception for email sent fail - eMailSender.sendMails(Settings.getInstance().getMailNotificationReceivers(), messageSubject, messageText); + String messageText = String.format(Settings.getInstance().getMailNotificationTextTemplate(), task.getName(), plantName, task.getNextExecution(), task.getDescription()); + try { + eMailSender.sendMails(Settings.getInstance().getMailNotificationReceivers(), messageSubject, messageText); + } catch (MessagingException e) { + e.printStackTrace(); + // TODO Logger + } } public void sendNotifications() throws IOException, MessagingException { @@ -36,6 +54,7 @@ public class Notifier { if (task.getNextNotification() != null && task.getNextNotification().isBefore(LocalDate.now().minusDays(1))) { sendNotification(task); task.setNextNotification(LocalDate.now().plusDays(1)); + taskList.saveTask(task); } } } diff --git a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java index 82f895a..1fa470c 100644 --- a/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java +++ b/src/main/java/ch/zhaw/gartenverwaltung/backgroundtasks/email/EMailSender.java @@ -30,12 +30,7 @@ public class EMailSender { message.setText(text); message.setSentDate(new Date()); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients, false)); - try{ - Transport.send(message); - } catch (MessagingException e) { - e.printStackTrace(); - // TODO logger - } + Transport.send(message); } private void printMail(String receiver, String subject, String text){ diff --git a/src/main/resources/META-INF/javamail.default.address.map b/src/main/resources/META-INF/javamail.default.address.map new file mode 100644 index 0000000..e69de29