implementation of the "bozo filter" on a topic level, including a topic-level

"Manage" screen (to hang "Rename Topic" from later, too).
This commit is contained in:
Eric J. Bowersox 2001-11-09 00:10:36 +00:00
parent bc859178f2
commit 0bb2e795a4
13 changed files with 727 additions and 38 deletions

View File

@ -306,15 +306,6 @@ CREATE TABLE confhotlist (
INDEX inorder (uid, sequence) INDEX inorder (uid, sequence)
); );
# The "bozo filter" list for a conference, for use by users in filtering out
# the rantings of other users who are bozos.
CREATE TABLE confbozo (
confid INT NOT NULL,
uid INT NOT NULL,
bozo_uid INT NOT NULL,
PRIMARY KEY (confid, uid, bozo_uid)
);
# The table describing topics within a conference. # The table describing topics within a conference.
CREATE TABLE topics ( CREATE TABLE topics (
topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, topicid INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
@ -343,6 +334,15 @@ CREATE TABLE topicsettings (
PRIMARY KEY (topicid, uid) PRIMARY KEY (topicid, uid)
); );
# The "bozo filter" list for a topic, for use by users in filtering out
# the rantings of other users who are bozos.
CREATE TABLE topicbozo (
topicid INT NOT NULL,
uid INT NOT NULL,
bozo_uid INT NOT NULL,
PRIMARY KEY (topicid, uid, bozo_uid)
);
# The "header" for a posted message. # The "header" for a posted message.
CREATE TABLE posts ( CREATE TABLE posts (
postid BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, postid BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT,

View File

@ -0,0 +1,146 @@
/*
* 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.util;
import java.util.BitSet;
public class OptionSet extends BitSet
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final String ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+ "!#$%&()*+,-./:;<=>?@[]^_`{|}~";
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
public OptionSet()
{
super();
} // end constructor
public OptionSet(int nbits)
{
super(Math.min(nbits,ALPHA.length()));
} // end constructor
public OptionSet(char[] options)
{
super(); // initialize all bits to 0
for (int i=0; i<options.length; i++)
{ // look at all the chars in the option string and set bits accordingly
int ndx = ALPHA.indexOf(options[i]);
if (ndx>=0)
super.set(ndx);
} // end for
} // end constructor
public OptionSet(String options)
{
this(options.toCharArray());
} // end constructor
private StringBuffer asStringBuffer()
{
StringBuffer b = new StringBuffer();
for (int i=0; i<super.length(); i++)
if (super.get(i))
b.append(ALPHA.charAt(i));
return b;
} // end asStringBuffer
/*--------------------------------------------------------------------------------
* Overrides from class BitSet
*--------------------------------------------------------------------------------
*/
public void clear(int bitIndex)
{
if (bitIndex>=ALPHA.length())
throw new IndexOutOfBoundsException();
super.clear(bitIndex);
} // end clear
public boolean get(int bitIndex)
{
if (bitIndex>=ALPHA.length())
throw new IndexOutOfBoundsException();
return super.get(bitIndex);
} // end get
public void set(int bitIndex)
{
if (bitIndex>=ALPHA.length())
throw new IndexOutOfBoundsException();
super.set(bitIndex);
} // end set
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public void assign(char[] options)
{
int i;
for (i=0; i<super.length(); i++)
super.clear(i);
for (i=0; i<options.length; i++)
{ // look at all the chars in the option string and set bits accordingly
int ndx = ALPHA.indexOf(options[i]);
if (ndx>=0)
super.set(ndx);
} // end for
} // end assign
public void assign(String options)
{
assign(options.toCharArray());
} // end assign
public char[] asCharArray()
{
return asStringBuffer().toString().toCharArray();
} // end asCharArray
public String asString()
{
return asStringBuffer().toString();
} // end asString
} // end class OptionSet

View File

@ -90,5 +90,13 @@ public interface TopicContext
public abstract List getActiveReaders() throws DataException, AccessError; public abstract List getActiveReaders() throws DataException, AccessError;
public abstract boolean isBozo(int other_uid) throws DataException;
public abstract void setBozo(int other_uid, boolean bozo) throws DataException;
public abstract boolean canSetBozo(int other_uid);
public abstract List getBozos() throws DataException;
} // end interface TopicContext } // end interface TopicContext

View File

@ -96,6 +96,7 @@ class BackgroundConferencePurge implements Runnable
{ // delete the topic header and settings rows first { // delete the topic header and settings rows first
stmt.executeUpdate("DELETE FROM topics WHERE topicid = " + topicids[i] + ";"); stmt.executeUpdate("DELETE FROM topics WHERE topicid = " + topicids[i] + ";");
stmt.executeUpdate("DELETE FROM topicsettings WHERE topicid = " + topicids[i] + ";"); stmt.executeUpdate("DELETE FROM topicsettings WHERE topicid = " + topicids[i] + ";");
stmt.executeUpdate("DELETE FROM topicbozo WHERE topicid = " + topicids[i] + ";");
// figure out how many posts are in this topic and create a BackgroundTopicPurge. // figure out how many posts are in this topic and create a BackgroundTopicPurge.
sql.setLength(0); sql.setLength(0);

View File

@ -54,6 +54,7 @@ class TopicUserContextImpl implements TopicContext
private boolean hidden; private boolean hidden;
private int unread; private int unread;
private boolean deleted = false; private boolean deleted = false;
private HashSet bozo_uids = null;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructors * Constructors
@ -99,6 +100,7 @@ class TopicUserContextImpl implements TopicContext
this.name = name; this.name = name;
this.hidden = false; this.hidden = false;
this.unread = 1; this.unread = 1;
this.bozo_uids = new HashSet(); // no bozos yet
} // end constructor } // end constructor
@ -160,6 +162,18 @@ class TopicUserContextImpl implements TopicContext
} // end refresh } // end refresh
private void loadBozo(Connection conn) throws SQLException
{
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT bozo_uid FROM topicbozo WHERE topicid = ");
sql.append(topicid).append(" AND uid = ").append(conf.realUID()).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
bozo_uids = new HashSet();
while (rs.next())
bozo_uids.add(new Integer(rs.getInt(1)));
} // end loadBozo
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface TopicContext * Implementations from interface TopicContext
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -874,7 +888,8 @@ class TopicUserContextImpl implements TopicContext
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
// lock some tables while we do the critical parts of the delete // lock some tables while we do the critical parts of the delete
stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, posts READ;"); stmt.executeUpdate("LOCK TABLES confs WRITE, topics WRITE, topicsettings WRITE, topicbozo WRITE, "
+ "posts READ;");
try try
{ // first delete the topic record itself { // first delete the topic record itself
StringBuffer sql = new StringBuffer("DELETE FROM topics WHERE topicid = "); StringBuffer sql = new StringBuffer("DELETE FROM topics WHERE topicid = ");
@ -886,6 +901,11 @@ class TopicUserContextImpl implements TopicContext
sql.append("DELETE FROM topicsettings WHERE topicid = ").append(topicid).append(';'); sql.append("DELETE FROM topicsettings WHERE topicid = ").append(topicid).append(';');
stmt.executeUpdate(sql.toString()); stmt.executeUpdate(sql.toString());
// and all topicbozo records
sql.setLength(0);
sql.append("DELETE FROM topicbozo WHERE topicid = ").append(topicid).append(';');
stmt.executeUpdate(sql.toString());
// and indicate that we updated the conference // and indicate that we updated the conference
conf.touchUpdate(conn,new java.util.Date()); conf.touchUpdate(conn,new java.util.Date());
@ -1068,6 +1088,145 @@ class TopicUserContextImpl implements TopicContext
} // end getActiveReaders } // end getActiveReaders
public boolean isBozo(int other_uid) throws DataException
{
if (deleted || conf.userIsAnonymous() || (other_uid==conf.realUID()))
return false; // no-op
if (bozo_uids==null)
{ // the bozo UIDs need to be loaded!
Connection conn = null;
try
{ // load the bozo filter UIDs from the database
conn = datapool.getConnection();
loadBozo(conn);
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error getting bozo list: " + e.getMessage(),e);
throw new DataException("unable to get bozo filter listing: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end if
return bozo_uids.contains(new Integer(other_uid));
} // end isBozo
public void setBozo(int other_uid, boolean bozo) throws DataException
{
if (deleted || conf.userIsAnonymous() || (other_uid==conf.realUID()))
return; // no-op
Connection conn = null;
try
{ // figure out what to do here
conn = datapool.getConnection();
refresh(conn);
if (deleted)
return; // one more check to make sure we're not deleted
if (bozo_uids==null)
loadBozo(conn); // load the bozo filter if we don't already have it
Integer uid_key = new Integer(other_uid);
Statement stmt;
StringBuffer sql;
if (bozo)
{ // this user is a bozo...
if (!(bozo_uids.contains(uid_key)))
{ // add them to the bozo list
sql = new StringBuffer("INSERT INTO topicbozo (topicid, uid, bozo_uid) VALUES (");
sql.append(topicid).append(", ").append(conf.realUID()).append(", ").append(other_uid).append(");");
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
bozo_uids.add(uid_key);
} // end if
// else this is a no-op
} // end if
else
{ // this user is no longer a bozo
if (bozo_uids.contains(uid_key))
{ // remove them from the bozo list
sql = new StringBuffer("DELETE FROM topicbozo WHERE topicid = ");
sql.append(topicid).append(" AND uid = ").append(conf.realUID()).append(" AND bozo_uid = ");
sql.append(other_uid).append(';');
stmt = conn.createStatement();
stmt.executeUpdate(sql.toString());
bozo_uids.remove(uid_key);
} // end if
// else this is a no-op
} // end else
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error updating bozo list: " + e.getMessage(),e);
throw new DataException("unable to update bozo filter list: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end setBozo
public boolean canSetBozo(int other_uid)
{
// 1. You can't set bozo filters on a deleted topic.
// 2. You can't set bozo filters if you're the anonymous user.
// 3. You can't bozo-filter yourself, silly.
return !(deleted || conf.userIsAnonymous() || (other_uid==conf.realUID()));
} // end canSetBozoFilter
public List getBozos() throws DataException
{
if (deleted || conf.userIsAnonymous())
return Collections.EMPTY_LIST; // no-op
if (bozo_uids==null)
{ // the bozo UIDs need to be loaded!
Connection conn = null;
try
{ // load the bozo filter UIDs from the database
conn = datapool.getConnection();
loadBozo(conn);
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error getting bozo list: " + e.getMessage(),e);
throw new DataException("unable to get bozo filter listing: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end if
return Collections.unmodifiableList(new ArrayList(bozo_uids));
} // end getBozos
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* External operations usable only from within the package * External operations usable only from within the package
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -364,12 +364,13 @@ public class ConfDisplay extends VeniceServlet
PostInterval piv = getInterval(engine,request,topic,on_error); PostInterval piv = getInterval(engine,request,topic,on_error);
boolean read_new = do_readnew && !(StringUtil.isStringEmpty(request.getParameter("rnm"))); boolean read_new = do_readnew && !(StringUtil.isStringEmpty(request.getParameter("rnm")));
boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac"))); boolean show_adv = !(StringUtil.isStringEmpty(request.getParameter("shac")));
boolean no_bozos = !(StringUtil.isStringEmpty(request.getParameter("nbz")));
// Create the post display. // Create the post display.
TopicPosts tpos = null;
try try
{ // create the display { // create the display
tpos = new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),read_new,show_adv); return new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),read_new,show_adv,
no_bozos);
} // end try } // end try
catch (DataException de) catch (DataException de)
@ -383,8 +384,6 @@ public class ConfDisplay extends VeniceServlet
} // end catch } // end catch
return tpos;
} // end if (messages in a topic) } // end if (messages in a topic)
else else
{ // we're displaying the conference's topic list { // we're displaying the conference's topic list
@ -403,8 +402,6 @@ public class ConfDisplay extends VeniceServlet
if (read_new) if (read_new)
{ // we need to generate a TopicPosts view { // we need to generate a TopicPosts view
TopicPosts tpos = null;
try try
{ // generate a topic list first { // generate a topic list first
List topic_list = conf.getTopicList(opts.getViewOption(conf.getConfID()), List topic_list = conf.getTopicList(opts.getViewOption(conf.getConfID()),
@ -433,7 +430,7 @@ public class ConfDisplay extends VeniceServlet
PostInterval piv = getInterval(engine,request,topic,on_error); PostInterval piv = getInterval(engine,request,topic,on_error);
// create the topic posts view // create the topic posts view
return new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),true,false); return new TopicPosts(request,engine,comm,conf,topic,piv.getFirst(),piv.getLast(),true,false,false);
} // end try } // end try
catch (DataException de) catch (DataException de)

View File

@ -133,6 +133,25 @@ public class PostOperations extends VeniceServlet
} // end if ("scribble") } // end if ("scribble")
if (cmd.equals("BY") || cmd.equals("BN"))
{ // we want to add or remove the bozo filter from the user here
try
{ // attempt to set the bozo filter status
topic.setBozo(msg.getCreatorUID(),cmd.equals("BY"));
// go back and display stuff
throw new RedirectResult(location);
} // end try
catch (DataException de)
{ // there was a database error
return new ErrorBox("Database Error","Database error setting filter status: " + de.getMessage(),
location);
} // end catch
} // end if
if (cmd.equals("NUKE")) if (cmd.equals("NUKE"))
{ // nuking requires confirmation { // nuking requires confirmation
try try

View File

@ -183,9 +183,51 @@ public class TopicOperations extends VeniceServlet
} // end if (delete) } // end if (delete)
// unrecognized command if (cmd.equals("RB"))
logger.error("invalid command to TopicOperations.doGet: " + cmd); { // "RB" = "Remove Bozo" (UID specified as parameter "u")
return new ErrorBox("Internal Error","Invalid command to TopicOperations.doGet",location); int uid = -1;
try
{ // get the user ID to un-bozo
String foo = request.getParameter("u");
if (foo!=null)
uid = Integer.parseInt(foo);
} // end try
catch (NumberFormatException nfe)
{ // just don't do anything on error
uid = -1;
} // end catch
try
{ // remove "bozo" status from this user
if (uid>0)
topic.setBozo(uid,false);
setMyLocation(request,"topicops?" + locator);
return new ManageTopic(user,comm,conf,topic);
} // end try
catch (DataException de)
{ // whoops! this is a problem!
return new ErrorBox("Database Error","Database error removing filtered user: " + de.getMessage(),
"topicops?" + locator);
} // end catch
} // end if (remove bozo)
// unrecognized command - load the "Manage Topic menu"
try
{ // return that "Manage Topic" page
setMyLocation(request,"topicops?" + locator);
return new ManageTopic(user,comm,conf,topic);
} // end try
catch (DataException de)
{ // whoops! this is a problem!
return new ErrorBox("Database Error","Database error loading manage page: " + de.getMessage(),location);
} // end catch
} // end doVeniceGet } // end doVeniceGet

View File

@ -0,0 +1,175 @@
/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.servlets.format;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.silverwrist.venice.core.*;
public class ManageTopic implements JSPRender
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
// Attribute name for request attribute
protected static final String ATTR_NAME = "com.silverwrist.venice.content.ManageTopic";
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private CommunityContext comm; // the community we're in
private ConferenceContext conf; // the conference being listed
private TopicContext topic; // the topic being managed
private String locator = null; // the locator we use
private List bozos_list; // the list of "bozo" users
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public ManageTopic(UserContext user, CommunityContext comm, ConferenceContext conf, TopicContext topic)
throws DataException
{
this.comm = comm;
this.conf = conf;
this.topic = topic;
// Load up the list of bozos, sorting them in user name order.
List bozo_uids = topic.getBozos();
if (bozo_uids.size()>0)
{ // use a TreeMap to do the sorting
TreeMap load_map = new TreeMap();
Iterator it = bozo_uids.iterator();
while (it.hasNext())
{ // fill in the list of user profiles
Integer uid = (Integer)(it.next());
UserProfile prof = user.getProfile(uid.intValue());
load_map.put(prof.getUserName(),prof);
} // end while
bozos_list = new ArrayList(load_map.values());
} // end if
else // no bozos - just set empty list
bozos_list = Collections.EMPTY_LIST;
} // end constructor
/*--------------------------------------------------------------------------------
* External static functions
*--------------------------------------------------------------------------------
*/
public static ManageTopic retrieve(ServletRequest request)
{
return (ManageTopic)(request.getAttribute(ATTR_NAME));
} // end retrieve
/*--------------------------------------------------------------------------------
* Implementations from interface VeniceContent
*--------------------------------------------------------------------------------
*/
public String getPageTitle(RenderData rdat)
{
return "Manage Topic: " + topic.getName();
} // end getPageTitle
public String getPageQID()
{
return null;
} // end getPageQID
/*--------------------------------------------------------------------------------
* Implementations from interface JSPRender
*--------------------------------------------------------------------------------
*/
public void store(ServletRequest request)
{
request.setAttribute(ATTR_NAME,this);
} // end store
public String getTargetJSPName()
{
return "manage_topic.jsp";
} // end getTargetJSPName
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public int getCommunityID()
{
return comm.getCommunityID();
} // end getCommunityID
public int getConfID()
{
return conf.getConfID();
} // end getConfID
public int getTopicNumber()
{
return topic.getTopicNumber();
} // end getTopicID
public String getTopicName()
{
return topic.getName();
} // end getConfName
public String getLocator()
{
if (locator==null)
locator = "sig=" + comm.getCommunityID() + "&conf=" + conf.getConfID() + "&top="
+ topic.getTopicNumber();
return locator;
} // end getLocator
public int getNumBozos()
{
return bozos_list.size();
} // end getNumBozos()
public Iterator getBozosIterator()
{
return bozos_list.iterator();
} // end getBozosIterator
} // end class ManageTopic

View File

@ -48,12 +48,14 @@ public class TopicPosts implements JSPRender
private int first; private int first;
private int last; private int last;
private boolean show_advanced; private boolean show_advanced;
private boolean no_bozos;
private int unread; private int unread;
private List messages; private List messages;
private TopicVisitOrder visit_order; private TopicVisitOrder visit_order;
private String topic_stem; private String topic_stem;
private String topic_qid; private String topic_qid;
private String cache_locator = null; private String cache_locator = null;
private HashSet bozo_uids = new HashSet();
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
@ -62,12 +64,12 @@ public class TopicPosts implements JSPRender
public TopicPosts(HttpServletRequest request, VeniceEngine engine, CommunityContext comm, public TopicPosts(HttpServletRequest request, VeniceEngine engine, CommunityContext comm,
ConferenceContext conf, TopicContext topic, int first, int last, boolean read_new, ConferenceContext conf, TopicContext topic, int first, int last, boolean read_new,
boolean show_advanced) throws DataException, AccessError boolean show_advanced, boolean no_bozos) throws DataException, AccessError
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("TopicPosts: comm=" + comm.getCommunityID() + ", conf=" + conf.getConfID() + ", topic=" logger.debug("TopicPosts: comm=" + comm.getCommunityID() + ", conf=" + conf.getConfID() + ", topic="
+ topic.getTopicNumber() + ", range=[" + first + ", " + last + "], rnm=" + read_new + topic.getTopicNumber() + ", range=[" + first + ", " + last + "], rnm=" + read_new
+ ", shac=" + show_advanced); + ", shac=" + show_advanced + ", nbz=" + no_bozos);
this.engine = engine; this.engine = engine;
this.comm = comm; this.comm = comm;
this.conf = conf; this.conf = conf;
@ -75,6 +77,7 @@ public class TopicPosts implements JSPRender
this.first = first; this.first = first;
this.last = last; this.last = last;
this.show_advanced = show_advanced; this.show_advanced = show_advanced;
this.no_bozos = no_bozos;
this.unread = topic.getUnreadMessages(); this.unread = topic.getUnreadMessages();
if (read_new) if (read_new)
topic.setUnreadMessages(0); topic.setUnreadMessages(0);
@ -88,6 +91,23 @@ public class TopicPosts implements JSPRender
topic_stem = (String)(aliases.get(0)) + "." + topic.getTopicNumber() + "."; topic_stem = (String)(aliases.get(0)) + "." + topic.getTopicNumber() + ".";
topic_qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0)) + "." + topic.getTopicNumber(); topic_qid = "go/" + comm.getAlias() + "!" + (String)(aliases.get(0)) + "." + topic.getTopicNumber();
// build up the list of users IN THIS VIEW that are bozo-filtered
HashSet saw_users = new HashSet();
Iterator it = messages.iterator();
while (it.hasNext())
{ // get the user IDs of all messages on this page
TopicMessageContext msg = (TopicMessageContext)(it.next());
Integer the_uid = new Integer(msg.getCreatorUID());
if (!(saw_users.contains(the_uid)))
{ // only check user IDs once per display operation
saw_users.add(the_uid);
if (topic.isBozo(the_uid.intValue()))
bozo_uids.add(the_uid);
} // end if
} // end while
} // end constructor } // end constructor
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
@ -426,4 +446,28 @@ public class TopicPosts implements JSPRender
} // end displayAttachmentInNewWindow } // end displayAttachmentInNewWindow
public boolean bozoFilterUser(int uid)
{
if (no_bozos)
return false;
else
return bozo_uids.contains(new Integer(uid));
} // end bozoFilterUser
public boolean showBozoFilteredIndicator(int uid)
{
if (no_bozos)
return bozo_uids.contains(new Integer(uid));
else
return false;
} // end showBozoFilteredIndicator
public boolean showFilterButton(int uid)
{
return !(bozo_uids.contains(new Integer(uid))) && topic.canSetBozo(uid);
} // end showFilterButton
} // end class TopicPosts } // end class TopicPosts

View File

@ -0,0 +1,71 @@
<%--
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):
--%>
<%@ page import = "java.util.*" %>
<%@ page import = "com.silverwrist.util.StringUtil" %>
<%@ page import = "com.silverwrist.venice.core.*" %>
<%@ page import = "com.silverwrist.venice.servlets.Variables" %>
<%@ page import = "com.silverwrist.venice.servlets.format.*" %>
<%
ManageTopic data = ManageTopic.retrieve(request);
Variables.failIfNull(data);
RenderData rdat = RenderConfig.createRenderData(application,request,response);
%>
<% if (rdat.useHTMLComments()) { %><!-- Managing topic #<%= data.getTopicNumber() %>
in conference #<%= data.getConfID() %> --><% } %>
<% rdat.writeContentHeader(out,"Manage Topic:",data.getTopicName()); %>
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator()) %>">Return to Topic</A>
</FONT><P>
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
<DIV ALIGN="LEFT"><B>Filtered users:</B></DIV>
<% if (data.getNumBozos()>0) { %>
<TABLE BORDER=0 ALIGN=CENTER CELLPADDING=0 CELLSPACING=2>
<% Iterator it = data.getBozosIterator(); %>
<% while (it.hasNext()) { %>
<% UserProfile prof = (UserProfile)(it.next()); %>
<TR>
<TD ALIGN=CENTER WIDTH=16>
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator() + "&cmd=RB&u="
+ prof.getUID()) %>"><IMG
SRC="<%= rdat.getFullImagePath("icn_x.gif") %>" ALT="Remove" BORDER=0 WIDTH=16
HEIGHT=16></A>
</TD>
<TD ALIGN=LEFT CLASS="content"><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
&lt;<A HREF="<%= rdat.getEncodedServletPath("user/" + prof.getUserName()) %>"><%= prof.getUserName() %></A>&gt;
<EM>(<%= StringUtil.encodeHTML(prof.getGivenName()) %>
<%= StringUtil.encodeHTML(prof.getFamilyName()) %>)</EM>
</FONT></TD>
</TR>
<% } // end while %>
</TABLE><P>
<TABLE ALIGN=CENTER BORDER=0 CELLPADDING=2 CELLSPACING=0>
<TR VALIGN=TOP>
<TD ALIGN=CENTER WIDTH=16>
<IMG SRC="<%= rdat.getFullImagePath("icn_x.gif") %>" ALT="Remove" BORDER=0 WIDTH=16 HEIGHT=16>
</TD>
<TD ALIGN=LEFT CLASS="content"><%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
Click this symbol to cease filtering this user in this topic.
</FONT></TD>
</TR>
</TABLE>
<% } else { %>
<DIV ALIGN="CENTER"><EM>No users currently filtered.</EM></DIV>
<% } // end if %>
</FONT>

View File

@ -39,7 +39,7 @@
<TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0> <TABLE BORDER=0 WIDTH="100%" CELLPADDING=0 CELLSPACING=0>
<TR VALIGN=BOTTOM> <TR VALIGN=BOTTOM>
<TD NOWRAP ALIGN=LEFT CLASS="content"> <TD NOWRAP ALIGN=LEFT COLSPAN=2 CLASS="content">
<% if (rdat.useHTMLComments()) { %><!-- Topic user controls section --><% } %> <% if (rdat.useHTMLComments()) { %><!-- Topic user controls section --><% } %>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getConfLocator()) %>"><IMG <A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getConfLocator()) %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_topic_list.gif") %>" ALT="Topic List" WIDTH=80 HEIGHT=24 SRC="<%= rdat.getFullImagePath("bn_topic_list.gif") %>" ALT="Topic List" WIDTH=80 HEIGHT=24
@ -68,7 +68,13 @@
&nbsp; &nbsp;
<% } // end if %> <% } // end if %>
<% } // end if %> <% } // end if %>
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator()) %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp;
</TD> </TD>
</TR>
<TR VALIGN=BOTTOM>
<TD>&nbsp;</TD>
<TD NOWRAP ALIGN=RIGHT CLASS="content"> <TD NOWRAP ALIGN=RIGHT CLASS="content">
<% if (rdat.useHTMLComments()) { %><!-- Topic admin controls section --><% } %> <% if (rdat.useHTMLComments()) { %><!-- Topic admin controls section --><% } %>
<% if (data.canFreezeTopic()) { %> <% if (data.canFreezeTopic()) { %>
@ -103,7 +109,6 @@
<% } // end if %> <% } // end if %>
</TD> </TD>
</TR> </TR>
<TR><TD COLSPAN=2>&nbsp;</TD></TR>
<TR VALIGN=BOTTOM> <TR VALIGN=BOTTOM>
<TD NOWRAP ALIGN=LEFT CLASS="content"> <TD NOWRAP ALIGN=LEFT CLASS="content">
<% if (rdat.useHTMLComments()) { %><!-- Go box --><% } %> <% if (rdat.useHTMLComments()) { %><!-- Go box --><% } %>
@ -159,7 +164,7 @@
<% if (data.showAdvanced()) { %> <% if (data.showAdvanced()) { %>
<BR> <BR>
<TABLE WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=TOP><TD NOWRAP ALIGN=LEFT CLASS="content"> <TABLE WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=TOP><TD NOWRAP ALIGN=LEFT CLASS="content">
<% } // end if %> <% } // end if (showing advanced controls) %>
<%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %> <%= rdat.getStdFontTag(ColorSelectors.CONTENT_FOREGROUND,2) %>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1=" <A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
+ msg.getPostNumber()) %>"><%= msg.getPostNumber() %></A> of + msg.getPostNumber()) %>"><%= msg.getPostNumber() %></A> of
@ -168,26 +173,40 @@
<% if (data.showAdvanced() && msg.isHidden()) { %> <% if (data.showAdvanced() && msg.isHidden()) { %>
<B><EM>(Hidden)</EM></B> <B><EM>(Hidden)</EM></B>
<% } // end if %> <% } // end if %>
<BR> <% if (data.showAdvanced() && data.showBozoFilteredIndicator(msg.getCreatorUID())) { %>
<B><%= msg.getPseud() %></B> <B><EM>(User filtered;
(<EM> <A HREF="<%= rdat.getEncodedServletPath("postops?" + data.getLocator() + "&msg="
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>, + msg.getPostNumber() + "&cmd=BN") %>">remove filter</A>)
<%= rdat.formatDateForDisplay(msg.getPostDate()) %> </EM></B>
</EM>)
<% if (msg.hasAttachment()) { %>
<A HREF="<%= rdat.getEncodedServletPath("attachment?" + data.getConfLocator() + "&msg="
+ msg.getPostID()) %>"
<% if (data.displayAttachmentInNewWindow(msg)) { %>TARGET="_blank"<% } %> ><IMG
SRC="<%= rdat.getFullImagePath("attachment.gif") %>"
ALT="(Attachment <%= msg.getAttachmentFilename() %> - <%= msg.getAttachmentLength() %> bytes)"
WIDTH=16 HEIGHT=16 BORDER=0></A>
<% } // end if %> <% } // end if %>
<% if (!(data.bozoFilterUser(msg.getCreatorUID()))) { %>
<BR>
<B><%= msg.getPseud() %></B>
(<EM>
<A HREF="<%= rdat.getEncodedServletPath("user/" + poster) %>" TARGET="_blank"><%= poster %></A>,
<%= rdat.formatDateForDisplay(msg.getPostDate()) %>
</EM>)
<% if (msg.hasAttachment()) { %>
<A HREF="<%= rdat.getEncodedServletPath("attachment?" + data.getConfLocator() + "&msg="
+ msg.getPostID()) %>"
<% if (data.displayAttachmentInNewWindow(msg)) { %>TARGET="_blank"<% } %> ><IMG
SRC="<%= rdat.getFullImagePath("attachment.gif") %>"
ALT="(Attachment <%= msg.getAttachmentFilename() %> - <%= msg.getAttachmentLength() %> bytes)"
WIDTH=16 HEIGHT=16 BORDER=0></A>
<% } // end if %>
<% } // end if (message not bozo-filtered) %>
</FONT><P><FONT COLOR="<%= rdat.getStdColor(ColorSelectors.CONTENT_FOREGROUND) %>"> </FONT><P><FONT COLOR="<%= rdat.getStdColor(ColorSelectors.CONTENT_FOREGROUND) %>">
<% if (msg.isScribbled()) { %> <% if (msg.isScribbled()) { %>
<SPAN CLASS="post"><TT><EM><B> <SPAN CLASS="post"><TT><EM><B>
(Scribbled by <%= data.getMessageBodyText(msg) %> on (Scribbled by <%= data.getMessageBodyText(msg) %> on
<%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>) <%= rdat.formatDateForDisplay(msg.getScribbleDate()) %>)
</B></EM></TT></SPAN><P> </B></EM></TT></SPAN><P>
<% } else if (data.bozoFilterUser(msg.getCreatorUID())) { %>
<SPAN CLASS="post"><TT><EM><B>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&nbz=1&p1="
+ msg.getPostNumber()) %>">(Message from Filtered User:
<%= msg.getNumLines() %> <% if (msg.getNumLines()==1) { %>Line<% } else { %>Lines<% } %>)</A>
</B></EM></TT></SPAN><P>
<% } else if (msg.isHidden() && !(data.showAdvanced())) { %> <% } else if (msg.isHidden() && !(data.showAdvanced())) { %>
<SPAN CLASS="post"><TT><EM><B> <SPAN CLASS="post"><TT><EM><B>
<A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1=" <A HREF="<%= rdat.getEncodedServletPath("confdisp?" + data.getLocator() + "&shac=1&p1="
@ -217,6 +236,11 @@
BORDER=0></A><P> BORDER=0></A><P>
<% } // end if (can scribble) %> <% } // end if (can scribble) %>
<% } // end if (not already scribbled) %> <% } // end if (not already scribbled) %>
<% if (data.showFilterButton(msg.getCreatorUID())) { %>
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=BY") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_filter_user.gif") %>" ALT="Filter User" WIDTH=80 HEIGHT=24
BORDER=0></A><P>
<% } // end if (can bozo filter) %>
<% if (msg.canNuke()) { %> <% if (msg.canNuke()) { %>
<A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=NUKE") %>"><IMG <A HREF="<%= rdat.getEncodedServletPath("postops?" + po_loc + "&cmd=NUKE") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_nuke.gif") %>" ALT="Nuke" WIDTH=80 HEIGHT=24 SRC="<%= rdat.getFullImagePath("bn_nuke.gif") %>" ALT="Nuke" WIDTH=80 HEIGHT=24
@ -290,6 +314,9 @@
&nbsp; &nbsp;
<% } // end if %> <% } // end if %>
<% } // end if %> <% } // end if %>
<A HREF="<%= rdat.getEncodedServletPath("topicops?" + data.getLocator()) %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp;
</TD> </TD>
<TD NOWRAP ALIGN=RIGHT>&nbsp;</TD> <TD NOWRAP ALIGN=RIGHT>&nbsp;</TD>
</TR> </TR>

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 B