package ch.rakudave.jnetmap.plugins;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import net.xeoh.plugins.base.annotations.PluginImplementation;
import ch.rakudave.jnetmap.model.Map;
import ch.rakudave.jnetmap.model.IF.NetworkIF;
import ch.rakudave.jnetmap.model.device.Device;
import ch.rakudave.jnetmap.model.device.DeviceEvent;
import ch.rakudave.jnetmap.model.device.DeviceEvent.Type;
import ch.rakudave.jnetmap.util.DeviceEventFilter;
import ch.rakudave.jnetmap.util.Icons;
import ch.rakudave.jnetmap.util.Lang;
import ch.rakudave.jnetmap.util.SwingHelper;
import ch.rakudave.jnetmap.util.logging.Logger;
import ch.rakudave.jnetmap.view.preferences.PreferencePanel;
@PluginImplementation
public class MailNotifier implements Notifier {
private String name, host, username, password, from, to;
private int port = 465;
private boolean useSSL = true;
private DeviceEventFilter filter = new DeviceEventFilter();
@Override
public void statusChanged(DeviceEvent e, Map m) {
boolean match = filter.matches(e);
Logger.debug("Attempting to send mail, filtered: "+!match);
if (!match) return;
try {
Message message = new MimeMessage(getSession());
message.addFrom(new InternetAddress[] {new InternetAddress(from)});
message.addRecipient(RecipientType.TO, new InternetAddress(to));
message.setSubject("jNetMap - " + m.getFileName());
StringBuffer sb = new StringBuffer();
if (Type.INTERFACE_STATUS_CHANGED.equals(e.getType())) {
formatIF(sb, (NetworkIF) e.getSubject());
sb.append("\n").append(Lang.getNoHTML("details")).append(":\n");
}
Device d = (Device) e.getSource();
sb.append(Lang.getNoHTML("device"));
sb.append(" \"").append(d.getName()).append("\"").append(": ");
sb.append(d.getStatus().getMessage()).append("\n");
for (NetworkIF nif : d.getInterfaces()) {
sb.append("\t");
formatIF(sb, nif);
}
message.setContent(sb.toString(), "text/plain");
Transport.send(message);
} catch (Exception ex) {
Logger.error("Failed to send mail from "+from+" to "+to, ex);
}
}
private void formatIF(StringBuffer sb, NetworkIF nif) {
if (sb == null || nif == null) return;
sb.append(Lang.getNoHTML("interface"));
sb.append(" \"").append(nif.getName()).append("\"");
sb.append(" ").append(nif.getAddress()).append(": ");
sb.append(nif.getStatus().getMessage()).append("\n");
}
@Override
public void showPropertiesWindow(Frame owner, boolean isSetup) {
final JDialog d = new JDialog(owner, getPluginName() + " - " + name, ModalityType.DOCUMENT_MODAL);
d.setMinimumSize(new Dimension(300, 500));
d.setLayout(new BorderLayout(5, 5));
final JTextField nameField = new JTextField(name);
JPanel smtpWrapper = new JPanel(new GridLayout(0, 2, 5, 5));
smtpWrapper.setBorder(BorderFactory.createTitledBorder("SMTP"));
final JTextField hostField = new JTextField(host);
final JSpinner portNr = new JSpinner(new SpinnerNumberModel(port, 0, 65535, 1));
final JCheckBox ssl = new JCheckBox("SSL", useSSL);
ssl.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
useSSL = ssl.isSelected();
portNr.setValue(useSSL?465:25);
}
});
final JTextField usernameField = new JTextField(username);
final JPasswordField pwField = new JPasswordField(password);
final JTextField fromField = new JTextField(from);
usernameField.addFocusListener(new FocusListener() {
@Override public void focusGained(FocusEvent e) {}
@Override
public void focusLost(FocusEvent e) {
if (fromField.getText().isEmpty() && usernameField.getText().contains("@")) {
fromField.setText(usernameField.getText());
}
}
});
final JTextField toField = new JTextField(to);
smtpWrapper.add(new JLabel("Host:")); smtpWrapper.add(hostField);
smtpWrapper.add(ssl); smtpWrapper.add(portNr);
smtpWrapper.add(new JLabel("Username:")); smtpWrapper.add(usernameField);
smtpWrapper.add(new JLabel("Password:")); smtpWrapper.add(pwField);
JPanel mailWrapper = new JPanel(new GridLayout(0, 2, 5, 5));
mailWrapper.setBorder(BorderFactory.createTitledBorder("Mail"));
mailWrapper.add(new JLabel("From:")); mailWrapper.add(fromField);
mailWrapper.add(new JLabel("To:")); mailWrapper.add(toField);
JPanel centerWrapper = new JPanel();
centerWrapper.setLayout(new BoxLayout(centerWrapper, BoxLayout.PAGE_AXIS));
centerWrapper.add(smtpWrapper);
centerWrapper.add(mailWrapper);
centerWrapper.add(filter.settingsPanel());
JPanel bottomRow = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 5));
JButton cancel = new JButton(Lang.get("action.cancel"), Icons.get("cancel"));
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
d.dispose();
}
});
JButton ok = new JButton(Lang.get("action.ok"), Icons.get("ok"));
ok.setPreferredSize(cancel.getPreferredSize());
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
name = nameField.getText();
host = hostField.getText();
port = (Integer) portNr.getValue();
username = usernameField.getText();
password = new String(pwField.getPassword());
from = fromField.getText();
to = toField.getText();
if (host.isEmpty() || username.isEmpty() || password.isEmpty() || from.isEmpty() || to.isEmpty()) {
JOptionPane.showMessageDialog(d, "Host, Username, Password, From and To may not be empty!",
"Error", JOptionPane.ERROR_MESSAGE);
return;
}
if (name.isEmpty()) name = "Mail to "+to;
d.dispose();
}
});
if (!isSetup) bottomRow.add(cancel);
bottomRow.add(ok);
d.add(nameField, BorderLayout.NORTH);
d.add(centerWrapper, BorderLayout.CENTER);
d.add(bottomRow, BorderLayout.SOUTH);
d.pack();
SwingHelper.centerTo(owner, d);
d.setVisible(true);
}
@Override
public String getName() {
return name;
}
@Override
public String getPluginName() {
return "Mail Notifier";
}
@Override
public String getAuthor() {
return "rakudave";
}
@Override
public String getDescription() {
return "Sends mails when a device/interface changes its status";
}
@Override
public Icon getIcon() {
return Icons.get("mail");
}
@Override
public boolean hasSettings() {
return false;
}
@Override
public PreferencePanel getSettingsPanel() {
return null;
}
@Override
public Notifier create() {
return new MailNotifier();
}
@SuppressWarnings("serial")
private Session getSession() {
Properties props = new Properties() {{
setProperty("mail.transport.protocol", "smtp");
setProperty("mail.host", host);
setProperty("mail.smtp.auth", "true");
setProperty("mail.smtp.port", String.valueOf(port));
setProperty("mail.user", "public@rakudave.ch");
setProperty("mail.password", "------");
}};
if (useSSL) props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
return Session.getInstance(props, new Authenticator());
}
private class Authenticator extends javax.mail.Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
}