,
+ * 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
diff --git a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
index 108d6d4..0301c1f 100644
--- a/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
+++ b/src/com/silverwrist/venice/core/impl/TopicUserContextImpl.java
@@ -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
+
+
diff --git a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
index 306caf2..d1e3d7b 100644
--- a/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
+++ b/src/com/silverwrist/venice/core/impl/VeniceEngineImpl.java
@@ -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 :-)");
diff --git a/src/com/silverwrist/venice/core/internals/CommunityBackend.java b/src/com/silverwrist/venice/core/internals/CommunityBackend.java
index a8dbe66..986c071 100644
--- a/src/com/silverwrist/venice/core/internals/CommunityBackend.java
+++ b/src/com/silverwrist/venice/core/internals/CommunityBackend.java
@@ -44,4 +44,6 @@ public interface CommunityBackend
public abstract boolean env_testPermission(String symbol);
+ public abstract String env_getCommunityName();
+
} // end interface CommunityBackend
diff --git a/src/com/silverwrist/venice/core/internals/ConferenceBackend.java b/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
index 1e95865..6e2a360 100644
--- a/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
+++ b/src/com/silverwrist/venice/core/internals/ConferenceBackend.java
@@ -49,4 +49,6 @@ public interface ConferenceBackend
public abstract int env_getConfLevel();
+ public abstract String env_getConfName();
+
} // end interface ConferenceBackend
diff --git a/src/com/silverwrist/venice/core/internals/EngineBackend.java b/src/com/silverwrist/venice/core/internals/EngineBackend.java
index e4205f2..3a76086 100644
--- a/src/com/silverwrist/venice/core/internals/EngineBackend.java
+++ b/src/com/silverwrist/venice/core/internals/EngineBackend.java
@@ -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;
diff --git a/src/com/silverwrist/venice/core/internals/EnvCommunity.java b/src/com/silverwrist/venice/core/internals/EnvCommunity.java
index f612fb4..2d95c2f 100644
--- a/src/com/silverwrist/venice/core/internals/EnvCommunity.java
+++ b/src/com/silverwrist/venice/core/internals/EnvCommunity.java
@@ -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
diff --git a/src/com/silverwrist/venice/core/internals/EnvConference.java b/src/com/silverwrist/venice/core/internals/EnvConference.java
index 9214025..d8f00b4 100644
--- a/src/com/silverwrist/venice/core/internals/EnvConference.java
+++ b/src/com/silverwrist/venice/core/internals/EnvConference.java
@@ -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
diff --git a/src/com/silverwrist/venice/core/internals/EnvEngine.java b/src/com/silverwrist/venice/core/internals/EnvEngine.java
index 11755d8..d6830e9 100644
--- a/src/com/silverwrist/venice/core/internals/EnvEngine.java
+++ b/src/com/silverwrist/venice/core/internals/EnvEngine.java
@@ -175,4 +175,10 @@ public class EnvEngine
} // end saveAuditRecord
+ public final String getStockMessage(String key)
+ {
+ return engine.getStockMessage(key);
+
+ } // end getStockMessage
+
} // end class EnvEngine
diff --git a/src/com/silverwrist/venice/core/internals/EnvUser.java b/src/com/silverwrist/venice/core/internals/EnvUser.java
index c0c6ac1..d9d87fd 100644
--- a/src/com/silverwrist/venice/core/internals/EnvUser.java
+++ b/src/com/silverwrist/venice/core/internals/EnvUser.java
@@ -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();
diff --git a/src/com/silverwrist/venice/servlets/TopicOperations.java b/src/com/silverwrist/venice/servlets/TopicOperations.java
index a40b934..7716f27 100644
--- a/src/com/silverwrist/venice/servlets/TopicOperations.java
+++ b/src/com/silverwrist/venice/servlets/TopicOperations.java
@@ -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
diff --git a/src/com/silverwrist/venice/servlets/format/ManageTopic.java b/src/com/silverwrist/venice/servlets/format/ManageTopic.java
index d88fd82..1e73ee2 100644
--- a/src/com/silverwrist/venice/servlets/format/ManageTopic.java
+++ b/src/com/silverwrist/venice/servlets/format/ManageTopic.java
@@ -173,4 +173,10 @@ public class ManageTopic implements JSPRender
} // end getBozosIterator
+ public boolean isSubscribed()
+ {
+ return topic.isSubscribed();
+
+ } // end isSubscribed
+
} // end class ManageTopic
diff --git a/web/format/manage_topic.jsp b/web/format/manage_topic.jsp
index 8c1c81b..6d5835d 100644
--- a/web/format/manage_topic.jsp
+++ b/web/format/manage_topic.jsp
@@ -34,7 +34,19 @@
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
-
Filtered users:
+ Topic Subscription:
+ <% if (data.isSubscribed()) { %>
+ You are currently subscribed to this topic, and will receive all new posts to it via E-mail.
+ ">Click Here
+ to Stop Subscribing To This Topic
+ <% } 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.
+ ">Click Here
+ to Start Subscribing To This Topic
+ <% } // end if %>
+
+ Filtered Users:
<% if (data.getNumBozos()>0) { %>
<% Iterator it = data.getBozosIterator(); %>