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 -->
|
<!-- Parameters: community.name = name of community -->
|
||||||
<subj-invite>Invitation to "${community.name}" Community</subj-invite>
|
<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>
|
</messages>
|
||||||
|
|
||||||
</venice-config>
|
</venice-config>
|
||||||
|
|
|
@ -335,6 +335,7 @@ CREATE TABLE topicsettings (
|
||||||
last_message INT DEFAULT -1,
|
last_message INT DEFAULT -1,
|
||||||
last_read DATETIME,
|
last_read DATETIME,
|
||||||
last_post DATETIME,
|
last_post DATETIME,
|
||||||
|
subscribe TINYINT DEFAULT 0,
|
||||||
PRIMARY KEY (topicid, uid)
|
PRIMARY KEY (topicid, uid)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -100,5 +100,9 @@ public interface TopicContext
|
||||||
|
|
||||||
public abstract List getBozos() throws DataException;
|
public abstract List getBozos() throws DataException;
|
||||||
|
|
||||||
|
public abstract boolean isSubscribed();
|
||||||
|
|
||||||
|
public abstract void setSubscribed(boolean flag) throws DataException;
|
||||||
|
|
||||||
} // end interface TopicContext
|
} // end interface TopicContext
|
||||||
|
|
||||||
|
|
|
@ -1458,6 +1458,12 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
|
||||||
|
|
||||||
} // end env_testPermission
|
} // end env_testPermission
|
||||||
|
|
||||||
|
public String env_getCommunityName()
|
||||||
|
{
|
||||||
|
return this.getName();
|
||||||
|
|
||||||
|
} // end env.getCommunityName()
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Static operations for use within the implementation package
|
* Static operations for use within the implementation package
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1612,6 +1612,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
|
||||||
|
|
||||||
} // end env_getConfLevel
|
} // end env_getConfLevel
|
||||||
|
|
||||||
|
public String env_getConfName()
|
||||||
|
{
|
||||||
|
return this.getName();
|
||||||
|
|
||||||
|
} // end env_getConfName
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------------
|
||||||
* Static functions usable only from within the package
|
* 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.sql.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.apache.log4j.*;
|
import org.apache.log4j.*;
|
||||||
|
import com.silverwrist.util.StringUtil;
|
||||||
import com.silverwrist.venice.core.*;
|
import com.silverwrist.venice.core.*;
|
||||||
import com.silverwrist.venice.core.internals.*;
|
import com.silverwrist.venice.core.internals.*;
|
||||||
import com.silverwrist.venice.db.*;
|
import com.silverwrist.venice.db.*;
|
||||||
|
@ -53,6 +54,7 @@ class TopicUserContextImpl implements TopicContext
|
||||||
private String name;
|
private String name;
|
||||||
private boolean hidden;
|
private boolean hidden;
|
||||||
private int unread;
|
private int unread;
|
||||||
|
private boolean subscribed;
|
||||||
private boolean deleted = false;
|
private boolean deleted = false;
|
||||||
private HashSet bozo_uids = null;
|
private HashSet bozo_uids = null;
|
||||||
|
|
||||||
|
@ -63,7 +65,8 @@ class TopicUserContextImpl implements TopicContext
|
||||||
|
|
||||||
protected TopicUserContextImpl(EnvConference env, int topicid, short topicnum, int creator_uid,
|
protected TopicUserContextImpl(EnvConference env, int topicid, short topicnum, int creator_uid,
|
||||||
int top_message, boolean frozen, boolean archived, java.util.Date created,
|
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.env = env;
|
||||||
this.topicid = topicid;
|
this.topicid = topicid;
|
||||||
|
@ -77,6 +80,7 @@ class TopicUserContextImpl implements TopicContext
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
this.unread = (unread<0 ? 0 : unread);
|
this.unread = (unread<0 ? 0 : unread);
|
||||||
|
this.subscribed = subscribed;
|
||||||
|
|
||||||
} // end constructor
|
} // end constructor
|
||||||
|
|
||||||
|
@ -94,6 +98,7 @@ class TopicUserContextImpl implements TopicContext
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.hidden = false;
|
this.hidden = false;
|
||||||
this.unread = 1;
|
this.unread = 1;
|
||||||
|
this.subscribed = false;
|
||||||
this.bozo_uids = new HashSet(); // no bozos yet
|
this.bozo_uids = new HashSet(); // no bozos yet
|
||||||
|
|
||||||
} // end constructor
|
} // end constructor
|
||||||
|
@ -109,7 +114,8 @@ class TopicUserContextImpl implements TopicContext
|
||||||
new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
|
new StringBuffer("SELECT topics.topicid, topics.num, topics.creator_uid, topics.top_message, "
|
||||||
+ "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
|
+ "topics.frozen, topics.archived, topics.createdate, topics.lastupdate, "
|
||||||
+ "topics.name, IFNULL(topicsettings.hidden,0) AS hidden, "
|
+ "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 "
|
+ "FROM topics LEFT JOIN topicsettings ON topics.topicid = topicsettings.topicid "
|
||||||
+ "AND topicsettings.uid = ");
|
+ "AND topicsettings.uid = ");
|
||||||
sql.append(uid).append(" WHERE topics.topicid = ").append(topicid).append(';');
|
sql.append(uid).append(" WHERE topics.topicid = ").append(topicid).append(';');
|
||||||
|
@ -129,6 +135,7 @@ class TopicUserContextImpl implements TopicContext
|
||||||
name = null;
|
name = null;
|
||||||
hidden = false;
|
hidden = false;
|
||||||
unread = -1;
|
unread = -1;
|
||||||
|
subscribed = false;
|
||||||
deleted = true;
|
deleted = true;
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
|
@ -149,6 +156,7 @@ class TopicUserContextImpl implements TopicContext
|
||||||
unread = rs.getInt(11);
|
unread = rs.getInt(11);
|
||||||
if (unread<0)
|
if (unread<0)
|
||||||
unread = 0;
|
unread = 0;
|
||||||
|
subscribed = rs.getBoolean(12);
|
||||||
|
|
||||||
} // end if
|
} // end if
|
||||||
else // this topic must have been deleted - fsck it
|
else // this topic must have been deleted - fsck it
|
||||||
|
@ -666,11 +674,15 @@ class TopicUserContextImpl implements TopicContext
|
||||||
java.util.Date posted_date;
|
java.util.Date posted_date;
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
AuditRecord ar = null;
|
AuditRecord ar = null;
|
||||||
|
ArrayList mailto_addrs = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{ // get a database connection
|
{ // get a database connection
|
||||||
conn = env.getConnection();
|
conn = env.getConnection();
|
||||||
Statement stmt = conn.createStatement();
|
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
|
// slap a lock on all the tables we need to touch
|
||||||
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, posts WRITE, postdata WRITE, "
|
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);
|
logger.debug("New post number: " + new_post_num);
|
||||||
|
|
||||||
// Add the post "header" to the posts table.
|
// Add the post "header" to the posts table.
|
||||||
StringBuffer sql = new StringBuffer("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, "
|
sql.append("INSERT INTO posts (parent, topicid, num, linecount, creator_uid, posted, pseud) VALUES (");
|
||||||
+ "posted, pseud) VALUES (");
|
|
||||||
sql.append(parent).append(", ").append(topicid).append(", ").append(new_post_num).append(", ");
|
sql.append(parent).append(", ").append(topicid).append(", ").append(new_post_num).append(", ");
|
||||||
sql.append(text_linecount).append(", ").append(env.getUserID()).append(", '");
|
sql.append(text_linecount).append(", ").append(env.getUserID()).append(", '");
|
||||||
posted_date = new java.util.Date();
|
posted_date = new java.util.Date();
|
||||||
|
@ -717,9 +728,9 @@ class TopicUserContextImpl implements TopicContext
|
||||||
stmt.executeUpdate(sql.toString());
|
stmt.executeUpdate(sql.toString());
|
||||||
|
|
||||||
// Retrieve the new post ID.
|
// Retrieve the new post ID.
|
||||||
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
rs = stmt.executeQuery("SELECT LAST_INSERT_ID();");
|
||||||
if (!(rs.next()))
|
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);
|
new_post_id = rs.getLong(1);
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("New post ID: " + new_post_id);
|
logger.debug("New post ID: " + new_post_id);
|
||||||
|
@ -761,6 +772,21 @@ class TopicUserContextImpl implements TopicContext
|
||||||
env.getConference().touchUpdate(conn,posted_date);
|
env.getConference().touchUpdate(conn,posted_date);
|
||||||
env.getConference().touchPost(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
|
// Fill in our own local variables to reflect the update. This includes the recalculation
|
||||||
// of "unread" based on the new value of "top_message".
|
// of "unread" based on the new value of "top_message".
|
||||||
int tmp_last_msg = top_message - unread;
|
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="
|
ar = env.newAudit(AuditRecord.POST_MESSAGE,"conf=" + env.getConfID() + ",topic=" + topicid + ",post="
|
||||||
+ new_post_id,"pseud=" + real_pseud);
|
+ 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
|
} // end try
|
||||||
catch (SQLException e)
|
catch (SQLException e)
|
||||||
{ // turn SQLException into data exception
|
{ // turn SQLException into data exception
|
||||||
|
@ -796,6 +839,15 @@ class TopicUserContextImpl implements TopicContext
|
||||||
|
|
||||||
} // end finally
|
} // 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 the new message context
|
||||||
return new TopicMessageUserContextImpl(env,new_post_id,parent,new_post_num,text_linecount,env.getUserID(),
|
return new TopicMessageUserContextImpl(env,new_post_id,parent,new_post_num,text_linecount,env.getUserID(),
|
||||||
posted_date,real_pseud);
|
posted_date,real_pseud);
|
||||||
|
@ -1159,6 +1211,78 @@ class TopicUserContextImpl implements TopicContext
|
||||||
|
|
||||||
} // end getBozos
|
} // 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
|
* External operations usable only from within the package
|
||||||
*--------------------------------------------------------------------------------
|
*--------------------------------------------------------------------------------
|
||||||
|
@ -1278,9 +1402,10 @@ class TopicUserContextImpl implements TopicContext
|
||||||
StringBuffer sql =
|
StringBuffer sql =
|
||||||
new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
|
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.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)
|
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(" 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(env.getUserID()).append(" WHERE t.confid = ").append(env.getConfID());
|
||||||
if (where_clause!=null)
|
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),
|
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),
|
rs.getBoolean(5),rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
|
||||||
SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
|
SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
|
||||||
rs.getInt(11));
|
rs.getInt(11),rs.getBoolean(12));
|
||||||
rc.add(top);
|
rc.add(top);
|
||||||
|
|
||||||
} // end while
|
} // 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),
|
return new TopicUserContextImpl(env,topicid,rs.getShort(2),rs.getInt(3),rs.getInt(4),rs.getBoolean(5),
|
||||||
rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
|
rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
|
||||||
SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
|
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
|
// else fall out and return null
|
||||||
|
|
||||||
} // end try
|
} // end try
|
||||||
|
@ -1378,7 +1503,8 @@ class TopicUserContextImpl implements TopicContext
|
||||||
StringBuffer sql =
|
StringBuffer sql =
|
||||||
new StringBuffer("SELECT t.topicid, t.num, t.creator_uid, t.top_message, t.frozen, t.archived, "
|
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.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 = ");
|
+ "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(env.getUserID()).append(" WHERE t.confid = ").append(env.getConfID());
|
||||||
sql.append(" AND t.num = ").append(topicnum).append(';');
|
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),
|
return new TopicUserContextImpl(env,rs.getInt(1),topicnum,rs.getInt(3),rs.getInt(4),rs.getBoolean(5),
|
||||||
rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
|
rs.getBoolean(6),SQLUtil.getFullDateTime(rs,7),
|
||||||
SQLUtil.getFullDateTime(rs,8),rs.getString(9),rs.getBoolean(10),
|
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
|
// else fall out and return null
|
||||||
|
|
||||||
} // end try
|
} // end try
|
||||||
|
@ -1412,3 +1538,5 @@ class TopicUserContextImpl implements TopicContext
|
||||||
} // end getTopicByNumber
|
} // end getTopicByNumber
|
||||||
|
|
||||||
} // end class TopicUserContextImpl
|
} // end class TopicUserContextImpl
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -721,7 +721,7 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||||
LazyTreeLexicon lex = new LazyTreeLexicon((String[])(dictionary_tmp.toArray(new String[0])));
|
LazyTreeLexicon lex = new LazyTreeLexicon((String[])(dictionary_tmp.toArray(new String[0])));
|
||||||
spell_rewriter.addDictionary(lex);
|
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.
|
// Create the HTML checker config used to post body text to the database.
|
||||||
HTMLCheckerConfig cfg = HTMLCheckerCreator.create();
|
HTMLCheckerConfig cfg = HTMLCheckerCreator.create();
|
||||||
|
@ -781,6 +781,15 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
|
||||||
cfg.addOutputFilter(html_filter);
|
cfg.addOutputFilter(html_filter);
|
||||||
html_configs[HTMLC_ESCAPE_BODY_PSEUD] = cfg;
|
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())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("initialize() complete :-)");
|
logger.debug("initialize() complete :-)");
|
||||||
|
|
||||||
|
|
|
@ -44,4 +44,6 @@ public interface CommunityBackend
|
||||||
|
|
||||||
public abstract boolean env_testPermission(String symbol);
|
public abstract boolean env_testPermission(String symbol);
|
||||||
|
|
||||||
|
public abstract String env_getCommunityName();
|
||||||
|
|
||||||
} // end interface CommunityBackend
|
} // end interface CommunityBackend
|
||||||
|
|
|
@ -49,4 +49,6 @@ public interface ConferenceBackend
|
||||||
|
|
||||||
public abstract int env_getConfLevel();
|
public abstract int env_getConfLevel();
|
||||||
|
|
||||||
|
public abstract String env_getConfName();
|
||||||
|
|
||||||
} // end interface ConferenceBackend
|
} // end interface ConferenceBackend
|
||||||
|
|
|
@ -36,6 +36,7 @@ public interface EngineBackend
|
||||||
public static final int HTMLC_POST_PSEUD = 1;
|
public static final int HTMLC_POST_PSEUD = 1;
|
||||||
public static final int HTMLC_PREVIEW_BODY = 2;
|
public static final int HTMLC_PREVIEW_BODY = 2;
|
||||||
public static final int HTMLC_ESCAPE_BODY_PSEUD = 3;
|
public static final int HTMLC_ESCAPE_BODY_PSEUD = 3;
|
||||||
|
public static final int HTMLC_MAIL_POST = 4;
|
||||||
|
|
||||||
// Integer parameter indexes
|
// Integer parameter indexes
|
||||||
public static final int IP_POSTSPERPAGE = 0;
|
public static final int IP_POSTSPERPAGE = 0;
|
||||||
|
|
|
@ -182,4 +182,16 @@ public class EnvCommunity extends EnvUser
|
||||||
|
|
||||||
} // end getCommunityDefaultRole
|
} // end getCommunityDefaultRole
|
||||||
|
|
||||||
|
public final String getCommunityName()
|
||||||
|
{
|
||||||
|
return comm.env_getCommunityName();
|
||||||
|
|
||||||
|
} // end getCommunityName
|
||||||
|
|
||||||
|
public final String getCommunityAlias()
|
||||||
|
{
|
||||||
|
return comm.realCommunityAlias();
|
||||||
|
|
||||||
|
} // end getCommunityAlias
|
||||||
|
|
||||||
} // end class EnvCommunity
|
} // end class EnvCommunity
|
||||||
|
|
|
@ -116,5 +116,17 @@ public class EnvConference extends EnvCommunity
|
||||||
|
|
||||||
} // end getConfID
|
} // end getConfID
|
||||||
|
|
||||||
|
public final String getConferenceAlias()
|
||||||
|
{
|
||||||
|
return conf.realConfAlias();
|
||||||
|
|
||||||
|
} // end getConfAlias
|
||||||
|
|
||||||
|
public final String getConferenceName()
|
||||||
|
{
|
||||||
|
return conf.env_getConfName();
|
||||||
|
|
||||||
|
} // end getConfName
|
||||||
|
|
||||||
} // end class EnvConference
|
} // end class EnvConference
|
||||||
|
|
||||||
|
|
|
@ -175,4 +175,10 @@ public class EnvEngine
|
||||||
|
|
||||||
} // end saveAuditRecord
|
} // end saveAuditRecord
|
||||||
|
|
||||||
|
public final String getStockMessage(String key)
|
||||||
|
{
|
||||||
|
return engine.getStockMessage(key);
|
||||||
|
|
||||||
|
} // end getStockMessage
|
||||||
|
|
||||||
} // end class EnvEngine
|
} // end class EnvEngine
|
||||||
|
|
|
@ -199,6 +199,12 @@ public class EnvUser extends EnvEngine
|
||||||
|
|
||||||
} // end getUserID
|
} // end getUserID
|
||||||
|
|
||||||
|
public final String getUserName()
|
||||||
|
{
|
||||||
|
return user.realUserName();
|
||||||
|
|
||||||
|
} // end getUserName
|
||||||
|
|
||||||
public final int getUserBaseLevel()
|
public final int getUserBaseLevel()
|
||||||
{
|
{
|
||||||
return user.realBaseLevel();
|
return user.realBaseLevel();
|
||||||
|
|
|
@ -216,6 +216,24 @@ public class TopicOperations extends VeniceServlet
|
||||||
|
|
||||||
} // end if (remove bozo)
|
} // 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"
|
// unrecognized command - load the "Manage Topic menu"
|
||||||
try
|
try
|
||||||
{ // return that "Manage Topic" page
|
{ // return that "Manage Topic" page
|
||||||
|
|
|
@ -173,4 +173,10 @@ public class ManageTopic implements JSPRender
|
||||||
|
|
||||||
} // end getBozosIterator
|
} // end getBozosIterator
|
||||||
|
|
||||||
|
public boolean isSubscribed()
|
||||||
|
{
|
||||||
|
return topic.isSubscribed();
|
||||||
|
|
||||||
|
} // end isSubscribed
|
||||||
|
|
||||||
} // end class ManageTopic
|
} // end class ManageTopic
|
||||||
|
|
|
@ -34,7 +34,19 @@
|
||||||
</FONT><P>
|
</FONT><P>
|
||||||
|
|
||||||
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
|
<%= 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) { %>
|
<% if (data.getNumBozos()>0) { %>
|
||||||
<TABLE BORDER=0 ALIGN=CENTER CELLPADDING=0 CELLSPACING=2>
|
<TABLE BORDER=0 ALIGN=CENTER CELLPADDING=0 CELLSPACING=2>
|
||||||
<% Iterator it = data.getBozosIterator(); %>
|
<% Iterator it = data.getBozosIterator(); %>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user