/* * FrontlineSMS <http://www.frontlinesms.com> * Copyright 2007, 2008 kiwanja * * This file is part of FrontlineSMS. * * FrontlineSMS is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * FrontlineSMS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FrontlineSMS. If not, see <http://www.gnu.org/licenses/>. */ package net.frontlinesms.csv; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.List; import net.frontlinesms.FrontlineUtils; import net.frontlinesms.data.domain.*; import net.frontlinesms.data.domain.FrontlineMessage.Type; import net.frontlinesms.data.repository.*; import net.frontlinesms.ui.UiGeneratorController; import net.frontlinesms.ui.i18n.InternationalisationUtils; import org.apache.log4j.Logger; import static net.frontlinesms.FrontlineSMSConstants.*; /** * This file contains methods for exporting data from the FrontlineSMS service to CSV files. * @author Alex Anderson alex(at)masabi(dot)com * @author Carlos Eduardo Genz * <li> kadu(at)masabi(dot)com </li> */ public class CsvExporter { //> STATIC CONSTANTS /** File extension for comma-separated value files */ public static final String CSV_FORMAT = "csv"; public static final String CSV_EXTENSION = "." + CSV_FORMAT; /** Logging object */ protected static Logger LOG = FrontlineUtils.getLogger(CsvExporter.class); /** The delimiter to use between group names when they are exported. */ public static final String GROUPS_DELIMITER = "\\"; //> UTILITY METHODS /** * Exports the passed messages to a file. * * @param exportFileName Filenane to be exported. * @param messages List of messages to be exported. * @param contactFactory * @throws IOException */ public static void export(String exportFileName, List<? extends FrontlineMessage> messages, ContactDao contactFactory) throws IOException { export(new File(exportFileName), messages, null, null, contactFactory); } /** * Exports the passed messages to a file, using the message and date formats * informed as well. * * @param exportFile Filename to be exported. * @param messages List of messages to be exported. * @param messageFormat The desired message format, if null, the default will be used. * @param dateFormat The desired date format, if null, the default will be used. * @param contactDao * @throws IOException */ public static void export(File exportFile, List<? extends FrontlineMessage> messages, CsvRowFormat messageFormat, String dateFormat, ContactDao contactDao) throws IOException { LOG.trace("ENTER"); if (messageFormat == null) messageFormat = getDefaultMessageExportFormat(); if (dateFormat == null) dateFormat = InternationalisationUtils.getI18nString(DEFAULT_EXPORT_DATE_FORMAT); LOG.debug("Message format [" + messageFormat + "]"); LOG.debug("Date format [" + dateFormat + "]"); LOG.debug("Filename [" + exportFile.getAbsolutePath() + "]"); Utf8FileWriter out = null; try { DateFormat dateFormatter = new SimpleDateFormat(dateFormat); out = new Utf8FileWriter(exportFile); CsvUtils.writeLine(out, messageFormat, CsvUtils.MARKER_MESSAGE_DATE, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_DATE), CsvUtils.MARKER_SENDER_NAME, /*->*/ InternationalisationUtils.getI18nString(COMMON_SENDER_NAME), CsvUtils.MARKER_SENDER_NUMBER, /*->*/ InternationalisationUtils.getI18nString(COMMON_SENDER_NUMBER), CsvUtils.MARKER_RECIPIENT_NAME, /*->*/ InternationalisationUtils.getI18nString(COMMON_RECIPIENT_NAME), CsvUtils.MARKER_RECIPIENT_NUMBER, /*->*/ InternationalisationUtils.getI18nString(COMMON_RECIPIENT_NUMBER), CsvUtils.MARKER_MESSAGE_CONTENT, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_CONTENT)); for (FrontlineMessage message : messages) { Contact sender = contactDao.getFromMsisdn(message.getSenderMsisdn()); String senderName = sender == null ? "" : sender.getName(); Contact recipient = contactDao.getFromMsisdn(message.getRecipientMsisdn()); String recipientName = recipient == null ? "" : recipient.getName(); CsvUtils.writeLine(out, messageFormat, CsvUtils.MARKER_MESSAGE_DATE, /*->*/ dateFormatter.format(new Date(message.getDate())), CsvUtils.MARKER_SENDER_NAME, /*->*/ senderName, CsvUtils.MARKER_SENDER_NUMBER, /*->*/ message.getSenderMsisdn(), CsvUtils.MARKER_RECIPIENT_NAME, /*->*/ recipientName, CsvUtils.MARKER_RECIPIENT_NUMBER, /*->*/ message.getSenderMsisdn(), CsvUtils.MARKER_MESSAGE_CONTENT, /*->*/ message.getTextContent().replace('\n', ' ').replace('\r', ' ')); } } finally { if (out != null) out.close(); LOG.trace("EXIT"); } } /** * Exports the passed messages to a file, using the given format. * * @param exportFile Filenane to be exported. * @param messages List of messages to be exported. * @param messageFormat The desired message format. * @param contactFactory * @throws IOException */ public static void exportMessages(File exportFile, Collection<FrontlineMessage> messages, CsvRowFormat messageFormat, ContactDao contactFactory) throws IOException { LOG.trace("ENTER : messages: " + messages.size()); LOG.debug("Message format [" + messageFormat + "]"); LOG.debug("Filename [" + exportFile.getAbsolutePath() + "]"); Utf8FileWriter out = null; try { DateFormat dateFormatter = new SimpleDateFormat(InternationalisationUtils.getI18nString(DEFAULT_EXPORT_DATE_FORMAT)); out = new Utf8FileWriter(exportFile); CsvUtils.writeLine(out, messageFormat, CsvUtils.MARKER_MESSAGE_TYPE, InternationalisationUtils.getI18nString(COMMON_MESSAGE_TYPE), CsvUtils.MARKER_MESSAGE_STATUS, InternationalisationUtils.getI18nString(COMMON_MESSAGE_STATUS), CsvUtils.MARKER_MESSAGE_DATE, InternationalisationUtils.getI18nString(COMMON_MESSAGE_DATE), CsvUtils.MARKER_MESSAGE_CONTENT, InternationalisationUtils.getI18nString(COMMON_MESSAGE_CONTENT), CsvUtils.MARKER_SENDER_NUMBER, InternationalisationUtils.getI18nString(COMMON_SENDER_NUMBER), CsvUtils.MARKER_RECIPIENT_NUMBER, InternationalisationUtils.getI18nString(COMMON_RECIPIENT_NUMBER), CsvUtils.MARKER_CONTACT_NAME, InternationalisationUtils.getI18nString(COMMON_CONTACT_NAME), CsvUtils.MARKER_CONTACT_OTHER_PHONE, InternationalisationUtils.getI18nString(COMMON_CONTACT_OTHER_PHONE_NUMBER), CsvUtils.MARKER_CONTACT_EMAIL, InternationalisationUtils.getI18nString(COMMON_CONTACT_E_MAIL_ADDRESS), CsvUtils.MARKER_CONTACT_NOTES, InternationalisationUtils.getI18nString(COMMON_CONTACT_NOTES)); for (FrontlineMessage message : messages) { Contact c; if (message.getType() == Type.RECEIVED) { c = contactFactory.getFromMsisdn(message.getSenderMsisdn()); } else { c = contactFactory.getFromMsisdn(message.getRecipientMsisdn()); } String name = ""; String otherPhone = ""; String email = ""; String notes = ""; String messageContent = ""; if (c != null) { name = c.getName(); otherPhone = c.getOtherPhoneNumber(); email = c.getEmailAddress(); notes = c.getNotes(); } if (message instanceof FrontlineMultimediaMessage) { messageContent = ((FrontlineMultimediaMessage) message).toString(false); } else { messageContent = message.getTextContent(); } CsvUtils.writeLine(out, messageFormat, CsvUtils.MARKER_MESSAGE_TYPE, InternationalisationUtils.getI18nString( message.getType() == Type.RECEIVED ? COMMON_RECEIVED : COMMON_SENT, InternationalisationUtils.getDefaultLanguageBundle()), CsvUtils.MARKER_MESSAGE_STATUS, UiGeneratorController.getMessageStatusAsString(message, InternationalisationUtils.getDefaultLanguageBundle()), CsvUtils.MARKER_MESSAGE_DATE, dateFormatter.format(new Date(message.getDate())), CsvUtils.MARKER_MESSAGE_CONTENT, messageContent.replace('\n', ' ').replace('\r', ' '), CsvUtils.MARKER_SENDER_NUMBER, message.getSenderMsisdn(), CsvUtils.MARKER_RECIPIENT_NUMBER, message.getRecipientMsisdn(), CsvUtils.MARKER_CONTACT_NAME, name, CsvUtils.MARKER_CONTACT_OTHER_PHONE, otherPhone, CsvUtils.MARKER_CONTACT_EMAIL, email, CsvUtils.MARKER_CONTACT_NOTES, notes); } } finally { if (out != null) out.close(); LOG.trace("EXIT"); } } /** * Exports the passed contacts to a file, using the given format. * * @param exportFile Filenane to be exported. * @param contacts List of contacts to be exported. * @param contactFormat The desired contact format. * @throws IOException */ public static void exportContacts(File exportFile, List<? extends Contact> contacts, GroupMembershipDao groupMembershipDao, CsvRowFormat contactFormat) throws IOException { LOG.trace("ENTER"); LOG.debug("Contact format [" + contactFormat + "]"); LOG.debug("Filename [" + exportFile.getAbsolutePath() + "]"); Utf8FileWriter out = null; try { out = new Utf8FileWriter(exportFile); CsvUtils.writeLine(out, contactFormat, CsvUtils.MARKER_CONTACT_NAME, InternationalisationUtils.getI18nString(COMMON_NAME), CsvUtils.MARKER_CONTACT_PHONE, InternationalisationUtils.getI18nString(COMMON_PHONE_NUMBER), CsvUtils.MARKER_CONTACT_OTHER_PHONE, InternationalisationUtils.getI18nString(COMMON_OTHER_PHONE_NUMBER), CsvUtils.MARKER_CONTACT_EMAIL, InternationalisationUtils.getI18nString(COMMON_E_MAIL_ADDRESS), CsvUtils.MARKER_CONTACT_STATUS, InternationalisationUtils.getI18nString(COMMON_CURRENT_STATUS), CsvUtils.MARKER_CONTACT_NOTES, InternationalisationUtils.getI18nString(COMMON_NOTES), CsvUtils.MARKER_CONTACT_GROUPS, InternationalisationUtils.getI18nString(COMMON_AT_LEAST_ONE_GROUP)); for (Contact contact : contacts) { CsvUtils.writeLine(out, contactFormat, CsvUtils.MARKER_CONTACT_NAME, contact.getName(), CsvUtils.MARKER_CONTACT_PHONE, contact.getPhoneNumber(), CsvUtils.MARKER_CONTACT_OTHER_PHONE, contact.getOtherPhoneNumber(), CsvUtils.MARKER_CONTACT_EMAIL, contact.getEmailAddress(), CsvUtils.MARKER_CONTACT_STATUS, Boolean.toString(contact.isActive()), CsvUtils.MARKER_CONTACT_NOTES, contact.getNotes(), CsvUtils.MARKER_CONTACT_GROUPS, FrontlineUtils.contactGroupsAsString(groupMembershipDao.getGroups(contact), GROUPS_DELIMITER)); } } finally { if(out!= null) out.close(); LOG.trace("EXIT"); } } /** * Exports the passed keywords to a file, using the given format. * * @param exportFile Filename to be exported. * @param keywords List of keywords to be exported. * @param rowFormat The desired message format. * @param contactFactory * @param messageFactory * @param messageType * @throws IOException */ public static void exportKeywords(File exportFile, List<? extends Keyword> keywords, CsvRowFormat rowFormat, ContactDao contactFactory, MessageDao messageFactory, FrontlineMessage.Type messageType) throws IOException { LOG.trace("ENTER"); LOG.debug("Keyword format [" + rowFormat + "]"); LOG.debug("Filename [" + exportFile.getAbsolutePath() + "]"); Utf8FileWriter out = null; try { DateFormat dateFormatter = new SimpleDateFormat(InternationalisationUtils.getI18nString(DEFAULT_EXPORT_DATE_FORMAT)); out = new Utf8FileWriter(exportFile); CsvUtils.writeLine(out, rowFormat, CsvUtils.MARKER_KEYWORD_KEY, /*->*/ InternationalisationUtils.getI18nString(COMMON_KEYWORD), CsvUtils.MARKER_KEYWORD_DESCRIPTION, /*->*/ InternationalisationUtils.getI18nString(COMMON_KEYWORD_DESCRIPTION), CsvUtils.MARKER_MESSAGE_TYPE, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_TYPE), CsvUtils.MARKER_MESSAGE_DATE, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_DATE), CsvUtils.MARKER_MESSAGE_CONTENT, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_CONTENT), CsvUtils.MARKER_SENDER_NUMBER, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_SENDER), CsvUtils.MARKER_RECIPIENT_NUMBER, /*->*/ InternationalisationUtils.getI18nString(COMMON_MESSAGE_RECIPIENT), CsvUtils.MARKER_CONTACT_NAME, /*->*/ InternationalisationUtils.getI18nString(COMMON_CONTACT_NAME), CsvUtils.MARKER_CONTACT_OTHER_PHONE, /*->*/ InternationalisationUtils.getI18nString(COMMON_CONTACT_OTHER_PHONE_NUMBER), CsvUtils.MARKER_CONTACT_EMAIL, /*->*/ InternationalisationUtils.getI18nString(COMMON_CONTACT_E_MAIL_ADDRESS), CsvUtils.MARKER_CONTACT_NOTES, /*->*/ InternationalisationUtils.getI18nString(COMMON_CONTACT_NOTES)); for (Keyword keyword : keywords) { if (messageType == null) { // User dont want any message from this keywords. CsvUtils.writeLine(out, rowFormat, CsvUtils.MARKER_KEYWORD_KEY, /*->*/ keyword.getKeyword(), CsvUtils.MARKER_KEYWORD_DESCRIPTION, /*->*/ keyword.getDescription()); } else { for (FrontlineMessage message : messageFactory.getMessagesForKeyword(messageType, keyword)) { Contact c; if (message.getType() == Type.RECEIVED) { c = contactFactory.getFromMsisdn(message.getSenderMsisdn()); } else { c = contactFactory.getFromMsisdn(message.getRecipientMsisdn()); } String name = ""; String otherPhone = ""; String email = ""; String notes = ""; if (c != null) { name = c.getName(); otherPhone = c.getOtherPhoneNumber(); email = c.getEmailAddress(); notes = c.getNotes(); } CsvUtils.writeLine(out, rowFormat, CsvUtils.MARKER_KEYWORD_KEY, /*->*/ keyword.getKeyword(), CsvUtils.MARKER_KEYWORD_DESCRIPTION, /*->*/ keyword.getDescription(), CsvUtils.MARKER_MESSAGE_TYPE, /*->*/ message.getType() == Type.RECEIVED ? InternationalisationUtils.getI18nString(COMMON_RECEIVED) : InternationalisationUtils.getI18nString(COMMON_SENT), CsvUtils.MARKER_MESSAGE_DATE, /*->*/ dateFormatter.format(new Date(message.getDate())), CsvUtils.MARKER_MESSAGE_CONTENT, /*->*/ message.getTextContent().replace('\n', ' ').replace('\r', ' '), CsvUtils.MARKER_SENDER_NUMBER, /*->*/ message.getSenderMsisdn(), CsvUtils.MARKER_RECIPIENT_NUMBER, /*->*/ message.getRecipientMsisdn(), CsvUtils.MARKER_CONTACT_NAME, /*->*/ name, CsvUtils.MARKER_CONTACT_OTHER_PHONE, /*->*/ otherPhone, CsvUtils.MARKER_CONTACT_EMAIL, /*->*/ email, CsvUtils.MARKER_CONTACT_NOTES, /*->*/ notes); } } } } finally { if (out != null) out.close(); LOG.trace("EXIT"); } } /** @return the default pattern for exporting messages */ private static final CsvRowFormat getDefaultMessageExportFormat() { CsvRowFormat rowFormat = new CsvRowFormat(); rowFormat.addMarker(CsvUtils.MARKER_SENDER_NUMBER); rowFormat.addMarker(CsvUtils.MARKER_SENDER_NAME); rowFormat.addMarker(CsvUtils.MARKER_RECIPIENT_NUMBER); rowFormat.addMarker(CsvUtils.MARKER_RECIPIENT_NAME); rowFormat.addMarker(CsvUtils.MARKER_MESSAGE_CONTENT); rowFormat.addMarker(CsvUtils.MARKER_MESSAGE_DATE); return rowFormat; } }