<commit_before>package com.hubspot.singularity.smtp;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.mesos.MesosUtils;
import com.hubspot.mesos.json.MesosFileChunkObject;
import com.hubspot.singularity.ExtendedTaskState;
import com.hubspot.singularity.SingularityTask;
import com.hubspot.singularity.SingularityTaskHistoryUpdate;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.config.EmailConfigurationEnums;
import com.hubspot.singularity.config.SMTPConfiguration;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.SandboxManager;
import org.apache.commons.lang3.text.WordUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * Helpers that get passed to the Jade renderer. These helpers manipulate information given to the
 * Jade context into different formats.
 */
@Singleton
public class MailTemplateHelpers {
  private static final Logger LOG = LoggerFactory.getLogger(SingularityMailer.class);

  /**
   * For fetching log files from mesos slaves.
   */
  private final SandboxManager sandboxManager;

  private static final String TASK_DATE_PATTERN = "MMM dd HH:mm:ss";
  private static final String TASK_LINK_FORMAT = "%s/task/%s";
  private static final String REQUEST_LINK_FORMAT = "%s/request/%s";
  private static final String LOG_LINK_FORMAT = "%s/task/%s/tail/%s";

  /**
   * Used to generate links, if no String is present, helpers will return empty Strings.
   */
  private final Optional<String> uiBaseUrl;
  private final Optional<SMTPConfiguration> smtpConfiguration;

  @Inject
  public MailTemplateHelpers(SandboxManager sandboxManager, SingularityConfiguration singularityConfiguration) {
    this.uiBaseUrl = singularityConfiguration.getUiConfiguration().getBaseUrl();
    this.sandboxManager = sandboxManager;
    this.smtpConfiguration = singularityConfiguration.getSmtpConfiguration();
  }

  /**
   * Format taskHistory information into a Map for Jade to generate a table from.
   *
   * @param taskHistory task history information.
   * @return map for Jade to pull "date", "update", and "message" information from.
   */
  public List<SingularityMailTaskHistoryUpdate> getJadeTaskHistory(Collection<SingularityTaskHistoryUpdate> taskHistory) {
    List<SingularityMailTaskHistoryUpdate> output = Lists.newArrayListWithCapacity(taskHistory.size());

    for (SingularityTaskHistoryUpdate taskUpdate : taskHistory) {
      output.add(
          new SingularityMailTaskHistoryUpdate(
              DateFormatUtils.formatUTC(taskUpdate.getTimestamp(), TASK_DATE_PATTERN), // date
              WordUtils.capitalize(taskUpdate.getTaskState().getDisplayName()), // update
              taskUpdate.getStatusMessage().or(""))); // message
    }

    return output;
  }

  /**
   * Format task logs into a List of SingularityMailTaskLog for Jade to interpret easily.
   *
   * @param taskId    task to get logs from.
   * @param task      task object to get logs from.
   * @param directory directory to read log from.
   * @return Jade interpretable List of SingularityMailTaskLog.
   */
  public List<SingularityMailTaskLog> getTaskLogs(SingularityTaskId taskId, Optional<SingularityTask> task, Optional<String> directory) {
    List<String> taskEmailTailFiles = smtpConfiguration.get().getTaskEmailTailFiles();
    List<SingularityMailTaskLog> logTails = Lists.newArrayListWithCapacity(taskEmailTailFiles.size());

    for (String filePath : taskEmailTailFiles) {
      // To enable support for tailing the service.log file, replace instances of $MESOS_TASK_ID.
      filePath = filePath.replaceAll("\\$MESOS_TASK_ID", MesosUtils.getSafeTaskIdForDirectory(taskId.getId()));

      logTails.add(
          new SingularityMailTaskLog(
              filePath,
              getFileName(filePath),
              getSingularityLogLink(filePath, taskId.getId()),
              getTaskLogFile(taskId, filePath, task, directory).or("")));
    }
<commit_msg>Be more defensive about Optionals. Add comment annotations to SingularityMailTaskLog constructor.<commit_after>package com.hubspot.singularity.smtp;

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.mesos.MesosUtils;
import com.hubspot.mesos.json.MesosFileChunkObject;
import com.hubspot.singularity.ExtendedTaskState;
import com.hubspot.singularity.SingularityTask;
import com.hubspot.singularity.SingularityTaskHistoryUpdate;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.config.EmailConfigurationEnums;
import com.hubspot.singularity.config.SMTPConfiguration;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.SandboxManager;
import org.apache.commons.lang3.text.WordUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;
import java.util.List;

/**
 * Helpers that get passed to the Jade renderer. These helpers manipulate information given to the
 * Jade context into different formats.
 */
@Singleton
public class MailTemplateHelpers {
  private static final Logger LOG = LoggerFactory.getLogger(SingularityMailer.class);

  /**
   * For fetching log files from mesos slaves.
   */
  private final SandboxManager sandboxManager;

  private static final String TASK_DATE_PATTERN = "MMM dd HH:mm:ss";
  private static final String TASK_LINK_FORMAT = "%s/task/%s";
  private static final String REQUEST_LINK_FORMAT = "%s/request/%s";
  private static final String LOG_LINK_FORMAT = "%s/task/%s/tail/%s";

  /**
   * Used to generate links, if no String is present, helpers will return empty Strings.
   */
  private final Optional<String> uiBaseUrl;
  private final Optional<SMTPConfiguration> smtpConfiguration;

  @Inject
  public MailTemplateHelpers(SandboxManager sandboxManager, SingularityConfiguration singularityConfiguration) {
    this.uiBaseUrl = singularityConfiguration.getUiConfiguration().getBaseUrl();
    this.sandboxManager = sandboxManager;
    this.smtpConfiguration = singularityConfiguration.getSmtpConfiguration();
  }

  /**
   * Format taskHistory information into a Map for Jade to generate a table from.
   *
   * @param taskHistory task history information.
   * @return map for Jade to pull "date", "update", and "message" information from.
   */
  public List<SingularityMailTaskHistoryUpdate> getJadeTaskHistory(Collection<SingularityTaskHistoryUpdate> taskHistory) {
    List<SingularityMailTaskHistoryUpdate> output = Lists.newArrayListWithCapacity(taskHistory.size());

    for (SingularityTaskHistoryUpdate taskUpdate : taskHistory) {
      output.add(
          new SingularityMailTaskHistoryUpdate(
              DateFormatUtils.formatUTC(taskUpdate.getTimestamp(), TASK_DATE_PATTERN), // date
              WordUtils.capitalize(taskUpdate.getTaskState().getDisplayName()), // update
              taskUpdate.getStatusMessage().or(""))); // message
    }

    return output;
  }

  /**
   * Format task logs into a List of SingularityMailTaskLog for Jade to interpret easily.
   *
   * @param taskId    task to get logs from.
   * @param task      task object to get logs from.
   * @param directory directory to read log from.
   * @return Jade interpretable List of SingularityMailTaskLog.
   */
  public List<SingularityMailTaskLog> getTaskLogs(SingularityTaskId taskId, Optional<SingularityTask> task, Optional<String> directory) {
    // No configuration for SMTP, what did you do to execute this?
    if (!smtpConfiguration.isPresent())
      return Lists.newArrayListWithCapacity(0);

    List<String> taskEmailTailFiles = smtpConfiguration.get().getTaskEmailTailFiles();
    List<SingularityMailTaskLog> logTails = Lists.newArrayListWithCapacity(taskEmailTailFiles.size());

    for (String filePath : taskEmailTailFiles) {
      // To enable support for tailing the service.log file, replace instances of $MESOS_TASK_ID.
      filePath = filePath.replaceAll("\\$MESOS_TASK_ID", MesosUtils.getSafeTaskIdForDirectory(taskId.getId()));

      logTails.add(
          new SingularityMailTaskLog(
              filePath, // path
              getFileName(filePath), // file
              getSingularityLogLink(filePath, taskId.getId()), // link
              getTaskLogFile(taskId, filePath, task, directory).or(""))); // log
    }

{'fraction_non_alphanumeric': 0.09080512351326624, 'fraction_numerical': 0.0010292772186642268, 'mean_word_length': 4.438432835820896, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '263285', 'n_tokens_mistral': 2534, 'n_tokens_neox': 2474, 'n_words': 595}