package dk.thoerup.traininfoservice; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import dk.thoerup.traininfoservice.banedk.TimeoutMap; public class RequestPlotter extends HttpServlet { private static final long serialVersionUID = 1L; static final Logger log = Logger.getLogger(RequestPlotter.class.getName()); static final String KML = "application/vnd.google-earth.kml"; static final String KMZ = "application/vnd.google-earth.kmz"; Map cache = new TimeoutMap(2*60*1000); class RequestPosition { public String ip; public Date time; public String lat; public String lng; } protected List getRequestsFromFile() throws IOException{ List positions = new ArrayList(); try { FileInputStream fis = new FileInputStream("/var/log/apache2/app_access.log"); BufferedReader in = new BufferedReader( new InputStreamReader(fis) ); SimpleDateFormat df = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss"); String line; while ( (line=in.readLine()) != null) { if (line.indexOf("LocateStation") == -1 ){ continue; } if (line.indexOf("latitude") == -1 ) { continue; } RequestPosition pos = new RequestPosition(); String toks[] = line.split(" "); pos.ip = toks[0]; pos.time = df.parse( toks[3].replace("[", "") ); String argpart = toks[6].split("\\?")[1]; String args[] = argpart.split("&"); pos.lat = args[0].split("=")[1]; pos.lng = args[1].split("=")[1]; positions.add(pos); } } catch (ParseException pe) { log.log(Level.SEVERE, "parseException", pe); throw new IOException(pe); } catch (IOException e) { log.log(Level.SEVERE, "getKml()", e); throw e; } return positions; } protected String formatXml(List list) { StringBuilder sb = new StringBuilder(); sb.append( "\n" ); sb.append( "\n" ); sb.append( "\n" ); sb.append( " \n"); sb.append( " \n" ); sb.append( " \n\n" ); /* String overlay = " " + " Absolute Positioning: Top left" + " Absolute Positioning: Top left" + " 1" + " " + " http://code.google.com/apis/kml/documentation/top_left.jpg" + " " + " " + " " + " " + " " + " " ; sb.append(overlay); */ final String STYLE_GREEN = "green"; final String STYLE_YELLOW = "yellow"; final String STYLE_RED = "red"; String oldstyle = null; Date now = new Date(); for(RequestPosition current : list) { String style; long timediff = now.getTime() - current.time.getTime(); if ( timediff < (3*60*60*1000) ) { style = STYLE_RED; } else if ( timediff < (24*60*60*1000)) { style = STYLE_YELLOW; } else { style = STYLE_GREEN; } if ( !style.equals(oldstyle) ) { if (oldstyle != null) sb.append( "\n"); sb.append( "\n"); sb.append( " " ).append(style).append("\n"); sb.append( " 0\n" ); oldstyle = style; } sb.append( " \n" ); sb.append( " #" + style + "\n" ); sb.append( " IP=" + current.ip + " Time=" + current.time + "\n" ); sb.append( " " + current.lng + "," + current.lat + ",0\n" ); sb.append( " \n" ); } sb.append( "\n" ); sb.append( "\n" ); sb.append( "\n" ); return sb.toString(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { final String KEY = "kmldata"; String kmlData = cache.get(KEY); if (kmlData == null) { kmlData = formatXml( getRequestsFromFile() ); cache.put(KEY, kmlData); kmlData += ""; } else { kmlData += ""; } if (req.getParameter("zip") != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zip = new ZipOutputStream(baos); zip.putNextEntry( new ZipEntry("trains.kml") ); zip.write( kmlData.getBytes() ); zip.closeEntry(); zip.close(); byte bytes[] = baos.toByteArray(); resp.setContentType(KMZ); resp.setContentLength( bytes.length ); resp.getOutputStream().write(bytes); } else { resp.setContentType(KML); resp.getWriter().print( kmlData ); } } }