Search in sources :

Example 1 with UsedImagesDirective

use of com.serotonin.m2m2.email.UsedImagesDirective in project ma-modules-public by infiniteautomation.

the class ReportChartCreator method createContent.

/**
 * Uses the given parameters to create the data for the fields of this class. Once the content has been created the
 * getters for the fields can be used to retrieve.
 *
 * @param host - Mango's hostname
 * @param port - Mango's port
 * @param reportInstance
 * @param reportDao
 * @param inlinePrefix
 *            if this is non-null, it implies that the content should be inline.
 * @param createExportFile
 */
public void createContent(String host, int port, ReportInstance reportInstance, ReportDao reportDao, String inlinePrefix, boolean createExportFile) {
    this.inlinePrefix = inlinePrefix;
    reportInstance.setTranslations(translations);
    // Use a stream handler to get the report data from the database.
    StreamHandler handler = new StreamHandler(host, port, reportInstance.getXidMap(), reportInstance.getReportStartTime(), reportInstance.getReportEndTime(), IMAGE_WIDTH, createExportFile, translations);
    // Process the report content with the handler.
    if (Common.databaseProxy.getNoSQLProxy() == null)
        reportDao.reportInstanceDataSQL(reportInstance.getId(), handler);
    else
        reportDao.reportInstanceDataNoSQL(reportInstance.getId(), handler);
    pointStatistics = handler.getPointStatistics();
    devices = handler.getDevices();
    pointMap = handler.getStatisticsMap();
    UsedImagesDirective inlineImages = new UsedImagesDirective();
    SubjectDirective subjectDirective = new SubjectDirective(translations);
    // Prepare the model for the content rendering.
    Map<String, Object> model = new HashMap<String, Object>();
    model.put("fmt", new MessageFormatDirective(translations));
    model.put("subject", subjectDirective);
    model.put("img", inlineImages);
    model.put("instance", reportInstance);
    model.put("timezone", timeZone.getID());
    model.put("points", pointStatistics);
    model.put("inline", inlinePrefix == null ? "" : "cid:");
    model.put("devices", devices);
    model.put("mapped", pointMap);
    model.put("ALPHANUMERIC", DataTypes.ALPHANUMERIC);
    model.put("BINARY", DataTypes.BINARY);
    model.put("MULTISTATE", DataTypes.MULTISTATE);
    model.put("NUMERIC", DataTypes.NUMERIC);
    model.put("IMAGE", DataTypes.IMAGE);
    // Create the individual point charts
    for (PointStatistics pointStat : pointStatistics) {
        PointTimeSeriesCollection ptsc = new PointTimeSeriesCollection(timeZone);
        if (pointStat.getNumericTimeSeries() != null)
            ptsc.addNumericTimeSeries(pointStat.getNumericTimeSeries());
        else if (pointStat.getDiscreteTimeSeries() != null)
            ptsc.addDiscreteTimeSeries(pointStat.getDiscreteTimeSeries());
        if (ptsc.hasData()) {
            if (inlinePrefix != null)
                model.put("chartName", inlinePrefix + pointStat.getChartName());
            pointStat.setImageData(ImageChartUtils.getChartData(ptsc, POINT_IMAGE_WIDTH, POINT_IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime()));
        }
        // in the report I'll add it here while we are already iterating over the points that are included in the report
        if (pointStat.getDataType() == DataTypes.IMAGE) {
            ValueChangeCounter pointStatisticsGenerator = (ValueChangeCounter) pointStat.getStats();
            ImageValue img = (ImageValue) (pointStatisticsGenerator.getLastValue());
            if (img != null) {
                try {
                    pointStat.setImageData(img.getImageData());
                    if (inlinePrefix != null)
                        model.put("chartName", inlinePrefix + pointStat.getChartName());
                    else {
                        // serve up the image using the reportImageChart servlet instead of the imageValueServlet that is used on flipbook page
                        // The path comes from the servlet path definition in web.xml.
                        model.put("chartName", IMAGE_SERVLET + pointStat.getChartName());
                    }
                } catch (IOException e) {
                    LOG.error("failed to retrieve image data", e);
                }
            }
        }
    }
    // consolidated chart
    PointTimeSeriesCollection ptsc = handler.getPointTimeSeriesCollection();
    if (ptsc.hasData()) {
        if (inlinePrefix != null)
            model.put("chartName", inlinePrefix + IMAGE_CONTENT_ID);
        else {
            chartName = "r" + reportInstance.getId() + ".png";
            // The path comes from the servlet path definition in web.xml.
            model.put("chartName", IMAGE_SERVLET + chartName);
        }
        imageData = ImageChartUtils.getChartData(ptsc, true, IMAGE_WIDTH, IMAGE_HEIGHT, reportInstance.getReportStartTime(), reportInstance.getReportEndTime());
    }
    List<EventInstance> events = null;
    if (reportInstance.getIncludeEvents() != ReportVO.EVENTS_NONE) {
        events = reportDao.getReportInstanceEvents(reportInstance.getId());
        model.put("includeEvents", true);
        model.put("events", events);
    } else
        model.put("includeEvents", false);
    List<ReportUserComment> comments = null;
    if (reportInstance.isIncludeUserComments()) {
        comments = reportDao.getReportInstanceUserComments(reportInstance.getId());
        // Only provide the list of point comments to the report. The event comments have already be correlated
        // into the events list.
        List<ReportUserComment> pointComments = new ArrayList<ReportUserComment>();
        for (ReportUserComment c : comments) {
            if (c.getCommentType() == UserCommentVO.TYPE_POINT)
                pointComments.add(c);
        }
        model.put("includeUserComments", true);
        model.put("userComments", pointComments);
    } else
        model.put("includeUserComments", false);
    // Create the template.
    Template ftl;
    StringWriter writer = new StringWriter();
    FileReader reader = null;
    try {
        File templateFile = ReportCommon.instance.getTemplateFile(reportInstance.getTemplateFile());
        reader = new FileReader(templateFile);
        ftl = new Template(reportInstance.getName(), reader, Common.freemarkerConfiguration);
        ftl.process(model, writer);
    } catch (FileNotFoundException e) {
        LOG.error("Unable to find report template file: " + reportInstance.getName());
    } catch (IOException e) {
        // Couldn't load the template?
        throw new ShouldNeverHappenException(e);
    } catch (Exception e) {
        // Error processing the FTL?
        throw new ShouldNeverHappenException(e);
    } finally {
        if (reader != null)
            try {
                reader.close();
            } catch (IOException e) {
                LOG.error("Error closing template file reader: " + e.getMessage(), e);
            }
    }
    // Save the content
    html = writer.toString();
    subject = subjectDirective.getSubject();
    inlineImageList = inlineImages.getImageList();
    // Save the export file (if any)
    exportFile = handler.exportFile;
    if (createExportFile && events != null) {
        try {
            eventFile = File.createTempFile("tempEventCSV", ".csv");
            new EventCsvStreamer(new PrintWriter(new FileWriter(eventFile)), events, translations);
        } catch (IOException e) {
            LOG.error("Failed to create temp event file", e);
        }
    }
    if (createExportFile && comments != null) {
        try {
            commentFile = File.createTempFile("tempCommentCSV", ".csv");
            new UserCommentCsvStreamer(new PrintWriter(new FileWriter(commentFile)), comments, translations);
        } catch (IOException e) {
            LOG.error("Failed to create temp comment file", e);
        }
    }
}
Also used : EventInstance(com.serotonin.m2m2.rt.event.EventInstance) EventCsvStreamer(com.serotonin.m2m2.vo.export.EventCsvStreamer) HashMap(java.util.HashMap) PointTimeSeriesCollection(com.serotonin.m2m2.util.chart.PointTimeSeriesCollection) FileWriter(java.io.FileWriter) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) Template(freemarker.template.Template) MessageFormatDirective(com.serotonin.m2m2.email.MessageFormatDirective) StringWriter(java.io.StringWriter) ExportDataStreamHandler(com.serotonin.m2m2.vo.export.ExportDataStreamHandler) ValueChangeCounter(com.serotonin.m2m2.view.stats.ValueChangeCounter) UsedImagesDirective(com.serotonin.m2m2.email.UsedImagesDirective) FileReader(java.io.FileReader) PrintWriter(java.io.PrintWriter) IOException(java.io.IOException) InvalidArgumentException(com.serotonin.InvalidArgumentException) FileNotFoundException(java.io.FileNotFoundException) ShouldNeverHappenException(com.serotonin.ShouldNeverHappenException) IOException(java.io.IOException) SubjectDirective(com.serotonin.m2m2.email.SubjectDirective) ShouldNeverHappenException(com.serotonin.ShouldNeverHappenException) ImageValue(com.serotonin.m2m2.rt.dataImage.types.ImageValue) File(java.io.File)

Example 2 with UsedImagesDirective

use of com.serotonin.m2m2.email.UsedImagesDirective in project ma-core-public by infiniteautomation.

the class EmailHandlerRT method sendEmail.

private static void sendEmail(EventInstance evt, NotificationType notificationType, Set<String> addresses, String alias, boolean includeSystemInfo, int pointValueCount, boolean includeLogs, String handlerXid, String customTemplate, List<IntStringPair> additionalContext, String script, SetCallback setCallback, ScriptPermissions permissions) {
    if (evt.getEventType().isSystemMessage()) {
        if (((SystemEventType) evt.getEventType()).getSystemEventType().equals(SystemEventType.TYPE_EMAIL_SEND_FAILURE)) {
            // Don't send email notifications about email send failures.
            LOG.info("Not sending email for event raised due to email failure");
            return;
        }
    }
    Translations translations = Common.getTranslations();
    if (StringUtils.isBlank(alias)) {
        // Just set the subject to the message
        alias = evt.getMessage().translate(translations);
        // Strip out the HTML and the &nbsp
        alias = StringEscapeUtils.unescapeHtml4(alias);
        // Since we have <br/> in the code and that isn't proper HTML we need to remove it by hand
        alias = alias.replace("<br/>", "\n");
    }
    // end if alias was blank
    // Determine the subject to use.
    TranslatableMessage subjectMsg;
    TranslatableMessage notifTypeMsg = new TranslatableMessage(notificationType.getKey());
    if (StringUtils.isBlank(alias)) {
        // Make these more descriptive
        if (evt.getId() == Common.NEW_ID)
            subjectMsg = new TranslatableMessage("ftl.subject.default", notifTypeMsg);
        else
            subjectMsg = new TranslatableMessage("ftl.subject.default.id", notifTypeMsg, evt.getId());
    } else {
        if (evt.getId() == Common.NEW_ID)
            subjectMsg = new TranslatableMessage("ftl.subject.alias", alias, notifTypeMsg);
        else
            subjectMsg = new TranslatableMessage("ftl.subject.alias.id", alias, notifTypeMsg, evt.getId());
    }
    String alarmLevel = AlarmLevels.getAlarmLevelMessage(evt.getAlarmLevel()).translate(translations);
    String subject = alarmLevel + " - " + subjectMsg.translate(translations);
    // Trim the subject if its too long
    if (subject.length() > 200)
        subject = subject.substring(0, 200);
    try {
        String[] toAddrs = addresses.toArray(new String[0]);
        UsedImagesDirective inlineImages = new UsedImagesDirective();
        // Send the email.
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("evt", evt);
        if (evt.getContext() != null)
            model.putAll(evt.getContext());
        model.put("img", inlineImages);
        model.put("instanceDescription", SystemSettingsDao.getValue(SystemSettingsDao.INSTANCE_DESCRIPTION));
        if (includeSystemInfo) {
            // Get the Work Items
            List<WorkItemModel> highPriorityWorkItems = Common.backgroundProcessing.getHighPriorityServiceItems();
            model.put("highPriorityWorkItems", highPriorityWorkItems);
            List<WorkItemModel> mediumPriorityWorkItems = Common.backgroundProcessing.getMediumPriorityServiceQueueItems();
            model.put("mediumPriorityWorkItems", mediumPriorityWorkItems);
            List<WorkItemModel> lowPriorityWorkItems = Common.backgroundProcessing.getLowPriorityServiceQueueItems();
            model.put("lowPriorityWorkItems", lowPriorityWorkItems);
            model.put("threadList", getThreadsList());
        }
        int type = SystemSettingsDao.getIntValue(SystemSettingsDao.EMAIL_CONTENT_TYPE);
        // If we are a point event then add the value
        if (evt.getEventType() instanceof DataPointEventType) {
            DataPointVO dp = (DataPointVO) evt.getContext().get("point");
            if (dp != null) {
                DataPointRT rt = Common.runtimeManager.getDataPoint(dp.getId());
                if (rt != null) {
                    List<PointValueTime> pointValues = null;
                    if (pointValueCount > 0)
                        pointValues = rt.getLatestPointValues(pointValueCount);
                    if ((pointValues != null) && (pointValues.size() > 0)) {
                        if (type == MangoEmailContent.CONTENT_TYPE_HTML || type == MangoEmailContent.CONTENT_TYPE_BOTH) {
                            List<RenderedPointValueTime> renderedPointValues = new ArrayList<RenderedPointValueTime>();
                            for (PointValueTime pvt : pointValues) {
                                RenderedPointValueTime rpvt = new RenderedPointValueTime();
                                rpvt.setValue(Functions.getHtmlText(rt.getVO(), pvt));
                                rpvt.setTime(Functions.getFullSecondTime(pvt.getTime()));
                                renderedPointValues.add(rpvt);
                            }
                            model.put("renderedHtmlPointValues", renderedPointValues);
                        }
                        if (type == MangoEmailContent.CONTENT_TYPE_TEXT || type == MangoEmailContent.CONTENT_TYPE_BOTH) {
                            List<RenderedPointValueTime> renderedPointValues = new ArrayList<RenderedPointValueTime>();
                            for (PointValueTime pvt : pointValues) {
                                RenderedPointValueTime rpvt = new RenderedPointValueTime();
                                rpvt.setValue(Functions.getRenderedText(rt.getVO(), pvt));
                                rpvt.setTime(Functions.getFullSecondTime(pvt.getTime()));
                                renderedPointValues.add(rpvt);
                            }
                            model.put("renderedPointValues", renderedPointValues);
                        }
                    }
                }
            }
        }
        // Build the additional context for the email model
        if (additionalContext == null || pointValueCount <= 0)
            model.put("additionalContext", new HashMap<>(0));
        else {
            Map<String, Map<String, Object>> context = new HashMap<>();
            for (IntStringPair pair : additionalContext) {
                Map<String, Object> point = new HashMap<String, Object>();
                DataPointRT rt = Common.runtimeManager.getDataPoint(pair.getKey());
                List<PointValueTime> pointValues;
                List<RenderedPointValueTime> renderedPointValues;
                DataPointVO dpvo;
                if (rt != null) {
                    dpvo = rt.getVO();
                    pointValues = rt.getLatestPointValues(pointValueCount);
                    renderedPointValues = new ArrayList<RenderedPointValueTime>();
                    if (pointValues != null && pointValues.size() > 0)
                        for (PointValueTime pvt : pointValues) {
                            RenderedPointValueTime rpvt = new RenderedPointValueTime();
                            rpvt.setValue(Functions.getRenderedText(rt.getVO(), pvt));
                            rpvt.setTime(Functions.getFullSecondTime(pvt.getTime()));
                            renderedPointValues.add(rpvt);
                        }
                } else {
                    dpvo = DataPointDao.instance.get(pair.getKey());
                    if (dpvo == null)
                        continue;
                    pointValues = Common.databaseProxy.newPointValueDao().getLatestPointValues(pair.getKey(), pointValueCount);
                    renderedPointValues = new ArrayList<RenderedPointValueTime>();
                    for (PointValueTime pvt : pointValues) {
                        RenderedPointValueTime rpvt = new RenderedPointValueTime();
                        rpvt.setValue(Functions.getRenderedText(dpvo, pvt));
                        rpvt.setTime(Functions.getFullSecondTime(pvt.getTime()));
                        renderedPointValues.add(rpvt);
                    }
                }
                point.put("values", renderedPointValues);
                point.put("deviceName", dpvo.getDeviceName());
                point.put("name", dpvo.getName());
                point.put("contextKey", pair.getValue());
                context.put(pair.getValue(), point);
            }
            model.put("additionalContext", context);
        }
        if (!StringUtils.isEmpty(script)) {
            // Okay, a script is defined, let's pass it the model so that it may add to it
            Map<String, Object> modelContext = new HashMap<String, Object>();
            modelContext.put("model", model);
            Map<String, IDataPointValueSource> context = new HashMap<String, IDataPointValueSource>();
            for (IntStringPair pair : additionalContext) {
                DataPointRT dprt = Common.runtimeManager.getDataPoint(pair.getKey());
                if (dprt == null) {
                    DataPointVO targetVo = DataPointDao.instance.getDataPoint(pair.getKey(), false);
                    if (targetVo == null) {
                        LOG.warn("Additional context point with ID: " + pair.getKey() + " and context name " + pair.getValue() + " could not be found.");
                        // Not worth aborting the email, just warn it
                        continue;
                    }
                    if (targetVo.getDefaultCacheSize() == 0)
                        targetVo.setDefaultCacheSize(1);
                    dprt = new DataPointRT(targetVo, targetVo.getPointLocator().createRuntime(), DataSourceDao.instance.getDataSource(targetVo.getDataSourceId()), null);
                    dprt.resetValues();
                }
                context.put(pair.getValue(), dprt);
            }
            List<JsonImportExclusion> importExclusions = new ArrayList<JsonImportExclusion>(1);
            importExclusions.add(new JsonImportExclusion("xid", handlerXid) {

                @Override
                public String getImporterType() {
                    return ConfigurationExportData.EVENT_HANDLERS;
                }
            });
            try {
                CompiledScript compiledScript = CompiledScriptExecutor.compile(script);
                CompiledScriptExecutor.execute(compiledScript, context, modelContext, Common.timer.currentTimeMillis(), DataTypes.ALPHANUMERIC, evt.isActive() || !evt.isRtnApplicable() ? evt.getActiveTimestamp() : evt.getRtnTimestamp(), permissions, SetPointHandlerRT.NULL_WRITER, new ScriptLog(SetPointHandlerRT.NULL_WRITER, LogLevel.FATAL), setCallback, importExclusions, false);
            } catch (ScriptPermissionsException | ScriptException | ResultTypeException e) {
                LOG.error("Exception running email handler script: " + e.getMessage(), e);
            }
        }
        MangoEmailContent content;
        if (StringUtils.isEmpty(customTemplate))
            content = new MangoEmailContent(notificationType.getFile(), model, translations, subject, Common.UTF8);
        else
            content = new MangoEmailContent(handlerXid, customTemplate, model, translations, subject);
        PostEmailRunnable[] postEmail = null;
        if (includeLogs) {
            final File logZip = getZippedLogfile(content, new File(Common.getLogsDir(), "ma.log"));
            // Setup To delete the temp files from zip
            if (logZip != null) {
                // See that the temp file(s) gets deleted after the email is sent.
                PostEmailRunnable deleteTempFile = new PostEmailRunnable() {

                    @Override
                    public void run() {
                        if (!logZip.delete())
                            LOG.warn("Temp file " + logZip.getPath() + " not deleted");
                    // Set our state to email failed if necessary
                    // TODO Create an Event to notify of Failed Emails...
                    // if(!this.isSuccess()){}
                    }
                };
                postEmail = new PostEmailRunnable[] { deleteTempFile };
            }
        }
        for (String s : inlineImages.getImageList()) content.addInline(new EmailInline.FileInline(s, Common.getWebPath(s)));
        EmailWorkItem.queueEmail(toAddrs, content, postEmail);
    } catch (Exception e) {
        LOG.error("", e);
    }
}
Also used : CompiledScript(javax.script.CompiledScript) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JsonImportExclusion(com.serotonin.m2m2.rt.script.JsonImportExclusion) ScriptLog(com.serotonin.m2m2.rt.script.ScriptLog) WorkItemModel(com.serotonin.m2m2.web.mvc.rest.v1.model.workitem.WorkItemModel) ScriptException(javax.script.ScriptException) ResultTypeException(com.serotonin.m2m2.rt.script.ResultTypeException) ScriptPermissionsException(com.serotonin.m2m2.rt.script.ScriptPermissionsException) DataPointRT(com.serotonin.m2m2.rt.dataImage.DataPointRT) RenderedPointValueTime(com.serotonin.m2m2.web.dwr.beans.RenderedPointValueTime) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime) UsedImagesDirective(com.serotonin.m2m2.email.UsedImagesDirective) TranslatableMessage(com.serotonin.m2m2.i18n.TranslatableMessage) DataPointEventType(com.serotonin.m2m2.rt.event.type.DataPointEventType) DataPointVO(com.serotonin.m2m2.vo.DataPointVO) IntStringPair(com.serotonin.db.pair.IntStringPair) ScriptException(javax.script.ScriptException) ResultTypeException(com.serotonin.m2m2.rt.script.ResultTypeException) ScriptPermissionsException(com.serotonin.m2m2.rt.script.ScriptPermissionsException) IOException(java.io.IOException) PostEmailRunnable(com.serotonin.m2m2.email.PostEmailRunnable) RenderedPointValueTime(com.serotonin.m2m2.web.dwr.beans.RenderedPointValueTime) IDataPointValueSource(com.serotonin.m2m2.rt.dataImage.IDataPointValueSource) MangoEmailContent(com.serotonin.m2m2.email.MangoEmailContent) Translations(com.serotonin.m2m2.i18n.Translations) Map(java.util.Map) HashMap(java.util.HashMap) File(java.io.File)

Aggregations

UsedImagesDirective (com.serotonin.m2m2.email.UsedImagesDirective)2 File (java.io.File)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 InvalidArgumentException (com.serotonin.InvalidArgumentException)1 ShouldNeverHappenException (com.serotonin.ShouldNeverHappenException)1 IntStringPair (com.serotonin.db.pair.IntStringPair)1 MangoEmailContent (com.serotonin.m2m2.email.MangoEmailContent)1 MessageFormatDirective (com.serotonin.m2m2.email.MessageFormatDirective)1 PostEmailRunnable (com.serotonin.m2m2.email.PostEmailRunnable)1 SubjectDirective (com.serotonin.m2m2.email.SubjectDirective)1 TranslatableMessage (com.serotonin.m2m2.i18n.TranslatableMessage)1 Translations (com.serotonin.m2m2.i18n.Translations)1 DataPointRT (com.serotonin.m2m2.rt.dataImage.DataPointRT)1 IDataPointValueSource (com.serotonin.m2m2.rt.dataImage.IDataPointValueSource)1 PointValueTime (com.serotonin.m2m2.rt.dataImage.PointValueTime)1 ImageValue (com.serotonin.m2m2.rt.dataImage.types.ImageValue)1 EventInstance (com.serotonin.m2m2.rt.event.EventInstance)1 DataPointEventType (com.serotonin.m2m2.rt.event.type.DataPointEventType)1