This is an automated email from the git hooks/post-receive script. New commit to branch feature/23_manage_notification in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 299c0b843599123c44b77e59fa677c1d67d25fad Author: Kevin Morin <morin@codelutin.com> Date: Tue May 9 11:44:03 2017 +0200 refs #23 création des jobs pour l'envoi de mails différés --- pollen-rest-api/pom.xml | 5 ++ .../rest/api/PollenRestApiApplicationListener.java | 86 ++++++++++++++++++++++ .../src/main/resources/pollen-rest-api.properties | 3 + pollen-services/pom.xml | 5 ++ pollen-services/src/main/config/PollenServices.ini | 11 +++ .../org/chorem/pollen/services/bean/VoteBean.java | 1 - .../pollen/services/job/AbstractPollenJob.java | 18 +++++ .../services/job/SendPollEndReminderJob.java | 64 ++++++++++++++++ .../pollen/services/job/SendVoteSummariesJob.java | 71 ++++++++++++++++++ .../pollen/services/service/PollService.java | 12 +++ .../pollen/services/service/VoteService.java | 11 ++- .../i18n/pollen-services_en_GB.properties | 10 ++- .../i18n/pollen-services_fr_FR.properties | 10 ++- pom.xml | 13 +++- 14 files changed, 311 insertions(+), 9 deletions(-) diff --git a/pollen-rest-api/pom.xml b/pollen-rest-api/pom.xml index 41fadf6..821451e 100644 --- a/pollen-rest-api/pom.xml +++ b/pollen-rest-api/pom.xml @@ -200,6 +200,11 @@ </dependency> <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + </dependency> + + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java index b42f467..b8b414b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/PollenRestApiApplicationListener.java @@ -22,6 +22,8 @@ package org.chorem.pollen.rest.api; */ import com.google.common.collect.Sets; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.chorem.pollen.persistence.entity.ChoiceType; import org.chorem.pollen.rest.api.converter.DateConverter; import org.chorem.pollen.rest.api.converter.JsonArrayConverter; @@ -43,10 +45,23 @@ import org.chorem.pollen.services.bean.VoteBean; import org.chorem.pollen.services.bean.VoteToChoiceBean; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.config.PollenServicesConfig; +import org.chorem.pollen.services.job.AbstractPollenJob; +import org.chorem.pollen.services.job.SendPollEndReminderJob; +import org.chorem.pollen.services.job.SendVoteSummariesJob; import org.debux.webmotion.server.WebMotionServerListener; import org.debux.webmotion.server.call.ServerContext; import org.debux.webmotion.server.mapping.Mapping; import org.nuiton.topia.persistence.TopiaIdFactory; +import org.quartz.CronScheduleBuilder; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; +import org.quartz.impl.StdSchedulerFactory; import java.util.Date; import java.util.Set; @@ -59,6 +74,9 @@ import java.util.Set; */ public class PollenRestApiApplicationListener implements WebMotionServerListener { + /** Logger. */ + private static final Log log = LogFactory.getLog(PollenRestApiApplicationListener.class); + protected static final Set<Class<?>> BEAN_TYPES = Sets.newHashSet( PollBean.class, ChoiceBean.class, @@ -76,6 +94,8 @@ public class PollenRestApiApplicationListener implements WebMotionServerListener PollenUIContext.class ); + private Scheduler scheduler; + @Override public void onStart(Mapping mapping, ServerContext serverContext) { @@ -109,11 +129,77 @@ public class PollenRestApiApplicationListener implements WebMotionServerListener serverContext.addInjector(new PollenServiceInjector()); serverContext.addInjector(new PollenBeanIdInjector(topiaIdFactory)); + // --- init crons --- // + + JobDataMap data = new JobDataMap(); + + data.put(AbstractPollenJob.APPLICATION_CONTEXT, applicationContext); + + JobDetail sendVoteSummariesJob = JobBuilder.newJob(SendVoteSummariesJob.class) + .usingJobData(data) + .withIdentity("sendVoteSummariesJob", "pollenJobs") + .build(); + + JobDetail sendPollEndReminderJob = JobBuilder.newJob(SendPollEndReminderJob.class) + .usingJobData(data) + .withIdentity("sendPollEndReminderJob", "pollenJobs") + .build(); + + try { + + scheduler = new StdSchedulerFactory().getScheduler(); + + PollenServicesConfig applicationConfig = applicationContext.getApplicationConfig(); + + // schedule send vote summaries (everynight at midnight) + Trigger sendVoteSummariesTrigger = TriggerBuilder + .newTrigger() + .withIdentity("sendVoteSummariesTrigger", "pollenTriggers") + .withSchedule(CronScheduleBuilder.cronSchedule(applicationConfig.getSendVoteSummariesCronSchedule())) + .build(); + + scheduler.scheduleJob(sendVoteSummariesJob, sendVoteSummariesTrigger); + + // schedule send poll end reminders (every 5 minutes) + Trigger sendPollEndReminderTrigger = TriggerBuilder + .newTrigger() + .withIdentity("sendPollEndReminderTrigger", "pollenTriggers") + .withSchedule(CronScheduleBuilder.cronSchedule(applicationConfig.getSendEndPollRemindersCronSchedule())) + .build(); + + scheduler.scheduleJob(sendPollEndReminderJob, sendPollEndReminderTrigger); + + scheduler.start(); + if (log.isDebugEnabled()) { + log.debug("schedulers launched"); + } + + } catch (SchedulerException e) { + if (log.isErrorEnabled()) { + log.error("Error while launching the jobs", e); + } + } } @Override public void onStop(ServerContext serverContext) { + //-- close scheduler ---// + if (scheduler != null) { + if (log.isInfoEnabled()) { + log.info("Stopping quartz sheduler"); + } + + try { + // wait for thread to complete + scheduler.shutdown(); + } catch (SchedulerException e) { + if (log.isWarnEnabled()) { + log.warn("Can't stop quartz", e); + } + } + } + // Get application context PollenRestApiApplicationContext applicationContext = PollenRestApiApplicationContext.getApplicationContext( diff --git a/pollen-rest-api/src/main/resources/pollen-rest-api.properties b/pollen-rest-api/src/main/resources/pollen-rest-api.properties index 66f7e5d..67d3c3c 100644 --- a/pollen-rest-api/src/main/resources/pollen-rest-api.properties +++ b/pollen-rest-api/src/main/resources/pollen-rest-api.properties @@ -29,3 +29,6 @@ hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConn hibernate.hikari.minimumIdle=2 hibernate.hikari.maximumPoolSize=20 hibernate.hikari.autoCommit=false + +pollen.sendVoteSummariesCronSchedule=0 0 0 * * ? +pollen.sendEndPollRemindersCronSchedule=0 0/5 * * * ? \ No newline at end of file diff --git a/pollen-services/pom.xml b/pollen-services/pom.xml index 9b0ba84..7fa0d31 100644 --- a/pollen-services/pom.xml +++ b/pollen-services/pom.xml @@ -158,6 +158,11 @@ </dependency> <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + </dependency> + + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> diff --git a/pollen-services/src/main/config/PollenServices.ini b/pollen-services/src/main/config/PollenServices.ini index 46a097e..be191b3 100644 --- a/pollen-services/src/main/config/PollenServices.ini +++ b/pollen-services/src/main/config/PollenServices.ini @@ -144,3 +144,14 @@ type = string transient = true final = true +[option sendVoteSummariesCronSchedule] +description = pollen.configuration.sendVoteSummariesCronSchedule +key = pollen.sendVoteSummariesCronSchedule +type = string +default = "0 0 0 * * ?" + +[option sendEndPollRemindersCronSchedule] +description = pollen.configuration.sendEndPollRemindersCronSchedule +key = pollen.sendEndPollRemindersCronSchedule +type = string +default = "0 0/5 * * * ?" diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java index 55ea6b3..a331bd5 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/VoteBean.java @@ -114,7 +114,6 @@ public class VoteBean extends PollenBean<Vote> { voter.setTopiaId(getVoterId().getEntityId()); voter.setName(getVoterName()); - for (VoteToChoiceBean choiceBean : choice) { VoteToChoice voteToChoice = choiceBean.toEntity(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java new file mode 100644 index 0000000..ff437b2 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/AbstractPollenJob.java @@ -0,0 +1,18 @@ +package org.chorem.pollen.services.job; + +import org.chorem.pollen.services.PollenApplicationContext; +import org.quartz.Job; +import org.quartz.JobExecutionContext; + +/** + * @author Kevin Morin (Code Lutin) + * @since 3.0 + */ +public abstract class AbstractPollenJob implements Job { + + public static final String APPLICATION_CONTEXT = "applicationContext"; + + protected PollenApplicationContext getApplicationContext(JobExecutionContext jobExecutionContext) { + return (PollenApplicationContext) jobExecutionContext.getMergedJobDataMap().get(APPLICATION_CONTEXT); + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java new file mode 100644 index 0000000..567b176 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendPollEndReminderJob.java @@ -0,0 +1,64 @@ +package org.chorem.pollen.services.job; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.persistence.PollenTopiaPersistenceContext; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.services.PollenApplicationContext; +import org.chorem.pollen.services.PollenServiceContext; +import org.chorem.pollen.services.service.NotificationService; +import org.chorem.pollen.services.service.PollService; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.util.Collection; +import java.util.Locale; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class SendPollEndReminderJob extends AbstractPollenJob { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SendPollEndReminderJob.class); + + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + PollenApplicationContext applicationContext = getApplicationContext(jobExecutionContext); + PollenTopiaPersistenceContext persistenceContext = applicationContext.newPersistenceContext(); + PollenServiceContext serviceContext = applicationContext.newServiceContext(persistenceContext, Locale.getDefault()); + + PollService pollService = serviceContext.newService(PollService.class); + Collection<Poll> pollsWithVoteReminderNeeded = pollService.getPollsWithReminderNeeded(); + + for (Poll poll : pollsWithVoteReminderNeeded) { + try { + Locale locale; + if (poll.getNotificationLocale() != null) { + locale = Locale.forLanguageTag(poll.getNotificationLocale()); + } else { + locale = Locale.getDefault(); + } + PollenServiceContext localizedServiceContext = applicationContext.newServiceContext(persistenceContext, locale); + localizedServiceContext.newService(NotificationService.class).sendPollEndReminder(poll); + + // save last notification date + poll.setPollEndReminderSent(true); + pollService.commit(); + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Error while sending end reminder for poll " + poll.getTopiaId(), e); + } + } + } + + if (!persistenceContext.isClosed()) { + persistenceContext.close(); + } else { + if (log.isInfoEnabled()) { + log.info("persistence context already closed..."); + } + } + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java new file mode 100644 index 0000000..18b5e7b --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/job/SendVoteSummariesJob.java @@ -0,0 +1,71 @@ +package org.chorem.pollen.services.job; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.persistence.PollenTopiaPersistenceContext; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Vote; +import org.chorem.pollen.services.PollenApplicationContext; +import org.chorem.pollen.services.PollenServiceContext; +import org.chorem.pollen.services.service.NotificationService; +import org.chorem.pollen.services.service.PollService; +import org.chorem.pollen.services.service.VoteService; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +/** + * @author Kevin Morin (Code Lutin) + */ +public class SendVoteSummariesJob extends AbstractPollenJob { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SendVoteSummariesJob.class); + + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + PollenApplicationContext applicationContext = getApplicationContext(jobExecutionContext); + PollenTopiaPersistenceContext persistenceContext = applicationContext.newPersistenceContext(); + PollenServiceContext serviceContext = applicationContext.newServiceContext(persistenceContext, Locale.getDefault()); + + PollService pollService = serviceContext.newService(PollService.class); + Collection<Poll> pollsWithVoteSummarySending = pollService.getPollsWithVoteSummarySending(); + + for (Poll poll : pollsWithVoteSummarySending) { + try { + Locale locale; + if (poll.getNotificationLocale() != null) { + locale = Locale.forLanguageTag(poll.getNotificationLocale()); + } else { + locale = Locale.getDefault(); + } + PollenServiceContext localizedServiceContext = applicationContext.newServiceContext(persistenceContext, locale); + + List<Vote> votesSinceLastNotification = localizedServiceContext.newService(VoteService.class).getVotesSinceLastNotification(poll.getTopiaId()); + if (!votesSinceLastNotification.isEmpty()) { + localizedServiceContext.newService(NotificationService.class).sendVoteSummary(poll, votesSinceLastNotification); + } + + // save last notification date + poll.setLastVoteNotification(serviceContext.getNow()); + pollService.commit(); + + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Error while sending vote summary for poll " + poll.getTopiaId(), e); + } + } + } + + if (!persistenceContext.isClosed()) { + persistenceContext.close(); + } else { + if (log.isInfoEnabled()) { + log.info("persistence context already closed..."); + } + } + } +} diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index c26e7ee..1569927 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -31,6 +31,7 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollType; import org.chorem.pollen.persistence.entity.PollenPrincipal; import org.chorem.pollen.persistence.entity.PollenUser; +import org.chorem.pollen.persistence.entity.VoteNotification; import org.chorem.pollen.services.bean.ChoiceBean; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; @@ -49,6 +50,7 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; @@ -398,6 +400,16 @@ public class PollService extends PollenServiceSupport { return toBean(PollBean.class, poll, pollBeanFunction); } + public Collection<Poll> getPollsWithVoteSummarySending() { + return getPollDao().forVoteNotificationEquals(VoteNotification.DAILY_SUMMARY) + .addEquals(Poll.PROPERTY_CLOSED, false) + .findAll(); + } + + public Collection<Poll> getPollsWithReminderNeeded() { + return getPollDao().findPollsWithReminderNeeded(); + } + protected Poll savePoll(PollBean poll, List<ChoiceBean> choices) { boolean pollExists = poll.isPersisted(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java index e8d02f9..5d8a368 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/VoteService.java @@ -60,6 +60,7 @@ public class VoteService extends PollenServiceSupport { private final Function<VoteBean, VoteBean> voteBeanFunction = input -> { if (isNotPermitted(PermissionVerb.editVote, input.getEntityId())) { input.setPermission(null); + input.setVoterName(null); } return input; }; @@ -108,6 +109,12 @@ public class VoteService extends PollenServiceSupport { } + public List<Vote> getVotesSinceLastNotification(String pollId) { + checkNotNull(pollId); + Poll poll = getPollService().getPoll0(pollId); + return getVoteDao().findAllSince(poll, poll.getLastVoteNotification()); + } + public VoteBean getVote(String pollId, String voteId) { checkNotNull(voteId); @@ -281,10 +288,8 @@ public class VoteService extends PollenServiceSupport { toSave.setPoll(poll); } - toSave.setAnonymous(vote.isAnonymous()); + toSave.setAnonymous(poll.isAnonymousVoteAllowed()); -// toSave.setText(vote.getText()); -// // -- author -- // toSave.getVoter().setName(vote.getVoterName()); diff --git a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties index 5a372b5..9e6e6b1 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_en_GB.properties @@ -6,6 +6,7 @@ pollen.configuration.defaultCommentVisibility=Default comment visibility pollen.configuration.defaultContinuousResults=Défault continuous results pollen.configuration.defaultFavoriteListMemberPageSize=Default number of participants per page pollen.configuration.defaultFavoriteListPageSize=Default number of favorite lists per page +pollen.configuration.defaultNotifyMeHoursBeforePollEnds=Default time before the end of the poll to send the reminder email pollen.configuration.defaultPollChoiceType=Default choice type used when creating a new poll pollen.configuration.defaultPollCommentVisibility=Default Poll comment visibility used when creating a new poll pollen.configuration.defaultPollPageSize=Default number of polls per page @@ -15,10 +16,13 @@ pollen.configuration.defaultPollVoteVisibility=Default Poll vote visibility used pollen.configuration.defaultPollenUserPageSize=Default number of users per pages pollen.configuration.defaultResultVisibility=Default Result visibility pollen.configuration.defaultVoteCountingType=Default vote counting type used when creating a new poll +pollen.configuration.defaultVoteNotification=Default notification type for the votes of a poll pollen.configuration.defaultVoteVisibility=Default vote visiblity pollen.configuration.devMode=Dev mode pollen.configuration.logConfigurationFile=Path to log configuration file pollen.configuration.secret= +pollen.configuration.sendEndPollRemindersCronSchedule=Time between two cron jobs of poll end reminder sending +pollen.configuration.sendVoteSummariesCronSchedule=Time between two cron jobs of vote summary sending pollen.configuration.sessionTimeoutDelay=Inactivity delay before invalidate the session of a user (in seconds) pollen.configuration.smptHost=Smtp Host pollen.configuration.smtpFrom=Smtp From @@ -107,6 +111,7 @@ pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Add Choice perio pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Add Choice period started for poll %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Poll %s is closed pollen.service.mail.PollCreatedEmail.subject=[Pollen] Poll creation (%s) +pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Your poll %s ends soon pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Vote period ended for poll %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Vote period started for poll %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Reminder to vote on poll %s @@ -114,5 +119,6 @@ pollen.service.mail.ResendValidationEmail.subject=[Pollen] Invitation to validat pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation to vote on poll %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation of account creation %s pollen.service.mail.VoteAddedEmail.subject=[Pollen] A vote was added in poll %s -pollen.service.mail.VoteDeletedEmail.subject=[Pollen] A vote was edited in poll %s -pollen.service.mail.VoteEditedEmail.subject=[Pollen] A vote was deleted in poll %s +pollen.service.mail.VoteDeletedEmail.subject=[Pollen] A vote was deleted in poll %s +pollen.service.mail.VoteEditedEmail.subject=[Pollen] A vote was edited in poll %s +pollen.service.mail.VoteSummaryEmail.subject=[Pollen] Summary of the votes since %s for the poll %s diff --git a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties index 318f403..bcf9cd2 100644 --- a/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties +++ b/pollen-services/src/main/resources/i18n/pollen-services_fr_FR.properties @@ -6,6 +6,7 @@ pollen.configuration.defaultCommentVisibility=Visibilité des commentaires par d pollen.configuration.defaultContinuousResults=Voire les résultats en continue par défaut pollen.configuration.defaultFavoriteListMemberPageSize=Nomnre de participants par page pollen.configuration.defaultFavoriteListPageSize=Nombre de liste de favoris par page +pollen.configuration.defaultNotifyMeHoursBeforePollEnds=Combien de temps par défaut avant la fin du sondage envoyer le rappel pollen.configuration.defaultPollChoiceType=Type de choix par défaut lors de la création d'un nouveau sondage pollen.configuration.defaultPollCommentVisibility=Visibilité des commentaires par défaut lors de la création d'un nouveau sondage pollen.configuration.defaultPollPageSize=Nombre de sondages par page @@ -15,10 +16,13 @@ pollen.configuration.defaultPollVoteVisibility=Visibilité des votes par défaut pollen.configuration.defaultPollenUserPageSize=Nombre d'utilisateurs par page pollen.configuration.defaultResultVisibility=Visibilité des résultats par défaut pollen.configuration.defaultVoteCountingType=Type de dépouillement par défaut lors de la création d'un nouveau sondage +pollen.configuration.defaultVoteNotification=Type de notification par défaut pour les votes pollen.configuration.defaultVoteVisibility=Visibilité des votes par défaut pollen.configuration.devMode=Mode développement pollen.configuration.logConfigurationFile=Chemin vers le fichier de configuration des logs pollen.configuration.secret= +pollen.configuration.sendEndPollRemindersCronSchedule=Intervalle entre deux lancements de la tâche d'envoi de mails de rappel de fin de sondage +pollen.configuration.sendVoteSummariesCronSchedule=Intervalle entre deux lancements de la tâche d'envoi de mails de résumé des votes pour un sondage pollen.configuration.sessionTimeoutDelay=Temps autorisé d'inactivité avant d'invalider une session utilisateur (en secondes) pollen.configuration.smptHost=Hôye smtp pollen.configuration.smtpFrom=Expéditeur @@ -106,6 +110,7 @@ pollen.service.mail.PollChoicePeriodEndedEmail.subject=[Pollen] Période d'ajout pollen.service.mail.PollChoicePeriodStartedEmail.subject=[Pollen] Période d'ajout de choix commencée pour le sondage %s pollen.service.mail.PollClosedEmail.subject=[Pollen] Le sondage %s est clôt pollen.service.mail.PollCreatedEmail.subject=[Pollen] Création du sondage %s +pollen.service.mail.PollEndReminderEmail.subject=[Pollen] Votre sondage %s se termine bientôt pollen.service.mail.PollVotePeriodEndedEmail.subject=[Pollen] Période de vote terminée pour le sondage %s pollen.service.mail.PollVotePeriodStartedEmail.subject=[Pollen] Période de vote commencée pour le sondage %s pollen.service.mail.PollVoteReminderEmail.subject=[Pollen] Rappel du vote au sondage %s @@ -113,5 +118,6 @@ pollen.service.mail.ResendValidationEmail.subject=[Pollen] Validation de votre c pollen.service.mail.RestrictedPollInvitationEmail.subject=[Pollen] Invitation au sondage %s pollen.service.mail.UserAccountCreatedEmail.subject=[Pollen] Confirmation de création du compte %s pollen.service.mail.VoteAddedEmail.subject=[Pollen] Un nouveau vote a été ajouté au sondage %s -pollen.service.mail.VoteDeletedEmail.subject=[Pollen] Un vote a été modifié sur le sondage %s -pollen.service.mail.VoteEditedEmail.subject=[Pollen] Un vote a été supprimé du sondage %s +pollen.service.mail.VoteDeletedEmail.subject=[Pollen] Un vote a été supprimé sur le sondage %s +pollen.service.mail.VoteEditedEmail.subject=[Pollen] Un vote a été modifié du sondage %s +pollen.service.mail.VoteSummaryEmail.subject=[Pollen] Résumé des votes depuis le %s pour le sondage %s diff --git a/pom.xml b/pom.xml index 8937880..371aa49 100644 --- a/pom.xml +++ b/pom.xml @@ -567,13 +567,24 @@ <scope>provided</scope> </dependency> - <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk16</artifactId> <version>1.46</version> </dependency> + <dependency> + <groupId>org.quartz-scheduler</groupId> + <artifactId>quartz</artifactId> + <version>2.3.0</version> + <exclusions> + <exclusion> + <groupId>c3p0</groupId> + <artifactId>c3p0</artifactId> + </exclusion> + </exclusions> + </dependency> + <!--dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.