implemented "Subscribe To Topic"
This commit is contained in:
		
							parent
							
								
									c7edf62aae
								
							
						
					
					
						commit
						239321bb61
					
				@ -438,6 +438,34 @@ Hope to see you in "${community.name}" soon!
 | 
			
		||||
    <!-- Parameters: community.name = name of community -->
 | 
			
		||||
    <subj-invite>Invitation to "${community.name}" Community</subj-invite>
 | 
			
		||||
 | 
			
		||||
    <!-- Template used for E-mailing posts to users (top half of E-mail) -->
 | 
			
		||||
    <!-- Parameters: message.poster, topic.name, topic.locator, conference.name, community.name -->
 | 
			
		||||
    <mail-post-top>
 | 
			
		||||
      <![CDATA[
 | 
			
		||||
The following message was just posted by "${message.poster}" to the
 | 
			
		||||
"${topic.name}" topic in the "${conference.name}" conference
 | 
			
		||||
of the "${community.name}" community on the Venice community system.
 | 
			
		||||
--------------------------------------------------------------------------
 | 
			
		||||
      ]]>
 | 
			
		||||
    </mail-post-top>
 | 
			
		||||
 | 
			
		||||
    <!-- Template used for E-mailing posts to users (bottom half of E-mail) -->
 | 
			
		||||
    <!-- Parameters: message.poster, topic.name, topic.locator, conference.name, community.name -->
 | 
			
		||||
    <mail-post-bottom>
 | 
			
		||||
      <![CDATA[
 | 
			
		||||
--------------------------------------------------------------------------
 | 
			
		||||
Join the ongoing discussion at:
 | 
			
		||||
http://delenn/venice/go/${topic.locator}
 | 
			
		||||
 | 
			
		||||
To stop receiving new posts in this topic by E-mail, visit the above URL,
 | 
			
		||||
click the "Manage" button, and click the "Stop Subscribing To This Topic" link.
 | 
			
		||||
      ]]>
 | 
			
		||||
    </mail-post-bottom>
 | 
			
		||||
 | 
			
		||||
    <!-- Subject line for posts that are E-mailed to users -->
 | 
			
		||||
    <!-- Parameters: message.poster, topic.name, topic.locator, conference.name, community.name -->
 | 
			
		||||
    <subj-mail-post>New Post in ${topic.name}</subj-mail-post>
 | 
			
		||||
 | 
			
		||||
  </messages>
 | 
			
		||||
 | 
			
		||||
</venice-config>
 | 
			
		||||
 | 
			
		||||
@ -335,6 +335,7 @@ CREATE TABLE topicsettings (
 | 
			
		||||
    last_message INT DEFAULT -1,
 | 
			
		||||
    last_read DATETIME,
 | 
			
		||||
    last_post DATETIME,
 | 
			
		||||
    subscribe TINYINT DEFAULT 0,
 | 
			
		||||
    PRIMARY KEY (topicid, uid)
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -100,5 +100,9 @@ public interface TopicContext
 | 
			
		||||
 | 
			
		||||
  public abstract List getBozos() throws DataException;
 | 
			
		||||
 | 
			
		||||
  public abstract boolean isSubscribed();
 | 
			
		||||
 | 
			
		||||
  public abstract void setSubscribed(boolean flag) throws DataException;
 | 
			
		||||
 | 
			
		||||
} // end interface TopicContext
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1458,6 +1458,12 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
 | 
			
		||||
 | 
			
		||||
  } // end env_testPermission
 | 
			
		||||
 | 
			
		||||
  public String env_getCommunityName()
 | 
			
		||||
  {
 | 
			
		||||
    return this.getName();
 | 
			
		||||
 | 
			
		||||
  } // end env.getCommunityName()
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static operations for use within the implementation package
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@ -1612,6 +1612,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
 | 
			
		||||
 | 
			
		||||
  } // end env_getConfLevel
 | 
			
		||||
 | 
			
		||||
  public String env_getConfName()
 | 
			
		||||
  {
 | 
			
		||||
    return this.getName();
 | 
			
		||||
 | 
			
		||||
  } // end env_getConfName
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static functions usable only from within the package
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										157
									
								
								src/com/silverwrist/venice/core/impl/PostDeliveryAgent.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/com/silverwrist/venice/core/impl/PostDeliveryAgent.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,157 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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 PostDeliveryAgent extends Thread
 | 
			
		||||
{
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Static data members
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(PostDeliveryAgent.class);
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Attributes
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private EnvEngine env;                    // the environment
 | 
			
		||||
  private String post_text;                 // the raw post text
 | 
			
		||||
  private String post_pseud;                // the raw pseud
 | 
			
		||||
  private List delivery_addresses;          // the addresses to deliver to
 | 
			
		||||
  private Map vars;                         // the replacement variables for the templates
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  PostDeliveryAgent(EnvConference env, String txt, String pseud, String topicname, int topicnum, List addrs)
 | 
			
		||||
  {
 | 
			
		||||
    super("PostDeliveryAgent");
 | 
			
		||||
    setDaemon(false);
 | 
			
		||||
 | 
			
		||||
    // Save the calling data.
 | 
			
		||||
    this.env = env;
 | 
			
		||||
    this.post_text = txt;
 | 
			
		||||
    this.post_pseud = pseud;
 | 
			
		||||
    this.delivery_addresses = addrs;
 | 
			
		||||
 | 
			
		||||
    // Now build the substitution table used to format the templates.
 | 
			
		||||
    HashMap xvars = new HashMap();
 | 
			
		||||
    xvars.put("message.poster",env.getUserName());
 | 
			
		||||
    xvars.put("topic.name",topicname);
 | 
			
		||||
    xvars.put("topic.locator",env.getCommunityAlias() + "!" + env.getConferenceAlias() + "." + topicnum);
 | 
			
		||||
    xvars.put("conference.name",env.getConferenceName());
 | 
			
		||||
    xvars.put("community.name",env.getCommunityName());
 | 
			
		||||
    vars = Collections.unmodifiableMap(xvars);
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Overrides from class Thread
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public void run()
 | 
			
		||||
  {
 | 
			
		||||
    NDC.push("PostDeliveryAgent");
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // kick off the delivery process
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
	logger.debug("PostDeliveryAgent started by " + vars.get("message.poster") + " with "
 | 
			
		||||
		     + delivery_addresses.size() + " mails to deliver");
 | 
			
		||||
 | 
			
		||||
      // To start off with, both the text and the pseud need to be "stripped" of all HTML.
 | 
			
		||||
      String real_text = null;
 | 
			
		||||
      String real_pseud = null;
 | 
			
		||||
      try
 | 
			
		||||
      { // run both arguments through the HTML checker
 | 
			
		||||
	HTMLChecker mail_checker = env.getEngine().createCheckerObject(EngineBackend.HTMLC_MAIL_POST);
 | 
			
		||||
	mail_checker.append(post_text);
 | 
			
		||||
	mail_checker.finish();
 | 
			
		||||
	real_text = mail_checker.getValue();
 | 
			
		||||
	mail_checker.reset();
 | 
			
		||||
	mail_checker.append(post_pseud);
 | 
			
		||||
	mail_checker.finish();
 | 
			
		||||
	real_pseud = mail_checker.getValue();
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (HTMLCheckerException e)
 | 
			
		||||
      { // this isn't right...
 | 
			
		||||
	logger.error("PostDeliveryAgent: threw HTMLCheckerException",e);
 | 
			
		||||
	throw new InternalStateError("HTMLChecker erroneously throwing exception",e);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
      // Format the three stock message parts.
 | 
			
		||||
      String msg_top = StringUtil.replaceAllVariables(env.getStockMessage("mail-post-top"),vars);
 | 
			
		||||
      String msg_bot = StringUtil.replaceAllVariables(env.getStockMessage("mail-post-bottom"),vars);
 | 
			
		||||
      String msg_subj = StringUtil.replaceAllVariables(env.getStockMessage("subj-mail-post"),vars);
 | 
			
		||||
 | 
			
		||||
      // Construct the full message body.
 | 
			
		||||
      StringBuffer body = new StringBuffer(msg_top);
 | 
			
		||||
      body.append("\n\n").append(real_pseud).append("\n\n").append(real_text).append("\n\n");
 | 
			
		||||
      body.append(msg_bot).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(msg_subj);
 | 
			
		||||
      em.setText(body.toString());
 | 
			
		||||
 | 
			
		||||
      // Deliver the mail to each of the target addresses in turn.
 | 
			
		||||
      Iterator it = delivery_addresses.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.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
 | 
			
		||||
    { // pop the nested diagnostic context before we go
 | 
			
		||||
      NDC.pop();
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
    
 | 
			
		||||
  } // end run
 | 
			
		||||
 | 
			
		||||
} // end class PostDeliveryAgent
 | 
			
		||||
@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
 | 
			
		||||
import java.sql.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
import com.silverwrist.venice.core.internals.*;
 | 
			
		||||
import com.silverwrist.venice.db.*;
 | 
			
		||||
@ -53,6 +54,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
  private String name;
 | 
			
		||||
  private boolean hidden;
 | 
			
		||||
  private int unread;
 | 
			
		||||
  private boolean subscribed;
 | 
			
		||||
  private boolean deleted = false;
 | 
			
		||||
  private HashSet bozo_uids = null;
 | 
			
		||||
 | 
			
		||||
@ -63,7 +65,8 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
 | 
			
		||||
  protected TopicUserContextImpl(EnvConference env, int topicid, short topicnum, int creator_uid,
 | 
			
		||||
				 int top_message, boolean frozen, boolean archived, java.util.Date created,
 | 
			
		||||
				 java.util.Date lastupdate, String name, boolean hidden, int unread)
 | 
			
		||||
				 java.util.Date lastupdate, String name, boolean hidden, int unread,
 | 
			
		||||
				 boolean subscribed)
 | 
			
		||||
  {
 | 
			
		||||
    this.env = env;
 | 
			
		||||
    this.topicid = topicid;
 | 
			
		||||
@ -77,6 +80,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    this.name = name;
 | 
			
		||||
    this.hidden = hidden;
 | 
			
		||||
    this.unread = (unread<0 ? 0 : unread);
 | 
			
		||||
    this.subscribed = subscribed;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
@ -94,6 +98,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    this.name = name;
 | 
			
		||||
    this.hidden = false;
 | 
			
		||||
    this.unread = 1;
 | 
			
		||||
    this.subscribed = false;
 | 
			
		||||
    this.bozo_uids = new HashSet();  // no bozos yet
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
@ -109,7 +114,8 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
      new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
 | 
			
		||||
		       + "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
 | 
			
		||||
		       + "topics.name, IFNULL(topicsettings.hidden,0) AS hidden, "
 | 
			
		||||
		       + "(topics.top_message - IFNULL(topicsettings.last_message,-1)) AS unread "
 | 
			
		||||
		       + "(topics.top_message - IFNULL(topicsettings.last_message,-1)) AS unread, "
 | 
			
		||||
		       + "IFNULL(topicsettings.subscribe,0) AS subscribe "
 | 
			
		||||
		       + "FROM topics LEFT JOIN topicsettings ON topics.topicid = topicsettings.topicid "
 | 
			
		||||
		       + "AND topicsettings.uid = ");
 | 
			
		||||
    sql.append(uid).append(" WHERE topics.topicid = ").append(topicid).append(';');
 | 
			
		||||
@ -129,6 +135,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    name = null;
 | 
			
		||||
    hidden = false;
 | 
			
		||||
    unread = -1;
 | 
			
		||||
    subscribed = false;
 | 
			
		||||
    deleted = true;
 | 
			
		||||
 | 
			
		||||
  } // end if
 | 
			
		||||
@ -149,6 +156,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
      unread = rs.getInt(11);
 | 
			
		||||
      if (unread<0)
 | 
			
		||||
	unread = 0;
 | 
			
		||||
      subscribed = rs.getBoolean(12);
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
    else // this topic must have been deleted - fsck it
 | 
			
		||||
@ -666,11 +674,15 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    java.util.Date posted_date;
 | 
			
		||||
    Connection conn = null;
 | 
			
		||||
    AuditRecord ar = null;
 | 
			
		||||
    ArrayList mailto_addrs = null;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = env.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
      ArrayList mailto_uids = null;
 | 
			
		||||
      StringBuffer sql = new StringBuffer();
 | 
			
		||||
      ResultSet rs;
 | 
			
		||||
 | 
			
		||||
      // slap a lock on all the tables we need to touch
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE, "
 | 
			
		||||
@ -706,8 +718,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	  logger.debug("New post number: " + new_post_num);
 | 
			
		||||
 | 
			
		||||
	// Add the post "header" to the posts table.
 | 
			
		||||
	StringBuffer sql = new StringBuffer("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, "
 | 
			
		||||
					    + "posted, pseud) VALUES (");
 | 
			
		||||
	sql.append("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, posted, pseud) VALUES (");
 | 
			
		||||
	sql.append(parent).append(", ").append(topicid).append(", ").append(new_post_num).append(", ");
 | 
			
		||||
	sql.append(text_linecount).append(", ").append(env.getUserID()).append(", '");
 | 
			
		||||
	posted_date = new java.util.Date();
 | 
			
		||||
@ -717,9 +728,9 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	stmt.executeUpdate(sql.toString());
 | 
			
		||||
 | 
			
		||||
	// Retrieve the new post ID.
 | 
			
		||||
	ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
 | 
			
		||||
	rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
 | 
			
		||||
	if (!(rs.next()))
 | 
			
		||||
	  throw new InternalStateError("postMessage(): Unable to get new post ID!");
 | 
			
		||||
	  throw new InternalStateError("postNewMessage(): Unable to get new post ID!");
 | 
			
		||||
	new_post_id = rs.getLong(1);
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("New post ID: " + new_post_id);
 | 
			
		||||
@ -761,6 +772,21 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	env.getConference().touchUpdate(conn,posted_date);
 | 
			
		||||
	env.getConference().touchPost(conn,posted_date);
 | 
			
		||||
 | 
			
		||||
	// Who's subscribed to this conference?  Whoever it is, they need to get this post via E-mail.
 | 
			
		||||
	sql.setLength(0);
 | 
			
		||||
	sql.append("SELECT uid FROM topicsettings WHERE topicid = ").append(topicid);
 | 
			
		||||
	sql.append(" AND subscribe = 1;");
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("SQL: " + sql.toString());
 | 
			
		||||
	rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
	while (rs.next())
 | 
			
		||||
	{ // load the UIDs here
 | 
			
		||||
	  if (mailto_uids==null)
 | 
			
		||||
	    mailto_uids = new ArrayList();
 | 
			
		||||
	  mailto_uids.add(new Integer(rs.getInt(1)));
 | 
			
		||||
 | 
			
		||||
	} // end while
 | 
			
		||||
 | 
			
		||||
	// Fill in our own local variables to reflect the update.  This includes the recalculation
 | 
			
		||||
	// of "unread" based on the new value of "top_message".
 | 
			
		||||
        int tmp_last_msg = top_message - unread;
 | 
			
		||||
@ -782,6 +808,23 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
      ar = env.newAudit(AuditRecord.POST_MESSAGE,"conf=" + env.getConfID() + ",topic=" + topicid + ",post="
 | 
			
		||||
			+ new_post_id,"pseud=" + real_pseud);
 | 
			
		||||
 | 
			
		||||
      if (mailto_uids!=null)
 | 
			
		||||
      { // We need to translate the "mailto" UIDs to E-mail addresses while we still have the database open!
 | 
			
		||||
	mailto_addrs = new ArrayList(mailto_uids.size());
 | 
			
		||||
	sql.setLength(0);
 | 
			
		||||
	sql.append("SELECT c.email FROM users u, contacts c WHERE u.contactid = c.contactid AND u.uid ");
 | 
			
		||||
	if (mailto_uids.size()==1)
 | 
			
		||||
	  sql.append("= ").append(mailto_uids.get(0)).append(';');
 | 
			
		||||
	else
 | 
			
		||||
	  sql.append("IN (").append(StringUtil.join(mailto_uids,", ")).append(");");
 | 
			
		||||
	if (logger.isDebugEnabled())
 | 
			
		||||
	  logger.debug("SQL: " + sql.toString());
 | 
			
		||||
	rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
	while (rs.next())
 | 
			
		||||
	  mailto_addrs.add(rs.getString(1));
 | 
			
		||||
 | 
			
		||||
      } // end if
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
@ -796,6 +839,15 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    if (mailto_addrs!=null)
 | 
			
		||||
    { // a copy of the post needs to be delivered via E-mail to the specified addresses
 | 
			
		||||
      // use our PostDeliveryAgent to do it in the background
 | 
			
		||||
      PostDeliveryAgent agent = new PostDeliveryAgent(env,text,pseud,name,topicnum,mailto_addrs);
 | 
			
		||||
      agent.start();
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
    // else don't bother - it would be a waste of time
 | 
			
		||||
 | 
			
		||||
    // return the new message context
 | 
			
		||||
    return new TopicMessageUserContextImpl(env,new_post_id,parent,new_post_num,text_linecount,env.getUserID(),
 | 
			
		||||
					   posted_date,real_pseud);
 | 
			
		||||
@ -1159,6 +1211,78 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
 | 
			
		||||
  } // end getBozos
 | 
			
		||||
 | 
			
		||||
  public boolean isSubscribed()
 | 
			
		||||
  {
 | 
			
		||||
    return subscribed;
 | 
			
		||||
 | 
			
		||||
  } // end isSubscribed
 | 
			
		||||
 | 
			
		||||
  public void setSubscribed(boolean flag) throws DataException
 | 
			
		||||
  {
 | 
			
		||||
    if ((subscribed==flag) || deleted || env.getUser().userIsAnonymous())
 | 
			
		||||
      return;  // no-op
 | 
			
		||||
 | 
			
		||||
    Connection conn = null;      // pooled database connection
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    { // get a database connection
 | 
			
		||||
      conn = env.getConnection();
 | 
			
		||||
      Statement stmt = conn.createStatement();
 | 
			
		||||
      stmt.executeUpdate("LOCK TABLES topicsettings WRITE, topics READ;");
 | 
			
		||||
 | 
			
		||||
      try
 | 
			
		||||
      { // start by trying to see if we can update topicsettings directly
 | 
			
		||||
	StringBuffer sql = new StringBuffer("UPDATE topicsettings SET subscribe = ");
 | 
			
		||||
	sql.append(flag ? '1' : '0').append(" WHERE topicid = ").append(topicid).append(" AND uid = ");
 | 
			
		||||
	sql.append(env.getUserID()).append(';');
 | 
			
		||||
	if (stmt.executeUpdate(sql.toString())>0)
 | 
			
		||||
	{ // that was all we needed - just save the flag and exit
 | 
			
		||||
	  subscribed = flag;
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	} // end if
 | 
			
		||||
 | 
			
		||||
	// OK, check: Is the topic still there?!?
 | 
			
		||||
	sql.setLength(0);
 | 
			
		||||
	sql.append("SELECT topicid from topics WHERE topicid = ").append(topicid).append(';');
 | 
			
		||||
	ResultSet rs = stmt.executeQuery(sql.toString());
 | 
			
		||||
	if (!(rs.next()))
 | 
			
		||||
	{ // the topic's been deleted - bail out
 | 
			
		||||
	  makeDeleted();
 | 
			
		||||
	  return;
 | 
			
		||||
 | 
			
		||||
	} // end if
 | 
			
		||||
 | 
			
		||||
	// OK, just insert a new row into topicsettings, why dontcha...
 | 
			
		||||
	sql.setLength(0);
 | 
			
		||||
	sql.append("INSERT INTO topicsettings (topicid, uid, subscribe) VALUES (").append(topicid);
 | 
			
		||||
	sql.append(", ").append(env.getUserID()).append(", ").append(flag ? '1' : '0').append(");");
 | 
			
		||||
	stmt.executeUpdate(sql.toString());
 | 
			
		||||
	subscribed = flag;  // successful completion
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      finally
 | 
			
		||||
      { // unlock the tables before we go
 | 
			
		||||
	Statement ulk_stmt = conn.createStatement();
 | 
			
		||||
	ulk_stmt.executeUpdate("UNLOCK TABLES;");
 | 
			
		||||
 | 
			
		||||
      } // end finally
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
    catch (SQLException e)
 | 
			
		||||
    { // turn SQLException into data exception
 | 
			
		||||
      logger.error("DB error setting topic data: " + e.getMessage(),e);
 | 
			
		||||
      throw new DataException("unable to set topic subscribed status: " + e.getMessage(),e);
 | 
			
		||||
 | 
			
		||||
    } // end catch
 | 
			
		||||
    finally
 | 
			
		||||
    { // make sure we release the connection before we go
 | 
			
		||||
      env.releaseConnection(conn);
 | 
			
		||||
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
  } // end setSubscribed
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External operations usable only from within the package
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
@ -1278,9 +1402,10 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
 | 
			
		||||
			 + "t.createdate, t.lastupdate, t.name, IFNULL(s.hidden,0) AS hidden, "
 | 
			
		||||
			 + "(t.top_message - IFNULL(s.last_message,-1)) AS unread");
 | 
			
		||||
			 + "(t.top_message - IFNULL(s.last_message,-1)) AS unread, "
 | 
			
		||||
			 + "IFNULL(s.subscribe,0) AS subscribe");
 | 
			
		||||
      if (get_option==ConferenceContext.DISPLAY_ACTIVE)
 | 
			
		||||
	sql.append(", SIGN(t.top_message - IFNULL(s.last_message,-1)) AS newflag");
 | 
			
		||||
	sql.append(", GREATEST(SIGN(t.top_message - IFNULL(s.last_message,-1)),0) AS newflag");
 | 
			
		||||
      sql.append(" FROM topics t LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ");
 | 
			
		||||
      sql.append(env.getUserID()).append(" WHERE t.confid = ").append(env.getConfID());
 | 
			
		||||
      if (where_clause!=null)
 | 
			
		||||
@ -1301,7 +1426,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	    new TopicUserContextImpl(env,rs.getInt(1),rs.getShort(2),rs.getInt(3),rs.getInt(4),
 | 
			
		||||
				     rs.getBoolean(5),rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
 | 
			
		||||
				     SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
 | 
			
		||||
				     rs.getInt(11));
 | 
			
		||||
				     rs.getInt(11),rs.getBoolean(12));
 | 
			
		||||
	rc.add(top);
 | 
			
		||||
 | 
			
		||||
      } // end while
 | 
			
		||||
@ -1341,7 +1466,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	return new TopicUserContextImpl(env,topicid,rs.getShort(2),rs.getInt(3),rs.getInt(4),rs.getBoolean(5),
 | 
			
		||||
					rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
 | 
			
		||||
					SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
 | 
			
		||||
					rs.getInt(11));
 | 
			
		||||
					rs.getInt(11),rs.getBoolean(12));
 | 
			
		||||
      // else fall out and return null
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
@ -1378,7 +1503,8 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
 | 
			
		||||
			 + "t.createdate, t.lastupdate, t.name, IFNULL(s.hidden,0) AS hidden, "
 | 
			
		||||
			 + "(t.top_message - IFNULL(s.last_message,-1)) AS unread FROM topics t "
 | 
			
		||||
			 + "(t.top_message - IFNULL(s.last_message,-1)) AS unread, "
 | 
			
		||||
			 + "IFNULL(s.subscribe,0) AS subscribe FROM topics t "
 | 
			
		||||
			 + "LEFT JOIN topicsettings s ON t.topicid = s.topicid AND s.uid = ");
 | 
			
		||||
      sql.append(env.getUserID()).append(" WHERE t.confid = ").append(env.getConfID());
 | 
			
		||||
      sql.append(" AND t.num = ").append(topicnum).append(';');
 | 
			
		||||
@ -1391,7 +1517,7 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	return new TopicUserContextImpl(env,rs.getInt(1),topicnum,rs.getInt(3),rs.getInt(4),rs.getBoolean(5),
 | 
			
		||||
					rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
 | 
			
		||||
					SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
 | 
			
		||||
					rs.getInt(11));
 | 
			
		||||
					rs.getInt(11),rs.getBoolean(12));
 | 
			
		||||
      // else fall out and return null
 | 
			
		||||
 | 
			
		||||
    } // end try
 | 
			
		||||
@ -1412,3 +1538,5 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
  } // end getTopicByNumber
 | 
			
		||||
 | 
			
		||||
} // end class TopicUserContextImpl
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -721,7 +721,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
    LazyTreeLexicon lex = new LazyTreeLexicon((String[])(dictionary_tmp.toArray(new String[0])));
 | 
			
		||||
    spell_rewriter.addDictionary(lex);
 | 
			
		||||
 | 
			
		||||
    html_configs = new HTMLCheckerConfig[4];  // create the array
 | 
			
		||||
    html_configs = new HTMLCheckerConfig[5];  // create the array
 | 
			
		||||
 | 
			
		||||
    // Create the HTML checker config used to post body text to the database.
 | 
			
		||||
    HTMLCheckerConfig cfg = HTMLCheckerCreator.create();
 | 
			
		||||
@ -781,6 +781,15 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
 | 
			
		||||
    cfg.addOutputFilter(html_filter);
 | 
			
		||||
    html_configs[HTMLC_ESCAPE_BODY_PSEUD] = cfg;
 | 
			
		||||
 | 
			
		||||
    // Create the HTML Checker used to strip HTML from posts that are sent via E-mail.
 | 
			
		||||
    cfg = HTMLCheckerCreator.create();
 | 
			
		||||
    cfg.setWordWrapLength((short)55);
 | 
			
		||||
    cfg.setProcessAngles(true);
 | 
			
		||||
    cfg.setProcessParens(false);
 | 
			
		||||
    cfg.setDiscardHTMLTags(true);
 | 
			
		||||
    cfg.configureNormalTagSet();
 | 
			
		||||
    html_configs[HTMLC_MAIL_POST] = cfg;
 | 
			
		||||
 | 
			
		||||
    if (logger.isDebugEnabled())
 | 
			
		||||
      logger.debug("initialize() complete :-)");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -44,4 +44,6 @@ public interface CommunityBackend
 | 
			
		||||
 | 
			
		||||
  public abstract boolean env_testPermission(String symbol);
 | 
			
		||||
 | 
			
		||||
  public abstract String env_getCommunityName();
 | 
			
		||||
 | 
			
		||||
} // end interface CommunityBackend
 | 
			
		||||
 | 
			
		||||
@ -49,4 +49,6 @@ public interface ConferenceBackend
 | 
			
		||||
 | 
			
		||||
  public abstract int env_getConfLevel();
 | 
			
		||||
 | 
			
		||||
  public abstract String env_getConfName();
 | 
			
		||||
 | 
			
		||||
} // end interface ConferenceBackend
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,7 @@ public interface EngineBackend
 | 
			
		||||
  public static final int HTMLC_POST_PSEUD = 1;
 | 
			
		||||
  public static final int HTMLC_PREVIEW_BODY = 2;
 | 
			
		||||
  public static final int HTMLC_ESCAPE_BODY_PSEUD = 3;
 | 
			
		||||
  public static final int HTMLC_MAIL_POST = 4;
 | 
			
		||||
 | 
			
		||||
  // Integer parameter indexes
 | 
			
		||||
  public static final int IP_POSTSPERPAGE = 0;
 | 
			
		||||
 | 
			
		||||
@ -182,4 +182,16 @@ public class EnvCommunity extends EnvUser
 | 
			
		||||
 | 
			
		||||
  } // end getCommunityDefaultRole
 | 
			
		||||
 | 
			
		||||
  public final String getCommunityName()
 | 
			
		||||
  {
 | 
			
		||||
    return comm.env_getCommunityName();
 | 
			
		||||
 | 
			
		||||
  } // end getCommunityName
 | 
			
		||||
 | 
			
		||||
  public final String getCommunityAlias()
 | 
			
		||||
  {
 | 
			
		||||
    return comm.realCommunityAlias();
 | 
			
		||||
 | 
			
		||||
  } // end getCommunityAlias
 | 
			
		||||
 | 
			
		||||
} // end class EnvCommunity
 | 
			
		||||
 | 
			
		||||
@ -116,5 +116,17 @@ public class EnvConference extends EnvCommunity
 | 
			
		||||
 | 
			
		||||
  } // end getConfID
 | 
			
		||||
 | 
			
		||||
  public final String getConferenceAlias()
 | 
			
		||||
  {
 | 
			
		||||
    return conf.realConfAlias();
 | 
			
		||||
 | 
			
		||||
  } // end getConfAlias
 | 
			
		||||
 | 
			
		||||
  public final String getConferenceName()
 | 
			
		||||
  {
 | 
			
		||||
    return conf.env_getConfName();
 | 
			
		||||
 | 
			
		||||
  } // end getConfName
 | 
			
		||||
 | 
			
		||||
} // end class EnvConference
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -175,4 +175,10 @@ public class EnvEngine
 | 
			
		||||
 | 
			
		||||
  } // end saveAuditRecord
 | 
			
		||||
 | 
			
		||||
  public final String getStockMessage(String key)
 | 
			
		||||
  {
 | 
			
		||||
    return engine.getStockMessage(key);
 | 
			
		||||
 | 
			
		||||
  } // end getStockMessage
 | 
			
		||||
 | 
			
		||||
} // end class EnvEngine
 | 
			
		||||
 | 
			
		||||
@ -199,6 +199,12 @@ public class EnvUser extends EnvEngine
 | 
			
		||||
 | 
			
		||||
  } // end getUserID
 | 
			
		||||
 | 
			
		||||
  public final String getUserName()
 | 
			
		||||
  {
 | 
			
		||||
    return user.realUserName();
 | 
			
		||||
 | 
			
		||||
  } // end getUserName
 | 
			
		||||
 | 
			
		||||
  public final int getUserBaseLevel()
 | 
			
		||||
  {
 | 
			
		||||
    return user.realBaseLevel();
 | 
			
		||||
 | 
			
		||||
@ -216,6 +216,24 @@ public class TopicOperations extends VeniceServlet
 | 
			
		||||
 | 
			
		||||
    } // end if (remove bozo)
 | 
			
		||||
 | 
			
		||||
    if (cmd.equals("SY") || cmd.equals("SN"))
 | 
			
		||||
    { // "SY", "SN" - Set subscription status
 | 
			
		||||
      try
 | 
			
		||||
      { // call down to set the topic!
 | 
			
		||||
	topic.setSubscribed(cmd.equals("SY"));
 | 
			
		||||
	setMyLocation(request,"topicops?" + locator);
 | 
			
		||||
	return new ManageTopic(user,comm,conf,topic);
 | 
			
		||||
 | 
			
		||||
      } // end try
 | 
			
		||||
      catch (DataException de)
 | 
			
		||||
      { // there was a database error
 | 
			
		||||
	return new ErrorBox("Database Error","Database error setting subscription status: " + de.getMessage(),
 | 
			
		||||
			    location);
 | 
			
		||||
 | 
			
		||||
      } // end catch
 | 
			
		||||
 | 
			
		||||
    } // end if (subscription control)
 | 
			
		||||
 | 
			
		||||
    // unrecognized command - load the "Manage Topic menu"
 | 
			
		||||
    try
 | 
			
		||||
    { // return that "Manage Topic" page
 | 
			
		||||
 | 
			
		||||
@ -173,4 +173,10 @@ public class ManageTopic implements JSPRender
 | 
			
		||||
 | 
			
		||||
  } // end getBozosIterator
 | 
			
		||||
 | 
			
		||||
  public boolean isSubscribed()
 | 
			
		||||
  {
 | 
			
		||||
    return topic.isSubscribed();
 | 
			
		||||
 | 
			
		||||
  } // end isSubscribed
 | 
			
		||||
 | 
			
		||||
} // end class ManageTopic
 | 
			
		||||
 | 
			
		||||
@ -34,7 +34,19 @@
 | 
			
		||||
</FONT><P>
 | 
			
		||||
 | 
			
		||||
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
 | 
			
		||||
  <DIV ALIGN="LEFT"><B>Filtered users:</B></DIV>
 | 
			
		||||
  <DIV ALIGN="LEFT"><B>Topic Subscription:</B></DIV>
 | 
			
		||||
  <% if (data.isSubscribed()) { %>
 | 
			
		||||
    You are currently subscribed to this topic, and will receive all new posts to it via E-mail.<P>
 | 
			
		||||
    <B><A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=SN") %>">Click Here
 | 
			
		||||
    to Stop Subscribing To This Topic</A></B>
 | 
			
		||||
  <% } else { %>
 | 
			
		||||
    You are not currently subscribed to this topic.  When you subscribe to a topic, you will receive all new
 | 
			
		||||
    posts to that topic via E-mail.<P>
 | 
			
		||||
    <B><A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=SY") %>">Click Here
 | 
			
		||||
    to Start Subscribing To This Topic</A></B>
 | 
			
		||||
  <% } // end if %>
 | 
			
		||||
  <BR><HR WIDTH="80%">
 | 
			
		||||
  <DIV ALIGN="LEFT"><B>Filtered Users:</B></DIV>
 | 
			
		||||
  <% if (data.getNumBozos()>0) { %>
 | 
			
		||||
    <TABLE BORDER=0 ALIGN=CENTER CELLPADDING=0 CELLSPACING=2>
 | 
			
		||||
      <% Iterator it = data.getBozosIterator(); %>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user