/* * Created on Oct 18, 2007 * *Copyright Reliable Response, 2007 */ package net.reliableresponse.notification.providers; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Hashtable; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimePart; import org.apache.commons.httpclient.methods.MultipartPostMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.intuit.quickbase.util.FileAttachment; import com.intuit.quickbase.util.QuickBaseClient; import com.intuit.quickbase.util.QuickBaseException; import com.lotus.sametime.core.util.enc.DiffieHellman; import com.lotus.sametime.post.PostEvent; import net.reliableresponse.notification.Notification; import net.reliableresponse.notification.NotificationException; import net.reliableresponse.notification.NotificationMessage; import net.reliableresponse.notification.broker.BrokerFactory; import net.reliableresponse.notification.device.Device; import net.reliableresponse.notification.device.QuickbaseDevice; import net.reliableresponse.notification.sender.EmailSender; import net.reliableresponse.notification.sender.NotificationSender; import net.reliableresponse.notification.usermgmt.User; import net.reliableresponse.notification.util.StringUtils; public class QuickBaseNotificationProvider extends AbstractNotificationProvider { public static Pattern digitsPattern; static { digitsPattern = Pattern.compile ("^.*\\b+(\\S+)\\s*\\#(\\d+).*"); } public boolean cancelPage(Notification notification) { return false; } public String getName() { return "QuickBase"; } public Hashtable getParameters(Notification notification, Device device) { Hashtable params = new Hashtable(); return params; } public String[] getResponses(Notification notification) { return new String[0]; } public void init(Hashtable params) throws NotificationException { } /** * Determines whether a QuickBase field is a file attachment * * @param fid * - The ID or name to look for * @param dbid * - The DBID * @param qbc * - An initialized QBC * @return boolean, true means it is a file attachment field * @throws QuickBaseException * @throws Exception */ private boolean isFileField(String fid, String dbid, QuickBaseClient qbc) throws QuickBaseException, Exception { Document document = qbc.getSchema(dbid); NodeList fields = document.getElementsByTagName("field"); for (int fieldNum = 0; fieldNum < fields.getLength(); fieldNum++) { Node fieldNode = fields.item(fieldNum); Node attribNode = fieldNode.getAttributes().getNamedItem("id"); if (attribNode != null) { String fieldID = attribNode.getNodeValue(); String label = ""; NodeList children = fieldNode.getChildNodes(); for (int childNum = 0; childNum < children.getLength(); childNum++) { Node child = children.item(childNum); BrokerFactory.getLoggingBroker().logDebug("child=" + child); BrokerFactory.getLoggingBroker().logDebug( "child name=" + child.getNodeName()); if (child.getNodeName().equalsIgnoreCase("label")) { label = child.getFirstChild().getNodeValue(); BrokerFactory.getLoggingBroker().logDebug( "label=" + label); } } BrokerFactory.getLoggingBroker().logDebug( "FID=" + fieldID + ", label=" + label); if (label == null) label = ""; if (fieldID.equals(fid) || label.equals(fid)) { String fieldType = fieldNode.getAttributes().getNamedItem( "field_type").getNodeValue(); if (fieldType.equals("file")) { return true; } } } } return false; } public Hashtable sendNotification(Notification notification, Device device) throws NotificationException { NotificationMessage[] messages = notification.getMessages(); StringBuffer messageText = new StringBuffer(); String photoURL = null; String dbid, username, password, relatedToFID, addedByFID, subjectFID, messageFID, photoFID, videoFID, documentFID; boolean sendConfirmation = false; StringBuffer confirmationMessage = new StringBuffer( "Your message with subject \"" + notification.getSubject() + "\"\n"); if (device instanceof QuickbaseDevice) { QuickbaseDevice qbDevice = (QuickbaseDevice) device; dbid = qbDevice.getDbid(); username = qbDevice.getUsername(); password = qbDevice.getPassword(); relatedToFID = qbDevice.getRelatedToFID(); addedByFID = qbDevice.getAddedByFID(); subjectFID = qbDevice.getSubjectFID(); messageFID = qbDevice.getMessageFID(); photoFID = qbDevice.getPhotoFID(); videoFID = qbDevice.getVideoFID(); documentFID = qbDevice.getDocumentFID(); sendConfirmation = qbDevice.sendConfirmation(); } else { return new Hashtable(); } QuickBaseClient qbc = new QuickBaseClient(username, password); String parentRID = notification.getSubject(); // Get the message text for (int messageNum = 0; messageNum < messages.length; messageNum++) { NotificationMessage message = messages[messageNum]; BrokerFactory.getLoggingBroker().logDebug( "Content type=" + message.getContentType()); if ((message.getContentType() .equalsIgnoreCase(NotificationMessage.NOTIFICATION_CONTENT_TYPE)) || (message.getContentType().toLowerCase() .startsWith("text/plain"))) { messageText.append(message.getMessage()); } else if ( (StringUtils.isEmpty(messageText.toString())) && (message.getContentType().toLowerCase() .startsWith("text/"))) { messageText.append(message.getMessage()); } } // Get the attachments boolean foundAttachment = false; for (int messageNum = 0; messageNum < messages.length; messageNum++) { NotificationMessage message = messages[messageNum]; if (message.getContentType().toLowerCase().startsWith("image/")) { foundAttachment = true; HashMap recorddata = new HashMap<String, String>(); BrokerFactory.getLoggingBroker().logDebug( "Adding to QB Record - " + messageFID + ": " + messageText); recorddata.put(subjectFID, notification.getSubject()); recorddata.put(relatedToFID, parentRID); try { if (isFileField(photoFID, dbid, qbc)) { BrokerFactory.getLoggingBroker().logDebug( "Adding file to QB Record - " + photoFID + ": " + photoURL); recorddata.put(photoFID, new FileAttachment(message .getFilename(), message.getContent())); } else { photoURL = BrokerFactory.getConfigurationBroker() .getStringValue("base.url") + "/AttachmentServlet?uuid=" + notification.getUuid() + "&messageID=" + messageNum; if (!StringUtils.isEmpty(photoURL)) { BrokerFactory.getLoggingBroker().logDebug( "Adding url to QB Record - " + photoFID + ": " + photoURL); recorddata.put(photoFID, photoURL); } } String newRecord = qbc.addRecord(dbid, recorddata); notification.addMessage("Adding record #" + newRecord + " to QuickBase", notification.getRecipient()); confirmationMessage.append("Has an image at https://www.quickbase.com/db/"+dbid+"?a=er&rid="+newRecord+"\n"); } catch (Exception e) { confirmationMessage.append("Was not able to attach an image named "+message.getFilename()); BrokerFactory.getLoggingBroker().logError(e); throw new NotificationException( NotificationException.FAILED, e.getMessage()); } } else if (message.getContentType().toLowerCase().startsWith( "video/")) { foundAttachment = true; photoURL = BrokerFactory.getConfigurationBroker() .getStringValue("base.url") + "/AttachmentServlet?uuid=" + notification.getUuid() + "&messageID=" + messageNum; HashMap recorddata = new HashMap<String, String>(); BrokerFactory.getLoggingBroker().logDebug( "Adding to QB Record - " + messageFID + ": " + messageText); recorddata.put(subjectFID, notification.getSubject()); recorddata.put(relatedToFID, parentRID); recorddata.put(messageFID, messageText.toString().replaceAll("\\p{Cntrl}", "")); recorddata.put(addedByFID, notification.getSender().toString()); try { if (isFileField(videoFID, dbid, qbc)) { BrokerFactory.getLoggingBroker().logDebug( "Adding file to QB Record - " + photoFID + ": " + photoURL); recorddata.put(videoFID, new FileAttachment(message .getFilename(), message.getContent())); } else { if (!StringUtils.isEmpty(photoURL)) { BrokerFactory.getLoggingBroker().logDebug( "Adding URL to QB Record - " + photoFID + ": " + photoURL); recorddata.put(videoFID, photoURL); } } String newRecord = qbc.addRecord(dbid, recorddata); notification.addMessage("Adding record #" + newRecord + " to QuickBase", notification.getRecipient()); confirmationMessage.append("Has a video at https://www.quickbase.com/db/"+dbid+"?a=er&rid="+newRecord+"\n"); } catch (Exception e) { confirmationMessage.append("Was not able to attach a video named "+message.getFilename()); BrokerFactory.getLoggingBroker().logError(e); throw new NotificationException( NotificationException.FAILED, e.getMessage()); } } else if (!(message.getContentType().toLowerCase().startsWith( "text/") && (!message.getContentType().equalsIgnoreCase( NotificationMessage.NOTIFICATION_CONTENT_TYPE)))) { // If it's not text, not a picture, not a video, not a // notification message, then add it as // a "document", which is a generic binary data type foundAttachment = true; photoURL = BrokerFactory.getConfigurationBroker() .getStringValue("base.url") + "/AttachmentServlet?uuid=" + notification.getUuid() + "&messageID=" + messageNum; HashMap recorddata = new HashMap<String, String>(); BrokerFactory.getLoggingBroker().logDebug( "Adding to QB Record - " + messageFID + ": " + messageText); recorddata.put(subjectFID, notification.getSubject()); recorddata.put(relatedToFID, parentRID); recorddata.put(messageFID, messageText.toString().replaceAll("\\p{Cntrl}", "")); recorddata.put(addedByFID, notification.getSender().toString()); Matcher digitsMatcher = QuickBaseNotificationProvider.digitsPattern.matcher(notification.getSubject()); if (digitsMatcher.matches()) { recorddata.put ("Related "+digitsMatcher.group(1), digitsMatcher.group(2)); BrokerFactory.getLoggingBroker().logDebug("Relating subject \""+notification.getSubject()+"\" to field Related "+digitsMatcher.group(1)+": "+digitsMatcher.group(2)); } else { BrokerFactory.getLoggingBroker().logDebug("Subject \""+notification.getSubject()+"\" didn't match"); } recorddata.put(messageFID, messageText.toString().replaceAll("\\p{Cntrl}", "")); recorddata.put(addedByFID, notification.getSender().toString()); try { if (isFileField(documentFID, dbid, qbc)) { BrokerFactory.getLoggingBroker().logDebug( "Adding file to QB Record - " + photoFID + ": " + photoURL); recorddata.put(documentFID, new FileAttachment(message .getFilename(), message.getContent())); } else { if (!StringUtils.isEmpty(photoURL)) { BrokerFactory.getLoggingBroker().logDebug( "Adding url to QB Record - " + photoFID + ": " + photoURL); recorddata.put(documentFID, photoURL); } } String newRecord = qbc.addRecord(dbid, recorddata); notification.addMessage("Adding record #" + newRecord + " to QuickBase", notification.getRecipient()); confirmationMessage.append("Has a document at https://www.quickbase.com/db/"+dbid+"?a=er&rid="+newRecord+"\n"); } catch (Exception e) { confirmationMessage.append("Was not able to attach a video named "+message.getFilename()); BrokerFactory.getLoggingBroker().logError(e); throw new NotificationException( NotificationException.FAILED, e.getMessage()); } } } if (!foundAttachment) { // If we didn't find any attachments, go ahead and make a new record // w/ no attachment data HashMap recorddata = new HashMap<String, String>(); BrokerFactory.getLoggingBroker().logDebug( "Adding to QB Record - " + messageFID + ": " + messageText); recorddata.put(subjectFID, notification.getSubject()); recorddata.put(relatedToFID, parentRID); recorddata.put(messageFID, messageText.toString().replaceAll("\\p{Cntrl}", "")); recorddata.put(addedByFID, notification.getSender().toString()); Matcher digitsMatcher = QuickBaseNotificationProvider.digitsPattern.matcher(notification.getSubject()); if (digitsMatcher.matches()) { recorddata.put ("Related "+digitsMatcher.group(1), digitsMatcher.group(2)); BrokerFactory.getLoggingBroker().logDebug("Relating subject \""+notification.getSubject()+"\" to field Related "+digitsMatcher.group(1)+": "+digitsMatcher.group(2)); } else { BrokerFactory.getLoggingBroker().logDebug("Subject \""+notification.getSubject()+"\" didn't match"); } recorddata.put(messageFID, messageText.toString().replaceAll("\\p{Cntrl}", "")); recorddata.put(addedByFID, notification.getSender().toString()); try { String newRecord = qbc.addRecord(dbid, recorddata); notification.addMessage("Adding record #" + newRecord + " to QuickBase", notification.getRecipient()); } catch (Exception e) { BrokerFactory.getLoggingBroker().logError(e); throw new NotificationException(NotificationException.FAILED, e .getMessage()); } confirmationMessage.append("Had no attachments added"); } // Send out the confirmatiuon message NotificationSender sender = notification.getSender(); if (sendConfirmation && (sender instanceof EmailSender)) { try { EmailSender emailSender = (EmailSender) sender; User recipient = (User) notification.getRecipient(); InternetAddress[] returnAddress = new InternetAddress[1]; returnAddress[0] = new InternetAddress("noreply-" + recipient.getEmailAddress()); InternetAddress to = new InternetAddress(emailSender .getAddress()); Session session = Session.getDefaultInstance(System .getProperties(), null); session.getProperties().setProperty( "mail.smtp.host", BrokerFactory.getConfigurationBroker().getStringValue( "smtp.server", "localhost")); MimeMessage message = new MimeMessage(session); message.addFrom(returnAddress); message.addRecipient(MimeMessage.RecipientType.TO, to); message.setSubject("Upload to QuickBase confirmation"); message.setText(confirmationMessage.toString()); Transport.send(message); } catch (Exception anyExc) { BrokerFactory.getLoggingBroker().logWarn( "Couldn't send confirmation to " + sender); } } return new Hashtable(); } public static void main(String[] args) throws Exception { BrokerFactory.getConfigurationBroker().setConfiguration( new FileInputStream("conf/reliable.properties")); QuickBaseNotificationProvider qb = new QuickBaseNotificationProvider(); Matcher matcher = QuickBaseNotificationProvider.digitsPattern.matcher("Contact #123: foo"); System.out.println (matcher.matches()); System.out.println (matcher.group(1)); System.out.println (matcher.group(2)); } }