Mercurial Hosting > nabble
diff src/nabble/modules/poll/NodeNamespaceExt.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/modules/poll/NodeNamespaceExt.java Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,376 @@ +package nabble.modules.poll; + +import fschmidt.db.DbDatabase; +import fschmidt.util.java.DateUtils; +import nabble.model.Node; +import nabble.model.Person; +import nabble.model.User; +import nabble.naml.compiler.Command; +import nabble.naml.compiler.CommandSpec; +import nabble.naml.compiler.IPrintWriter; +import nabble.naml.compiler.Interpreter; +import nabble.naml.compiler.Namespace; +import nabble.naml.compiler.NamespaceExtension; +import nabble.naml.compiler.ScopedInterpreter; +import nabble.naml.namespaces.StringList; +import nabble.view.web.template.DateNamespace; +import nabble.view.web.template.NodeNamespace; +import nabble.view.web.template.RequestNamespace; +import nabble.view.web.template.ServletNamespace; +import nabble.view.web.template.ServletNamespaceUtils; + +import javax.servlet.ServletException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +@NamespaceExtension( + name = "node_poll", + target = NodeNamespace.class +) +public class NodeNamespaceExt { + + private final Node node; + private final ServletNamespaceUtils servletNsUtils; + + public NodeNamespaceExt(NodeNamespace ns) { + this.node = ns.node(); + this.servletNsUtils = ns.servletNsUtils; + } + + private Poll getPoll() { + return Poll.of(node); + } + + public static final CommandSpec set_poll = CommandSpec.DO() + .parameters("poll_question", "poll_options") + .optionalParameters("poll_max_choices","poll_days_left", + "poll_allow_vote_change","poll_show_results_before_vote", + "poll_show_results_before_end") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void set_poll(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) + throws ServletException, Poll.PollEditException, Poll.PollFormatException + { + User user = servletNsUtils.visitorUser(interp); + if (!node.getOwner().equals(user)) + throw new Poll.PollEditException(); + String pollQuestion = interp.getArgString("poll_question"); + RequestNamespace.ParameterValueList pollOptionsList = interp.getArgAsNamespace(RequestNamespace.ParameterValueList.class, "poll_options"); + String[] pollOptions = pollOptionsList.values().toArray(new String[0]); + int maxChoices = interp.getArgAsInt("poll_max_choices",1); + int daysLeft = interp.getArgAsInt("poll_days_left", 0); + boolean allowVoteChange = interp.getArgAsBoolean("poll_allow_vote_change",false); + boolean showResultsBeforeVote = interp.getArgAsBoolean("poll_show_results_before_vote",false); + boolean showResultsBeforeEnd = interp.getArgAsBoolean("poll_show_results_before_end",false); + setPoll( + pollQuestion, + pollOptions, + maxChoices, + daysLeft, + allowVoteChange, + showResultsBeforeVote, + showResultsBeforeEnd + ); + } + + private void setPoll(String pollQuestion, String[] pollOptions, int maxChoices, int daysLeft, boolean allowVoteChange, boolean showResultsBeforeVote, boolean showResultsBeforeEnd) + throws Poll.PollFormatException + { + DbDatabase db = node.getSite().getDb(); + if( !db.isInTransaction() ) { + db.beginTransaction(); + try { + setPoll( + pollQuestion, + pollOptions, + maxChoices, + daysLeft, + allowVoteChange, + showResultsBeforeVote, + showResultsBeforeEnd + ); + db.commitTransaction(); + } finally { + db.endTransaction(); + } + return; + } + Poll poll = new Poll( node.getGoodCopy(), pollOptions.length ); + poll.set(pollQuestion, pollOptions); + poll.setMaxChoices(maxChoices); + if (daysLeft > 0) poll.setEndDate(DateUtils.addDays(new Date(), daysLeft)); + poll.setAllowVoteChange(allowVoteChange); + poll.setShowResultsBeforeVote(showResultsBeforeVote); + poll.setShowResultsBeforeEnd(showResultsBeforeEnd); + } + + public static final CommandSpec edit_poll = CommandSpec.DO() + .optionalParameters("poll_max_choices","poll_days_left", + "poll_allow_vote_change","poll_show_results_before_vote", + "poll_show_results_before_end") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void edit_poll(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) + throws ServletException, Poll.PollEditException, Poll.PollFormatException + { + User user = servletNsUtils.visitorUser(interp); + if (!node.getOwner().equals(user)) + throw new Poll.PollEditException(); + Poll poll = getPoll(); + poll.setMaxChoices(interp.getArgAsInt("poll_max_choices",1)); + String daysLeftS = interp.getArgString("poll_days_left"); + if (daysLeftS != null) { + int daysLeft; + try { + daysLeft = Integer.parseInt(daysLeftS); + } catch (NumberFormatException e) { + throw new Poll.PollFormatException(); + } + Date endDate = poll.endDate(); + Date now = new Date(); + if (endDate==null) { + poll.setEndDate(DateUtils.addDays(now, daysLeft)); + } else { + int daysLeftOrig = DateUtils.datesBetween(now, endDate); + if (daysLeftOrig != daysLeft) { + poll.setEndDate(DateUtils.addDays(endDate, daysLeft-daysLeftOrig)); + } + } + } else { + poll.setEndDate(null); + } + poll.setAllowVoteChange(interp.getArgAsBoolean("poll_allow_vote_change",false)); + poll.setShowResultsBeforeVote(interp.getArgAsBoolean("poll_show_results_before_vote",false)); + poll.setShowResultsBeforeEnd(interp.getArgAsBoolean("poll_show_results_before_end",false)); + } + + public static final CommandSpec delete_poll = CommandSpec.DO() + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void delete_poll(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) + throws ServletException, Poll.PollEditException + { + User user = servletNsUtils.visitorUser(interp); + if (!node.getOwner().equals(user)) + throw new Poll.PollEditException(); + DbDatabase db = node.getSite().getDb(); + db.beginTransaction(); + try { + Poll poll = Poll.of( node.getGoodCopy() ); + if( poll != null ) + poll.delete(); + db.commitTransaction(); + } finally { + db.endTransaction(); + } + } + + public static final CommandSpec has_poll = CommandSpec.DO; + + @Command public void has_poll(IPrintWriter out, Interpreter interp) { + out.print(getPoll()!=null); + } + + public static final CommandSpec poll_question = CommandSpec.DO; + + @Command public void poll_question(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().getQuestion()); + } + + public static final CommandSpec poll_option_list = CommandSpec.DO; + + @Command public void poll_option_list(IPrintWriter out,ScopedInterpreter<PollOptionList> interp) { + List<String> options = Arrays.asList(getPoll().getOptions()); + Object block = interp.getArg(new PollOptionList(options, getPoll().getNode().getId()),"do"); + out.print(block); + } + + public static final CommandSpec poll_max_choices = CommandSpec.DO; + + @Command public void poll_max_choices(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().maxChoices()); + } + + public static final CommandSpec poll_has_end_date = CommandSpec.DO; + + @Command public void poll_has_end_date(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().endDate()!=null); + } + + public static final CommandSpec poll_end_date = CommandSpec.DO; + + @Command public void poll_end_date(IPrintWriter out,ScopedInterpreter<DateNamespace> interp) { + out.print(interp.getArg( new DateNamespace(getPoll().endDate()), "do" )); + } + + public static final CommandSpec poll_days_left = CommandSpec.DO; + + @Command public void poll_days_left(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + Date endDate = getPoll().endDate(); + if (endDate!=null) { + out.print(DateUtils.datesBetween(new Date(), endDate)); + } + } + + public static final CommandSpec poll_allow_vote_change = CommandSpec.DO; + + @Command public void poll_allow_vote_change(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().allowVoteChange()); + } + + public static final CommandSpec poll_show_results_before_vote = CommandSpec.DO; + + @Command public void poll_show_results_before_vote(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().showResultsBeforeVote()); + } + + public static final CommandSpec poll_show_results_before_end = CommandSpec.DO; + + @Command public void poll_show_results_before_end(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) { + out.print(getPoll().showResultsBeforeEnd()); + } + + public static final CommandSpec poll_vote_counts = CommandSpec.DO() + .build() + ; + + @Command public void poll_vote_counts(IPrintWriter out,ScopedInterpreter<PollOptionList> interp) { + int[] v = getPoll().getVoteCounts(); + List<String> voteCounts = new ArrayList<String>(); + for (int n : v) { + voteCounts.add(String.valueOf(n)); + } + Object block = interp.getArg(new PollOptionList(voteCounts, getPoll().getNode().getId()),"do"); + out.print(block); + } + + public static final CommandSpec poll_visitor_has_voted = CommandSpec.DO() + .dotParameter("index") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void poll_visitor_has_voted(IPrintWriter out,ScopedInterpreter<StringList> interp) + throws ServletException + { + int index = interp.getArgAsInt("index"); + User viewer = servletNsUtils.visitorUser(interp); + int[] v = getPoll().getVotes(viewer); + for (int i : v) { + if (i==index) { + out.print(true); + return; + } + } + out.print(false); + } + + public static final CommandSpec poll_visitor_can_see_votes = CommandSpec.DO() + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void poll_visitor_can_see_votes(IPrintWriter out,Interpreter interp) + throws ServletException + { + Poll poll = getPoll(); + User viewer = servletNsUtils.visitorUser(interp); + Person owner = node.getOwner(); + if (viewer!=null && viewer.equals(owner)) { + out.print(true); + return; + } + if (poll.endDate()!=null) { + Date now = new Date(); + if (!poll.showResultsBeforeEnd() && poll.endDate().after(now)) { + out.print(false); + return; + } + if (poll.endDate().before(now)) { + out.print(true); + return; + } + } + if (!poll.showResultsBeforeVote() && (viewer==null || poll.getVotes(viewer).length==0)) { + out.print(false); + return; + } + out.print(true); + } + + public static final CommandSpec poll_has_ended = CommandSpec.DO; + + @Command public void poll_has_ended(IPrintWriter out,Interpreter interp) + throws ServletException + { + Poll poll = getPoll(); + boolean hasEnded = poll.endDate() != null && poll.endDate().before(new Date()); + out.print(hasEnded); + } + + public static final CommandSpec poll_visitor_can_vote = CommandSpec.DO() + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void poll_visitor_can_vote(IPrintWriter out,Interpreter interp) + throws ServletException + { + Poll poll = getPoll(); + User viewer = servletNsUtils.visitorUser(interp); + if (poll.endDate()!=null && poll.endDate().before(new Date())) { + out.print(false); + return; + } + if (!poll.allowVoteChange() && (viewer==null || poll.getVotes(viewer).length>0)) { + out.print(false); + return; + } + out.print(true); + } + + public static final CommandSpec poll_vote = CommandSpec.DO() + .parameters("votes") + .requiredInStack(ServletNamespace.class) + .build() + ; + + @Command public void poll_vote(IPrintWriter out,ScopedInterpreter<NodeNamespace> interp) + throws ServletException, Poll.PollVoteException { + Poll poll = getPoll(); + User voter = servletNsUtils.visitorUser(interp); + RequestNamespace.ParameterValueList vlist = interp.getArgAsNamespace(RequestNamespace.ParameterValueList.class, "votes"); + if (vlist==null) return; + List<String> votes = vlist.values(); + int[] v = new int[votes.size()]; + for (int i=0; i<v.length; i++) + v[i] = Integer.parseInt(votes.get(i)); + poll.vote(voter, v); + } + + @Namespace( + name = "poll_option_list", + global = true + ) + public static final class PollOptionList extends StringList { + + private final long nodeId; + + PollOptionList(List<String> list, long nodeId) { + super(list); + this.nodeId = nodeId; + } + + @Command public void option_id(IPrintWriter out,Interpreter interp) { + out.print(nodeId + "-" + index); + } + } +}