class ICFS::Email::Core

Core email processing engine.

Constants

ContentFields

Content related fields

CopyFields

Basic header fields to copy

DefaultContent

Default content

DefaultEmail

Filename for processed content without attachments

DefaultOrig

Filename for original content

DefaultTitle

Default title

FieldsSet

Set of header fields to copy set

ValFile

A file to attach

ValReceive

Results of processing a valid message

Public Class Methods

new(api, log, st=nil) click to toggle source

New instance

@param api [ICFS::Api] the ICFS API @param log [Logger] The log @param st [Array] the middleware

# File lib/icfs/email/core.rb, line 119
def initialize(api, log, st=nil)
  @api = api
  @log = log
  self.stack_set(st) if st
end

Public Instance Methods

receive(msg) click to toggle source

Process a received email using the middleware stack

@param msg [::Mail::Message] the email message @return [Array] results, first field is a Symbol, second field is error or

the recorded message
# File lib/icfs/email/core.rb, line 146
def receive(msg)
  @log.debug('Email: Processing %s' % msg.message_id)

  # setup the environment
  env = {
    orig: msg.raw_source.dup, # the original text email
    msg: msg,                 # the email message being worked on
    files: [],                # files to attach to the entry
    api: @api,                # the ICFS API
  }

  # process all middleware
  @stack.each do |mid|
    resp, err = mid.receive(env)
    case resp
    when :continue
      next
    when :stop
      break
    when :failure
      return [:failure, err]
    else
      raise ScriptError
    end
  end

  # check that all required fields were completed
  err = Validate.check(env, ValReceive)
  if err
    @log.info('Email: Invalid: %s' % err.inspect)
    return [:invalid, err]
  end

  # API set to active user
  @api.user = env[:user]

  # if an entry was specified
  if env[:entry] && env[:entry] != 0
    ent = @api.entry_read(env[:caseid], env[:entry])
    ent.delete('icfs')
    ent.delete('log')
    ent.delete('user')
    ent.delete('tags') if ent['tags'][0] == ICFS::TagNone
  else
    ent = {}
    ent['caseid'] = env[:caseid]
  end

  # build entry
  ent['time'] = env[:time] if env[:time]
  ent['title'] = env[:title] if env[:title]
  ent['title'] ||= DefaultTitle
  ent['content'] = env[:content] if env[:content]
  ent['content'] ||= DefaultContent
  if env[:tags]
    ent['tags'] ||= []
    ent['tags'] = (ent['tags'] + env[:tags]).uniq
  end
  ent['perms'] = env[:perms].uniq if env[:perms]
  ent['stats'] = env[:stats] if env[:stats]

  # files
  files = env[:files].map do |fd|
    tmp = @api.tempfile
    tmp.write(fd[:content])
    { 'name' => fd[:name], 'temp' => tmp }
  end
  if env[:save_original]
    tmp = @api.tempfile
    tmp.write(env[:orig])
    files << { 'name' => DefaultOrig, 'temp' => tmp }
  end
  if env[:save_email]
    tmp = @api.tempfile
    env[:msg].header.fields.delete_if do |fi|
      !FieldsSet.include?(fi.name.downcase)
    end
    tmp.write(env[:msg].encoded)
    files << { 'name' => DefaultEmail, 'temp' => tmp }
  end
  unless files.empty?
    ent['files'] ||= []
    ent['files'] = ent['files'] + files
  end

  # try to record it
  @api.record(ent, nil, nil, nil)

  @log.info('Email: Success: %s %d-%d' %
      [ent['caseid'], ent['entry'], ent['log']])
  return [:success, ent]

rescue ICFS::Error::Conflict => ex
  @log.warn('Email: Conflict: %s' % ex.message)
  return [:conflict, ex.message]
rescue ICFS::Error::NotFound => ex
  @log.warn('Email: Not Found: %s' % ex.message)
  return [:notfound, ex.message]
rescue ICFS::Error::Perms => ex
  @log.warn('Email: Permissions: %s' % ex.message)
  return [:perms, ex.message]
rescue ICFS::Error::Value => ex
  @log.warn('Email: Value: %s' % ex.message)
  return [:value, ex.message]
end
stack_set(st) click to toggle source

Set the middleware stack

Each middleware object must respond to receive and return one of:

* :continue - process more middleware
* :success - stops further middleare, and records the entry
* :failure - stops further middlware and does not record
# File lib/icfs/email/core.rb, line 134
def stack_set(st)
  @stack = st
end