branch feature/14_add_rss_feed created (now a8face4)
This is an automated email from the git hooks/post-receive script. New change to branch feature/14_add_rss_feed in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git at a8face4 refs #14 création du flux atom à la création du sondage + ajout des entrées dans le flux pour l'ajout, la suppression et la modification d'un vote + ajout du bouton pour lire le flux à partir du sondage This branch includes the following new commits: new a8face4 refs #14 création du flux atom à la création du sondage + ajout des entrées dans le flux pour l'ajout, la suppression et la modification d'un vote + ajout du bouton pour lire le flux à partir du sondage The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit a8face4b03d26cb2d2b2a6edc69bd805f5e93533 Author: Kevin Morin <morin@codelutin.com> Date: Fri May 12 09:26:40 2017 +0200 refs #14 création du flux atom à la création du sondage + ajout des entrées dans le flux pour l'ajout, la suppression et la modification d'un vote + ajout du bouton pour lire le flux à partir du sondage -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/14_add_rss_feed in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit a8face4b03d26cb2d2b2a6edc69bd805f5e93533 Author: Kevin Morin <morin@codelutin.com> Date: Fri May 12 09:26:40 2017 +0200 refs #14 création du flux atom à la création du sondage + ajout des entrées dans le flux pour l'ajout, la suppression et la modification d'un vote + ajout du bouton pour lire le flux à partir du sondage --- pollen-persistence/src/main/xmi/pollen.properties | 1 + pollen-persistence/src/main/xmi/pollen.zargo | Bin 24937 -> 25019 bytes .../org/chorem/pollen/rest/api/v1/PollApi.java | 6 ++ pollen-rest-api/src/main/resources/mapping | 2 + pollen-services/pom.xml | 6 +- .../pollen/services/service/FeedService.java | 116 +++++++++++++++++++++ .../pollen/services/service/PollService.java | 1 + .../services/service/PollenServiceSupport.java | 28 +++++ .../pollen/services/service/VoteService.java | 3 + .../pollen/services/service/mail/EmailService.java | 35 +------ .../i18n/pollen-services_en_GB.properties | 5 + .../i18n/pollen-services_fr_FR.properties | 5 + .../src/main/web/tag/poll/Poll.tag.html | 3 +- pom.xml | 8 +- 14 files changed, 181 insertions(+), 38 deletions(-) diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index e074670..3dccb21 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -27,6 +27,7 @@ model.tagValue.hibernateAttributeType.String=string package.org.chorem.pollen.persistence.entity.stereotype=entity # Text org.chorem.pollen.persistence.entity.Poll.attribute.description.tagValue.hibernateAttributeType=text +org.chorem.pollen.persistence.entity.Poll.attribute.feedContent.tagValue.hibernateAttributeType=text org.chorem.pollen.persistence.entity.Choice.attribute.description.tagValue.hibernateAttributeType=text org.chorem.pollen.persistence.entity.Comment.attribute.text.tagValue.hibernateAttributeType=text # Blob diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 6f6fdb3..aa99064 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java index 732839b..0c25748 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollApi.java @@ -32,9 +32,11 @@ import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.VoterListBean; import org.chorem.pollen.services.bean.VoterListMemberBean; +import org.chorem.pollen.services.service.FeedService; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollService; import org.debux.webmotion.server.WebMotionController; +import org.debux.webmotion.server.render.Render; import java.io.File; import java.util.List; @@ -133,4 +135,8 @@ public class PollApi extends WebMotionController { public PollBean assignPoll(PollService pollService, PollenEntityId<Poll> pollId) { return pollService.assignPollToConnectedUser(pollId.getEntityId()); } + + public Render getFeedForPoll(FeedService feedService, PollenEntityId<Poll> pollId) { + return renderAtom(feedService.getFeedForPoll(pollId.getEntityId())); + } } diff --git a/pollen-rest-api/src/main/resources/mapping b/pollen-rest-api/src/main/resources/mapping index c1a63e2..b434a60 100644 --- a/pollen-rest-api/src/main/resources/mapping +++ b/pollen-rest-api/src/main/resources/mapping @@ -123,6 +123,8 @@ PUT /v1/polls/{pollId}/close PollApi.closePoll PUT /v1/polls/{pollId}/reopen PollApi.reopenPoll PUT /v1/polls/{pollId}/assign PollApi.assignPoll +GET /v1/polls/{pollId}/feed PollApi.getFeedForPoll + # PollenResourceApi GET /v1/resources/{resourceId} PollenResourceApi.getResource diff --git a/pollen-services/pom.xml b/pollen-services/pom.xml index 7fa0d31..2a5151d 100644 --- a/pollen-services/pom.xml +++ b/pollen-services/pom.xml @@ -126,10 +126,10 @@ <artifactId>guava</artifactId> </dependency> - <!--dependency> - <groupId>rome</groupId> + <dependency> + <groupId>com.rometools</groupId> <artifactId>rome</artifactId> - </dependency--> + </dependency> <dependency> <groupId>junit</groupId> diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/FeedService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/FeedService.java new file mode 100644 index 0000000..9623986 --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/FeedService.java @@ -0,0 +1,116 @@ +package org.chorem.pollen.services.service; + +import com.rometools.rome.feed.synd.SyndContent; +import com.rometools.rome.feed.synd.SyndContentImpl; +import com.rometools.rome.feed.synd.SyndEntry; +import com.rometools.rome.feed.synd.SyndEntryImpl; +import com.rometools.rome.feed.synd.SyndFeed; +import com.rometools.rome.feed.synd.SyndFeedImpl; +import com.rometools.rome.io.FeedException; +import com.rometools.rome.io.SyndFeedInput; +import com.rometools.rome.io.SyndFeedOutput; +import org.chorem.pollen.persistence.entity.Poll; +import org.chorem.pollen.persistence.entity.Vote; +import org.chorem.pollen.services.PollenTechnicalException; +import org.chorem.pollen.services.service.security.PermissionVerb; + +import java.io.StringReader; +import java.text.DateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.nuiton.i18n.I18n.n; +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin (Code Lutin) + * @since 3.0 + */ +public class FeedService extends PollenServiceSupport { + + public static final String FEED_TYPE = "atom_1.0"; + public static final String DESCRIPTION_TYPE = "text/plain"; + + public void onPollCreated(Poll poll) { + SyndFeed feed = new SyndFeedImpl(); + feed.setFeedType(FEED_TYPE); + + feed.setTitle(poll.getTitle()); + String voteUrl = getPollVoteUrl(poll); + feed.setLink(voteUrl); + feed.setDescription(poll.getDescription()); + + SyndEntry entry = new SyndEntryImpl(); + entry.setTitle(t("pollen.service.feed.pollCreated.title", poll.getCreator().getName(), poll.getTitle())); + entry.setLink(voteUrl); + entry.setPublishedDate(poll.getTopiaCreateDate()); + + SyndContent description = new SyndContentImpl(); + description.setType(DESCRIPTION_TYPE); + description.setValue(t("pollen.service.feed.pollCreated.description", + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(poll.getTopiaCreateDate()), + poll.getCreator().getName(), + poll.getTitle())); + entry.setDescription(description); + + List<SyndEntry> feedEntries = Collections.singletonList(entry); + feed.setEntries(feedEntries); + + saveFeed(poll, feed); + } + + public void onVoteAdded(Poll poll, Vote vote) { + addVoteFeedEntry(poll, vote, n("pollen.service.feed.voteAdded.title")); + } + + public void onVoteEdited(Poll poll, Vote vote) { + addVoteFeedEntry(poll, vote, n("pollen.service.feed.voteEdited.title")); + } + + public void onVoteDeleted(Poll poll, Vote vote) { + addVoteFeedEntry(poll, vote, n("pollen.service.feed.voteDeleted.title")); + } + + public SyndFeed getFeedForPoll(String pollId) { + checkNotNull(pollId); + checkPermission(PermissionVerb.readPoll, pollId); + + Poll poll = getPollService().getPoll0(pollId); + + try { + SyndFeedInput feedInput = new SyndFeedInput(true, getLocale()); + return feedInput.build(new StringReader(poll.getFeedContent())); + + } catch (FeedException e) { + throw new PollenTechnicalException("Error while reading the feed", e); + } + } + + private void addVoteFeedEntry(Poll poll, Vote vote, String messageKey) { + SyndFeed feed = getFeedForPoll(poll.getTopiaId()); + List<SyndEntry> entries = new ArrayList<>(feed.getEntries()); + + SyndEntry entry = new SyndEntryImpl(); + entry.setTitle(t(messageKey, vote.getVoter().getName())); + entry.setLink(getPollVoteUrl(poll)); + entry.setPublishedDate(vote.getTopiaCreateDate()); + + entries.add(entry); + feed.setEntries(entries); + + saveFeed(poll, feed); + } + + private void saveFeed(Poll poll, SyndFeed feed) { + try { + SyndFeedOutput output = new SyndFeedOutput(); + String feedContent = output.outputString(feed); + poll.setFeedContent(feedContent); + commit(); + + } catch (FeedException e) { + throw new PollenTechnicalException("Error while creating the feed", e); + } + } +} 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 1569927..0618b9a 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 @@ -225,6 +225,7 @@ public class PollService extends PollenServiceSupport { commit(); getNotificationService().onPollCreated(savedPoll); + getFeedService().onPollCreated(savedPoll); return PollenEntityRef.of(savedPoll); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java index f6076a6..62704bd 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java @@ -33,6 +33,7 @@ import org.chorem.pollen.persistence.entity.ChoiceTopiaDao; import org.chorem.pollen.persistence.entity.CommentTopiaDao; import org.chorem.pollen.persistence.entity.FavoriteListMemberTopiaDao; import org.chorem.pollen.persistence.entity.FavoriteListTopiaDao; +import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollTopiaDao; import org.chorem.pollen.persistence.entity.PollenPrincipalTopiaDao; import org.chorem.pollen.persistence.entity.PollenResourceTopiaDao; @@ -49,6 +50,7 @@ import org.chorem.pollen.services.PollenUIContext; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenBean; import org.chorem.pollen.services.bean.PollenBeans; +import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.config.PollenServicesConfig; import org.chorem.pollen.services.service.mail.EmailService; import org.chorem.pollen.services.service.security.PermissionVerb; @@ -128,6 +130,10 @@ public abstract class PollenServiceSupport implements PollenService { return newService(NotificationService.class); } + protected FeedService getFeedService() { + return newService(FeedService.class); + } + protected PollService getPollService() { return newService(PollService.class); } @@ -447,4 +453,26 @@ public abstract class PollenServiceSupport implements PollenService { } + protected <E extends TopiaEntity> PollenEntityId<E> getPollenEntityId(E entity) { + PollenEntityId<E> pollenEntityId = PollenEntityId.newId((Class<E>) entity.getClass()); + pollenEntityId.setEntityId(entity.getTopiaId()); + pollenEntityId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); + return pollenEntityId; + } + + protected String getPollVoteUrl(Poll poll) { + return getPollVoteUrl(getPollenEntityId(poll), null); + } + + protected String getPollVoteUrl(Poll poll, String token) { + return getPollVoteUrl(getPollenEntityId(poll), token); + } + + protected String getPollVoteUrl(PollenEntityId<Poll> pollId, String token) { + return getPollenUIUrlRenderService().getPollVoteUrl + (getUIContext().getPollVoteUrl(), + pollId.getReducedId(), + token); + } + } 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 5d8a368..32c7e5e 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 @@ -145,6 +145,7 @@ public class VoteService extends PollenServiceSupport { commit(); getNotificationService().onVoteAdded(poll, result); + getFeedService().onVoteAdded(poll, result); return PollenEntityRef.of(result); @@ -166,6 +167,7 @@ public class VoteService extends PollenServiceSupport { commit(); getNotificationService().onVoteEdited(poll, result); + getFeedService().onVoteEdited(poll, result); return toBean(VoteBean.class, result); @@ -185,6 +187,7 @@ public class VoteService extends PollenServiceSupport { commit(); getNotificationService().onVoteDeleted(poll, vote); + getFeedService().onVoteDeleted(poll, vote); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java index a104a06..6555fda 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/mail/EmailService.java @@ -146,10 +146,7 @@ public class EmailService extends PollenServiceSupport { email.setPollenUrl(getUIContext().getUiEndPoint()); - PollenEntityId<Poll> pollId = PollenEntityId.newId(Poll.class); - pollId.setEntityId(poll.getTopiaId()); - pollId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); - + PollenEntityId<Poll> pollId = getPollenEntityId(poll); email.setUrl(getPollenUIUrlRenderService().getPollEditUrl(getUIContext().getPollEditUrl(), pollId.getReducedId(), poll.getCreator().getPermission().getToken())); @@ -196,15 +193,7 @@ public class EmailService extends PollenServiceSupport { public PollInvitationEmail newPollInvitationEmail(Poll poll) { PollInvitationEmail email = new PollInvitationEmail(getLocale()); email.setPoll(poll); - - PollenEntityId<Poll> pollId = PollenEntityId.newId(Poll.class); - pollId.setEntityId(poll.getTopiaId()); - pollId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); - - email.setVoteUrl(getPollenUIUrlRenderService().getPollVoteUrl - (getUIContext().getPollVoteUrl(), - pollId.getReducedId(), - null)); + email.setVoteUrl(getPollVoteUrl(poll)); return email; } @@ -213,15 +202,7 @@ public class EmailService extends PollenServiceSupport { RestrictedPollInvitationEmail email = new RestrictedPollInvitationEmail(getLocale()); email.setPoll(poll); email.setPrincipal(principal); - - PollenEntityId<Poll> pollId = PollenEntityId.newId(Poll.class); - pollId.setEntityId(poll.getTopiaId()); - pollId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); - - email.setVoteUrl(getPollenUIUrlRenderService().getPollVoteUrl - (getUIContext().getPollVoteUrl(), - pollId.getReducedId(), - principal.getPermission().getToken())); + email.setVoteUrl(getPollVoteUrl(poll, principal.getPermission().getToken())); email.setToken(principal.getPermission().getToken()); @@ -234,10 +215,7 @@ public class EmailService extends PollenServiceSupport { email.setPollenUrl(pollenUIContext.getUiEndPoint()); - PollenEntityId<PollenUser> userId = PollenEntityId.newId(PollenUser.class); - userId.setEntityId(user.getTopiaId()); - userId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); - + PollenEntityId<PollenUser> userId = getPollenEntityId(user); email.setValidateUrl(getPollenUIUrlRenderService().getUserValidateUrl(pollenUIContext.getUserValidateUrl(), userId.getReducedId(), user.getEmailActivationToken().getToken())); @@ -250,10 +228,7 @@ public class EmailService extends PollenServiceSupport { email.setUser(user); email.setPollenUrl(pollenUIContext.getUiEndPoint()); - PollenEntityId<PollenUser> userId = PollenEntityId.newId(PollenUser.class); - userId.setEntityId(user.getTopiaId()); - userId.encode(serviceContext.getTopiaApplicationContext().getTopiaIdFactory()); - + PollenEntityId<PollenUser> userId = getPollenEntityId(user); email.setValidateUrl(getPollenUIUrlRenderService().getUserValidateUrl(pollenUIContext.getUserValidateUrl(), userId.getReducedId(), user.getEmailActivationToken().getToken())); 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 9e6e6b1..a854b1e 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 @@ -100,6 +100,11 @@ pollen.error.voterList.member.weight.greaterThan0=member weight must be greater pollen.error.voterList.name.alreadyUsed=voterList name already used pollen.error.voterList.name.mandatory=voterList name can not be empty pollen.error.voterList.weight.greaterThan0=voterList weight must be greater than 0 +pollen.service.feed.pollCreated.description=On the %s, %s created the poll "%s". +pollen.service.feed.pollCreated.title=%s created the poll "%s" +pollen.service.feed.voteAdded.title=%s voted +pollen.service.feed.voteDeleted.title=%s deleted his vote +pollen.service.feed.voteEdited.title=%s edited his vote pollen.service.mail.ChoiceAddedEmail.subject=[Pollen] A choice was added in poll %s pollen.service.mail.ChoiceDeletedEmail.subject=[Pollen] A choice was deleted in poll %s pollen.service.mail.ChoiceEditedEmail.subject=[Pollen] A choice was edited in 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 bcf9cd2..dc26311 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 @@ -99,6 +99,11 @@ pollen.error.voterList.member.weight.greaterThan0=Le membre doit avoir un poid s pollen.error.voterList.name.alreadyUsed=Le nom de la liste de votant existe déjà pollen.error.voterList.name.mandatory=Nom de la liste de votant est obligatoire pollen.error.voterList.weight.greaterThan0=Poid de la liste de votant doit être supérieur à 0 +pollen.service.feed.pollCreated.description=Le %s, %s a créé le sondage %s. +pollen.service.feed.pollCreated.title=%s a créé le sondage "%s" +pollen.service.feed.voteAdded.title=%s a voté +pollen.service.feed.voteDeleted.title=%s a supprimé son vote +pollen.service.feed.voteEdited.title=%s a modifié son vote pollen.service.mail.ChoiceAddedEmail.subject=[Pollen] Un choix a été ajouté au sondage %s pollen.service.mail.ChoiceDeletedEmail.subject=[Pollen] Un choix a été supprimé du sondage %s pollen.service.mail.ChoiceEditedEmail.subject=[Pollen] Un choix a été modifié sur le sondage %s diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html index eae9ce3..6f57e39 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Poll.tag.html @@ -120,7 +120,8 @@ require("../popup/QrCodeButton.tag.html"); <h1> <QrCodeButton if={poll.pollType === "FREE"} value="{window.location.origin}{window.location.pathname}#poll/{poll.id}/vote"/> {poll.title} - <h1> + <a href="{session.configuration.endPoint}/v1/polls/{poll.id}/feed" class="fa fa-rss-square" aria-hidden="true"></a> + </h1> <h3>{poll.description}</h3> diff --git a/pom.xml b/pom.xml index 371aa49..2af2b0b 100644 --- a/pom.xml +++ b/pom.xml @@ -464,11 +464,11 @@ <!-- Rome (rss) --> - <!--dependency> - <groupId>rome</groupId> + <dependency> + <groupId>com.rometools</groupId> <artifactId>rome</artifactId> - <version>1.0</version> - </dependency--> + <version>1.7.2</version> + </dependency> <!-- Logging --> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm