implemented Conference E-Mail - automagically send E-mail to all readers

or posters in a conference or topic
This commit is contained in:
Eric J. Bowersox
2001-12-04 05:11:45 +00:00
parent 89eb0b23d2
commit d89c2bfdcb
12 changed files with 627 additions and 1 deletions

View File

@@ -171,4 +171,7 @@ public interface ConferenceContext
public abstract boolean canSendInvitation();
public abstract void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
throws AccessError, DataException;
} // end interface ConferenceContext

View File

@@ -110,5 +110,8 @@ public interface TopicContext
public abstract boolean canSendInvitation();
public abstract void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
throws AccessError, DataException;
} // end interface TopicContext

View File

@@ -888,6 +888,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
public TopicContext addTopic(String title, String zp_pseud, String zp_text)
throws DataException, AccessError
{
if (logger.isDebugEnabled())
logger.debug("addTopic(\"" + title + "\") entry");
if (!(getConferenceData().canCreateTopic(level)))
{ // not allowed to create a topic - bail out
logger.error("addTopic(): user not permitted to create new topic");
@@ -920,6 +922,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
{ // call down to create the new topic!
real_title = title_ch.getValue();
new_topic_inf = getConferenceData().createNewTopic(env,real_title,zp_pseud_ch.getValue(),zp_text);
if (logger.isDebugEnabled())
logger.debug("Created new topic ID #" + new_topic_inf.getTopicID());
} // end try
catch (NotYetFinishedException e)
@@ -939,6 +943,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
StringBuffer sql = new StringBuffer("INSERT INTO topicsettings (topicid, uid, last_post) VALUES (");
sql.append(new_topic_inf.getTopicID()).append(", ").append(env.getUserID()).append(", '");
sql.append(SQLUtil.encodeDate(new_topic_inf.getCreateDate())).append("');");
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
stmt.executeUpdate(sql.toString());
// update the conference last-post information
@@ -1489,6 +1495,90 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end canSendInvitation
public void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
throws AccessError, DataException
{
if (logger.isDebugEnabled())
logger.debug("sendMailToParticipants(" + posters + "," + day_limit + ")");
if (!(env.testPermission("Conference.EMailParticipants")))
throw new AccessError("You are not permitted to send E-mail to conference participants.");
if (day_limit==0)
return; // no-op
java.util.Date stop_point = null;
if (day_limit>0)
{ // compute stop point as a number of days back from this instant
Calendar right_now = Calendar.getInstance();
right_now.add(Calendar.DAY_OF_MONTH,-day_limit);
stop_point = right_now.getTime();
} // end if
Connection conn = null;
ArrayList rc = new ArrayList();
try
{ // retrieve a connection
conn = env.getConnection();
Statement stmt = conn.createStatement();
// Build the SQL statement.
StringBuffer sql = new StringBuffer("SELECT c.email, ");
if (posters)
sql.append("s.last_post");
else
sql.append("s.last_read");
sql.append(" FROM contacts c, users u, confsettings s WHERE c.contactid = u.contactid "
+ "AND u.uid = s.uid AND s.confid = ").append(confid).append(" AND u.is_anon = 0 AND ");
if (posters)
sql.append("ISNULL(s.last_post) = 0 ORDER BY s.last_post DESC;");
else
sql.append("ISNULL(s.last_read) = 0 ORDER BY s.last_read DESC;");
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
// Execute the query and start reading E-mail addresses.
ResultSet rs = stmt.executeQuery(sql.toString());
while (rs.next())
{ // accumulate E-mail addresses
if (stop_point!=null)
{ // see if we can stop the loop yet
java.util.Date x = SQLUtil.getFullDateTime(rs,2);
if (stop_point.compareTo(x)>0)
break;
} // end if
rc.add(rs.getString(1)); // save off the E-mail address
} // end while
if (logger.isDebugEnabled())
logger.debug("Selected " + rc.size() + " address(es) for E-mailing");
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error getting active poster list: " + e.getMessage(),e);
throw new DataException("unable to get active poster listing: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
env.releaseConnection(conn);
} // end finally
if (rc.size()>0)
{ // send the actual E-mail messages in the background
MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(),
rc,subject,text);
agent.start();
} // end if
} // end if
/*--------------------------------------------------------------------------------
* Implementations from interface ConferenceBackend
*--------------------------------------------------------------------------------

View File

@@ -0,0 +1,118 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.core.impl;
import java.util.*;
import org.apache.log4j.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.internals.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.htmlcheck.*;
class MailerAgent extends Thread
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static Category logger = Category.getInstance(MailerAgent.class);
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private EnvUser env; // the environment
private String from_name; // the "from" name
private String from_addr; // the "from" address
private List recipients; // who gets the message
private String subject; // message subject
private String text; // message text
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
MailerAgent(EnvUser env, String from_name, String from_addr, List recipients, String subject, String text)
{
super();
setDaemon(false);
this.env = env;
this.from_name = from_name;
this.from_addr = from_addr;
this.recipients = recipients;
this.subject = subject;
this.text = text;
} // end constructor
/*--------------------------------------------------------------------------------
* Overrides from class Thread
*--------------------------------------------------------------------------------
*/
public void run()
{
NDC.push("MailerAgent");
try
{ // attach the signature to the message
StringBuffer buf = new StringBuffer(text);
buf.append("\n--\n").append(env.getStockMessage("signature"));
// Create the emailer object and load it up with most of the data.
Emailer em = env.getEngine().createEmailer();
em.setSubject(subject);
em.setText(buf.toString());
// Deliver the mail to each of the target addresses in turn.
Iterator it = recipients.iterator();
while (it.hasNext())
{ // get ready to deliver the mail...
String addr = (String)(it.next());
if (logger.isDebugEnabled())
logger.debug("Delivering to " + addr);
try
{ // set the recipient and send it out
em.setFrom(from_name,from_addr);
em.setTo(addr);
em.send();
} // end try
catch (EmailException e)
{ // log the error and move on
logger.error("Caught EmailException when trying to send to " + addr,e);
} // end catch
} // end while
} // end try
finally
{ // make sure and pop the diagnostic context before we go
NDC.pop();
} // end finally
} // end run
} // end class MailerAgent

View File

@@ -51,7 +51,7 @@ class PostDeliveryAgent extends Thread
PostDeliveryAgent(EnvConference env, String txt, String pseud, String topicname, int topicnum, List addrs)
{
super("PostDeliveryAgent");
super();
setDaemon(false);
// Save the calling data.

View File

@@ -1310,6 +1310,90 @@ class TopicUserContextImpl implements TopicContext
} // end canSendInvitation
public void sendMailToParticipants(boolean posters, int day_limit, String subject, String text)
throws AccessError, DataException
{
if (logger.isDebugEnabled())
logger.debug("sendMailToParticipants(" + posters + "," + day_limit + ")");
if (!(env.testPermission("Conference.EMailParticipants")))
throw new AccessError("You are not permitted to send E-mail to conference participants.");
if (day_limit==0)
return; // no-op
java.util.Date stop_point = null;
if (day_limit>0)
{ // compute stop point as a number of days back from this instant
Calendar right_now = Calendar.getInstance();
right_now.add(Calendar.DAY_OF_MONTH,-day_limit);
stop_point = right_now.getTime();
} // end if
Connection conn = null;
ArrayList rc = new ArrayList();
try
{ // retrieve a connection
conn = env.getConnection();
Statement stmt = conn.createStatement();
// Build the SQL statement.
StringBuffer sql = new StringBuffer("SELECT c.email, ");
if (posters)
sql.append("s.last_post");
else
sql.append("s.last_read");
sql.append(" FROM contacts c, users u, topicsettings s WHERE c.contactid = u.contactid "
+ "AND u.uid = s.uid AND s.topicid = ").append(topicid).append(" AND u.is_anon = 0 AND ");
if (posters)
sql.append("ISNULL(s.last_post) = 0 ORDER BY s.last_post DESC;");
else
sql.append("ISNULL(s.last_read) = 0 ORDER BY s.last_read DESC;");
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
// Execute the query and start reading E-mail addresses.
ResultSet rs = stmt.executeQuery(sql.toString());
while (rs.next())
{ // accumulate E-mail addresses
if (stop_point!=null)
{ // see if we can stop the loop yet
java.util.Date x = SQLUtil.getFullDateTime(rs,2);
if (stop_point.compareTo(x)>0)
break;
} // end if
rc.add(rs.getString(1)); // save off the E-mail address
} // end while
if (logger.isDebugEnabled())
logger.debug("Selected " + rc.size() + " address(es) for E-mailing");
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error getting active poster list: " + e.getMessage(),e);
throw new DataException("unable to get active poster listing: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
env.releaseConnection(conn);
} // end finally
if (rc.size()>0)
{ // send the actual E-mail messages in the background
MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(),
rc,subject,text);
agent.start();
} // end if
} // end sendMailToParticipants
/*--------------------------------------------------------------------------------
* External operations usable only from within the package
*--------------------------------------------------------------------------------

View File

@@ -158,6 +158,7 @@ public class ConfOperations extends VeniceServlet
* E = Edit Conference Settings (requires conference parameter)
* FX = Fixseen (requires conference parameter)
* H = Add Conference to Hotlist (requires conference parameter)
* I = Conference E-Mail (requires conference parameter)
* M = Manage Conference Membership (requires conference parameter)
* Q = Display Conference Manage menu (requires conference parameter)
* RP = Report on Posters (requires conference parameter)
@@ -589,6 +590,30 @@ public class ConfOperations extends VeniceServlet
} // end if ("H" command)
if (cmd.equals("I"))
{ // "I" = "Conference E-Mail" (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=Q";
try
{ // return the conference E-mail view
return new ConferenceEMail(comm,conf);
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error getting topic list " + de.getMessage(),
on_error);
} // end catch
catch (AccessError ae)
{ // some lack of access is causing problems
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
} // end if ("I" command)
if (cmd.equals("DEL"))
{ // "DEL" = "Delete Conference (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
@@ -1040,6 +1065,80 @@ public class ConfOperations extends VeniceServlet
} // end if ("M" command)
if (cmd.equals("I"))
{ // "I" = "Conference E-Mail"
ConferenceContext conf = getConferenceParameter(request,comm,true,on_error);
on_error = "confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&cmd=I";
if (isImageButtonClicked(request,"cancel")) // "Cancel" button pressed - bail out
throw new RedirectResult("confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=Q");
if (isImageButtonClicked(request,"send"))
{ // OK, figure out who we want to send E-mail to
try
{ // retrieve the topic we want to send to
TopicContext topic = null;
String s = request.getParameter("top");
if ((s!=null) && !(s.equals("0")))
topic = conf.getTopic(Short.parseShort(s));
// retrieve other parameters
final String ZERO = "0";
boolean posters = ZERO.equals(request.getParameter("porl"));
final String YES = "Y";
int ndays = -1;
if (YES.equals(request.getParameter("xday")))
{ // they selected "within the last X days"
try
{ // parse the number of days
s = request.getParameter("day");
if (s!=null)
ndays = Integer.parseInt(s);
else
ndays = 0;
} // end try
catch (NumberFormatException nfe)
{ // always fail safe when doing e-mail parameters!
ndays = 0;
} // end catch
} // end if
if (topic!=null)
topic.sendMailToParticipants(posters,ndays,request.getParameter("subj"),
request.getParameter("pb"));
else
conf.sendMailToParticipants(posters,ndays,request.getParameter("subj"),
request.getParameter("pb"));
} // end try
catch (AccessError ae)
{ // some sort of access error - display an error dialog
return new ErrorBox("Access Error",ae.getMessage(),on_error);
} // end catch
catch (DataException de)
{ // database error creating the conference
return new ErrorBox("Database Error","Database error sending E-mail: " + de.getMessage(),
on_error);
} // end catch
// all done - bounce back to the menu
throw new RedirectResult("confops?sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID()
+ "&cmd=Q");
} // end if ("send" pressed)
// we don't know what button was pressed
logger.error("no known button click on ConfOperations.doPost, cmd=I");
return new ErrorBox("Internal Error","Unknown command button pressed",on_error);
} // end if ("I" command)
// unrecognized command!
logger.error("invalid command to ConfOperations.doPost: " + cmd);
return new ErrorBox("Internal Error","Invalid command to ConfOperations.doPost",on_error);

View File

@@ -0,0 +1,152 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
public class ConferenceEMail implements JSPRender
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
// Attribute name for request attribute
protected static final String ATTR_NAME = "com.silverwrist.venice.content.ConferenceEMail";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private CommunityContext comm; // the community we're in
private ConferenceContext conf; // the conference being listed
private List topics; // list of topics in that conference
private String locator = null; // locator string
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ConferenceEMail(CommunityContext comm, ConferenceContext conf) throws DataException, AccessError
{
this.comm = comm;
this.conf = conf;
this.topics = conf.getTopicList(ConferenceContext.DISPLAY_ALL,ConferenceContext.SORT_NAME);
} // end constructor
/*--------------------------------------------------------------------------------
* External static functions
*--------------------------------------------------------------------------------
*/
public static ConferenceEMail retrieve(ServletRequest request)
{
return (ConferenceEMail)(request.getAttribute(ATTR_NAME));
} // end retrieve
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceContent
*--------------------------------------------------------------------------------
*/
public String getPageTitle(RenderData rdat)
{
return "Conference E-Mail: " + conf.getName();
} // end getPageTitle
public String getPageQID()
{
return null;
} // end getPageQID
/*--------------------------------------------------------------------------------
* Implementations from interface JSPRender
*--------------------------------------------------------------------------------
*/
public void store(ServletRequest request)
{
request.setAttribute(ATTR_NAME,this);
} // end store
public String getTargetJSPName()
{
return "conf_email.jsp";
} // end getTargetJSPName
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public final int getCommunityID()
{
return comm.getCommunityID();
} // end getCommunityID
public final int getConferenceID()
{
return conf.getConfID();
} // end getConferenceID
public final String getConferenceName()
{
return conf.getName();
} // end getConferenceName
public final String getLocator()
{
if (locator==null)
locator = "sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID();
return locator;
} // end getLocator
public final void writeTopicChoices(Writer out) throws IOException
{
out.write("<OPTION VALUE=\"0\" SELECTED>(Entire conference)</OPTION>\n");
Iterator it = topics.iterator();
while (it.hasNext())
{ // write out the entire topic list as a drop-down list
TopicContext topic = (TopicContext)(it.next());
out.write("<OPTION VALUE=\"" + topic.getTopicNumber() + "\">" + StringUtil.encodeHTML(topic.getName())
+ "</OPTION>\n");
} // end while
} // end writeTopicChoices
} // end class ConferenceEMail