/* * This source is part of the * _____ ___ ____ * __ / / _ \/ _ | / __/___ _______ _ * / // / , _/ __ |/ _/_/ _ \/ __/ _ `/ * \___/_/|_/_/ |_/_/ (_)___/_/ \_, / * /___/ * repository. * * Copyright (C) 2014-2015 Carmen Alvarez (c@rmen.ca) * * Licensed 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. */ package ca.rmen.android.networkmonitor.app.email; import android.content.Context; import android.text.TextUtils; import java.io.File; import java.util.Set; import ca.rmen.android.networkmonitor.BuildConfig; import ca.rmen.android.networkmonitor.Constants; import ca.rmen.android.networkmonitor.R; import ca.rmen.android.networkmonitor.app.dbops.backend.export.CSVExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.DBExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.ExcelExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.FileExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.GnuplotExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.HTMLExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.SummaryExport; import ca.rmen.android.networkmonitor.app.dbops.backend.export.kml.KMLExport; import ca.rmen.android.networkmonitor.app.email.EmailPreferences.EmailConfig; import ca.rmen.android.networkmonitor.app.email.EmailPreferences.EmailSecurity; import ca.rmen.android.networkmonitor.app.service.NetMonNotification; import ca.rmen.android.networkmonitor.provider.NetMonColumns; import ca.rmen.android.networkmonitor.util.Log; import java8.util.stream.Collectors; import java8.util.stream.StreamSupport; /** * Sends a mail to a recipient or recipients, including (or not) some file attachments with exports of the log. */ public class ReportEmailer { private static final String TAG = Constants.TAG + ReportEmailer.class.getSimpleName(); private final Context mContext; public ReportEmailer(Context context) { Log.v(TAG, "Constructor"); mContext = context.getApplicationContext(); } /** * Send the e-mail report. */ public synchronized void send() { Log.v(TAG, "send"); if (shouldSendMail()) { final EmailConfig emailConfig = EmailPreferences.getInstance(mContext).getEmailConfig(); if (emailConfig.isValid()) { sendEmail(emailConfig); } else { Log.w(TAG, "Cannot send mail with the current email settings: " + emailConfig); } } else { Log.v(TAG, "Won't send mail"); } } /** * @return true if it has been longer than our report interval since we last successfully sent a mail. */ private boolean shouldSendMail() { Log.v(TAG, "shouldSendMail"); int reportInterval = EmailPreferences.getInstance(mContext).getEmailReportInterval(); if (reportInterval == 0) { Log.v(TAG, "shouldSendMail: mails not enabled"); return false; } long lastEmailSent = EmailPreferences.getInstance(mContext).getLastEmailSent(); long now = System.currentTimeMillis(); Log.v(TAG, "shouldSendMail: sent mail " + (now - lastEmailSent) + " ms ago, vs report duration = " + reportInterval + " ms"); return now - lastEmailSent > reportInterval; } /** * Send the e-mail with the given e-mail settings. */ private void sendEmail(final EmailConfig emailConfig) { Log.v(TAG, "sendEmail: emailConfig = " + emailConfig); // Prepare the file attachments before we start to send the e-mail. Set<File> attachments = StreamSupport.stream(emailConfig.reportFormats) .map(this::createAttachment) .collect(Collectors.toSet()); final String protocol; if(emailConfig.security == EmailSecurity.TLS) protocol = "TLS"; else if(emailConfig.security == EmailSecurity.SSL) protocol = "SSL"; else protocol = null; String from = getFromAddress(emailConfig); String[] recipients = TextUtils.split(emailConfig.recipients.trim(), "[,; ]+"); String subject = mContext.getString(R.string.export_subject_send_log); String body = getMessageBody(emailConfig); try { Emailer.sendEmail(protocol, emailConfig.server, emailConfig.port, emailConfig.user, emailConfig.password, from, recipients, subject, body, attachments, BuildConfig.DEBUG); Log.v(TAG, "sent message"); // The mail was sent file. Dismiss the e-mail error notification if it's showing. NetMonNotification.dismissEmailFailureNotification(mContext); EmailPreferences.getInstance(mContext).setLastEmailSent(System.currentTimeMillis()); } catch (Exception e) { Log.e(TAG, "Could not send mail " + e.getMessage(), e); // There was an error sending the mail. Show an error notification. NetMonNotification.showEmailFailureNotification(mContext); } } /** * Construct the from address based on the user name and possibly the smtp server name. */ private static String getFromAddress(EmailConfig emailConfig) { Log.v(TAG, "getFromAddress: emailConfig = " + emailConfig); // We try to guess the from address. final String from; // If the user name for the smtp server is an e-mail address, we just use that. if (emailConfig.user.indexOf("@") > 0) { from = emailConfig.user; } // Otherwise we use the user@server. We try to strip any "smtp" part of the server domain. else { String server = emailConfig.server.replaceAll("smtp[^\\.]*\\.", ""); from = emailConfig.user + "@" + server; } Log.v(TAG, "getFromAddress: Sending mail from " + from); return from; } /** * @param fileType one of the file types the user selected in the preference * @return the BodyPart containing the exported file of this type. */ private File createAttachment(String fileType) { Log.v(TAG, "createAttachment: fileType = " + fileType); // Get the FileExport instance which can export mContext file type. final FileExport fileExport; switch(fileType) { case "csv": fileExport = new CSVExport(mContext); break; case "html": fileExport = new HTMLExport(mContext, true); break; case "excel": fileExport = new ExcelExport(mContext); break; case "kml": fileExport = new KMLExport(mContext, NetMonColumns.SOCKET_CONNECTION_TEST); break; case "gnuplot": fileExport = new GnuplotExport(mContext); break; case "db": default: fileExport = new DBExport(mContext); break; } fileExport.execute(null); return fileExport.getFile(); } /** * @return the text of the mail that the recipient will receive. */ private String getMessageBody(EmailConfig emailConfig) { Log.v(TAG, "getMessageBody, emailConfig =" + emailConfig); String reportSummary = SummaryExport.getSummary(mContext); String dateRange = SummaryExport.getDataCollectionDateRange(mContext); String messageBody = mContext.getString(R.string.export_message_text, dateRange); // If we're attaching files, add a sentence to the mail saying so. if (!emailConfig.reportFormats.isEmpty()) messageBody += mContext.getString(R.string.export_message_text_file_attached); messageBody += reportSummary; Log.v(TAG, "getMessageBody, created message body " + messageBody); return messageBody; } }