diff --git a/etc/venice-config.xml b/etc/venice-config.xml index 9d5d913..f188011 100644 --- a/etc/venice-config.xml +++ b/etc/venice-config.xml @@ -438,6 +438,34 @@ Hope to see you in "${community.name}" soon! Invitation to "${community.name}" Community + + + + + + + + + + + + + + + New Post in ${topic.name} + diff --git a/setup/database.sql b/setup/database.sql index a84bae8..8cda1e6 100644 --- a/setup/database.sql +++ b/setup/database.sql @@ -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) ); diff --git a/src/com/silverwrist/venice/core/TopicContext.java b/src/com/silverwrist/venice/core/TopicContext.java index 558efd2..4c82181 100644 --- a/src/com/silverwrist/venice/core/TopicContext.java +++ b/src/com/silverwrist/venice/core/TopicContext.java @@ -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 diff --git a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java index 16c705b..5eb21b5 100644 --- a/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/CommunityUserContextImpl.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java index 41616bf..87ba787 100644 --- a/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java +++ b/src/com/silverwrist/venice/core/impl/ConferenceUserContextImpl.java @@ -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 *-------------------------------------------------------------------------------- diff --git a/src/com/silverwrist/venice/core/impl/PostDeliveryAgent.java b/src/com/silverwrist/venice/core/impl/PostDeliveryAgent.java new file mode 100644 index 0000000..be3856a --- /dev/null +++ b/src/com/silverwrist/venice/core/impl/PostDeliveryAgent.java @@ -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 . + * + * 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 , + * 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(); %>