- Implemented e-mail subscription (new item notification).

- Updated DB schema:
  * New "subscription" table
  * EPerson: renamed "active" to "can_log_in", and added "last_active",
    "self_registered" and "sub_frequency" columns (unused right now, but
    easier to make the changes at once)
- Updated EPerson object to reflect table changes, and callers of EPerson
  object
- Removed MIT-only filters from web.xml


git-svn-id: http://scm.dspace.org/svn/repo/trunk@446 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Robert Tansley
2002-10-18 11:22:00 +00:00
parent f943f24f23
commit ed9f5052fa
22 changed files with 1030 additions and 122 deletions

51
dspace/bin/sub-daily Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/sh
###########################################################################
#
# install-configs
#
# Version: $Revision$
#
# Date: $Date$
#
# Copyright (c) 2001, Hewlett-Packard Company and Massachusetts
# Institute of Technology. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# - Neither the name of the Hewlett-Packard Company nor the name of the
# Massachusetts Institute of Technology nor the names of their
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
###########################################################################
# Shell script for processing daily subscriptions. Sends mail about new
# items that became available yesterday.
# Get the DSPACE/bin directory
BINDIR=`dirname $0`
$BINDIR/dsrun org.dspace.eperson.Subscribe

View File

@@ -0,0 +1,12 @@
# E-mail sent to DSpace users when new items appear in collections they are
# subscribed to
#
# Parameters: {0} is the details of the new collections and items
# See org.dspace.core.Email for information on the format of this file.
#
Subject: DSpace Subscription
New items are available in the collections you have subscribed to:
{0}
DSpace @ MIT

View File

@@ -72,6 +72,7 @@ DROP TABLE ItemsByTitle;
DROP TABLE ItemsByAuthor; DROP TABLE ItemsByAuthor;
DROP TABLE HistoryState; DROP TABLE HistoryState;
DROP TABLE History; DROP TABLE History;
DROP TABLE Subscription;
DROP TABLE RegistrationData; DROP TABLE RegistrationData;
DROP TABLE TasklistItem; DROP TABLE TasklistItem;
DROP TABLE WorkflowItem; DROP TABLE WorkflowItem;
@@ -118,6 +119,7 @@ DROP SEQUENCE workspaceitem_seq;
DROP SEQUENCE workflowitem_seq; DROP SEQUENCE workflowitem_seq;
DROP SEQUENCE tasklistitem_seq; DROP SEQUENCE tasklistitem_seq;
DROP SEQUENCE registrationdata_seq; DROP SEQUENCE registrationdata_seq;
DROP SEQUENCE subscription_seq;
DROP SEQUENCE history_seq; DROP SEQUENCE history_seq;
DROP SEQUENCE historystate_seq; DROP SEQUENCE historystate_seq;
DROP SEQUENCE itemsbyauthor_seq; DROP SEQUENCE itemsbyauthor_seq;

View File

@@ -100,6 +100,7 @@ CREATE SEQUENCE workspaceitem_seq;
CREATE SEQUENCE workflowitem_seq; CREATE SEQUENCE workflowitem_seq;
CREATE SEQUENCE tasklistitem_seq; CREATE SEQUENCE tasklistitem_seq;
CREATE SEQUENCE registrationdata_seq; CREATE SEQUENCE registrationdata_seq;
CREATE SEQUENCE subscription_seq;
CREATE SEQUENCE history_seq; CREATE SEQUENCE history_seq;
CREATE SEQUENCE historystate_seq; CREATE SEQUENCE historystate_seq;
CREATE SEQUENCE itemsbyauthor_seq; CREATE SEQUENCE itemsbyauthor_seq;
@@ -160,8 +161,11 @@ CREATE TABLE EPerson
password VARCHAR(64), password VARCHAR(64),
firstname VARCHAR(64), firstname VARCHAR(64),
lastname VARCHAR(64), lastname VARCHAR(64),
active BOOL, can_log_in BOOL,
require_certificate BOOL, require_certificate BOOL,
self_registered BOOL,
last_active TIMESTAMP,
sub_frequency INTEGER,
phone VARCHAR(32) phone VARCHAR(32)
); );
@@ -391,6 +395,17 @@ CREATE TABLE RegistrationData
); );
-------------------------------------------------------
-- Subscription table
-------------------------------------------------------
CREATE TABLE Subscription
(
subscription_id INTEGER PRIMARY KEY,
eperson_id INTEGER REFERENCES EPerson(eperson_id),
collection_id INTEGER REFERENCES Collection(collection_id)
);
------------------------------------------------------- -------------------------------------------------------
-- History table -- History table
------------------------------------------------------- -------------------------------------------------------

View File

@@ -77,6 +77,7 @@ SELECT setval('workspaceitem_seq', max(workspace_item_id)) FROM workspaceitem;
SELECT setval('workflowitem_seq', max(workflow_id)) FROM workflowitem; SELECT setval('workflowitem_seq', max(workflow_id)) FROM workflowitem;
SELECT setval('tasklistitem_seq', max(tasklist_id)) FROM tasklistitem; SELECT setval('tasklistitem_seq', max(tasklist_id)) FROM tasklistitem;
SELECT setval('registrationdata_seq', max(registrationdata_id)) FROM registrationdata; SELECT setval('registrationdata_seq', max(registrationdata_id)) FROM registrationdata;
SELECT setval('subscription_seq', max(subscription_id)) FROM subscription;
SELECT setval('history_seq', max(history_id)) FROM history; SELECT setval('history_seq', max(history_id)) FROM history;
SELECT setval('historystate_seq', max(history_state_id)) FROM historystate; SELECT setval('historystate_seq', max(history_state_id)) FROM historystate;
SELECT setval('itemsbyauthor_seq', max(items_by_author_id)) FROM itemsbyauthor; SELECT setval('itemsbyauthor_seq', max(items_by_author_id)) FROM itemsbyauthor;

View File

@@ -92,48 +92,8 @@
</filter-mapping> </filter-mapping>
<filter-mapping> <filter-mapping>
<filter-name>mit-only</filter-name> <filter-name>registered-only</filter-name>
<url-pattern>/browse-author</url-pattern> <url-pattern>/subscribe</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/browse-date</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/browse-title</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/community-list</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/display-item</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/items-by-author</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/communities/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/retrieve/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>mit-only</filter-name>
<url-pattern>/simple-search</url-pattern>
</filter-mapping> </filter-mapping>
@@ -290,6 +250,11 @@
<servlet-class>org.dspace.app.webui.servlet.SubmitServlet</servlet-class> <servlet-class>org.dspace.app.webui.servlet.SubmitServlet</servlet-class>
</servlet> </servlet>
<servlet>
<servlet-name>subscribe</servlet-name>
<servlet-class>org.dspace.app.webui.servlet.SubscribeServlet</servlet-class>
</servlet>
<servlet> <servlet>
<servlet-name>workflow</servlet-name> <servlet-name>workflow</servlet-name>
<servlet-class>org.dspace.app.webui.servlet.admin.WorkflowAbortServlet</servlet-class> <servlet-class>org.dspace.app.webui.servlet.admin.WorkflowAbortServlet</servlet-class>
@@ -428,6 +393,11 @@
<url-pattern>/submit</url-pattern> <url-pattern>/submit</url-pattern>
</servlet-mapping> </servlet-mapping>
<servlet-mapping>
<servlet-name>subscribe</servlet-name>
<url-pattern>/subscribe</url-pattern>
</servlet-mapping>
<servlet-mapping> <servlet-mapping>
<servlet-name>workflow</servlet-name> <servlet-name>workflow</servlet-name>
<url-pattern>/admin/workflow</url-pattern> <url-pattern>/admin/workflow</url-pattern>

View File

@@ -79,7 +79,7 @@
<th class="oddRowEvenCol"><strong><A HREF="<%= request.getContextPath() %>/admin/edit-epeople?sortby=email">E-mail Address</A></strong></th> <th class="oddRowEvenCol"><strong><A HREF="<%= request.getContextPath() %>/admin/edit-epeople?sortby=email">E-mail Address</A></strong></th>
<th class="oddRowOddCol"><strong><A HREF="<%= request.getContextPath() %>/admin/edit-epeople?sortby=lastname">Last Name</A></strong></th> <th class="oddRowOddCol"><strong><A HREF="<%= request.getContextPath() %>/admin/edit-epeople?sortby=lastname">Last Name</A></strong></th>
<th class="oddRowEvenCol"><strong>First Name</strong></th> <th class="oddRowEvenCol"><strong>First Name</strong></th>
<th class="oddRowOddCol"><strong>Active?</strong></th> <th class="oddRowOddCol"><strong>Can Log In?</strong></th>
<th class="oddRowEvenCol"><strong>Must Use Cert?</strong></th> <th class="oddRowEvenCol"><strong>Must Use Cert?</strong></th>
<th class="oddRowOddCol"><strong>Telephone</strong></th> <th class="oddRowOddCol"><strong>Telephone</strong></th>
<th class="oddRowEvenCol">&nbsp;</th> <th class="oddRowEvenCol">&nbsp;</th>
@@ -104,7 +104,7 @@
<input type="text" name="firstname" value="<%= (epeople[i].getFirstName() == null ? "" : epeople[i].getFirstName()) %>" size=12> <input type="text" name="firstname" value="<%= (epeople[i].getFirstName() == null ? "" : epeople[i].getFirstName()) %>" size=12>
</td> </td>
<td class="<%= row %>RowOddCol" align="center"> <td class="<%= row %>RowOddCol" align="center">
<input type="checkbox" name="active" value="true"<%= epeople[i].getActive() ? " CHECKED" : "" %>> <input type="checkbox" name="active" value="true"<%= epeople[i].canLogIn() ? " CHECKED" : "" %>>
</td> </td>
<td class="<%= row %>RowEvenCol" align="center"> <td class="<%= row %>RowEvenCol" align="center">
<input type="checkbox" name="require_certificate" value="true"<%= epeople[i].getRequireCertificate() ? " CHECKED" : "" %>> <input type="checkbox" name="require_certificate" value="true"<%= epeople[i].getRequireCertificate() ? " CHECKED" : "" %>>

View File

@@ -44,6 +44,10 @@
- Attributes required: - Attributes required:
- community - Collection to render home page for - community - Collection to render home page for
- collection - Community this collection is in - collection - Community this collection is in
- last.submitted.titles - String[], titles of recent submissions
- last.submitted.urls - String[], corresponding URLs
- logged.in - Boolean, true if a user is logged in
- subscribed - Boolean, true if user is subscribed to this collection
--%> --%>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %> <%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
@@ -61,6 +65,10 @@
request.getAttribute("last.submitted.titles"); request.getAttribute("last.submitted.titles");
String[] lastSubmittedURLs = (String[]) String[] lastSubmittedURLs = (String[])
request.getAttribute("last.submitted.urls"); request.getAttribute("last.submitted.urls");
boolean loggedIn =
((Boolean) request.getAttribute("logged.in")).booleanValue();
boolean subscribed =
((Boolean) request.getAttribute("subscribed")).booleanValue();
// Put the metadata values into guaranteed non-null variables // Put the metadata values into guaranteed non-null variables
String name = collection.getMetadata("name"); String name = collection.getMetadata("name");
@@ -102,26 +110,29 @@
</tr> </tr>
</table> </table>
<%= intro %> <%-- Search/Browse --%>
<form method=GET>
<%-- Search --%>
<form action="simple-search" method=GET>
<table class=miscTable align=center> <table class=miscTable align=center>
<tr> <tr>
<td class="evenRowEvenCol"> <td class="evenRowEvenCol" colspan=2>
<table> <table>
<tr> <tr>
<td> <td class="standard">
<strong>Search:</strong>&nbsp;<select name="location"> <small><strong>In:</strong></small>&nbsp;<select name="location">
<option value="ALL">All of DSpace</option> <option value="/">All of DSpace</option>
<option selected value="<%= community.getID() %>"><%= communityName %></option> <option selected value="/communities/<%= community.getID() %>/"><%= communityName %></option>
<option selected value="<%= community.getID() %>/<%= collection.getID() %>"><%= name %></option> <option selected value="/communities/<%= community.getID() %>/collections/<%= collection.getID() %>/"><%= name %></option>
</select> </select>
</td> </td>
</tr> </tr>
<tr> <tr>
<td align=center> <td class="standard" align=center>
for&nbsp;<input type="text" name="query">&nbsp;<input type="submit" value="Go"> <small><strong>Search</strong>&nbsp;for&nbsp;</small><input type="text" name="query">&nbsp;<input type="submit" name="submit_search" value="Go">
</td>
</tr>
<tr>
<td align=center class="standard">
<small>or&nbsp;<strong>browse</strong>&nbsp;</small><input type="submit" name="submit_titles" value="Titles">&nbsp;<input type="submit" name="submit_authors" value="Authors">&nbsp;<input type="submit" name="submit_dates" value="By Date">
</td> </td>
</tr> </tr>
</table> </table>
@@ -129,18 +140,49 @@
</tr> </tr>
</table> </table>
</form> </form>
<P align=center><strong>Browse</strong> the collection by <A HREF="browse-title">Title</A>,
<A HREF="browse-author">Author</A>, or <A HREF="browse-date">Date</A>.</P>
<%-- HACK: <center> used for Netscape 4.x, which doesn't accept align=center <table width="100%" align="center" cellspacing=10>
<tr>
<td>
<%-- HACK: <center> used for Netscape 4.x, which doesn't accept align=center
for a paragraph with a button in it --%> for a paragraph with a button in it --%>
<center> <center>
<form action="<%= request.getContextPath() %>/submit" method=POST> <form action="<%= request.getContextPath() %>/submit" method=POST>
<input type=hidden name=collection value="<%= collection.getID() %>"> <input type=hidden name=collection value="<%= collection.getID() %>">
<P><input type=submit name=submit value="Submit to This Collection"></P> <input type=submit name=submit value="Submit to This Collection">
</form> </form>
</center> </center>
</td>
<td class="oddRowEvenCol">
<form method=GET>
<table>
<tr>
<td class="standard">
<% if (loggedIn && subscribed)
{ %>
<small>You are subscribed to this collection. <A HREF="<%= request.getContextPath() %>/subscribe">See&nbsp;Subscriptions</A></small>
</td>
<td class="standard">
<input type="submit" name="submit_unsubscribe" value="Unsubscribe">
<% } else { %>
<small>
Subscribe to this collection to receive daily e-mail notification of new additions
</small>
</td>
<td class="standard">
<input type="submit" name="submit_subscribe" value="Subscribe">
<% } %>
</td>
</tr>
</table>
</td>
</form>
</tr>
</table>
<%= intro %>
<P class="copyrightText"><%= copyright %></P> <P class="copyrightText"><%= copyright %></P>
@@ -155,7 +197,6 @@
} }
%> %>
<%= sidebar %> <%= sidebar %>
</dspace:sidebar> </dspace:sidebar>
</dspace:layout> </dspace:layout>

View File

@@ -0,0 +1,138 @@
<%--
- subscription.jsp
-
- Version: $Revision$
-
- Date: $Date$
-
- Copyright (c) 2001, Hewlett-Packard Company and Massachusetts
- Institute of Technology. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- - Neither the name of the Hewlett-Packard Company nor the name of the
- Massachusetts Institute of Technology nor the names of their
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGE.
--%>
<%--
- Show a user's subscriptions and allow them to be modified
-
- Attributes:
- subscriptions - Collection[] - collections user is subscribed to
- communities - Community[] - communities that subscribed collections
- are in - i.e. subscriptions[0] is in communities[0].
- updated - Boolean - if true, subscriptions have just been updated
--%>
<%@ taglib uri="http://www.dspace.org/dspace-tags.tld" prefix="dspace" %>
<%@ page import="org.dspace.content.Community" %>
<%@ page import="org.dspace.content.Collection" %>
<%
Collection[] subscriptions =
(Collection[]) request.getAttribute("subscriptions");
Community[] communities =
(Community[]) request.getAttribute("communities");
boolean updated =
((Boolean) request.getAttribute("updated")).booleanValue();
%>
<dspace:layout locbar="link"
parenttitle="My DSpace"
parentlink="/mydspace "
title="Your Subscriptions">
<H1>Your Subscriptions</H1>
<%
if (updated)
{
%>
<P><strong>Your subscriptions have been updated.</strong></P>
<%
}
if (subscriptions.length > 0)
{
%>
<P>Below are the collections you are subscribed to. You will be sent an
e-mail each day detailing new items that have become available in these
collection. On days that no new items have appeared, no e-mail will be
sent.</P>
<center>
<table class="miscTable">
<%
String row = "odd";
for (int i = 0; i < subscriptions.length; i++)
{
%>
<tr>
<%--
- HACK: form shouldn't open here, but IE adds a carraige
- return where </form> is placed, breaking our nice layout.
--%>
<form method=POST>
<td class="<%= row %>RowOddCol">
<A HREF="<%= request.getContextPath() %>/communities/<%= communities[i].getID() %>/collections/<%= subscriptions[i].getID() %>/"><%= subscriptions[i].getMetadata("name") %></A>
</td>
<td class="<%= row %>RowEvenCol">
<input type="hidden" name="collection" value="<%= subscriptions[i].getID() %>">
<input type="submit" name="submit_unsubscribe" value="Unsubscribe">
</td>
</form>
</tr>
<%
row = (row.equals("even") ? "odd" : "even" );
}
%>
</table>
</center>
<br>
<center>
<form method=POST>
<input type="submit" name="submit_clear" value="Remove All Subscriptions">
</form>
</center>
<%
}
else
{
%>
<P>You are not currently subscribed to any collections.</P>
<%
}
%>
<P align="center"><A HREF="<%= request.getContextPath() %>/mydspace">Go to
My DSpace </A></P>
</dspace:layout>

View File

@@ -98,12 +98,12 @@
// Scope of the search was all of DSpace. The scope control will list // Scope of the search was all of DSpace. The scope control will list
// "all of DSpace" and the communities. // "all of DSpace" and the communities.
%> %>
<option selected value="ALL">All of DSpace</option> <option selected value="/">All of DSpace</option>
<% <%
for (int i = 0; i < communityArray.length; i++) for (int i = 0; i < communityArray.length; i++)
{ {
%> %>
<option value="<%= communityArray[i].getID() %>"><%= communityArray[i].getMetadata("name") %></option> <option value="/communities/<%= communityArray[i].getID() %>/"><%= communityArray[i].getMetadata("name") %></option>
<% <%
} }
} }
@@ -112,13 +112,13 @@
// Scope of the search was within a community. Scope control will list // Scope of the search was within a community. Scope control will list
// "all of DSpace", the community, and the collections within the community. // "all of DSpace", the community, and the collections within the community.
%> %>
<option value="ALL">All of DSpace</option> <option value="/">All of DSpace</option>
<option selected value="<%= community.getID() %>"><%= community.getMetadata("name") %></option> <option selected value="/communities/<%= community.getID() %>/"><%= community.getMetadata("name") %></option>
<% <%
for (int i = 0; i < collectionArray.length; i++) for (int i = 0; i < collectionArray.length; i++)
{ {
%> %>
<option value="<%= community.getID() %>/<%= collectionArray[i].getID() %>"><%= collectionArray[i].getMetadata("name") %></option> <option value="/communities/<%= community.getID() %>/collections/<%= collectionArray[i].getID() %>/"><%= collectionArray[i].getMetadata("name") %></option>
<% <%
} }
} }
@@ -126,9 +126,9 @@
{ {
// Scope of the search is a specific collection // Scope of the search is a specific collection
%> %>
<option value="ALL">All of DSpace</option> <option value="/">All of DSpace</option>
<option value="<%= community.getID() %>"><%= community.getMetadata("name") %></option> <option value="/communities/<%= community.getID() %>/"><%= community.getMetadata("name") %></option>
<option selected value="<%= community.getID() %>/<%= collection.getID() %>"><%= collection.getMetadata("name") %></option> <option selected value="/communities/<%= community.getID() %>/collections/<%= collection.getID() %>/"><%= collection.getMetadata("name") %></option>
<% <%
} }
%> %>

View File

@@ -158,8 +158,9 @@ public class CreateAdministrator
eperson.setLastName (lastName ); eperson.setLastName (lastName );
eperson.setFirstName(firstName); eperson.setFirstName(firstName);
eperson.setPassword (password1); eperson.setPassword (password1);
eperson.setActive (true ); eperson.setCanLogIn (true );
eperson.setRequireCertificate(false); eperson.setRequireCertificate(false);
eperson.setSelfRegistered(false);
eperson.update(); eperson.update();
admins.addMember(eperson); admins.addMember(eperson);

View File

@@ -41,6 +41,7 @@
package org.dspace.app.webui.servlet; package org.dspace.app.webui.servlet;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@@ -49,6 +50,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.webui.util.Authenticate;
import org.dspace.app.webui.util.JSPManager; import org.dspace.app.webui.util.JSPManager;
import org.dspace.app.webui.util.UIUtil; import org.dspace.app.webui.util.UIUtil;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
@@ -62,6 +64,8 @@ import org.dspace.content.Item;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.LogManager; import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Subscribe;
import org.dspace.handle.HandleManager; import org.dspace.handle.HandleManager;
/** /**
@@ -169,17 +173,102 @@ public class LocationServlet extends DSpaceServlet
// Show community or collection home page? // Show community or collection home page?
if (path.equals("/")) if (path.equals("/"))
{ {
if (collection == null) /*
* Work out if a browse or search was performed
*
* submit_search, submit_titles, submit_authors, submit_dates
* are the buttons
* location gives the value of the drop-down box in the form
* "/",
* "/communities/123/" or
* "/communities/123/collections/456/"
* which means it can just be prepended to the appropriate
* search or browse URL to get the right scope.
*/
String button = UIUtil.getSubmitButton(request, "");
String location = request.getParameter("location");
if (button.equals("submit_titles"))
{ {
// Redirect to browse by title
String url = request.getContextPath() + location +
"browse-title";
response.sendRedirect(response.encodeRedirectURL(url));
}
else if (button.equals("submit_authors"))
{
// Redirect to browse authors
String url = request.getContextPath() + location +
"browse-author";
response.sendRedirect(response.encodeRedirectURL(url));
}
else if (button.equals("submit_dates"))
{
// Redirect to browse by date
String url = request.getContextPath() + location +
"browse-date";
response.sendRedirect(response.encodeRedirectURL(url));
}
else if (button.equals("submit_search") ||
request.getParameter("query") != null)
{
/*
* Have to check for search button and query - in some
* browsers, typing a query into the box and hitting
* return doesn't produce a submit button parameter.
* Redirect to appropriate search page
*/
String url = request.getContextPath() + location +
"simple-search?query=" +
URLEncoder.encode(request.getParameter("query"));
response.sendRedirect(response.encodeRedirectURL(url));
}
else if (collection == null)
{
// Community home page, no button pressed
showCommunityHome(context, request, response, community); showCommunityHome(context, request, response, community);
} }
else else
{ {
boolean updated = false;
// Collection home page. Check for collection home
// buttons
if (button.equals("submit_subscribe"))
{
if (context.getCurrentUser() == null)
{
// Only registered can subscribe
Authenticate.startAuthentication(context, request,
response);
return;
}
else
{
Subscribe.subscribe(context,
context.getCurrentUser(),
collection);
updated = true;
}
}
else if (button.equals("submit_unsubscribe"))
{
Subscribe.unsubscribe(context,
context.getCurrentUser(),
collection);
updated = true;
}
showCollectionHome(context, showCollectionHome(context,
request, request,
response, response,
community, community,
collection); collection);
if (updated)
{
context.complete();
}
} }
} }
else else
@@ -292,11 +381,21 @@ public class LocationServlet extends DSpaceServlet
String[] itemTitles = getItemTitles(items); String[] itemTitles = getItemTitles(items);
String[] itemLinks = getItemURLs(context, items); String[] itemLinks = getItemURLs(context, items);
// Forward to community home page // Is the user logged in/subscribed?
EPerson e = context.getCurrentUser();
boolean subscribed = false;
if (e != null)
{
subscribed = Subscribe.isSubscribed(context, e, collection);
}
// Forward to collection home page
request.setAttribute("last.submitted.titles", itemTitles); request.setAttribute("last.submitted.titles", itemTitles);
request.setAttribute("last.submitted.urls", itemLinks); request.setAttribute("last.submitted.urls", itemLinks);
request.setAttribute("community", community); request.setAttribute("community", community);
request.setAttribute("collection", collection); request.setAttribute("collection", collection);
request.setAttribute("logged.in", new Boolean(e != null));
request.setAttribute("subscribed", new Boolean(subscribed));
JSPManager.showJSP(request, response, "/collection-home.jsp"); JSPManager.showJSP(request, response, "/collection-home.jsp");
} }

View File

@@ -94,7 +94,7 @@ public class PasswordServlet extends DSpaceServlet
boolean loggedIn = false; boolean loggedIn = false;
// Verify the password // Verify the password
if (eperson != null && eperson.getActive()) if (eperson != null && eperson.canLogIn())
{ {
// e-mail address corresponds to active account // e-mail address corresponds to active account
if (eperson.getRequireCertificate()) if (eperson.getRequireCertificate())

View File

@@ -145,9 +145,9 @@ public class RegisterServlet extends DSpaceServlet
* An inactive (unregistered) eperson is trying to set a new p/w * An inactive (unregistered) eperson is trying to set a new p/w
*/ */
if (eperson == null || if (eperson == null ||
(eperson.getActive() && registering) || (eperson.canLogIn() && registering) ||
(eperson.getActive() && eperson.getRequireCertificate() && registering) || (eperson.canLogIn() && eperson.getRequireCertificate() && registering) ||
(!registering && !eperson.getActive())) (!registering && !eperson.canLogIn()))
{ {
// Invalid token // Invalid token
JSPManager.showJSP(request, JSPManager.showJSP(request,
@@ -236,7 +236,7 @@ public class RegisterServlet extends DSpaceServlet
if (eperson != null) if (eperson != null)
{ {
// Can't register an already active user // Can't register an already active user
if (eperson.getActive() && registering) if (eperson.canLogIn() && registering)
{ {
log.info(LogManager.getHeader(context, log.info(LogManager.getHeader(context,
"already_registered", "already_registered",
@@ -249,7 +249,7 @@ public class RegisterServlet extends DSpaceServlet
} }
// Can't give new password to inactive user // Can't give new password to inactive user
if (!eperson.getActive() && !registering) if (!eperson.canLogIn() && !registering)
{ {
log.info(LogManager.getHeader(context, log.info(LogManager.getHeader(context,
"unregistered_forgot_password", "unregistered_forgot_password",
@@ -407,7 +407,7 @@ public class RegisterServlet extends DSpaceServlet
AccountManager.deleteToken(context, key); AccountManager.deleteToken(context, key);
// Set the user as active // Set the user as active
eperson.setActive(true); eperson.setCanLogIn(true);
eperson.update(); eperson.update();
JSPManager.showJSP(request, response, "/register/registered.jsp"); JSPManager.showJSP(request, response, "/register/registered.jsp");

View File

@@ -106,32 +106,9 @@ public class SimpleSearchServlet extends DSpaceServlet
// do the search with the correct location. // do the search with the correct location.
if (location != null && !location.equals("")) if (location != null && !location.equals(""))
{ {
int slash = location.indexOf('/');
// We have a location parameter, so do a redirect
if (location.equals("ALL"))
{
// All of DSpace location
newURL = "/";
}
else if (slash > -1)
{
// community and collection location
newURL = "/communities/" +
location.substring(0, slash) +
"/collections/" +
location.substring(slash + 1) +
"/";
}
else
{
// community location
newURL = "/communities/" + location + "/";
}
// Do the redirect // Do the redirect
response.sendRedirect(response.encodeRedirectURL( response.sendRedirect(response.encodeRedirectURL(
request.getContextPath() + newURL + request.getContextPath() + location +
"simple-search?query=" + query)); "simple-search?query=" + query));
return; return;

View File

@@ -0,0 +1,169 @@
/*
* SubscribeServlet.java
*
* Version: $Revision$
*
* Date: $Date$
*
* Copyright (c) 2001, Hewlett-Packard Company and Massachusetts
* Institute of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Hewlett-Packard Company nor the name of the
* Massachusetts Institute of Technology nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package org.dspace.app.webui.servlet;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.dspace.app.webui.util.JSPManager;
import org.dspace.app.webui.util.UIUtil;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Community;
import org.dspace.content.Collection;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Subscribe;
/**
* Servlet for constructing the components of the "My DSpace" page
*
* @author Robert Tansley
* @version $Revision$
*/
public class SubscribeServlet extends DSpaceServlet
{
/** Logger */
private static Logger log = Logger.getLogger(SubscribeServlet.class);
protected void doDSGet(Context context,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException, SQLException, AuthorizeException
{
// Simply show list of subscriptions
showSubscriptions(context, request, response, false);
}
protected void doDSPost(Context context,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException, SQLException, AuthorizeException
{
/*
* Parameters:
* submit_unsubscribe - unsubscribe from a collection
* submit_clear - clear all subscriptions
* submit_cancel - cancel update - go to My DSpace.
*/
String submit = UIUtil.getSubmitButton(request, "submit");
EPerson e = context.getCurrentUser();
if (submit.equals("submit_clear"))
{
// unsubscribe user from everything
Subscribe.unsubscribe(context, e, null);
// Show the list of subscriptions
showSubscriptions(context, request, response, true);
context.complete();
}
else if (submit.equals("submit_unsubscribe"))
{
int collID = UIUtil.getIntParameter(request, "collection");
Collection c = Collection.find(context, collID);
// Sanity check - ignore duff values
if (c != null)
{
Subscribe.unsubscribe(context, e, c);
}
// Show the list of subscriptions
showSubscriptions(context, request, response, true);
context.complete();
}
else
{
// Back to "My DSpace"
response.sendRedirect(response.encodeRedirectURL(
request.getContextPath() + "/mydspace"));
}
}
/**
* Show the list of subscriptions
*
* @param context DSpace context
* @param request HTTP request
* @param response HTTP response
* @param updated if <code>true</code>, write a message indicating that
* updated subscriptions have been stored
*/
private void showSubscriptions(Context context,
HttpServletRequest request,
HttpServletResponse response,
boolean updated)
throws ServletException, IOException, SQLException
{
// Subscribed collections
Collection[] subs = Subscribe.getSubscriptions(context,
context.getCurrentUser());
// Get corresponding communities to make the link
Community[] communities = new Community[subs.length];
for (int i = 0; i < subs.length; i++)
{
Community[] theseComms = subs[i].getCommunities();
// FIXME: Assume first community is container - maybe something
// more context sensitive?
communities[i] = theseComms[0];
}
request.setAttribute("subscriptions", subs);
request.setAttribute("communities", communities);
request.setAttribute("updated", new Boolean(updated));
JSPManager.showJSP(request, response, "/mydspace/subscriptions.jsp");
}
}

View File

@@ -129,7 +129,7 @@ public class X509CertificateServlet extends DSpaceServlet
EPerson eperson = X509Manager.getUser(context, certs[0]); EPerson eperson = X509Manager.getUser(context, certs[0]);
// Do we have an e-person? // Do we have an e-person?
if (eperson != null && eperson.getActive()) if (eperson != null && eperson.canLogIn())
{ {
// Everything OK - log them in. // Everything OK - log them in.
Authenticate.loggedIn(context, request, eperson); Authenticate.loggedIn(context, request, eperson);

View File

@@ -108,7 +108,7 @@ public class EditEPersonServlet extends DSpaceServlet
? null ? null
: request.getParameter("phone")); : request.getParameter("phone"));
e.setActive(request.getParameter("active") != null && e.setCanLogIn(request.getParameter("active") != null &&
request.getParameter("active").equals("true")); request.getParameter("active").equals("true"));
e.setRequireCertificate( e.setRequireCertificate(

View File

@@ -394,23 +394,23 @@ public class EPerson implements DSpaceObject
/** /**
* Set active/inactive * Indicate whether the user can log in
* *
* @param isactive boolean yes/no * @param login boolean yes/no
*/ */
public void setActive(boolean isactive) public void setCanLogIn(boolean login)
{ {
myRow.setColumn("active", isactive); myRow.setColumn("can_log_in", login);
} }
/** /**
* Get active/inactive * Can the user log in?
* *
* @return isactive boolean, yes/no * @return boolean, yes/no
*/ */
public boolean getActive() public boolean canLogIn()
{ {
return myRow.getBooleanColumn("active"); return myRow.getBooleanColumn("can_log_in");
} }
@@ -436,6 +436,27 @@ public class EPerson implements DSpaceObject
} }
/**
* Indicate whether the user self-registered
*
* @param sr boolean yes/no
*/
public void setSelfRegistered(boolean sr)
{
myRow.setColumn("self_registered", sr);
}
/**
* Can the user log in?
*
* @return boolean, yes/no
*/
public boolean setSelfRegistered()
{
return myRow.getBooleanColumn("self_registered");
}
/** /**
* Get the value of a metadata field * Get the value of a metadata field
* *

View File

@@ -0,0 +1,411 @@
/*
* Subscribe.java
*
* Version: $Revision$
*
* Date: $Date$
*
* Copyright (c) 2001, Hewlett-Packard Company and Massachusetts
* Institute of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Hewlett-Packard Company nor the name of the
* Massachusetts Institute of Technology nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package org.dspace.eperson;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.mail.MessagingException;
import org.apache.log4j.Logger;
import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.TableRowIterator;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.AuthorizeManager;
import org.dspace.content.Collection;
import org.dspace.content.DCDate;
import org.dspace.content.DCValue;
import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.Email;
import org.dspace.core.LogManager;
import org.dspace.handle.HandleManager;
import org.dspace.search.Harvest;
import org.dspace.search.HarvestedItemInfo;
/**
* Class defining methods for sending new item e-mail alerts to users
*
* @author Robert Tansley
* @version $Revision$
*/
public class Subscribe
{
/** log4j logger */
private static Logger log = Logger.getLogger(Group.class);
/**
* Subscribe an e-person to a collection. An e-mail will be sent every day
* a new item appears in the collection.
*
* @param context DSpace context
* @param eperson EPerson to subscribe
* @param collection Collection to subscribe to
*/
public static void subscribe(Context context, EPerson eperson,
Collection collection)
throws SQLException, AuthorizeException
{
// Check authorisation. Must be administrator, or the eperson.
if (AuthorizeManager.isAdmin(context) ||
(context.getCurrentUser() != null &&
context.getCurrentUser().getID() == eperson.getID()))
{
// already subscribed?
TableRowIterator r = DatabaseManager.query(context,
"SELECT * FROM subscription WHERE eperson_id=" +
eperson.getID() + " AND collection_id=" +
collection.getID());
if (!r.hasNext())
{
// Not subscribed, so add them
TableRow row = DatabaseManager.create(context, "subscription");
row.setColumn("eperson_id", eperson.getID());
row.setColumn("collection_id", collection.getID());
DatabaseManager.update(context, row);
log.info(LogManager.getHeader(context,
"subscribe",
"eperson_id=" + eperson.getID() + ",collection_id="
+ collection.getID()));
}
}
else
{
throw new AuthorizeException(
"Only admin or e-person themselves can subscribe");
}
}
/**
* Unsubscribe an e-person to a collection. Passing in <code>null</code>
* for the collection unsubscribes the e-person from all collections they
* are subscribed to.
*
* @param context DSpace context
* @param eperson EPerson to unsubscribe
* @param collection Collection to unsubscribe from
*/
public static void unsubscribe(Context context, EPerson eperson,
Collection collection)
throws SQLException, AuthorizeException
{
// Check authorisation. Must be administrator, or the eperson.
if (AuthorizeManager.isAdmin(context) ||
(context.getCurrentUser() != null &&
context.getCurrentUser().getID() == eperson.getID()))
{
if (collection == null)
{
// Unsubscribe from all
DatabaseManager.updateQuery(context,
"DELETE FROM subscription WHERE eperson_id=" +
eperson.getID());
}
else
{
DatabaseManager.updateQuery(context,
"DELETE FROM subscription WHERE eperson_id=" +
eperson.getID() + " AND collection_id=" +
collection.getID());
log.info(LogManager.getHeader(context,
"unsubscribe",
"eperson_id=" + eperson.getID() + ",collection_id="
+ collection.getID()));
}
}
else
{
throw new AuthorizeException(
"Only admin or e-person themselves can unsubscribe");
}
}
/**
* Find out which collections an e-person is subscribed to
*
* @param context DSpace context
* @param eperson EPerson
* @return array of collections e-person is subscribed to
*/
public static Collection[] getSubscriptions(Context context,
EPerson eperson)
throws SQLException
{
TableRowIterator tri = DatabaseManager.query(context,
"SELECT collection_id FROM subscription WHERE eperson_id=" +
eperson.getID());
List collections = new ArrayList();
while (tri.hasNext())
{
TableRow row = tri.next();
collections.add(Collection.find(context,
row.getIntColumn("collection_id")));
}
Collection[] collArray = new Collection[collections.size()];
return (Collection[]) collections.toArray(collArray);
}
/**
* Is that e-person subscribed to that collection?
*
* @param context DSpace context
* @param eperson find out if this e-person is subscribed
* @param collection find out if subscribed to this collection
* @return <code>true</code> if they are subscribed
*/
public static boolean isSubscribed(Context context, EPerson eperson,
Collection collection)
throws SQLException
{
TableRowIterator tri = DatabaseManager.query(
context,
"SELECT * FROM subscription WHERE eperson_id=" + eperson.getID() +
" AND collection_id=" + collection.getID());
return tri.hasNext();
}
/**
* Process subscriptions. This must be invoked only once a day.
* Messages are only sent out when a collection has actually received
* new items, so that people's mailboxes are not clogged with many "no
* new items" mails.<P>
* Yesterday's newly available items are included. If this is run
* at for example midday, any items that have been made available during
* the current day will not be included, but will be included in the next
* day's run.<P>
* For example, if today's date is 2002-10-10 (in UTC) items made available
* during 2002-10-09 (UTC) will be included.
*
* @param context DSpace context object
*/
public static void processDaily(Context context)
throws SQLException, MessagingException, IOException
{
// Grab the subscriptions
TableRowIterator tri = DatabaseManager.query(context,
"SELECT * FROM subscription ORDER BY eperson_id");
EPerson currentEPerson = null;
List collections = null; // List of Collections
// Go through the list collating subscriptions for each e-person
while (tri.hasNext())
{
TableRow row = tri.next();
// Does this row relate to the same e-person as the last?
if (currentEPerson == null ||
row.getIntColumn("eperson_id") != currentEPerson.getID())
{
// New e-person. Send mail for previous e-person
if (currentEPerson != null)
{
sendEmail(context, currentEPerson, collections);
}
currentEPerson = EPerson.find(context,
row.getIntColumn("eperson_id"));
collections = new ArrayList();
}
collections.add(
Collection.find(context,
row.getIntColumn("collection_id")));
}
// Process the last person
if (currentEPerson != null)
{
sendEmail(context, currentEPerson, collections);
}
}
/**
* Sends an email to the given e-person with details of new items in the
* given collections, items that appeared yesterday. No e-mail is sent if
* there aren't any new items in any of the collections.
*
* @param context DSpace context object
* @param eperson eperson to send to
* @param collections List of collection IDs (Integers)
*/
public static void sendEmail(Context context,
EPerson eperson, List collections)
throws IOException, MessagingException, SQLException
{
// Get the start and end dates for yesterday
Date thisTimeYesterday = new Date(
System.currentTimeMillis() - (24 * 60 * 60 * 1000));
DCDate dcDateYesterday = new DCDate(thisTimeYesterday);
// this time yesterday in ISO 8601, stripping the time
String isoDateYesterday =
dcDateYesterday.toString().substring(0, 10);
String startDate = isoDateYesterday;
String endDate = isoDateYesterday + "T23:59:59Z";
// FIXME: text of email should be more configurable from an
// i18n viewpoint
StringBuffer emailText = new StringBuffer();
boolean isFirst = true;
for (int i = 0; i < collections.size(); i++)
{
Collection c = (Collection) collections.get(i);
List itemInfos = Harvest.harvest(context,
c,
startDate,
endDate,
true, // Need item objects
false); // But not containers
// Only add to buffer if there are new items
if (itemInfos.size() > 0)
{
if (!isFirst)
{
emailText.append(
"\n---------------------------------------\n");
}
else
{
isFirst = false;
}
emailText.append("New items in collection ")
.append(c.getMetadata("name"))
.append(": ")
.append(itemInfos.size())
.append("\n\n");
for (int j = 0; j < itemInfos.size(); j++)
{
HarvestedItemInfo hii =
(HarvestedItemInfo) itemInfos.get(j);
DCValue[] titles = hii.item.getDC("title", null, Item.ANY);
emailText.append(" Title: ");
if (titles.length > 0)
{
emailText.append(titles[0].value);
}
else
{
emailText.append("Untitled");
}
DCValue[] authors = hii.item.getDC("contributor", Item.ANY,
Item.ANY);
if (authors.length > 0)
{
emailText.append("\n Authors: ")
.append(authors[0].value);
for (int k = 1; k < authors.length; k++)
{
emailText.append("\n ")
.append(authors[k].value);
}
}
emailText.append("\n ID: ")
.append(HandleManager.getCanonicalForm(hii.handle))
.append("\n\n");
}
}
}
// Send an e-mail if there were any new items
if (emailText.length() > 0)
{
Email email = ConfigurationManager.getEmail("subscription");
email.addArgument(emailText.toString());
email.send();
log.info(LogManager.getHeader(context,
"sent_subscription",
"eperson_id=" + eperson.getID()));
}
}
/**
* Method for invoking subscriptions via the command line
*
* @param argv command-line arguments, none used yet
*/
public static void main(String[] argv)
throws Exception
{
Context context = new Context();
processDaily(context);
// Nothing is actually written
context.abort();
}
}

View File

@@ -81,7 +81,7 @@ public class EPersonTest extends TestCase
e1.setFirstName("Bob"); e1.setFirstName("Bob");
e1.setLastName("Brannigan"); e1.setLastName("Brannigan");
e1.setPassword("password"); e1.setPassword("password");
e1.setActive(true); e1.setCanLogIn(true);
e1.setRequireCertificate(false); e1.setRequireCertificate(false);
e1.update(); e1.update();

View File

@@ -806,7 +806,7 @@ public class HistoryManager
eperson.getLastName()); eperson.getLastName());
model.add(res, model.add(res,
model.createProperty(getPropertyId(shortname, "active")), model.createProperty(getPropertyId(shortname, "active")),
eperson.getActive()); eperson.canLogIn());
model.add(res, model.add(res,
model.createProperty(getPropertyId(shortname, "require_certificate")), model.createProperty(getPropertyId(shortname, "require_certificate")),
eperson.getRequireCertificate()); eperson.getRequireCertificate());