<commit_before>import { createTransport } from 'nodemailer'
import { markdown as nodemailerMarkdown } from 'nodemailer-markdown'
import { promisify } from 'promise-toolbox'

// ===================================================================

const markdownCompiler = nodemailerMarkdown()

const logAndRethrow = error => {
  console.error('[WARN] plugin transport-email:', error && error.stack || error)

  throw error
}

// ===================================================================

export const configurationSchema = {
  type: 'object',

  properties: {
    from: {
      type: 'object',

      properties: {
        name: {
          type: 'string'
        },
        address: {
          type: 'string'
        }
      },

      additionalProperties: false,
      required: ['address']
    },

    transport: {
      type: 'object',

      properties: {
        host: {
          type: 'string',
          description: 'hostname or IP address of the SMTP server'
        },
        port: {
          type: 'integer',
          description: 'port of the SMTP server (defaults to 25 or 465)'
        },
        secure: {
          type: 'boolean',
          description: 'whether the connection should use SSL'
        },
        ignoreUnauthorized: {
          type: 'boolean',
          description: 'ignore certificates error (e.g. self-signed certificate)'
        },

        // FIXME: xo-web does not support edition of too nested
        user: {
          type: 'string',
          description: 'name to use to authenticate'
        },
        password: {
          type: 'string',
          description: 'password to use to authenticate'
        }
        // properties.
        // auth: {
        //   type: 'object',

        //   properties: {
        //     user: {
        //       type: 'string',
        //       description: 'name to use to authenticate'
        //     },
        //     pass: {
        //       type: 'string',
        //       description: 'password to use to authenticate'
        //     }
        //   },

        //   additionalProperties: false,
        //   required: ['user', 'pass']
        // }
      },

      additionalProperties: false,
      required: ['host']
    }
  },

  additionalProperties: false,
  required: ['from', 'transport']
}

export const testSchema = {
  type: 'object',

  properties: {
    to: {
      type: 'string',
      description: 'recipient of the test mail'
    }
  },

  additionalProperties: false,
  required: ['to']
}

// ===================================================================

class TransportEmailPlugin {
  constructor ({ xo }) {
    this._sendEmail = ::this._sendEmail
    this._set = ::xo.defineProperty
    this._unset = null

    // Defined in configure().
    this._conf = null
    this._send = null
  }

  configure ({
    transport: {
      ignoreUnauthorized,
      password,
      user,
      ...transportConf
    },
    ...conf
  }) {
    if (ignoreUnauthorized != null) {
      (
        transportConf.tls ||
        (transportConf.tls = {})
      ).rejectUnauthorized = !ignoreUnauthorized
    }

    if (user != null && password != null) {
      transportConf.auth = { user, pass: password }
    }

    const transport = createTransport(transportConf)
    transport.use('compile', markdownCompiler)

    this._conf = conf
    this._send = promisify(transport.sendMail, transport)
  }

  load () {
    this._unset = this._set('sendEmail', this._sendEmail)
  }

  unload () {
    this._unset()
  }

  test ({to}) {
    return this._sendEmail({
      to,
      subject: '[Xen Orchestra] Test of transport-email plugin',
      markdown: `Hi there,

The transport-email plugin for Xen Orchestra server seems to be working fine, nicely done :)`
    })
  }

  _sendEmail ({
    from = this._conf.from,
    to, cc, bcc,
    subject,
    markdown
  }) {
    // TODO: handle errors
    return this._send({
      from,
      to,
      cc,
      bcc,
      subject,
      markdown
    }).catch(logAndRethrow)
  }
}

// ===================================================================

export default opts => new TransportEmailPlugin(opts)<commit_msg>feat: attachments support (#13)<commit_after>import { createTransport } from 'nodemailer'
import { markdown as nodemailerMarkdown } from 'nodemailer-markdown'
import { promisify } from 'promise-toolbox'

// ===================================================================

const markdownCompiler = nodemailerMarkdown()

const logAndRethrow = error => {
  console.error('[WARN] plugin transport-email:', error && error.stack || error)

  throw error
}

// ===================================================================

export const configurationSchema = {
  type: 'object',

  properties: {
    from: {
      type: 'object',

      properties: {
        name: {
          type: 'string'
        },
        address: {
          type: 'string'
        }
      },

      additionalProperties: false,
      required: ['address']
    },

    transport: {
      type: 'object',

      properties: {
        host: {
          type: 'string',
          description: 'hostname or IP address of the SMTP server'
        },
        port: {
          type: 'integer',
          description: 'port of the SMTP server (defaults to 25 or 465)'
        },
        secure: {
          type: 'boolean',
          description: 'whether the connection should use SSL'
        },
        ignoreUnauthorized: {
          type: 'boolean',
          description: 'ignore certificates error (e.g. self-signed certificate)'
        },

        // FIXME: xo-web does not support edition of too nested
        user: {
          type: 'string',
          description: 'name to use to authenticate'
        },
        password: {
          type: 'string',
          description: 'password to use to authenticate'
        }
        // properties.
        // auth: {
        //   type: 'object',

        //   properties: {
        //     user: {
        //       type: 'string',
        //       description: 'name to use to authenticate'
        //     },
        //     pass: {
        //       type: 'string',
        //       description: 'password to use to authenticate'
        //     }
        //   },

        //   additionalProperties: false,
        //   required: ['user', 'pass']
        // }
      },

      additionalProperties: false,
      required: ['host']
    }
  },

  additionalProperties: false,
  required: ['from', 'transport']
}

export const testSchema = {
  type: 'object',

  properties: {
    to: {
      type: 'string',
      description: 'recipient of the test mail'
    }
  },

  additionalProperties: false,
  required: ['to']
}

// ===================================================================

class TransportEmailPlugin {
  constructor ({ xo }) {
    this._sendEmail = ::this._sendEmail
    this._set = ::xo.defineProperty
    this._unset = null

    // Defined in configure().
    this._conf = null
    this._send = null
  }

  configure ({
    transport: {
      ignoreUnauthorized,
      password,
      user,
      ...transportConf
    },
    ...conf
  }) {
    if (ignoreUnauthorized != null) {
      (
        transportConf.tls ||
        (transportConf.tls = {})
      ).rejectUnauthorized = !ignoreUnauthorized
    }

    if (user != null && password != null) {
      transportConf.auth = { user, pass: password }
    }

    const transport = createTransport(transportConf)
    transport.use('compile', markdownCompiler)

    this._conf = conf
    this._send = promisify(transport.sendMail, transport)
  }

  load () {
    this._unset = this._set('sendEmail', this._sendEmail)
  }

  unload () {
    this._unset()
  }

  test ({to}) {
    return this._sendEmail({
      to,
      subject: '[Xen Orchestra] Test of transport-email plugin',
      markdown: `Hi there,

The transport-email plugin for Xen Orchestra server seems to be working fine, nicely done :)`
    })
  }

  _sendEmail ({
    from = this._conf.from,
    to, cc, bcc,
    subject,
    markdown,
    attachments
  }) {
    // TODO: handle errors
    return this._send({
      from,
      to,
      cc,
      bcc,
      subject,
      markdown,
      attachments
    }).catch(logAndRethrow)
  }
}

// ===================================================================

export default opts => new TransportEmailPlugin(opts)
{'fraction_non_alphanumeric': 0.17932187201528177, 'fraction_numerical': 0.0014326647564469914, 'mean_word_length': 2.0285610990600143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '1782034', 'n_tokens_mistral': 2356, 'n_tokens_neox': 2246, 'n_words': 586}