Implemented partial support for conference hotlists ("Add To Hotlist"

button, Conferences sidebox).
This commit is contained in:
Eric J. Bowersox 2001-02-17 06:51:40 +00:00
parent bda25d9aa2
commit 7b7e6be996
16 changed files with 424 additions and 57 deletions

16
TODO
View File

@ -12,6 +12,16 @@ Lots!
- There's no system admin functionality AT ALL. We need to have this stuff - There's no system admin functionality AT ALL. We need to have this stuff
before we go live. (It plugs into the Administrative SIG features.) before we go live. (It plugs into the Administrative SIG features.)
- Unimplemented functions on the Top page:
Manage SIG list (SIG sidebox)
Manage Conference Hotlist (Conference sidebox)
Customize Sideboxes
- The plan for the "main" part of the Top page is to let a sysadmin put
notices there by "publishing" selected conference messages to the front page.
We may include a welcome message up top to be displayed if the user's not
logged in.
- Implement quick e-mail from the user profile display (engine support and - Implement quick e-mail from the user profile display (engine support and
UI). UI).
@ -23,14 +33,12 @@ Lots!
- Slippage during posting is still untested. - Slippage during posting is still untested.
- Functions still to do on conferencing "topics" page:
Add Conference To Hotlist
- We need a "manage" button at conference list level so we can use that to - We need a "manage" button at conference list level so we can use that to
manage the ordering of conferences. This operation should be accessible manage the ordering of conferences. This operation should be accessible
only to users with "create" privilege on the SIG. only to users with "create" privilege on the SIG.
- Implement conference hotlist for users. - Conference hotlist is now partially implemented, but we need some more work
at engine level.
- Not everybody likes purple. Provide a way to change the default colors. - Not everybody likes purple. Provide a way to change the default colors.
Probably via entries in render-config.xml. Of course, if we go to a Probably via entries in render-config.xml. Of course, if we go to a

Binary file not shown.

Before

Width:  |  Height:  |  Size: 685 B

View File

@ -1325,6 +1325,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
# new users. # new users.
INSERT INTO sideboxes (uid, boxid, sequence, param) INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (1, 1, 100, NULL), (1, 2, 200, NULL); VALUES (1, 1, 100, NULL), (1, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (1, 100, 2, 2);
# Add the 'Administrator' user to the users table. # Add the 'Administrator' user to the users table.
# (UID = 2, CONTACTID = 2) # (UID = 2, CONTACTID = 2)
@ -1337,6 +1339,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
# Create the default view for Administrator. # Create the default view for Administrator.
INSERT INTO sideboxes (uid, boxid, sequence, param) INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (2, 1, 100, NULL), (2, 2, 200, NULL); VALUES (2, 1, 100, NULL), (2, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (2, 100, 2, 2);
# Add the administration SIG to the SIGs table. # Add the administration SIG to the SIGs table.
# (SIGID = 1, CONTACTID = 3) # (SIGID = 1, CONTACTID = 3)
@ -1432,6 +1436,8 @@ INSERT INTO contacts (contactid, given_name, family_name, locality, region, pcod
VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3); VALUES (5, 'Test', 'User', 'Denver', 'CO', '80231', 'US', 'testuser@example.com', 3);
INSERT INTO sideboxes (uid, boxid, sequence, param) INSERT INTO sideboxes (uid, boxid, sequence, param)
VALUES (3, 1, 100, NULL), (3, 2, 200, NULL); VALUES (3, 1, 100, NULL), (3, 2, 200, NULL);
INSERT INTO confhotlist (uid, sequence, sigid, confid)
VALUES (3, 100, 2, 2);
INSERT INTO sigmember (sigid, uid, granted_lvl, locked) INSERT INTO sigmember (sigid, uid, granted_lvl, locked)
VALUES (2, 3, 6500, 1); VALUES (2, 3, 6500, 1);

View File

@ -141,4 +141,12 @@ public interface ConferenceContext
public abstract boolean canDeleteConference(); public abstract boolean canDeleteConference();
public abstract boolean isInHotlist();
public abstract void addToHotlist() throws DataException;
public abstract boolean canAddToHotlist();
public abstract SIGContext getEnclosingSIG();
} // end interface ConferenceContext } // end interface ConferenceContext

View File

@ -0,0 +1,26 @@
/*
* 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;
public interface ConferenceHotlistEntry
{
public abstract ConferenceContext getConference();
public abstract int getSequence();
} // end interface ConferenceHotlistEntry

View File

@ -87,4 +87,6 @@ public interface UserContext extends SearchMode
public abstract List getSideBoxList() throws DataException; public abstract List getSideBoxList() throws DataException;
public abstract List getConferenceHotlist() throws DataException;
} // end interface UserContext } // end interface UserContext

View File

@ -116,6 +116,37 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end class FixSeenHelper } // end class FixSeenHelper
/*--------------------------------------------------------------------------------
* Static class used to return hot list entries
*--------------------------------------------------------------------------------
*/
static class MyHotlist implements ConferenceHotlistEntry
{
private ConferenceContext conf;
private int seq;
MyHotlist(ConferenceContext conf, int seq)
{
this.conf = conf;
this.seq = seq;
} // end constructor
public ConferenceContext getConference()
{
return conf;
} // end getConference
public int getSequence()
{
return seq;
} // end getSequence
} // end class MyHotlist
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Static data members * Static data members
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -515,8 +546,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (post>create) if (post>create)
{ // Post level should be no greater than Create { // Post level should be no greater than Create
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Post level (" + String.valueOf(post) + ") was greater than create level (" logger.debug("Post level (" + post + ") was greater than create level (" + create + "), correcting");
+ String.valueOf(create) + "), correcting");
post = create; post = create;
} // end if } // end if
@ -524,8 +554,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (read>post) if (read>post)
{ // Read level should be no greater than Post { // Read level should be no greater than Post
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Read level (" + String.valueOf(read) + ") was greater than post level (" logger.debug("Read level (" + read + ") was greater than post level (" + post + "), correcting");
+ String.valueOf(post) + "), correcting");
read = post; read = post;
} // end if } // end if
@ -533,8 +562,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (change>delete) if (change>delete)
{ // Change level should be no greater than Delete { // Change level should be no greater than Delete
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Change level (" + String.valueOf(change) + ") was greater than delete level (" logger.debug("Change level (" + change + ") was greater than delete level (" + delete
+ String.valueOf(delete) + "), correcting"); + "), correcting");
change = delete; change = delete;
} // end if } // end if
@ -542,8 +571,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (nuke>delete) if (nuke>delete)
{ // Nuke level should be no greater than Delete { // Nuke level should be no greater than Delete
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Nuke level (" + String.valueOf(nuke) + ") was greater than delete level (" logger.debug("Nuke level (" + nuke + ") was greater than delete level (" + delete + "), correcting");
+ String.valueOf(delete) + "), correcting");
nuke = delete; nuke = delete;
} // end if } // end if
@ -551,8 +579,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
if (hide>nuke) if (hide>nuke)
{ // Hide level should be no greater than Nuke { // Hide level should be no greater than Nuke
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Hide level (" + String.valueOf(hide) + ") was greater than nuke level (" logger.debug("Hide level (" + hide + ") was greater than nuke level (" + nuke + "), correcting");
+ String.valueOf(nuke) + "), correcting");
hide = nuke; hide = nuke;
} // end if } // end if
@ -791,7 +818,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
public boolean anyUnread() public boolean anyUnread()
{ {
if (deleted) if (deleted || sig.userIsAnonymous())
return false; return false;
Connection conn = null; // pooled database connection Connection conn = null; // pooled database connection
@ -1228,6 +1255,110 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end canDeleteConference } // end canDeleteConference
public boolean isInHotlist()
{
Connection conn = null;
try
{ // retrieve a connection from the datapool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// do a quickie query
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
sql.append(confid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
return rs.next();
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error checking hotlist: " + e.getMessage(),e);
return false;
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end isInHotlist
public void addToHotlist() throws DataException
{
Connection conn = null;
try
{ // retrieve a connection from the datapool
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
stmt.executeUpdate("LOCK TABLES confhotlist WRITE;");
try
{ // do a quickie query to see if we're already in the hotlist
StringBuffer sql = new StringBuffer("SELECT sequence FROM confhotlist WHERE uid = ");
sql.append(sig.realUID()).append(" AND sigid = ").append(sig.realSIGID()).append(" AND confid = ");
sql.append(confid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (rs.next())
return; // already in hotlist - this is a no-op
// find a sequence number for the new entry
sql.setLength(0);
sql.append("SELECT MAX(sequence) FROM confhotlist WHERE uid = ").append(sig.realUID()).append(';');
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new InternalStateError("bogus query result on addToHotlist");
int new_sequence = rs.getInt(1) + 100;
// add the new record
sql.setLength(0);
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES (").append(sig.realUID());
sql.append(", ").append(new_sequence).append(", ").append(sig.realSIGID()).append(", ");
sql.append(confid).append(");");
stmt.executeUpdate(sql.toString());
} // end try
finally
{ // make sure the table is unlocked before we go
Statement ulk_stmt = conn.createStatement();
ulk_stmt.executeUpdate("UNLOCK TABLES;");
} // end finally
} // end try
catch (SQLException e)
{ // this becomes a DataException
logger.error("DB error adding to hotlist: " + e.getMessage(),e);
throw new DataException("error adding to hotlist: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
} // end addToHotList
public boolean canAddToHotlist()
{
if (sig.userIsAnonymous())
return false;
return !(isInHotlist());
} // end canAddToHotlist
public SIGContext getEnclosingSIG()
{
return sig.selfSIG();
} // end getEnclosingSIG
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface UserBackend * Implementations from interface UserBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -1268,6 +1399,12 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public SIGContext selfSIG()
{
return sig.selfSIG();
} // end selfsig;
public int realSIGID() public int realSIGID()
{ {
return sig.realSIGID(); return sig.realSIGID();
@ -1468,8 +1605,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
static List getSIGConferences(EngineBackend engine, SIGBackend sig, DataPool datapool) throws DataException static List getSIGConferences(EngineBackend engine, SIGBackend sig, DataPool datapool) throws DataException
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("getSIGConferences for SIG # " + String.valueOf(sig.realSIGID()) + ", user #" logger.debug("getSIGConferences for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
+ String.valueOf(sig.realUID()));
Vector rc = new Vector(); // return from this function Vector rc = new Vector(); // return from this function
Connection conn = null; // pooled database connection Connection conn = null; // pooled database connection
@ -1529,8 +1665,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
int confid) throws DataException int confid) throws DataException
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("getConference(#" + String.valueOf(confid) + ") for SIG # " logger.debug("getConference(#" + confid + ") for SIG # " + sig.realSIGID() + ", user #" + sig.realUID());
+ String.valueOf(sig.realSIGID()) + ", user #" + String.valueOf(sig.realUID()));
Connection conn = null; // pooled database connection Connection conn = null; // pooled database connection
@ -1553,8 +1688,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
// Run that monster query! // Run that monster query!
ResultSet rs = stmt.executeQuery(sql.toString()); ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next())) if (!(rs.next()))
throw new DataException("conference ID#" + String.valueOf(confid) + " not found in SIG#" throw new DataException("conference ID#" + confid + " not found in SIG#" + sig.realSIGID());
+ String.valueOf(sig.realSIGID()));
// pass back the new object // pass back the new object
return new ConferenceUserContextImpl(engine,sig,datapool,confid,rs.getString(2), return new ConferenceUserContextImpl(engine,sig,datapool,confid,rs.getString(2),
@ -1581,8 +1715,8 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
String alias) throws DataException String alias) throws DataException
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("getConference(\"" + alias + "\") for SIG # " + String.valueOf(sig.realSIGID()) logger.debug("getConference(\"" + alias + "\") for SIG # " + sig.realSIGID() + ", user #"
+ ", user #" + String.valueOf(sig.realUID())); + sig.realUID());
Connection conn = null; // pooled database connection Connection conn = null; // pooled database connection
@ -1607,8 +1741,7 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
// Run that monster query! // Run that monster query!
ResultSet rs = stmt.executeQuery(sql.toString()); ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next())) if (!(rs.next()))
throw new DataException("conference \"" + alias + "\" not found in SIG#" throw new DataException("conference \"" + alias + "\" not found in SIG#" + sig.realSIGID());
+ String.valueOf(sig.realSIGID()));
// pass back the new object // pass back the new object
return new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(1),rs.getString(3),rs.getString(4), return new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(1),rs.getString(3),rs.getString(4),
@ -1630,4 +1763,77 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
} // end getConference } // end getConference
static List getUserHotlist(EngineBackend engine, UserBackend user, DataPool datapool) throws DataException
{
if (logger.isDebugEnabled())
logger.debug("getUserHotlist for user #" + user.realUID());
Connection conn = null; // pooled database connection
Vector rc = new Vector(); // return from this function
try
{ // get a database connection
conn = datapool.getConnection();
Statement stmt = conn.createStatement();
// Build a monster query! We pull the SIGID and ConfID entries from the confhotlist table,
// but we need to pull in "confs" and "confmember" (left joined) to get enough data to create
// a ConferenceUserContextImpl object.
StringBuffer sql =
new StringBuffer("SELECT h.sigid, h.confid, c.name, c.descr, c.createdate, s.granted_lvl, "
+ "f.granted_lvl, h.sequence FROM confhotlist h, sigtoconf s, confs c "
+ "LEFT JOIN confmember f ON h.confid = f.confid AND h.uid = f.uid "
+ "WHERE h.confid = s.confid AND c.confid = h.confid AND h.uid = ");
sql.append(user.realUID()).append(" ORDER BY h.sequence ASC;");
if (logger.isDebugEnabled())
logger.debug("SQL: " + sql.toString());
// Run that puppy!
ResultSet rs = stmt.executeQuery(sql.toString());
// Create some temporary data structures to assist us in building the return list.
HashMap sig_backend_cache = new HashMap();
while (rs.next())
{ // retrieve the sigid from the resultset first
Integer sigid = new Integer(rs.getInt(1));
// we need a SIG backend for our conference, so make sure we have one
SIGBackend sig = (SIGBackend)(sig_backend_cache.get(sigid));
if (sig==null)
{ // get it and make sure it's in the cache for next time
sig = SIGUserContextImpl.getSIGBackend(engine,user,datapool,conn,sigid.intValue());
sig_backend_cache.put(sigid,sig);
} // end if
// make the new ConferenceContext
ConferenceContext conf =
new ConferenceUserContextImpl(engine,sig,datapool,rs.getInt(2),rs.getString(3),rs.getString(4),
SQLUtil.getFullDateTime(rs,5),rs.getInt(6),rs.getInt(7),conn);
// and create the actual return value
ConferenceHotlistEntry hle = new MyHotlist(conf,rs.getInt(8));
rc.add(hle);
} // end while
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error reading hotlist entries: " + e.getMessage(),e);
throw new DataException("unable to retrieve hotlist information: " + e.getMessage(),e);
} // end catch
finally
{ // make sure we release the connection before we go
if (conn!=null)
datapool.releaseConnection(conn);
} // end finally
return new ReadOnlyVector(rc);
} // end getUserHotlist
} // end class ConferenceUserContextImpl } // end class ConferenceUserContextImpl

View File

@ -7,7 +7,7 @@
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License. * language governing rights and limitations under the License.
* *
* The Original Code is the Venice Web Community System. * The Original Code is the Venice Web Communities System.
* *
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>, * 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 * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
@ -18,9 +18,12 @@
package com.silverwrist.venice.core.impl; package com.silverwrist.venice.core.impl;
import com.silverwrist.venice.core.DataException; import com.silverwrist.venice.core.DataException;
import com.silverwrist.venice.core.SIGContext;
public interface SIGBackend extends UserBackend public interface SIGBackend extends UserBackend
{ {
public abstract SIGContext selfSIG();
public abstract int realSIGID(); public abstract int realSIGID();
public abstract boolean userHideHiddenConferences(); public abstract boolean userHideHiddenConferences();

View File

@ -229,6 +229,38 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end testConferenceAccess } // end testConferenceAccess
private static SIGUserContextImpl getSIGPrivate(EngineBackend engine, UserBackend user, DataPool datapool,
Connection conn, int sigid) throws DataException
{
try
{ // create the query to find the SIG in the table
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
sql.append(sigid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
{ // the SIG entry was not found
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
} // end if
// initialize the object and check membership info
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
rs.getString("alias"));
sc.checkMembership(conn);
return sc;
} // end try
catch (SQLException e)
{ // turn SQLException into data exception
logger.error("DB error reading SIG entry: " + e.getMessage(),e);
throw new DataException("unable to retrieve SIG information: " + e.getMessage(),e);
} // end catch
} // end getSIGPrivate
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from class SIGContext * Implementations from class SIGContext
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
@ -1132,6 +1164,12 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public SIGContext selfSIG()
{
return this;
} // end selfsig;
public int realSIGID() public int realSIGID()
{ {
return sigid; return sigid;
@ -1248,23 +1286,8 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
{ // get a database connection { // get a database connection
conn = datapool.getConnection(); conn = datapool.getConnection();
// create the query to find the SIG in the table // return the SIG we want
Statement stmt = conn.createStatement(); return getSIGPrivate(engine,user,datapool,conn,sigid);
StringBuffer sql = new StringBuffer("SELECT signame, alias FROM sigs WHERE sigid = ");
sql.append(sigid).append(';');
ResultSet rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
{ // the SIG entry was not found
logger.error("SIG " + String.valueOf(sigid) + " not found in database");
throw new DataException("SIG #" + String.valueOf(sigid) + " was not found in the database.");
} // end if
// initialize the object and check membership info
SIGUserContextImpl sc = new SIGUserContextImpl(engine,user,datapool,sigid,rs.getString("signame"),
rs.getString("alias"));
sc.checkMembership(conn);
return sc;
} // end try } // end try
catch (SQLException e) catch (SQLException e)
@ -1325,6 +1348,13 @@ class SIGUserContextImpl implements SIGContext, SIGBackend
} // end getSIGContext } // end getSIGContext
static SIGBackend getSIGBackend(EngineBackend engine, UserBackend user, DataPool datapool, Connection conn,
int sigid) throws DataException
{
return getSIGPrivate(engine,user,datapool,conn,sigid);
} // end getSIGBackend
static List searchForSIGs(EngineBackend engine, UserBackend user, DataPool datapool, int field, static List searchForSIGs(EngineBackend engine, UserBackend user, DataPool datapool, int field,
int mode, String term, int offset, int count) throws DataException int mode, String term, int offset, int count) throws DataException
{ {

View File

@ -862,6 +862,12 @@ class UserContextImpl implements UserContext, UserBackend
} // end getSideBoxList } // end getSideBoxList
public List getConferenceHotlist() throws DataException
{
return ConferenceUserContextImpl.getUserHotlist(engine,this,datapool);
} // end getConferenceHotlist
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Implementations from interface UserBackend * Implementations from interface UserBackend
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------

View File

@ -874,7 +874,8 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
{ // look to see if the user name is already present { // look to see if the user name is already present
conn = datapool.getConnection(); conn = datapool.getConnection();
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE;"); stmt.executeUpdate("LOCK TABLES users WRITE, userprefs WRITE, sigmember WRITE, sideboxes WRITE, "
+ "confhotlist WRITE;");
try try
{ // make sure the user name isn't there already { // make sure the user name isn't there already
ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';"); ResultSet rs = stmt.executeQuery("SELECT uid FROM users WHERE username = '" + encode_username + "';");
@ -967,6 +968,31 @@ public class VeniceEngineImpl implements VeniceEngine, EngineBackend
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("...loaded default sidebox config"); logger.debug("...loaded default sidebox config");
// get the hotlist configuration for this user
rs = stmt.executeQuery("SELECT confhotlist.sequence, confhotlist.sigid, confhotlist.confid FROM "
+ "confhotlist, users WHERE confhotlist.uid = users.uid AND users.is_anon = 1;");
sql.setLength(0);
while (rs.next())
{ // set up to insert into the confhotlist table
if (sql.length()==0)
sql.append("INSERT INTO confhotlist (uid, sequence, sigid, confid) VALUES ");
else
sql.append(", ");
sql.append('(').append(new_uid).append(", ").append(rs.getInt(1)).append(", ").append(rs.getInt(2));
sql.append(", ").append(rs.getInt(3)).append(')');
} // end while
if (sql.length()>0)
{ // execute the big update
sql.append(';');
stmt.executeUpdate(sql.toString());
} // end if
if (logger.isDebugEnabled())
logger.debug("...loaded default hotlist config");
} // end try } // end try
finally finally
{ // make sure the tables get unlocked before we go { // make sure the tables get unlocked before we go

View File

@ -326,6 +326,28 @@ public class ConfOperations extends VeniceServlet
} // end if ("M" command) } // end if ("M" command)
if (cmd.equals("H"))
{ // "H" = "Add Conference To Hotlist" (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);
on_error = "confdisp?sig=" + sig.getSIGID() + "&conf=" + conf.getConfID();
try
{ // add to the hotlist
conf.addToHotlist();
// and trap back to the conference display
throw new RedirectResult(on_error);
} // end try
catch (DataException de)
{ // something wrong in the database
return new ErrorBox("Database Error","Database error adding to hotlist: " + de.getMessage(),
on_error);
} // end catch
} // end if ("H" command)
if (cmd.equals("DEL")) if (cmd.equals("DEL"))
{ // "DEL" = "Delete Conference (requires conference parameter) { // "DEL" = "Delete Conference (requires conference parameter)
ConferenceContext conf = getConferenceParameter(request,sig,true,on_error); ConferenceContext conf = getConferenceParameter(request,sig,true,on_error);

View File

@ -19,6 +19,7 @@ package com.silverwrist.venice.servlets.format;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.core.*; import com.silverwrist.venice.core.*;
public class SideBoxConferences implements ContentRender public class SideBoxConferences implements ContentRender
@ -29,15 +30,17 @@ public class SideBoxConferences implements ContentRender
*/ */
private UserContext uc; private UserContext uc;
private List hotlist;
/*-------------------------------------------------------------------------------- /*--------------------------------------------------------------------------------
* Constructor * Constructor
*-------------------------------------------------------------------------------- *--------------------------------------------------------------------------------
*/ */
public SideBoxConferences(UserContext uc, String parameter) public SideBoxConferences(UserContext uc, String parameter) throws DataException
{ {
this.uc = uc; this.uc = uc;
this.hotlist = uc.getConferenceHotlist();
} // end constructor } // end constructor
@ -62,14 +65,34 @@ public class SideBoxConferences implements ContentRender
public void renderHere(Writer out, RenderData rdat) throws IOException public void renderHere(Writer out, RenderData rdat) throws IOException
{ {
/* BEGIN TEMP */ out.write(rdat.getStdFontTag(null,2) + "\n");
out.write("<FONT FACE=\"Arial, Helvetica\" SIZE=2><UL>\n"); if (hotlist.size()>0)
out.write("<LI>BOFH (Benevolent Dictators)</LI>\n"); { // display the list of conferences
out.write("<LI>Playground (Electric Minds)</LI>\n"); out.write("<TABLE ALIGN=CENTER BORDER=0 CELLPADDING=0 CELLSPACING=2>\n");
out.write("<LI>Commons (Electric Minds)</LI>\n"); Iterator it = hotlist.iterator();
out.write("<LI>Top Ten Lists (Pamela's Lounge)</LI>\n"); while (it.hasNext())
out.write("</UL></FONT>\n"); { // display the names of the conferences and SIGs one by one
/* END TEMP */ ConferenceHotlistEntry hle = (ConferenceHotlistEntry)(it.next());
ConferenceContext conf = hle.getConference();
String href = "confdisp?sig=" + conf.getEnclosingSIG().getSIGID() + "&conf=" + conf.getConfID();
out.write("<TR VALIGN=MIDDLE>\n<TD ALIGN=CENTER WIDTH=14><IMG SRC=\""
+ rdat.getFullImagePath("purple-ball.gif")
+ "\" ALT=\"*\" WIDTH=14 HEIGHT=14 BORDER=0></TD>\n");
out.write("<TD ALIGN=LEFT>\n" + rdat.getStdFontTag(null,2) + "<B><A HREF=\""
+ rdat.getEncodedServletPath(href) + "\">" + StringUtil.encodeHTML(conf.getName())
+ "</A></B> (" + StringUtil.encodeHTML(conf.getEnclosingSIG().getName()) + ")</FONT>\n");
if (conf.anyUnread())
out.write("&nbsp;<IMG SRC=\"" + rdat.getFullImagePath("tag_new.gif")
+ "\" ALT=\"New!\" BORDER=0 WIDTH=40 HEIGHT=20>\n");
out.write("</TD>\n</TR>\n");
} // end while
out.write("</TABLE>\n");
} // end if
else
out.write(rdat.getStdFontTag(null,2) + "<EM>You have no conferences in your hotlist.</EM></FONT>\n");
// write the link at the end // write the link at the end
out.write("<P>" + rdat.getStdFontTag(null,1) + "<B>[ <A HREF=\"" + rdat.getEncodedServletPath("TODO") out.write("<P>" + rdat.getStdFontTag(null,1) + "<B>[ <A HREF=\"" + rdat.getEncodedServletPath("TODO")

View File

@ -154,7 +154,7 @@ public class TopicListing implements JSPRender
public boolean canAddToHotlist() public boolean canAddToHotlist()
{ {
return false; // TODO: fix this return conf.canAddToHotlist();
} // end canAddToHotlist } // end canAddToHotlist

View File

@ -44,12 +44,13 @@
SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24 SRC="<%= rdat.getFullImagePath("bn_read_new.gif") %>" ALT="Read New" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp; BORDER=0></A>&nbsp;
<% } // end if %> <% } // end if %>
<A HREF="<%= "confops?" + data.getLocator() + "&cmd=Q" %>"><IMG <A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=Q") %>"><IMG
SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24 SRC="<%= rdat.getFullImagePath("bn_manage.gif") %>" ALT="Manage" WIDTH=80 HEIGHT=24
BORDER=0></A>&nbsp; BORDER=0></A>&nbsp;
<% if (data.canAddToHotlist()) { %> <% if (data.canAddToHotlist()) { %>
<A HREF="TODO"><IMG SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>" <A HREF="<%= rdat.getEncodedServletPath("confops?" + data.getLocator() + "&cmd=H") %>"><IMG
ALT="Add to HotList" WIDTH=80 HEIGHT=24 BORDER=0></A>&nbsp; SRC="<%= rdat.getFullImagePath("bn_add_to_hotlist.gif") %>" ALT="Add to HotList" WIDTH=80
HEIGHT=24 BORDER=0></A>&nbsp;
<% } // end if %> <% } // end if %>
</DIV> </DIV>
<% if (data.anyTopics()) { %> <% if (data.anyTopics()) { %>

BIN
web/images/tag_new.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B