import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* Pet Monitor
*
*
Program processes the log file (events.log) created by listen.c
*
Program will read through the log file and determine if the user needs to be notifed.
* If they do, a Pushbullet notification is sent to the user.
*
* @author Takari Donaville
tdnville@memphis.edu
*
TECH 4945
*
Senior Project
*
Fall 2015
*
The University of Memphis
* @version 1.0
* @since 1.0
*/
public class monitor
{
/**
* Determines the location of the log file
* @return
*/
public static String getLogPath() throws UnsupportedEncodingException
{
URL path = ClassLoader.getSystemResource("events.log");
return URLDecoder.decode(path.toString().substring(5), "UTF-8"); //Use for windows testing
//return path.toString().substring(5); //truncate the string to remove "file:"
}
/**
* Determine the location of the Pushbullet script
* @return
*/
public static String getPushPath()
{
URL path = ClassLoader.getSystemResource("petpush.sh");
return path.toString().substring(5); //truncate the string to remove "file:"
}
/**
* Program execution
* @param args User configuration
*/
public static void main(String[] args) throws UnsupportedEncodingException
{
/**
* args[0] = Pet name
* args[1] = number of events to remember
* args[2] = time window
* args[3] = API key
* args[4] = Pushbullet channel
*/
System.out.println("Initializing...");
/**Variable setup*/
final String apiKey = args[3]; //User's API key
final String petName = args[0]; //Pet's name
final String channel = args[4]; //Pushbullet channel
final int usrNbrOfEvents = Integer.parseInt(args[1]); //User specified length
final int userTime = Integer.parseInt(args[2]); //User specified time window
final String logFile = getLogPath(); //Logfile path
final String pushScript = getPushPath(); //Pushbullet script path
String[] pushCommand = {pushScript, petName, args[1], args[2], apiKey, channel}; //args[] is used here to
// prevent
// uneeded unit conversions
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM d HH:mm:ss yyyy"); //Format for entries
boolean alert;
int foundEvents; //Event counter
int pos; //Buffer position (subtracted from tail position)
RingBuffer timeBuff; //Ring buffer object to hold entries
FileInputStream logStream;
BufferedReader br;
String logLine = null;
LocalDateTime toAdd; //LDT object representing the current line in the logfile
LocalDateTime now; //LDT object representing the current time
try
{
//Prepare to call the Pushbullet script
ProcessBuilder callPushbullet = new ProcessBuilder(pushCommand);
/**Debugging**/
//callPushbullet.start();
//Create the RingBuffer object and set up the file input stream/BufferedReader to read the file.
timeBuff = new RingBuffer(usrNbrOfEvents);
logStream = new FileInputStream(logFile);
br = new BufferedReader(new InputStreamReader(logStream));
//Read the file
while(true)
{
//Read the file until the end is reached
while ((logLine = br.readLine()) != null)
{
//System.out.println("Line contents: " + logLine);
//Format the most recently read line
//Remove possible double spaces created by a single digit date
logLine = logLine.replaceAll(" +", " ");
toAdd = LocalDateTime.parse(logLine, formatter);
//Place in ring buffer
timeBuff.add(toAdd);
}
/**Debugging**/
//if(timeBuff.getLength() > 2)
//{
// System.out.println("End of file reached.");
// System.out.println("Buffer length: " + timeBuff.getLength());
// System.out.println("Contents");
// timeBuff.printAll();
// //System.out.println("Minutes since newest entry: " + // Duration.between(timeBuff.getTail(),now).toMinutes());
//}
//Update the LDT object to the current time
//Reset other conditions to prepare to process the buffer's contents.
now = LocalDateTime.now();
foundEvents = 0;
pos = 0;
alert = false;
//Determine if the current element is within the user's specified window
//pos = 0 is the insertion point in the buffer, the oldest position
if(timeBuff.getLength() > 2)
{
try
{
while (((Duration.between(timeBuff.getPos(pos, usrNbrOfEvents), now).toMinutes()) < userTime) && !alert)
{
System.out.println("In loop\npos: " +pos);
if (foundEvents >= usrNbrOfEvents)
{
//Call the Pushbullet script
System.out.println("Calling!");
callPushbullet.start();
alert = true;
//Pause to prevent a repeat trigger.
//Converts userTime to minutes
Thread.sleep(60000 * userTime);
}
//Increment the count, move to the next position in the buffer
foundEvents++;
pos++;
}
}
catch(NullPointerException npe){}
}
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}