diff --git a/WebCallerID/pom.xml b/WebCallerID/pom.xml
index 1c9bc49..affae25 100755
--- a/WebCallerID/pom.xml
+++ b/WebCallerID/pom.xml
@@ -15,5 +15,15 @@
commons-codec
20041127.091804
+
+ javax.mail
+ mail
+ 1.4.5
+
+
+ com.martiansoftware
+ jsap
+ 2.1
+
\ No newline at end of file
diff --git a/WebCallerID/src/main/java/de/tilman/callerId/CallerIdClient.java b/WebCallerID/src/main/java/de/tilman/callerId/CallerIdClient.java
index 34b2217..297ba28 100755
--- a/WebCallerID/src/main/java/de/tilman/callerId/CallerIdClient.java
+++ b/WebCallerID/src/main/java/de/tilman/callerId/CallerIdClient.java
@@ -7,36 +7,64 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
+import java.util.Calendar;
+import java.util.Properties;
+
+import javax.mail.Message;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
+import com.martiansoftware.jsap.JSAP;
+import com.martiansoftware.jsap.JSAPException;
+import com.martiansoftware.jsap.JSAPResult;
+import com.martiansoftware.jsap.Switch;
+import com.martiansoftware.jsap.UnflaggedOption;
+
public class CallerIdClient {
private final static Logger log = Logger.getLogger(CallerIdClient.class);
+ private static final String TEXT_UNKNOWN = "unbekannt";
+ private static final String TEXT_MAILPREFIX = "Anruf von ";
+
String password;
+ int updateInterval;
+ JSAPResult config;
String cookie = null;
- public CallerIdClient(String routerPassword) {
- BasicConfigurator.configure(new ConsoleAppender(new PatternLayout("%d{ISO8601} - %m%n")));
- this.password = new String(Base64.encodeBase64(routerPassword.getBytes()));
+ public CallerIdClient(JSAPResult config) {
+ this.config = config;
+ this.password = new String(Base64.encodeBase64(config.getString("router password").getBytes()));
+ this.updateInterval = config.getInt("update interval");
try {
+ log.info("logging in to Speedport router");
postUrl("https://speedport.ip/index/login.cgi", "Username=" + URLEncoder.encode("admin", "UTF-8") + "&" + "Password="
+ password);
+
+ log.info("retrieving call list");
getUrl("https://speedport.ip/auth/hcti_status_telanrl.php?cookie=SessionID_R3," + cookie);
+
+ log.info("logging out");
postUrl("https://speedport.ip/auth/logout.cgi?RequestFile=/pub/top_beenden.php&cookie=SessionID_R3," + cookie, "");
} catch (Exception e) {
- e.printStackTrace();
+ log.error(e.getMessage(), e);
}
+
+ log.info("done");
}
private void getUrl(String urlString) throws Exception {
- log.info("getUrl(" + urlString + ")");
+ log.debug("getUrl(" + urlString + ")");
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
@@ -48,16 +76,46 @@ public class CallerIdClient {
while ((line = in.readLine()) != null) {
if (line.startsWith("var in_call_list")) {
- // TODO get list
+ // analyze caller list
+
+ String s = line.substring(39);
+ log.debug(" " + line);
+
+ String[] result = s.split("new Array\\(");
+ for (int x = 0; x < result.length; x++) {
+ // check for unanswered calls
+ if (result[x].substring(result[x].lastIndexOf('"') - 8, result[x].lastIndexOf('"')).equals("00:00:00")) {
+ log.debug("Unanswered call: " + result[x]);
+
+ // determine call time
+ int year = Integer.parseInt(result[x].substring(7, 11));
+ int month = Integer.parseInt(result[x].substring(4, 6));
+ int date = Integer.parseInt(result[x].substring(1, 3));
+ int hour = Integer.parseInt(result[x].substring(12, 14));
+ int min = Integer.parseInt(result[x].substring(15, 17));
+ int sec = Integer.parseInt(result[x].substring(18, 20));
+
+ Calendar callTime = Calendar.getInstance();
+ callTime.set(year, month - 1, date, hour, min, sec);
+
+ Calendar lastCheck = Calendar.getInstance();
+ lastCheck.setTimeInMillis(System.currentTimeMillis() - updateInterval * 1000 * 60);
+
+ if (callTime.after(lastCheck)) {
+ sendNotification(result[x].substring(1, 20), result[x].substring(23, result[x].indexOf('"', 23)));
+ }
+ }
+ }
+
}
-// log.info(" " + line);
+ log.debug(" " + line);
}
in.close();
}
private void postUrl(String urlString, String payload) throws Exception {
- log.info("postUrl(" + urlString + ", " + payload + ")");
+ log.debug("postUrl(" + urlString + ", " + payload + ")");
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
@@ -72,7 +130,7 @@ public class CallerIdClient {
connection.setRequestProperty("Cookie", "SessionID_R3=" + cookie);
}
// connection.setRequestProperty("Referer", "https://speedport.ip/auth/hcti_status_telanrl.php?cookie=SessionID_R3," + cookie);
-
+
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
if (payload.length() > 0) {
writer.write(payload);
@@ -85,13 +143,13 @@ public class CallerIdClient {
if (line.startsWith("SessionID_R3")) {
cookie = line.substring(13);
} else {
- log.info(" Received unexpected response: " + line);
+ log.error(" Received unexpected response: " + line);
}
}
writer.close();
reader.close();
-
+
showHeaders(connection);
}
@@ -106,21 +164,131 @@ public class CallerIdClient {
}
if (headerName == null) {
// The header value contains the server's HTTP version
- log.info(" Server HTTP version, Response code: " + headerValue);
+ log.debug(" Server HTTP version, Response code: " + headerValue);
} else {
- log.info(" Header: " + headerName + ", Value: " + headerValue);
+ log.debug(" Header: " + headerName + ", Value: " + headerValue);
}
}
}
-
+
+ private void sendNotification(String time, String number) throws Exception {
+ log.info("Sende Nachricht: " + "Anruf von " + number + "\n" + time);
+
+ if (number.equals(" "))
+ number = TEXT_UNKNOWN;
+
+ String host = config.getString("SMTP server address"); // "smtp.gmail.com"
+ String from = config.getString("e-mail adress");
+ String pass = config.getString("e-mail password");
+ Properties props = System.getProperties();
+ props.put("mail.smtp.starttls.enable", "true");
+ props.put("mail.smtp.host", host);
+ props.put("mail.smtp.user", from);
+ props.put("mail.smtp.password", pass);
+ props.put("mail.smtp.port", "587");
+ props.put("mail.smtp.auth", "true");
+
+ String[] to = config.getStringArray("recipient");
+
+ Session session = Session.getDefaultInstance(props, null);
+ MimeMessage message = new MimeMessage(session);
+ message.setFrom(new InternetAddress(from));
+
+ InternetAddress[] toAddress = new InternetAddress[to.length];
+
+ for (int i = 0; i < to.length; i++) {
+ toAddress[i] = new InternetAddress(to[i]);
+ }
+ System.out.println(Message.RecipientType.TO);
+
+ for (int i = 0; i < toAddress.length; i++) {
+ message.addRecipient(Message.RecipientType.TO, toAddress[i]);
+ }
+
+ message.setSubject(TEXT_MAILPREFIX + number);
+ message.setText(TEXT_MAILPREFIX + number + "\n" + time);
+
+ log.info("sending message for call from " + number + " at " + time);
+
+ Transport transport = session.getTransport("smtp");
+ transport.connect(host, from, pass);
+ transport.sendMessage(message, message.getAllRecipients());
+ transport.close();
+ }
+
/**
* @param args
*/
public static void main(String[] args) {
- if (args.length != 1)
- System.out.println("usage: CallerIdClient ");
- else
- new CallerIdClient(args[0]);
+ BasicConfigurator.configure(new ConsoleAppender(new PatternLayout("%d{ISO8601} - %m%n")));
+ log.info("Starting CallerIdClient version 1.0.0");
+
+ JSAP jsap = new JSAP();
+
+ try {
+ UnflaggedOption routerPassword = new UnflaggedOption("router password").setStringParser(JSAP.STRING_PARSER)
+ .setRequired(true);
+ routerPassword.setHelp("the login password for the Speedport W 723V (A) router");
+ jsap.registerParameter(routerPassword);
+
+ UnflaggedOption updateInterval = new UnflaggedOption("update interval").setStringParser(JSAP.INTEGER_PARSER)
+ .setRequired(true);
+ updateInterval.setHelp("the interval beetween runs in minutes");
+ jsap.registerParameter(updateInterval);
+
+ UnflaggedOption smtpServer = new UnflaggedOption("SMTP server address").setStringParser(JSAP.INETADDRESS_PARSER)
+ .setRequired(true);
+ smtpServer.setHelp("the SMTP server to send notifications with");
+ jsap.registerParameter(smtpServer);
+
+ UnflaggedOption fromAddress = new UnflaggedOption("e-mail adress").setStringParser(JSAP.STRING_PARSER).setRequired(
+ true);
+ fromAddress.setHelp("e-mail address to send from");
+ jsap.registerParameter(fromAddress);
+
+ UnflaggedOption emailPassword = new UnflaggedOption("e-mail password").setStringParser(JSAP.STRING_PARSER)
+ .setRequired(true);
+ emailPassword.setHelp("the login password for the e-mail account");
+ jsap.registerParameter(emailPassword);
+
+ UnflaggedOption recipients = new UnflaggedOption("recipient").setStringParser(JSAP.STRING_PARSER).setRequired(true)
+ .setGreedy(true);
+ recipients.setHelp("e-mail addresses to send notifications to");
+ jsap.registerParameter(recipients);
+
+ Switch debugSwitch = new Switch("debug").setLongFlag("debug");
+ debugSwitch.setHelp("print debug messages");
+ jsap.registerParameter(debugSwitch);
+
+ Switch helpSwitch = new Switch("help").setLongFlag("help").setShortFlag('?');
+ helpSwitch.setHelp("print help and exit");
+ jsap.registerParameter(helpSwitch);
+
+ } catch (JSAPException e) {
+ log.fatal(e.getMessage(), e);
+ System.exit(-1001);
+ }
+
+ JSAPResult config = jsap.parse(args);
+
+ if (!config.success() || config.getBoolean("help")) {
+ for (java.util.Iterator errs = config.getErrorMessageIterator(); errs.hasNext();) {
+ log.error("Error: " + errs.next());
+ }
+
+ log.error("Usage: java -jar speedportcallerid.jar " + jsap.getUsage() + "\n\n" + jsap.getHelp());
+ System.exit(-1002);
+ }
+
+ if (config.getBoolean("debug")) {
+ log.setLevel(Level.DEBUG);
+ }
+ else {
+ log.setLevel(Level.INFO);
+ }
+ log.info("Log level set to " + log.getLevel());
+
+ new CallerIdClient(config);
}
}
diff --git a/WebCallerID/src/main/java/de/tilman/callerId/ClientApp.java b/WebCallerID/src/main/java/de/tilman/callerId/ClientApp.java
deleted file mode 100755
index b80afdf..0000000
--- a/WebCallerID/src/main/java/de/tilman/callerId/ClientApp.java
+++ /dev/null
@@ -1,212 +0,0 @@
-//package de.tilman.callerId;
-//
-///*
-// * $HeadURL$
-// * $Revision$
-// * $Date$
-// * ====================================================================
-// *
-// * Licensed to the Apache Software Foundation (ASF) under one or more
-// * contributor license agreements. See the NOTICE file distributed with
-// * this work for additional information regarding copyright ownership.
-// * The ASF licenses this file to You under the Apache License, Version 2.0
-// * (the "License"); you may not use this file except in compliance with
-// * the License. You may obtain a copy of the License at
-// *
-// * http://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing, software
-// * distributed under the License is distributed on an "AS IS" BASIS,
-// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// * See the License for the specific language governing permissions and
-// * limitations under the License.
-// * ====================================================================
-// *
-// * This software consists of voluntary contributions made by many
-// * individuals on behalf of the Apache Software Foundation. For more
-// * information on the Apache Software Foundation, please see
-// * .
-// *
-// * [Additional notices, if required by prior licensing conditions]
-// *
-// */
-//
-//import java.awt.BorderLayout;
-//import java.awt.FlowLayout;
-//import java.awt.event.ActionEvent;
-//import java.awt.event.ActionListener;
-//import java.awt.event.WindowAdapter;
-//import java.awt.event.WindowEvent;
-//import java.io.ByteArrayInputStream;
-//import java.io.IOException;
-//
-//import javax.swing.JButton;
-//import javax.swing.JComboBox;
-//import javax.swing.JEditorPane;
-//import javax.swing.JFrame;
-//import javax.swing.JLabel;
-//import javax.swing.JPanel;
-//import javax.swing.JScrollPane;
-//import javax.swing.JSplitPane;
-//import javax.swing.JTextArea;
-//import javax.swing.SwingUtilities;
-//import javax.swing.text.BadLocationException;
-//import javax.swing.text.html.HTMLDocument;
-//
-//import org.apache.commons.httpclient.HttpClient;
-//import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
-//import org.apache.commons.httpclient.methods.GetMethod;
-//
-///**
-// * A simple Swing application that demonstrates how to use the Jakarta
-// * HttpClient API. This application loads HTML from servers and displays the
-// * content as text and as rendered HTML.
-// *
-// * @author Sean C. Sullivan
-// * @author Ortwin Glück
-// * @author Michael Becke
-// */
-//public class ClientApp {
-//
-// public static void main(String[] args) {
-// HttpClientFrame f = new HttpClientFrame();
-// f.setTitle("HttpClient demo application");
-// f.setSize(700, 500);
-// f.addWindowListener(new WindowAdapter() {
-// public void windowClosing(WindowEvent e) {
-// System.exit(0);
-// }
-// });
-// f.setVisible(true);
-// }
-//
-// public static class HttpClientFrame extends JFrame {
-//
-// private JComboBox cmbURL;
-// private JTextArea taTextResponse;
-// private JEditorPane htmlPane;
-//
-// private HttpClient client;
-//
-// public HttpClientFrame() {
-// client = new HttpClient(new MultiThreadedHttpConnectionManager());
-// client.getHttpConnectionManager().getParams()
-// .setConnectionTimeout(30000);
-//
-// JPanel panInput = new JPanel(new FlowLayout());
-//
-// String[] aURLs = { "http://www.apache.org/",
-// "http://www.google.com/", "http://www.opensource.org/",
-// "http://www.anybrowser.org/", "http://jakarta.apache.org/",
-// "http://www.w3.org/" };
-//
-// final JButton btnGET = new JButton("GET");
-// btnGET.addActionListener(new ActionListener() {
-// public void actionPerformed(ActionEvent ae) {
-// String url = (String) cmbURL.getSelectedItem();
-// if (url != null && url.length() > 0) {
-// loadPage(url);
-// }
-// }
-// });
-//
-// cmbURL = new JComboBox(aURLs);
-// cmbURL.setToolTipText("Enter a URL");
-// cmbURL.setEditable(true);
-// cmbURL.setSelectedIndex(0);
-//
-// JLabel lblURL = new JLabel("URL:");
-//
-// panInput.add(lblURL);
-// panInput.add(cmbURL);
-// panInput.add(btnGET);
-//
-// taTextResponse = new JTextArea();
-// taTextResponse.setEditable(false);
-// taTextResponse.setCaretPosition(0);
-//
-// htmlPane = new JEditorPane();
-// htmlPane.setContentType("text/html");
-// htmlPane.setEditable(false);
-//
-// JSplitPane splitResponsePane = new JSplitPane(
-// JSplitPane.HORIZONTAL_SPLIT,
-// new JScrollPane(taTextResponse), new JScrollPane(htmlPane));
-// splitResponsePane.setOneTouchExpandable(false);
-// splitResponsePane.setDividerLocation(350);
-// // it would be better to set resizeWeight, but this method does
-// // not exist in JRE 1.2.2
-// // splitResponsePane.setResizeWeight(0.5);
-//
-// this.getContentPane().setLayout(new BorderLayout());
-// this.getContentPane().add(panInput, BorderLayout.NORTH);
-// this.getContentPane().add(splitResponsePane, BorderLayout.CENTER);
-// }
-//
-// /**
-// * Sets the HTML content to be displayed.
-// *
-// * @param content
-// * an HTML document
-// */
-// private void setDocumentContent(String content) {
-//
-// HTMLDocument doc = new HTMLDocument();
-// try {
-// doc.remove(0, doc.getLength());
-// } catch (BadLocationException e) {
-// e.printStackTrace();
-// }
-// doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
-//
-// try {
-// htmlPane.read(new ByteArrayInputStream(content.getBytes()), doc);
-// } catch (IOException e) {
-// e.printStackTrace();
-// }
-//
-// htmlPane.setDocument(doc);
-// htmlPane.setCaretPosition(0);
-//
-// taTextResponse.setText(content);
-// taTextResponse.setCaretPosition(0);
-// taTextResponse.requestFocus();
-// }
-//
-// /**
-// * Loads the page at the given URL from a separate thread.
-// *
-// * @param url
-// */
-// private void loadPage(final String url) {
-// // create a new thread to load the URL from
-// new Thread() {
-// public void run() {
-// GetMethod get = new GetMethod(url);
-// get.setFollowRedirects(true);
-//
-// try {
-// int iGetResultCode = client.executeMethod(get);
-// final String strGetResponseBody = get
-// .getResponseBodyAsString();
-//
-// if (strGetResponseBody != null) {
-// // set the HTML on the UI thread
-// SwingUtilities.invokeLater(new Runnable() {
-// public void run() {
-// setDocumentContent(strGetResponseBody);
-// }
-// });
-// }
-// } catch (Exception ex) {
-// ex.printStackTrace();
-// } finally {
-// get.releaseConnection();
-// }
-// }
-// }.start();
-// }
-//
-// }
-//
-//}