added some safeguards for the mail to community members/conference
participants: to wit, any user can opt-out from ALL those mailings with one setting; each message now carries a standard disKlaimer indicating how the user can opt-out (and it's REAL opt-out, not this fakey stuff the spammers do)
This commit is contained in:
		
							parent
							
								
									e35045acf4
								
							
						
					
					
						commit
						9cc34facf6
					
				@ -485,6 +485,55 @@ click the "Manage" button, and click the "Stop Subscribing To This Topic" link.
 | 
			
		||||
    <!-- Parameters: message.poster, topic.name, topic.locator, conference.name, community.name -->
 | 
			
		||||
    <subj-mail-post>New Post in ${topic.name}</subj-mail-post>
 | 
			
		||||
 | 
			
		||||
    <!-- Mass mail notification reminder for communities -->
 | 
			
		||||
    <!-- Parameters: community.name -->
 | 
			
		||||
    <mass-community-notice><![CDATA[
 | 
			
		||||
You are receiving this message because you are a member of the Venice community "${community.name}".
 | 
			
		||||
The sender is a host of this community.  To stop receiving mass E-mailed notices from all
 | 
			
		||||
Venice community and conference hosts, visit Venice, click on the "Profile" link, check the box labeled
 | 
			
		||||
"Don't send me mass E-mail from community/conference hosts," and click Update to save this preference.
 | 
			
		||||
    ]]></mass-community-notice>
 | 
			
		||||
 | 
			
		||||
    <!-- Mass mail notification reminder for conference posters -->
 | 
			
		||||
    <!-- Parameters: community.name, conference.name -->
 | 
			
		||||
    <mass-conference-notice-poster><![CDATA[
 | 
			
		||||
You are receiving this message because you are a participant in the "${conference.name}" conference
 | 
			
		||||
in the Venice community "${community.name}".  The sender is a host of this conference.  To stop receiving
 | 
			
		||||
mass E-mailed notices from all Venice community and conference hosts, visit Venice, click on the "Profile"
 | 
			
		||||
link, check the box labeled "Don't send me mass E-mail from community/conference hosts," and click Update
 | 
			
		||||
to save this preference.
 | 
			
		||||
    ]]></mass-conference-notice-poster>
 | 
			
		||||
 | 
			
		||||
    <!-- Mass mail notification reminder for conference readers -->
 | 
			
		||||
    <!-- Parameters: community.name, conference.name -->
 | 
			
		||||
    <mass-conference-notice-reader><![CDATA[
 | 
			
		||||
You are receiving this message because you are a reader of the "${conference.name}" conference
 | 
			
		||||
in the Venice community "${community.name}".  The sender is a host of this conference.  To stop receiving
 | 
			
		||||
mass E-mailed notices from all Venice community and conference hosts, visit Venice, click on the "Profile"
 | 
			
		||||
link, check the box labeled "Don't send me mass E-mail from community/conference hosts," and click Update
 | 
			
		||||
to save this preference.
 | 
			
		||||
    ]]></mass-conference-notice-reader>
 | 
			
		||||
 | 
			
		||||
    <!-- Mass mail notification reminder for topic posters -->
 | 
			
		||||
    <!-- Parameters: community.name, conference.name, topic.name -->
 | 
			
		||||
    <mass-topic-notice-poster><![CDATA[
 | 
			
		||||
You are receiving this message because you are a participant in the "${topic.name}" topic in the
 | 
			
		||||
"${conference.name}" conference in the Venice community "${community.name}".  The sender is a host of the
 | 
			
		||||
"${conference.name}" conference.  To stop receiving mass E-mailed notices from all Venice community and
 | 
			
		||||
conference hosts, visit Venice, click on the "Profile" link, check the box labeled "Don't send me mass
 | 
			
		||||
E-mail from community/conference hosts," and click Update to save this preference.
 | 
			
		||||
    ]]></mass-topic-notice-poster>
 | 
			
		||||
 | 
			
		||||
    <!-- Mass mail notification reminder for topic readers -->
 | 
			
		||||
    <!-- Parameters: community.name, conference.name, topic.name -->
 | 
			
		||||
    <mass-topic-notice-reader><![CDATA[
 | 
			
		||||
You are receiving this message because you are a reader of the "${topic.name}" topic in the
 | 
			
		||||
"${conference.name}" conference in the Venice community "${community.name}".  The sender is a host of the
 | 
			
		||||
"${conference.name}" conference.  To stop receiving mass E-mailed notices from all Venice community and
 | 
			
		||||
conference hosts, visit Venice, click on the "Profile" link, check the box labeled "Don't send me mass
 | 
			
		||||
E-mail from community/conference hosts," and click Update to save this preference.
 | 
			
		||||
    ]]></mass-topic-notice-reader>
 | 
			
		||||
 | 
			
		||||
  </messages>
 | 
			
		||||
 | 
			
		||||
</venice-config>
 | 
			
		||||
 | 
			
		||||
@ -257,4 +257,17 @@ public class OptionSet extends BitSet
 | 
			
		||||
 | 
			
		||||
  } // end asString
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * External static operations
 | 
			
		||||
   *--------------------------------------------------------------------------------
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  public static final char getOptionChar(int index)
 | 
			
		||||
  {
 | 
			
		||||
    if ((index<0) || (index>=ALPHA.length()))
 | 
			
		||||
      throw new IndexOutOfBoundsException();
 | 
			
		||||
    return ALPHA.charAt(index);
 | 
			
		||||
 | 
			
		||||
  } // end getOptionChar
 | 
			
		||||
 | 
			
		||||
} // end class OptionSet
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ public class UserProperties
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  private boolean display_post_pictures;
 | 
			
		||||
  private boolean mass_mail_opt_out;
 | 
			
		||||
 | 
			
		||||
  /*--------------------------------------------------------------------------------
 | 
			
		||||
   * Constructor
 | 
			
		||||
@ -34,6 +35,7 @@ public class UserProperties
 | 
			
		||||
  public UserProperties()
 | 
			
		||||
  {
 | 
			
		||||
    display_post_pictures = false;
 | 
			
		||||
    mass_mail_opt_out = false;
 | 
			
		||||
 | 
			
		||||
  } // end constructor
 | 
			
		||||
 | 
			
		||||
@ -54,4 +56,16 @@ public class UserProperties
 | 
			
		||||
 | 
			
		||||
  } // end setDisplayPostPictures
 | 
			
		||||
 | 
			
		||||
  public final boolean getMassMailOptOut()
 | 
			
		||||
  {
 | 
			
		||||
    return mass_mail_opt_out;
 | 
			
		||||
 | 
			
		||||
  } // end getMassMailOptOut
 | 
			
		||||
 | 
			
		||||
  public final void setMassMailOptOut(boolean b)
 | 
			
		||||
  {
 | 
			
		||||
    mass_mail_opt_out = b;
 | 
			
		||||
 | 
			
		||||
  } // end setMassMailOptOut
 | 
			
		||||
 | 
			
		||||
} // end class UserProperties
 | 
			
		||||
 | 
			
		||||
@ -144,6 +144,7 @@ class AdminUserContextImpl implements AdminUserContext
 | 
			
		||||
    AdminUserProperties rc = new AdminUserProperties();
 | 
			
		||||
    rc.setDisplayPostPictures(flags.get(UserContextImpl.BF_POSTPICTURES));
 | 
			
		||||
    rc.setDisallowPhoto(flags.get(UserContextImpl.BF_ADM_NOPHOTO));
 | 
			
		||||
    rc.setMassMailOptOut(flags.get(UserContextImpl.BF_MASSMAIL_OPTOUT));
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end createProperties
 | 
			
		||||
@ -156,6 +157,8 @@ class AdminUserContextImpl implements AdminUserContext
 | 
			
		||||
      rc.set(UserContextImpl.PROP_FLAGS);
 | 
			
		||||
    if (flags.assign(UserContextImpl.BF_ADM_NOPHOTO,props.getDisallowPhoto()))
 | 
			
		||||
      rc.set(UserContextImpl.PROP_FLAGS);
 | 
			
		||||
    if (flags.assign(UserContextImpl.BF_MASSMAIL_OPTOUT,props.getMassMailOptOut()))
 | 
			
		||||
      rc.set(UserContextImpl.PROP_FLAGS);
 | 
			
		||||
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1838,9 +1838,11 @@ class CommunityCoreData implements CommunityData, CommunityDataBackend
 | 
			
		||||
 | 
			
		||||
      // create the SQL statement
 | 
			
		||||
      StringBuffer sql =
 | 
			
		||||
	  new StringBuffer("SELECT c.email FROM contacts c, users u, sigmember m "
 | 
			
		||||
	  new StringBuffer("SELECT c.email FROM contacts c, users u, sigmember m, propuser p "
 | 
			
		||||
			   + "WHERE c.contactid = u.contactid AND u.uid = m.uid AND m.sigid = ");
 | 
			
		||||
      sql.append(cid).append(" AND u.is_anon = 0;");
 | 
			
		||||
      sql.append(cid).append(" AND u.is_anon = 0 AND p.uid = u.uid AND p.ndx = ");
 | 
			
		||||
      sql.append(UserContextImpl.PROP_FLAGS).append(" AND p.data NOT LIKE '%");
 | 
			
		||||
      sql.append(OptionSet.getOptionChar(UserContextImpl.BF_MASSMAIL_OPTOUT)).append("%';");
 | 
			
		||||
      if (logger.isDebugEnabled())
 | 
			
		||||
	logger.debug("SQL: " + sql.toString());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1378,9 +1378,16 @@ class CommunityUserContextImpl implements CommunityContext, CommunityBackend
 | 
			
		||||
    // get the mailing list
 | 
			
		||||
    List mail_list = getData().getMassMailList();
 | 
			
		||||
    if (mail_list.size()>0)
 | 
			
		||||
    { // send the mail in the background!
 | 
			
		||||
    { // prepare the E-mail message text; append the disKlaimer at the end
 | 
			
		||||
      HashMap vars = new HashMap();
 | 
			
		||||
      vars.put("community.name",env.getCommunityName());
 | 
			
		||||
      String disklaimer = env.getStockMessage("mass-community-notice");
 | 
			
		||||
      StringBuffer buf = new StringBuffer(text);
 | 
			
		||||
      buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
 | 
			
		||||
 | 
			
		||||
      // send the mail in the background!
 | 
			
		||||
      MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(),
 | 
			
		||||
					  mail_list,subject,text);
 | 
			
		||||
					  mail_list,subject,buf.toString());
 | 
			
		||||
      agent.start();
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
@ -1528,8 +1528,11 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
 | 
			
		||||
	sql.append("s.last_post");
 | 
			
		||||
      else
 | 
			
		||||
	sql.append("s.last_read");
 | 
			
		||||
      sql.append(" FROM contacts c, users u, confsettings s WHERE c.contactid = u.contactid "
 | 
			
		||||
		 + "AND u.uid = s.uid AND s.confid = ").append(confid).append(" AND u.is_anon = 0 AND ");
 | 
			
		||||
      sql.append(" FROM contacts c, users u, confsettings s, propuser p WHERE c.contactid = u.contactid "
 | 
			
		||||
		 + "AND u.uid = s.uid AND s.confid = ").append(confid);
 | 
			
		||||
      sql.append(" AND u.is_anon = 0 AND u.uid = p.uid AND p.ndx = ").append(UserContextImpl.PROP_FLAGS);
 | 
			
		||||
      sql.append(" AND p.data NOT LIKE '%");
 | 
			
		||||
      sql.append(OptionSet.getOptionChar(UserContextImpl.BF_MASSMAIL_OPTOUT)).append("%' AND ");
 | 
			
		||||
      if (posters)
 | 
			
		||||
	sql.append("ISNULL(s.last_post) = 0 ORDER BY s.last_post DESC;");
 | 
			
		||||
      else
 | 
			
		||||
@ -1570,9 +1573,18 @@ class ConferenceUserContextImpl implements ConferenceContext, ConferenceBackend
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    if (rc.size()>0)
 | 
			
		||||
    { // send the actual E-mail messages in the background
 | 
			
		||||
    { // prepare the E-mail message text; append the disKlaimer at the end
 | 
			
		||||
      HashMap vars = new HashMap();
 | 
			
		||||
      vars.put("community.name",env.getCommunityName());
 | 
			
		||||
      vars.put("conference.name",env.getConferenceName());
 | 
			
		||||
      String disklaimer =
 | 
			
		||||
	  env.getStockMessage(posters ? "mass-conference-notice-poster" : "mass-conference-notice-reader");
 | 
			
		||||
      StringBuffer buf = new StringBuffer(text);
 | 
			
		||||
      buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
 | 
			
		||||
 | 
			
		||||
      // send the actual E-mail messages in the background
 | 
			
		||||
      MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(),
 | 
			
		||||
					  rc,subject,text);
 | 
			
		||||
					  rc,subject,buf.toString());
 | 
			
		||||
      agent.start();
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
@ -20,6 +20,7 @@ package com.silverwrist.venice.core.impl;
 | 
			
		||||
import java.sql.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
import org.apache.log4j.*;
 | 
			
		||||
import com.silverwrist.util.OptionSet;
 | 
			
		||||
import com.silverwrist.util.StringUtil;
 | 
			
		||||
import com.silverwrist.venice.core.*;
 | 
			
		||||
import com.silverwrist.venice.core.internals.*;
 | 
			
		||||
@ -1343,8 +1344,11 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
	sql.append("s.last_post");
 | 
			
		||||
      else
 | 
			
		||||
	sql.append("s.last_read");
 | 
			
		||||
      sql.append(" FROM contacts c, users u, topicsettings s WHERE c.contactid = u.contactid "
 | 
			
		||||
		 + "AND u.uid = s.uid AND s.topicid = ").append(topicid).append(" AND u.is_anon = 0 AND ");
 | 
			
		||||
      sql.append(" FROM contacts c, users u, topicsettings s, propuser p WHERE c.contactid = u.contactid "
 | 
			
		||||
		 + "AND u.uid = s.uid AND s.topicid = ").append(topicid);
 | 
			
		||||
      sql.append(" AND u.is_anon = 0 AND u.uid = p.uid AND p.ndx = ").append(UserContextImpl.PROP_FLAGS);
 | 
			
		||||
      sql.append(" AND p.data NOT LIKE '%");
 | 
			
		||||
      sql.append(OptionSet.getOptionChar(UserContextImpl.BF_MASSMAIL_OPTOUT)).append("%' AND ");
 | 
			
		||||
      if (posters)
 | 
			
		||||
	sql.append("ISNULL(s.last_post) = 0 ORDER BY s.last_post DESC;");
 | 
			
		||||
      else
 | 
			
		||||
@ -1385,9 +1389,19 @@ class TopicUserContextImpl implements TopicContext
 | 
			
		||||
    } // end finally
 | 
			
		||||
 | 
			
		||||
    if (rc.size()>0)
 | 
			
		||||
    { // send the actual E-mail messages in the background
 | 
			
		||||
    { // prepare the E-mail message text; append the disKlaimer at the end
 | 
			
		||||
      HashMap vars = new HashMap();
 | 
			
		||||
      vars.put("community.name",env.getCommunityName());
 | 
			
		||||
      vars.put("conference.name",env.getConferenceName());
 | 
			
		||||
      vars.put("topic.name",name);
 | 
			
		||||
      String disklaimer =
 | 
			
		||||
	  env.getStockMessage(posters ? "mass-topic-notice-poster" : "mass-topic-notice-reader");
 | 
			
		||||
      StringBuffer buf = new StringBuffer(text);
 | 
			
		||||
      buf.append("\n\n").append(StringUtil.replaceAllVariables(disklaimer,vars));
 | 
			
		||||
      
 | 
			
		||||
      // send the actual E-mail messages in the background
 | 
			
		||||
      MailerAgent agent = new MailerAgent(env,env.getUser().realUserName(),env.getUser().realEmailAddress(),
 | 
			
		||||
					  rc,subject,text);
 | 
			
		||||
					  rc,subject,buf.toString());
 | 
			
		||||
      agent.start();
 | 
			
		||||
 | 
			
		||||
    } // end if
 | 
			
		||||
 | 
			
		||||
@ -43,6 +43,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  // Boolean flag indexes
 | 
			
		||||
  static final int BF_POSTPICTURES = 0;
 | 
			
		||||
  static final int BF_ADM_NOPHOTO = 1;
 | 
			
		||||
  static final int BF_MASSMAIL_OPTOUT = 2;
 | 
			
		||||
 | 
			
		||||
  private static Category logger = Category.getInstance(UserContextImpl.class);
 | 
			
		||||
 | 
			
		||||
@ -311,6 +312,7 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
  {
 | 
			
		||||
    UserProperties rc = new UserProperties();
 | 
			
		||||
    rc.setDisplayPostPictures(flags.get(BF_POSTPICTURES));
 | 
			
		||||
    rc.setMassMailOptOut(flags.get(BF_MASSMAIL_OPTOUT));
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
  } // end createProperties
 | 
			
		||||
@ -321,6 +323,8 @@ class UserContextImpl implements UserContext, UserBackend
 | 
			
		||||
 | 
			
		||||
    if (flags.assign(BF_POSTPICTURES,props.getDisplayPostPictures()))
 | 
			
		||||
      rc.set(PROP_FLAGS);
 | 
			
		||||
    if (flags.assign(BF_MASSMAIL_OPTOUT,props.getMassMailOptOut()))
 | 
			
		||||
      rc.set(PROP_FLAGS);
 | 
			
		||||
 | 
			
		||||
    return rc;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -148,6 +148,9 @@ public class AdminModifyUserDialog extends ContentDialog
 | 
			
		||||
    addFormField(new CDFormCategoryHeader("User Preferences"));
 | 
			
		||||
    addFormField(new CDCheckBoxFormField("pic_in_post","Display user photos next to conference posts",
 | 
			
		||||
					 "(where applicable)",YES));
 | 
			
		||||
    addFormField(new CDCheckBoxFormField("no_mass_mail",
 | 
			
		||||
                                         "Don't send user mass E-mail from community/conference hosts",
 | 
			
		||||
                                          null,YES));
 | 
			
		||||
    addFormField(new CDLocaleListFormField("locale","Default locale","(for formatting dates/times)",true));
 | 
			
		||||
    addFormField(new CDTimeZoneListFormField("tz","Default time zone",null,true));
 | 
			
		||||
    addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24));
 | 
			
		||||
@ -289,6 +292,8 @@ public class AdminModifyUserDialog extends ContentDialog
 | 
			
		||||
    photo_control.setLinkURL("adminuserphoto?uid=" + admuser.getUID());
 | 
			
		||||
    if (props.getDisplayPostPictures())
 | 
			
		||||
      setFieldValue("pic_in_post",YES);
 | 
			
		||||
    if (props.getMassMailOptOut())
 | 
			
		||||
      setFieldValue("no_mass_mail",YES);
 | 
			
		||||
    setFieldValue("locale",admuser.getLocale().toString());
 | 
			
		||||
    setFieldValue("tz",admuser.getTimeZone().getID());
 | 
			
		||||
 | 
			
		||||
@ -348,6 +353,7 @@ public class AdminModifyUserDialog extends ContentDialog
 | 
			
		||||
    ci.setPrivateEmail(YES.equals(getFieldValue("pvt_email")));
 | 
			
		||||
    ci.setURL(getFieldValue("url"));
 | 
			
		||||
    props.setDisplayPostPictures(YES.equals(getFieldValue("pic_in_post")));
 | 
			
		||||
    props.setMassMailOptOut(YES.equals(getFieldValue("no_mass_mail")));
 | 
			
		||||
 | 
			
		||||
    // Store the completed contact info.
 | 
			
		||||
    admuser.putContactInfo(ci);
 | 
			
		||||
 | 
			
		||||
@ -141,6 +141,9 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
    addFormField(new CDFormCategoryHeader("User Preferences"));
 | 
			
		||||
    addFormField(new CDCheckBoxFormField("pic_in_post","Display user photos next to conference posts",
 | 
			
		||||
					 "(where applicable)",YES));
 | 
			
		||||
    addFormField(new CDCheckBoxFormField("no_mass_mail",
 | 
			
		||||
                                         "Don't send me mass E-mail from community/conference hosts",
 | 
			
		||||
                                          null,YES));
 | 
			
		||||
    addFormField(new CDLocaleListFormField("locale","Default locale","(for formatting dates/times)",true));
 | 
			
		||||
    addFormField(new CDTimeZoneListFormField("tz","Default time zone",null,true));
 | 
			
		||||
    addCommandButton(new CDImageButton("update","bn_update.gif","Update",80,24));
 | 
			
		||||
@ -241,6 +244,8 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
    photo_control.setLinkURL("userphoto?tgt=" + URLEncoder.encode(target));
 | 
			
		||||
    if (props.getDisplayPostPictures())
 | 
			
		||||
      setFieldValue("pic_in_post",YES);
 | 
			
		||||
    if (props.getMassMailOptOut())
 | 
			
		||||
      setFieldValue("no_mass_mail",YES);
 | 
			
		||||
    setFieldValue("locale",uc.getLocale().toString());
 | 
			
		||||
    setFieldValue("tz",uc.getTimeZone().getID());
 | 
			
		||||
 | 
			
		||||
@ -285,6 +290,7 @@ public class EditProfileDialog extends ContentDialog
 | 
			
		||||
 | 
			
		||||
    // Save off the properties.
 | 
			
		||||
    props.setDisplayPostPictures(YES.equals(getFieldValue("pic_in_post")));
 | 
			
		||||
    props.setMassMailOptOut(YES.equals(getFieldValue("no_mass_mail")));
 | 
			
		||||
    uc.setProperties(props);
 | 
			
		||||
 | 
			
		||||
    // Save off the user's description and preferences.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user