Module: MsgExtractor

Defined in:
lib/msg_extractor.rb,
lib/msg_extractor/cli.rb,
lib/msg_extractor/task.rb,
lib/msg_extractor/util.rb,
lib/msg_extractor/errors.rb,
lib/msg_extractor/contact.rb,
lib/msg_extractor/headers.rb,
lib/msg_extractor/message.rb,
lib/msg_extractor/version.rb,
lib/msg_extractor/cfbf/fat.rb,
lib/msg_extractor/cfbf/file.rb,
lib/msg_extractor/mapi/ptag.rb,
lib/msg_extractor/recipient.rb,
lib/msg_extractor/attachment.rb,
lib/msg_extractor/appointment.rb,
lib/msg_extractor/cfbf/header.rb,
lib/msg_extractor/mapi/decoders.rb,
lib/msg_extractor/cfbf/directory.rb,
lib/msg_extractor/message_object.rb,
lib/msg_extractor/rtf/decapsulator.rb,
lib/msg_extractor/rtf/compressed_rtf.rb,
lib/msg_extractor/mapi/property_store.rb,
lib/msg_extractor/mapi/named_property_map.rb

Defined Under Namespace

Modules: Cfbf, Mapi, Rtf, Util Classes: Appointment, Attachment, CLI, Contact, CorruptFileError, Error, Headers, InvalidFormatError, Message, MessageObject, Recipient, Task, UnsupportedTypeError

Constant Summary collapse

DISPATCH =
[
  [/\A(ipm\.note|report)/i, :Message],
  [/\Aipm\.(contact|distlist)/i, :Contact],
  [/\A(ipm\.appointment|ipm\.schedule\.meeting)/i, :Appointment],
  # Note: intentionally also matches IPM.TaskRequest.* (delegation messages) per the spec's IPM.Task* scope.
  [/\Aipm\.task/i, :Task]
].freeze
VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.from_storage(cfbf, storage, named: nil, kind: :root, strict: true) ⇒ Object

Builds the right model class for a message storage (the file root or an embedded message). Used internally by open and Attachment#message.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/msg_extractor.rb', line 47

def self.from_storage(cfbf, storage, named: nil, kind: :root, strict: true)
  base = MessageObject.new(cfbf, storage: storage, named: named, kind: kind)
  message_class = base.message_class
  if message_class.nil?
    raise InvalidFormatError, "MSG file has no message class" if strict
    return base
  end
  match = DISPATCH.find { |pattern, _| pattern.match?(message_class) }
  if match.nil?
    if strict
      raise UnsupportedTypeError, "unsupported message class #{message_class.inspect}"
    end
    return base
  end
  const_get(match[1]).new(cfbf, storage: storage, named: base.named, kind: kind, properties: base.properties)
end

.open(source, strict: true) ⇒ Object

Opens a .msg file (path, binary String, or IO) and returns the model object matching its MAPI message class.

strict: when false, unknown/unsupported message classes return a generic MessageObject instead of raising.



37
38
39
40
41
42
43
# File 'lib/msg_extractor.rb', line 37

def self.open(source, strict: true)
  cfbf = Cfbf::File.read(source)
  unless cfbf.entry("__properties_version1.0")
    raise InvalidFormatError, "OLE file does not contain MSG property streams"
  end
  from_storage(cfbf, cfbf.root, kind: :root, strict: strict)
end