adding in web polling

This commit is contained in:
Chad Pilkey 2012-10-11 15:44:40 +00:00
parent 1e813affd1
commit ad519be5d7
19 changed files with 498 additions and 0 deletions

3
web-polling/README Normal file
View File

@ -0,0 +1,3 @@
The web-polling project (p) is a Dynamic Web Project created in Eclipse EE.
To install place p.war into /var/lib/tomcat6/webapps, and p.nginx into /etc/bigbluebutton/nginx.

23
web-polling/p.nginx Normal file
View File

@ -0,0 +1,23 @@
# Forward request to /p to tomcat. This is for
# the BigBlueButton web polling capabilities.
location /p {
proxy_pass http://127.0.0.1:8080;
proxy_redirect default;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Allow 30M uploaded presentation document.
client_max_body_size 30m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
include fastcgi_params;
}

BIN
web-polling/p.war Executable file

Binary file not shown.

17
web-polling/p/.classpath Executable file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6">
<attributes>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v6.0">
<attributes>
<attribute name="owner.project.facets" value="jst.web"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>

36
web-polling/p/.project Executable file
View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>p</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="WebContent"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
<attributes>
<attribute name="hide" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
<classpathentry kind="output" path=""/>
</classpath>

View File

@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="p">
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
<property name="context-root" value="p"/>
<property name="java-output-path" value="/p/build/classes"/>
</wb-module>
</project-modules>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime name="Apache Tomcat v6.0"/>
<fixed facet="wst.jsdt.web"/>
<fixed facet="java"/>
<fixed facet="jst.web"/>
<installed facet="java" version="1.6"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>

View File

@ -0,0 +1 @@
org.eclipse.wst.jsdt.launching.baseBrowserLibrary

View File

@ -0,0 +1 @@
Window

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

Binary file not shown.

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>p</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -0,0 +1,136 @@
<%
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
%>
<jsp:useBean id="connection" class="connection.JedisConnection" scope="session"/>
<jsp:setProperty name="connection" property="*"/>
<%@page import="javax.servlet.http.Cookie"%>
<%
String poll = request.getParameter( "poll" );
boolean validVote = false;
String error = null;
// grab cookies and look for the bbbpollstaken cookie
String cookieValue = null;
Cookie [] cookies = request.getCookies();
if (cookies != null) {
for (int i=0; i < cookies.length; i++) {
if (cookies[i].getName().equals("bbbpollstaken")) {
cookieValue = cookies[i].getValue();
}
}
}
String vote = null;
String [] votes = null;
if (connection.getTitle() != null) {
if (connection.getMultiple().equals("false")) {
vote = request.getParameter( "answers" );
} else {
votes = request.getParameterValues( "answers" );
}
}
if (poll == null) {
error = "Error: No poll entered.";
} else if (poll.equals("youshallnotpass")) {
error = "Error: Requested resource not found.";
} else if (connection.cleanWebKey(poll)) {
error = "Error: Improper formatting.";
} else if (connection.sessionVoted(poll) || (cookieValue != null && connection.cookieCheck(cookieValue, poll))) { // already voted
error = "Error: Already voted.";
} else if (!connection.retrievePoll(poll)) { // tries to find poll
error = "Error: Poll not found.";
} else if (connection.getMultiple().equals("false") && vote != null) { // radio buttons used
// check to see if they pressed they selected an answer
validVote = true;
connection.recordRadioVote(vote);
} else if (connection.getMultiple().equals("true") && votes != null) { // checkboxes used
validVote = true;
connection.recordCheckVote(votes);
} else {
String [] answers = connection.getAnswers();
session.setAttribute("webkey", poll); %>
<html>
<head>
<title><%= connection.getTitle()%></title>
</head>
<body>
<%= connection.getQuestion()%> <br /> <br />
<form method="post" action="<%= poll%>">
<%
// determine whether to use checkboxes or radio buttons
String type;
if (connection.getMultiple().equals("true")) {
type = "checkbox";
} else {
type = "radio";
}
// display the possible answers
for (int i=0; i < answers.length; i++){
%>
<input type="<%= type%>" name="answers" value="<%= i+1%>" /> <%= answers[i]%> <br />
<%
}
%>
<br />
<input type="submit" value="Submit" />
</form>
<%
}
// check if an error was recorded
if (error != null) {
%>
<html>
<head>
<title>Error</title>
</head>
<body>
<h1> <%= error%> </h1>
<%
} else if (validVote) {
%>
<html>
<head>
<title><%= connection.getTitle()%></title>
</head>
<body>
Thank you for voting!
<%
// write to the cookie
if (cookieValue == null) {
cookieValue = "," + (String) session.getAttribute("webkey") + ",";
} else {
cookieValue += session.getAttribute("webkey") + ",";
}
Cookie bbbpollstaken = new Cookie("bbbpollstaken", cookieValue);
bbbpollstaken.setMaxAge(60*60*8); // expire after 4h
response.addCookie( bbbpollstaken );
}
%>
</body>
</html>

Binary file not shown.

View File

@ -0,0 +1,228 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package connection;
import java.util.ArrayList;
import java.util.Scanner;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.io.File;
import java.io.FileReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* @author Chad Pilkey <capilkey@gmail.com>
* @version 1.0
* @since 2012-03-05
*/
public class JedisConnection {
JedisPool redisPool;
String pollKey;
String title;
String question;
String multiple;
ArrayList<String> answers;
String curWebKey;
ArrayList<String> pollsVoted = new ArrayList<String>();
private static String BBB_FILE =
"/var/lib/tomcat6/webapps/bigbluebutton/WEB-INF/classes/bigbluebutton.properties";
private static String BBB_SERVER_FIELD = "bigbluebutton.web.serverURL";
public static Jedis dbConnect(){
String serverIP = "127.0.0.1";
//String serverIP = getLocalIP();
//serverIP = serverIP.substring(7);
JedisPool redisPool = new JedisPool(serverIP, 6379);
try{
return redisPool.getResource();
}
catch (Exception e){
//log.error("Error in PollApplication.dbConnect():");
///log.error(e.toString());
}
//log.error("Returning NULL from dbConnect()");
return null;
}
/*private static String getLocalIP() {
File parseFile = new File(BBB_FILE);
try{
Scanner scanner = new Scanner(new FileReader(parseFile));
Boolean found = false;
String serverAddress = "";
while (!found && scanner.hasNextLine()){
serverAddress = processLine(scanner.nextLine());
if (!serverAddress.equals("")){
found = true;
}
}
scanner.close();
return serverAddress;
}
catch (Exception e){
//log.error("Error in scanning " + BBB_FILE + " to find server address.");
}
return null;
}
private static String processLine(String line) {
//use a second Scanner to parse the content of each line
Scanner scanner = new Scanner(line);
scanner.useDelimiter("=");
if ( scanner.hasNext() ){
String name = scanner.next();
if (name.equals(BBB_SERVER_FIELD)){
String value = scanner.next();
return value;
}
}
return "";
}*/
/**
* Retrieves a poll from the local computer's Redis database.
*
* @param webKey 4 digit number for poll you want
* @return Returns true if the poll is retrieved otherwise false
*/
public boolean retrievePoll(String webKey) {
Jedis jedis = dbConnect();
if (jedis.exists(webKey) && jedis.hget(jedis.get(webKey), "title") != null) {
curWebKey = webKey;
pollKey = jedis.get(webKey);
title = jedis.hget(pollKey, "title");
question = jedis.hget(pollKey, "question");
multiple = jedis.hget(pollKey, "multiple");
long pollSize = jedis.hlen(pollKey);
int otherFields = 10;
long numAnswers = (pollSize-otherFields)/2;
answers = new ArrayList <String>();
for (int j = 1; j <= numAnswers; j++) {
answers.add(jedis.hget(pollKey, "answer"+j+"text"));
}
return true;
} else
return false;
}
/**
* Increases the passed answer's vote count by one and also increases
* the total votes by one.
*
* @param vote the answer number of the answer to be increased
*/
public void recordRadioVote(String vote) {
Jedis jedis = dbConnect();
jedis.hincrBy(pollKey, "totalVotes", 1);
jedis.hincrBy(pollKey, "answer"+vote, 1);
pollsVoted.add(curWebKey);
}
/**
* Increases each of the passed answers' vote counts by one and
* increases the total votes by one.
*
* @param votes the answer numbers to be increased
*/
public void recordCheckVote(String [] votes) {
Jedis jedis = dbConnect();
jedis.hincrBy(pollKey, "totalVotes", 1);
for (int i=0; i<votes.length; i++) {
jedis.hincrBy(pollKey, "answer"+votes[i], 1);
}
pollsVoted.add(curWebKey);
}
/**
* Tries to find the passed webkey in the contents of the passed string.
*
* @param cv the contents of the bigbluebutton cookie
* @param webkey the webkey that you want to search for
* @return true if the webkey is found, otherwise false
*/
public boolean cookieCheck(String cv, String webkey) {
Pattern p = Pattern.compile(","+webkey+",");
Matcher m = p.matcher(cv);
return m.find(0);
}
/**
* Checks the passed webkey for any non-digit character.
*
* @param key the webkey that you want to check
* @return true if a non-digit character is found, otherwise false
*/
public boolean cleanWebKey(String key) {
Pattern p = Pattern.compile("[^\\d]");
Matcher m = p.matcher(key);
return m.find(0);
}
/**
* Checks the current object to see if the poll has already been voted on.
*
* @param poll poll to try and find
* @return true if the poll has already been voted on, otherwise false
*/
public boolean sessionVoted(String poll) {
return pollsVoted.contains(poll);
}
public String getTitle() {
return title;
}
public String getQuestion() {
return question;
}
public String getMultiple() {
return multiple;
}
public String [] getAnswers() {
String [] temp = new String [answers.size()];
return answers.toArray(temp);
}
public String getWebKey() {
return curWebKey;
}
}