/*******************************************************************************
* Copyright (c) 2013 Hani Naguib.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* Hani Naguib - initial API and implementation
******************************************************************************/
package com.gvmax.server.handlers;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.gvmax.common.model.Email;
import com.gvmax.common.model.Stats;
import com.gvmax.common.model.User;
import com.gvmax.common.relay.GVMaxRelay;
import com.gvmax.common.util.MiscUtils;
import com.gvmax.common.util.PhoneUtil;
import com.gvmax.data.user.UserDAO;
import com.gvmax.server.util.ContactUtil;
import com.gvmax.server.util.Notifier;
public class SMSInHandler {
private static final Logger logger = Logger.getLogger(SMSInHandler.class);
private UserDAO userDAO;
private GVMaxRelay relay;
// Extracted Info
private User user;
private SMS sms;
public SMSInHandler(UserDAO userDAO, GVMaxRelay relay) {
this.userDAO = userDAO;
this.relay = relay;
}
public void handle(Email email) {
extractInfo(email);
if (user == null) {
logger.debug("Unable to retrieve user from email: " + email.getTo());
return;
}
if (sms == null) {
logger.debug("Unable to retrieve sms from email");
return;
}
if (!user.isMonitorSMS()) {
return;
}
userDAO.incrementSMSInCount(user.getEmail());
Notifier notifier = new Notifier(user, userDAO, relay);
// Send notifications
if (user.isSendProwl()) {
try {
notifier.sendProwlNotification("GV SMS", sms.contact, sms.text, user.getProwlSMSPriority());
} catch (IOException e) {
MiscUtils.emptyBlock();
}
}
if (user.isSendHowl()) {
try {
notifier.sendHowlNotification("GV SMS", sms.contact, sms.text);
} catch (IOException e) {
MiscUtils.emptyBlock();
}
}
if (user.isSendEmail()) {
notifier.sendEmailNotification(sms.number, "New SMS from " + sms.contact, sms.text);
}
if (user.isSendSMS()) {
notifier.sendSMSNotification(sms.number, sms.text);
}
if (user.isSendPost()) {
notifier.sendPostNotification("SMS", sms.number, sms.contact, sms.text, null);
}
if (user.isSendTwitter()) {
notifier.sendTwitterNotification(" SMS from " + sms.contact + " - " + sms.text);
}
if (user.isSendAutoResponse()) {
notifier.sendAutoResponse(sms.number);
}
if (user.isSendGTalk()) {
boolean sent = notifier.sendGTalkNotification(sms.number, sms.contact, sms.text);
if (sent) {
userDAO.clearFallbackCount(user.getEmail());
}
if (!sent && notifier.canFallback()) {
if (!StringUtils.isBlank(user.getProwlApiKeys())) {
try {
logger.warn("Attempting to fallback to prowl");
notifier.sendProwlNotification("GV SMS", sms.contact, sms.text, user.getProwlSMSPriority());
return;
} catch (IOException e) {
MiscUtils.emptyBlock();
}
}
if (!StringUtils.isBlank(user.getHowlUsername())) {
try {
logger.warn("Attempting to fallback to howl");
notifier.sendHowlNotification("GV SMS", sms.contact, sms.text);
return;
} catch (IOException e) {
MiscUtils.emptyBlock();
}
}
Stats stats = userDAO.getStats(user.getEmail());
if (stats == null) {
logger.error("unable to find stats for user: "+user.getEmail());
return;
}
logger.warn("Attempting to fallback to email: fbc=" + stats.getFallbackCount());
userDAO.incrementFallbackCount(user.getEmail());
if (stats.getFallbackCount() < 10) {
String msg = sms.text;
msg += "\n\nYou are receiving this email because GVMax was unable to send you a GTalk notification.";
msg += "\nPlease ensure you are logged into GTalk";
notifier.sendEmailNotification(sms.number, "SMS from " + sms.contact, msg);
}
}
}
}
// ----------------
// EXTRACT INFO
// ----------------
static class SMS {
private String number;
private String contact;
private String text;
}
private void extractInfo(Email email) {
String pin = email.getTo().substring(0, email.getTo().indexOf("@"));
user = userDAO.retrieveByPin(pin);
if (user == null) {
return;
}
extractSMS(email);
}
private void extractSMS(Email email) {
sms = new SMS();
// Number
sms.number = extractSMSNumber(email.getSubject());
// Contact
sms.contact = extractSMSContact(user, email.getSubject(), sms.number);
// Text
StringBuffer text = new StringBuffer("");
// Extract smsText (note special support for beejive media links)
try {
BufferedReader reader = new BufferedReader(new StringReader(email.getText()));
String line = reader.readLine();
while (line != null) {
// Special beejive tweek to deal with media content
if (line.contains("beejive.com")) {
line += " ";
} else {
line = line.trim();
}
if (line.equals("--")) {
break;
}
if (!"".equals(line)) {
text.append(line);
text.append("\n");
}
line = reader.readLine();
}
} catch (Exception e) {
sms = null;
return;
}
sms.text = text.toString();
if (!"".equals(sms.text)) {
sms.text = sms.text.substring(0, sms.text.length() - 1);
}
return;
}
private static String extractSMSNumber(String subject) {
String fromNumber = subject.substring("SMS from ".length());
int bPos = fromNumber.indexOf('[');
if (bPos != -1) {
fromNumber = fromNumber.substring(bPos + 1, fromNumber.length() - 1);
}
return PhoneUtil.normalizeNumber(fromNumber);
}
private static String extractSMSContact(User user, String subject, String number) {
String contact = ContactUtil.getContact(user, number);
if (contact == null) {
contact = extractSMSContactFromSubject(subject);
}
if (contact == null) {
contact = number;
}
return contact;
}
private static String extractSMSContactFromSubject(String subject) {
String from = subject.substring("SMS from ".length());
int bPos = from.indexOf('[');
if (bPos != -1) {
return from.substring(0, bPos).trim();
}
return null;
}
}