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);
+		}
+	}
+}