Package org.dspace.eperson

Source Code of org.dspace.eperson.LoadLastLogin

/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.eperson;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jdbm.RecordManager;
import jdbm.RecordManagerFactory;
import jdbm.RecordManagerOptions;
import jdbm.btree.BTree;
import jdbm.helper.StringComparator;
import jdbm.helper.Tuple;
import jdbm.helper.TupleBrowser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.Context;

/**
* Examine a collection of DSpace log files, building a table of last login
* times for known EPersons, and then update EPerson records with the latest
* dates.
*
* @author mwood
*/
public class LoadLastLogin
{
    public static void main(String[] argv)
            throws IOException, SQLException, AuthorizeException
    {
        final String USAGE = "LoadLastLogin [options] path...path\n\n"
                + "'path's are paths to DSpace log files";

        final String loginRE =
            "([0-9-]+) ([0-9:]+)[^@]+@ " // Date(1), time(2), goop
            + "([^:]+):" // user(3)
            + "session_id=[^:]+:"
            + "ip_addr=[0-9a-f.:]+:"
            + "login:type=(implicit|explicit)";

        // Handle options, if any
        Options options = new Options();
        options.addOption("h", "help", false, "Explain options");
        options.addOption("p", "pretend", false, "Output TSV instead of updating database");
        options.addOption("v", "verbose", false, "Talk more about what we are doing");

        PosixParser parser = new PosixParser();
        CommandLine command = null;
        try {
            command = parser.parse(options, argv);
        } catch (org.apache.commons.cli.ParseException ex) {
            System.err.println(ex.getMessage());
            if (! (ex instanceof MissingOptionException))
                new HelpFormatter().printHelp(USAGE, options);
            System.exit(1);
        }

        if (command.hasOption('h'))
        {
            System.out.println("Load users' last_active dates into the database from DSpace logs.");
            System.out.println();
            new HelpFormatter().printHelp(USAGE, options);
            System.exit(0);
        }

        final boolean VERBOSE = command.hasOption('v');
        final boolean PRETEND = command.hasOption('p');

        String[] args = command.getArgs();

        // Set up a "table" that can overflow to storage
        final Properties rmProps = new Properties();
        rmProps.put(RecordManagerOptions.DISABLE_TRANSACTIONS, "true");

        String dbname = new File(System.getProperty("java.io.tmpdir"), "lastlogindb").getCanonicalPath();
        if (VERBOSE)
            System.out.println("dbname:  " + dbname);
        RecordManager stamps = RecordManagerFactory.createRecordManager(dbname, rmProps);
        BTree stampDb = BTree.createInstance(stamps, new StringComparator());

        // Scan log files looking for login records
        final Pattern loginCracker = Pattern.compile(loginRE);
        final SimpleDateFormat dateEncoder = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (String logName : args)
        {
            BufferedReader logReader = new BufferedReader(new FileReader(logName));
            while(true)
            {
                String line = logReader.readLine();
                // End of file?
                if (null == line)
                    break;
                // Skip if definitely not a login record
                if (!line.contains(":login:"))
                    continue;

                // Try to recognize the interesting fields
                Matcher loginMatcher = loginCracker.matcher(line);
                if (!loginMatcher.matches())
                    continue;

                // Pretty sure we have a login
                String date = loginMatcher.group(1);
                String time = loginMatcher.group(2);
                String user = loginMatcher.group(3);

                String logDateTime = date + ' ' + time;
                Date stamp;
                try {
                    stamp = dateEncoder.parse(logDateTime);
                } catch (ParseException ex) {
                    System.err.println("Skipping log record:  " + ex.getMessage());
                    continue;
                }
                Date previous = (Date) stampDb.find(user);
                if (null == previous || stamp.after(previous))
                {
                    stampDb.insert(user, stamp, true); // Record this user's newest login so far
                }
            }
            logReader.close();
        }

        // Now walk the cache and update EPersons
        TupleBrowser walker = stampDb.browse();
        Tuple stamp = new Tuple();
        Context ctx = new Context();
        ctx.turnOffAuthorisationSystem();

        while(walker.getNext(stamp))
        {
            // Update an EPerson's last login
            String name = (String) stamp.getKey();
            Date date = (Date) stamp.getValue();
            EPerson ePerson;
            ePerson = EPerson.findByEmail(ctx, name);
            if (null == ePerson)
                ePerson = EPerson.findByNetid(ctx, name);
            if (null == ePerson)
            {
                System.err.println("Skipping unknown user:  " + name);
                continue;
            }
            Date previous = ePerson.getLastActive();
            if ((null == previous) || date.after(previous))
            {
                if (PRETEND)
                {
                    System.out.printf("%d\t%s\t%s\t%s\t%s\n",
                            ePerson.getID(),
                            date,
                            ePerson.getEmail(),
                            ePerson.getNetid(),
                            ePerson.getFullName());
                }
                else
                {
                    ePerson.setLastActive(date);
                    ePerson.update();
                    ctx.commit();
                }
            }
        }

        ctx.complete();

        stamps.close();

        // Clean up external data and index files, if any
        File target;

        target = new File(dbname + ".db");
        if (target.exists())
            target.delete();

        target = new File(dbname + ".lg");
        if (target.exists())
            target.delete();
    }
}
TOP

Related Classes of org.dspace.eperson.LoadLastLogin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.