(Scott Phillips) Added an activity viewer to the Control Panel showing the current user activity on the repository.

git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2897 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Scott Phillips
2008-04-15 04:14:43 +00:00
parent 616a4f0221
commit b55360719d
7 changed files with 578 additions and 13 deletions

View File

@@ -44,6 +44,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
@@ -69,6 +70,7 @@ import org.dspace.app.xmlui.wing.element.TextArea;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.AuthorizeManager;
import org.dspace.core.ConfigurationManager;
import org.dspace.eperson.EPerson;
import org.xml.sax.SAXException;
/**
@@ -90,6 +92,9 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
private static final Message T_option_dspace = message("xmlui.administrative.ControlPanel.option_dspace");
private static final Message T_option_knots = message("xmlui.administrative.ControlPanel.option_knots");
private static final Message T_option_alerts = message("xmlui.administrative.ControlPanel.option_alerts");
private static final Message T_seconds = message("xmlui.administrative.ControlPanel.seconds");
private static final Message T_hours = message("xmlui.administrative.ControlPanel.hours");
private static final Message T_minutes = message("xmlui.administrative.ControlPanel.minutes");
private static final Message T_JAVA_HEAD = message("xmlui.administrative.ControlPanel.java_head");
private static final Message T_JAVA_VERSION = message("xmlui.administrative.ControlPanel.java_version");
private static final Message T_JAVA_VENDOR = message("xmlui.administrative.ControlPanel.java_vendor");
@@ -121,8 +126,6 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
private static final Message T_knots_column1 = message("xmlui.administrative.ControlPanel.knots_column1");
private static final Message T_knots_column2 = message("xmlui.administrative.ControlPanel.knots_column2");
private static final Message T_knots_column3 = message("xmlui.administrative.ControlPanel.knots_column3");
private static final Message T_knots_hours = message("xmlui.administrative.ControlPanel.knots_hours");
private static final Message T_knots_minutes = message("xmlui.administrative.ControlPanel.knots_minutes");
private static final Message T_knots_expired = message("xmlui.administrative.ControlPanel.knots_expired");
private static final Message T_knots_active = message("xmlui.administrative.ControlPanel.knots_active");
private static final Message T_knots_none = message("xmlui.administrative.ControlPanel.knots_none");
@@ -139,6 +142,16 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
private static final Message T_alerts_countdown_keep = message("xmlui.administrative.ControlPanel.alerts_countdown_keep");
private static final Message T_alerts_submit_activate = message("xmlui.administrative.ControlPanel.alerts_submit_activate");
private static final Message T_alerts_submit_deactivate = message("xmlui.administrative.ControlPanel.alerts_submit_deactivate");
private static final Message T_activity_head = message("xmlui.administrative.ControlPanel.activity_head");
private static final Message T_activity_sort_time = message("xmlui.administrative.ControlPanel.activity_sort_time");
private static final Message T_activity_sort_user = message("xmlui.administrative.ControlPanel.activity_sort_user");
private static final Message T_activity_sort_ip = message("xmlui.administrative.ControlPanel.activity_sort_ip");
private static final Message T_activity_sort_url = message("xmlui.administrative.ControlPanel.activity_sort_url");
private static final Message T_activity_sort_agent = message("xmlui.administrative.ControlPanel.activity_sort_Agent");
private static final Message T_activity_anonymous = message("xmlui.administrative.ControlPanel.activity_anonymous");
private static final Message T_activity_none = message("xmlui.administrative.ControlPanel.activity_none");
private static final Message T_activity_hideself = message("xmlui.administrative.ControlPanel.activity_hideself");
private static final Message T_activity_showself = message("xmlui.administrative.ControlPanel.activity_showself");
private static final Message T_select_panel = message("xmlui.administrative.ControlPanel.select_panel");
/**
* The service manager allows us to access the continuation's
@@ -149,7 +162,7 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
/**
* The four states that this page can be in.
*/
private enum OPTIONS {java, dspace,knots,alerts};
private enum OPTIONS {java, dspace, knots, alerts, activity};
/**
* From the servicable api, give us a service manager.
@@ -184,6 +197,8 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
option = OPTIONS.knots;
if (request.getParameter("alerts") != null)
option = OPTIONS.alerts;
if (request.getParameter("activity") != null)
option = OPTIONS.activity;
Division div = body.addInteractiveDivision("control-panel", contextPath+"/admin/panel", Division.METHOD_POST, "primary administrative");
div.setHead(T_head);
@@ -212,6 +227,16 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
else
options.addItemXref("?alerts",T_option_alerts);
String userSortTarget = "?activity";
if (request.getParameter("sortBy") != null)
userSortTarget += "&sortBy="+request.getParameter("sortBy");
if (request.getParameter("showSelf") != null)
userSortTarget += "&showSelf="+request.getParameter("showSelf");
if (option == OPTIONS.activity)
options.addItem().addHighlight("bold").addXref(userSortTarget,"Current Activity");
else
options.addItemXref(userSortTarget,"Current Activity");
// The main content:
if (option == OPTIONS.java)
@@ -222,7 +247,10 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
addWebContinuations(div);
else if (option == OPTIONS.alerts)
addAlerts(div);
else{
else if (option == OPTIONS.activity)
addActivity(div);
else
{
div.addPara(T_select_panel);
}
@@ -380,9 +408,9 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
Message lastAccessMessage = null;
long lastAccess = System.currentTimeMillis() - knot.getLastAccessTime();
if (lastAccess > 2*60*60*1000)
lastAccessMessage = T_knots_hours.parameterize((lastAccess / (60*60*1000)));
lastAccessMessage = T_hours.parameterize((lastAccess / (60*60*1000)));
else
lastAccessMessage = T_knots_minutes.parameterize((lastAccess / (60*1000)));
lastAccessMessage = T_minutes.parameterize((lastAccess / (60*1000)));
row = activeFlows.addRow();
row.addCellContent(interpreter);
@@ -453,5 +481,192 @@ public class ControlPanel extends AbstractDSpaceTransformer implements Serviceab
}
/** The possible sorting parameters */
private static enum EventSort { TIME, URL, SESSION, AGENT, IP };
/**
* Create a list of all activity.
*/
private void addActivity(Division div) throws WingException, SQLException
{
// 0) Show my requests
Request request = ObjectModelHelper.getRequest(objectModel);
String showSelf = request.getParameter("showSelf");
if (showSelf == null || !showSelf.equals("false"))
showSelf = "true";
// 1) Determine how to sort
EventSort sortBy = EventSort.TIME;
String sortByString = request.getParameter("sortBy");
if (EventSort.TIME.toString().equals(sortByString))
sortBy = EventSort.TIME;
if (EventSort.URL.toString().equals(sortByString))
sortBy = EventSort.URL;
if (EventSort.SESSION.toString().equals(sortByString))
sortBy = EventSort.SESSION;
if (EventSort.AGENT.toString().equals(sortByString))
sortBy = EventSort.AGENT;
if (EventSort.IP.toString().equals(sortByString))
sortBy = EventSort.IP;
// 2) Sort the events by the requested sorting parameter
java.util.List<CurrentActivityAction.Event> events = CurrentActivityAction.getEvents();
Collections.sort(events, new ActivitySort<CurrentActivityAction.Event>(sortBy));
Collections.reverse(events);
// 3) self toggle
if (showSelf.equals("true"))
div.addPara().addXref("?activity&sortBy="+sortBy+"&showSelf=false").addContent(T_activity_hideself);
else
div.addPara().addXref("?activity&sortBy="+sortBy+"&showSelf=true").addContent(T_activity_showself);
// 4) Display the results Table
// TABLE: activeUsers
Table activeUsers = div.addTable("users",1,1);
activeUsers.setHead(T_activity_head);
Row row = activeUsers.addRow(Row.ROLE_HEADER);
if (sortBy == EventSort.TIME)
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.TIME+"&showSelf="+showSelf).addContent(T_activity_sort_time);
else
row.addCell().addXref("?activity&sortBy="+EventSort.TIME+"&showSelf="+showSelf).addContent(T_activity_sort_time);
if (sortBy == EventSort.SESSION)
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.SESSION+"&showSelf="+showSelf).addContent(T_activity_sort_user);
else
row.addCell().addXref("?activity&sortBy="+EventSort.SESSION+"&showSelf="+showSelf).addContent(T_activity_sort_user);
if (sortBy == EventSort.IP)
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.IP+"&showSelf="+showSelf).addContent(T_activity_sort_ip);
else
row.addCell().addXref("?activity&sortBy="+EventSort.IP+"&showSelf="+showSelf).addContent(T_activity_sort_ip);
if (sortBy == EventSort.URL)
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.URL+"&showSelf="+showSelf).addContent(T_activity_sort_url);
else
row.addCell().addXref("?activity&sortBy="+EventSort.URL+"&showSelf="+showSelf).addContent(T_activity_sort_url);
if (sortBy == EventSort.AGENT)
row.addCell().addHighlight("bold").addXref("?activity&sortBy="+EventSort.AGENT+"&showSelf="+showSelf).addContent(T_activity_sort_agent);
else
row.addCell().addXref("?activity&sortBy="+EventSort.AGENT+"&showSelf="+showSelf).addContent(T_activity_sort_agent);
// Keep track of how many individual anonymous users there are, each unique anonymous
// user is assigned an index based upon the servlet session id.
HashMap<String,Integer> anonymousHash = new HashMap<String,Integer>();
int anonymousCount = 1;
int shown = 0;
for (CurrentActivityAction.Event event : events)
{
// Skip out if the user does not want to see their requests.
if (showSelf.equals("false") && event.getEPersonID() == context.getCurrentUser().getID())
continue;
shown++;
Message timeStampMessage = null;
long ago = System.currentTimeMillis() - event.getTimeStamp();
if (ago > 2*60*60*1000)
timeStampMessage = T_hours.parameterize((ago / (60*60*1000)));
else if (ago > 60*1000)
timeStampMessage = T_minutes.parameterize((ago / (60*1000)));
else
timeStampMessage = T_seconds.parameterize((ago / (1000)));
Row eventRow = activeUsers.addRow();
eventRow.addCellContent(timeStampMessage);
int eid = event.getEPersonID();
EPerson eperson = EPerson.find(context, eid);
if (eperson != null)
{
String name = eperson.getFullName();
eventRow.addCellContent(name);
}
else
{
// Is this a new anonymous user?
if (!anonymousHash.containsKey(event.getSessionID()))
anonymousHash.put(event.getSessionID(), anonymousCount++);
eventRow.addCellContent(T_activity_anonymous.parameterize(anonymousHash.get(event.getSessionID())));
}
eventRow.addCellContent(event.getIP());
eventRow.addCell().addXref(contextPath+"/"+event.getURL()).addContent("/"+event.getURL());
eventRow.addCellContent(event.getDectectedBrowser());
}
if (shown == 0)
{
activeUsers.addRow().addCell(1, 5).addContent(T_activity_none.parameterize(CurrentActivityAction.MAX_EVENTS));
}
}
/**
* Comparator to sort activity events by their access times.
*/
public static class ActivitySort<E extends CurrentActivityAction.Event> implements Comparator<E>
{
// Sort parameter
private EventSort sortBy;
public ActivitySort(EventSort sortBy)
{
this.sortBy = sortBy;
}
/**
* Compare these two activity events based upon the given sort parameter. In the case of a tie,
* allways fallback to sorting based upon the timestamp.
*/
public int compare(E a, E b)
{
// Sort by the given ordering matrix
if (EventSort.URL == sortBy)
{
String aURL = a.getURL();
String bURL = b.getURL();
int cmp = aURL.compareTo(bURL);
if (cmp != 0)
return cmp;
}
else if (EventSort.AGENT == sortBy)
{
String aAgent = a.getDectectedBrowser();
String bAgent = b.getDectectedBrowser();
int cmp = aAgent.compareTo(bAgent);
if (cmp != 0)
return cmp;
}
else if (EventSort.IP == sortBy)
{
String aIP = a.getIP();
String bIP = b.getIP();
int cmp = aIP.compareTo(bIP);
if (cmp != 0)
return cmp;
}
else if (EventSort.SESSION == sortBy)
{
String aSession = a.getSessionID();
String bSession = b.getSessionID();
int cmp = aSession.compareTo(bSession);
if (cmp != 0)
return cmp;
}
// All ways fall back to sorting by time, when events are equal.
if (a.getTimeStamp() > b.getTimeStamp())
return 1; // A > B
else if (a.getTimeStamp() > b.getTimeStamp())
return -1; // B < A
return 0; // A == B
}
}
}

View File

@@ -0,0 +1,320 @@
/*
* CurrentActivityAction.java
*
* Version: $Revision: 1.1 $
*
* Date: $Date: 2006/05/01 22:33:39 $
*
* Copyright (c) 2002, 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.xmlui.aspect.administrative;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.acting.AbstractAction;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.dspace.app.xmlui.utils.ContextUtil;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
/**
*
* This action simply records pipeline events that it sees, keeping track of the users and
* pages they are viewing. Later the control panel's activity viewer can access this data to
* get a realtime snap shot of current activity of the repository.
*
* @author Scott Phillips
*/
public class CurrentActivityAction extends AbstractAction
{
/** The maximum number of events that are recorded */
public static int MAX_EVENTS = 250;
/** The HTTP header that contains the real IP for this request, this is used when DSpace is placed behind a load balancer */
public static String IP_HEADER = "X-Forwarded-For";
/** The ordered list of events, by access time */
private static Queue<Event> events = new LinkedList<Event>();
/**
* Allow the DSpace.cfg to override our activity max and ip header.
*/
static {
// If the dspace.cfg has a max event count then use it.
if (ConfigurationManager.getProperty("xmlui.controlpanel.activity.max") != null)
MAX_EVENTS = ConfigurationManager.getIntProperty("xmlui.controlpanel.activity.max");
if (ConfigurationManager.getProperty("xmlui.controlpanel.activity.ipheader") != null)
IP_HEADER = ConfigurationManager.getProperty("xmlui.controlpanel.activity.ipheader");
}
/**
* Record this current event.
*/
public Map act(Redirector redirector, SourceResolver resolver, Map objectModel,
String source, Parameters parameters) throws Exception
{
Request request = ObjectModelHelper.getRequest(objectModel);
Context context = ContextUtil.obtainContext(objectModel);
// Create and store our events
Event event = new Event(context,request);
events.add(event);
// Remove the oldest element from the list if we are over our max
// number of elements.
while(events.size() > MAX_EVENTS)
events.poll();
return null;
}
/**
* @return a list of all current events.
*/
public static List<Event> getEvents()
{
List<Event> list = new ArrayList<Event>();
list.addAll(events);
return list;
}
/**
* An object that represents an activity event.
*/
public static class Event
{
/** The Servlet session */
private String sessionID;
/** The eperson ID */
private int epersonID = -1;
/** The url being viewed */
private String url;
/** A timestap of this event */
private long timestamp;
/** The user-agent for the request */
private String userAgent;
/** The ip address of the requester */
private String ip;
/**
* Construct a new activity event, grabing various bits of data about the request from the context and request.
*/
public Event(Context context, Request request)
{
if (context != null)
{
EPerson eperson = context.getCurrentUser();
if (eperson != null)
epersonID = eperson.getID();
}
if (request != null)
{
url = request.getSitemapURI();
Session session = request.getSession(true);
if (session != null)
sessionID = session.getId();
userAgent = request.getHeader("User-Agent");
ip = request.getHeader(IP_HEADER);
if (ip == null)
ip = request.getRemoteAddr();
}
// The current time
timestamp = System.currentTimeMillis();
}
public String getSessionID()
{
return sessionID;
}
public int getEPersonID()
{
return epersonID;
}
public String getURL()
{
return url;
}
public long getTimeStamp()
{
return timestamp;
}
public String getUserAgent()
{
return userAgent;
}
public String getIP()
{
return ip;
}
/**
* Return the activity viewer's best guess as to what browser or bot was initiating the request.
*
* @return A short name for the browser or bot.
*/
public String getDectectedBrowser()
{
// BOTS
if (userAgent.toLowerCase().contains("google/"))
return "Google (bot)";
if (userAgent.toLowerCase().contains("msnbot/"))
return "MSN (bot)";
if (userAgent.toLowerCase().contains("googlebot/"))
return "Google (bot)";
if (userAgent.toLowerCase().contains("webcrawler/"))
return "WebCrawler (bot)";
if (userAgent.toLowerCase().contains("inktomi"))
return "Inktomi (bot)";
if (userAgent.toLowerCase().contains("teoma"))
return "Teoma (bot)";
// Normal Browsers
if (userAgent.contains("Lotus-Notes/"))
return "Lotus-Notes";
if (userAgent.contains("Opera"))
return "Opera";
if (userAgent.contains("Safari/"))
return "Safari";
if (userAgent.contains("Konqueror/"))
return "Konqueror";
// Internet explorer browsers
if (userAgent.contains("MSIE"))
{
if (userAgent.contains("MSIE 8"))
return "MSIE 8";
if (userAgent.contains("MSIE 7"))
return "MSIE 7";
if (userAgent.contains("MSIE 6"))
return "MSIE 6";
if (userAgent.contains("MSIE 5"))
return "MSIE 5";
// Can't fine the version number
return "MSIE";
}
// Gecko based browsers
if (userAgent.contains("Gecko/"))
{
if (userAgent.contains("Camio/"))
return "Gecko/Camino";
if (userAgent.contains("Chimera/"))
return "Gecko/Chimera";
if (userAgent.contains("Firebird/"))
return "Gecko/Firebird";
if (userAgent.contains("Phoenix/"))
return "Gecko/Phoenix";
if (userAgent.contains("Galeon"))
return "Gecko/Galeon";
if (userAgent.contains("Firefox/1"))
return "Firefox 1.x";
if (userAgent.contains("Firefox/2"))
return "Firefox 2.x";
if (userAgent.contains("Firefox/3"))
return "Firefox 3.x";
if (userAgent.contains("Firefox/"))
return "Firefox"; // can't find the exact version
if (userAgent.contains("Netscape/"))
return "Netscape";
// Can't find the exact distribution
return "Gecko";
}
// Generic browser types (lots of things report these names)
if (userAgent.contains("KHTML/"))
return "KHTML";
if (userAgent.contains("Netscape/"))
return "Netscape";
if (userAgent.contains("Mozilla/"))
return "Mozilla"; // Almost everything says they are mozilla.
// if you get all the way to the end and still nothing, return unknown.
return "Unknown";
}
}
}

View File

@@ -46,10 +46,8 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Matcher;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.avalon.excalibur.pool.Recyclable;
@@ -189,8 +187,8 @@ public class BitstreamReader extends AbstractReader implements Recyclable
{
this.request = ObjectModelHelper.getRequest(objectModel);
this.response = ObjectModelHelper.getResponse(objectModel);
Context context = ContextUtil.obtainContext(objectModel);
Context context = ContextUtil.obtainContext(objectModel);
// Get our parameters that identify the bitstream
int itemID = par.getParameterAsInteger("itemID", -1);
int bitstreamID = par.getParameterAsInteger("bitstreamID", -1);

View File

@@ -115,6 +115,7 @@ to administer DSpace.
<map:actions>
<map:action name="ControlPanelAction" src="org.dspace.app.xmlui.aspect.administrative.ControlPanelAction" />
<map:action name="CurrentActivityAction" src="org.dspace.app.xmlui.aspect.administrative.CurrentActivityAction" />
</map:actions>
<map:selectors>
@@ -262,6 +263,7 @@ to administer DSpace.
</map:select>
<map:generate/>
<map:act type="CurrentActivityAction"/>
<map:transform type="SystemwideAlerts"/>
<map:transform type="Navigation"/>

View File

@@ -1446,6 +1446,9 @@
<message key="xmlui.administrative.ControlPanel.option_dspace">DSpace Configuration</message>
<message key="xmlui.administrative.ControlPanel.option_knots">Web Continuations</message>
<message key="xmlui.administrative.ControlPanel.option_alerts">System-wide Alerts</message>
<message key="xmlui.administrative.ControlPanel.hours">{0} h</message>
<message key="xmlui.administrative.ControlPanel.minutes">{0} m</message>
<message key="xmlui.administrative.ControlPanel.seconds">{0} s</message>
<message key="xmlui.administrative.ControlPanel.java_head">Java and Operating System</message>
<message key="xmlui.administrative.ControlPanel.java_version">Java Runtime Environment Version</message>
<message key="xmlui.administrative.ControlPanel.java_vendor">Java Runtime Environment Vendor</message>
@@ -1477,8 +1480,6 @@
<message key="xmlui.administrative.ControlPanel.knots_column1">Interpreter</message>
<message key="xmlui.administrative.ControlPanel.knots_column2">Last Access</message>
<message key="xmlui.administrative.ControlPanel.knots_column3">State</message>
<message key="xmlui.administrative.ControlPanel.knots_hours">{0} hours</message>
<message key="xmlui.administrative.ControlPanel.knots_minutes">{0} minutes</message>
<message key="xmlui.administrative.ControlPanel.knots_expired">Expired</message>
<message key="xmlui.administrative.ControlPanel.knots_active">Active</message>
<message key="xmlui.administrative.ControlPanel.knots_none">There are no active continuations.</message>
@@ -1495,6 +1496,17 @@
<message key="xmlui.administrative.ControlPanel.alerts_countdown_keep">Keep the current count down timer</message>
<message key="xmlui.administrative.ControlPanel.alerts_submit_activate">Activate</message>
<message key="xmlui.administrative.ControlPanel.alerts_submit_deactivate">Deactivate</message>
<message key="xmlui.administrative.ControlPanel.activity_head">Current Activity ({0} pages maximum)</message>
<message key="xmlui.administrative.ControlPanel.activity_sort_time">Time Stamp</message>
<message key="xmlui.administrative.ControlPanel.activity_sort_user">User</message>
<message key="xmlui.administrative.ControlPanel.activity_sort_ip">IP Address</message>
<message key="xmlui.administrative.ControlPanel.activity_sort_url">URL Page</message>
<message key="xmlui.administrative.ControlPanel.activity_sort_Agent">User-Agent</message>
<message key="xmlui.administrative.ControlPanel.activity_anonymous">Anonymous {0}</message>
<message key="xmlui.administrative.ControlPanel.activity_hideself">Hide my page views</message>
<message key="xmlui.administrative.ControlPanel.activity_showself">Show my page views</message>
<message key="xmlui.administrative.ControlPanel.activity_none">Other than yourself, there have been no page views in the past {0} pages.</message>
<message key="xmlui.administrative.ControlPanel.select_panel">Use the tabs above to select the information to display</message>
<!-- org.dspace.app.xmlui.administrative.SystemwideAlerts -->

View File

@@ -1165,7 +1165,6 @@ webui.suggest.enable = false
# repository home page.
#xmlui.user.loginredirect=/profile
# Allow the user to override which theme is used to display a particular page.
# When submitting a request add the HTTP parameter "themepath" which corresponds
# to a particular theme, that specified theme will be used instead of the any
@@ -1212,6 +1211,18 @@ webui.suggest.enable = false
# Take this key (just the UA-XXXXXX-X part) and place it here in this parameter.
#xmlui.google.analytics.key=UA-XXXXXX-X
# Assign how many page views will be recorded and displayed in the control panel's
# activity viewer. The activity tab allows an administrator to debug problems in a
# running DSpace by understanding who and how their dspace is currently being used.
# The default value is 250.
#xmlui.controlpanel.activity.max = 250
# Determine where the control panel's activity viwer recieves an events IP address
# from. If your DSpace is in a load balanced enviornment or otherwise behind a
# context-switch then you will need to set the paramater to the HTTP parameter that
# records the original IP address.
#xmlui.controlpanel.activity.ipheader = X-Forward-For
#---------------------------------------------------------------#
#--------------OAI-PMH SPECIFIC CONFIGURATIONS------------------#
#---------------------------------------------------------------#

View File

@@ -870,6 +870,13 @@ More information is provide below in <a href="#newfilter">Creating a new Media/F
<td>If you would like to use google analytics to track general website statistics then provide your google analytics key in this parameter. First sign up for an account at <a href="http://analytics.google.com">http://analytics.google.com</a>, then create an entry for your repositories website. Analytics will give you a snipit of javascript code to place on your site, inside that snip it is your google analytics key usually found in the line, "<code>_uacct = 'UA-XXXXXXX-X'</code>" Take this key (just the <code>UA-XXXXXX-X</code> part) and place it here in this parameter.</td>
</tr>
<tr>
<td><code>xmlui.controlpanel.activity.max</code></td>
<td><code>250</code></td>
<td>Assign how many page views will be recorded and displayed in the control panel's activity viewer. The activity tab allows an administrator to debug problems in a running DSpace by understanding who and how their dspace is currently being used. The default value is 250.</td>
</tr>
<tr>
<td><code>xmlui.force.ssl</code></td>