Class: MsgExtractor::Attachment

Inherits:
Object
  • Object
show all
Defined in:
lib/msg_extractor/attachment.rb

Constant Summary collapse

BY_VALUE =
1
EMBEDDED_MSG =
5

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cfbf, storage, named: nil) ⇒ Attachment

Returns a new instance of Attachment.



8
9
10
11
12
13
# File 'lib/msg_extractor/attachment.rb', line 8

def initialize(cfbf, storage, named: nil)
  @cfbf = cfbf
  @storage = storage
  @named = named
  @properties = Mapi::PropertyStore.new(cfbf, storage, :attachment)
end

Instance Attribute Details

#propertiesObject (readonly)

Returns the value of attribute properties.



6
7
8
# File 'lib/msg_extractor/attachment.rb', line 6

def properties
  @properties
end

Instance Method Details

#attach_methodObject



21
# File 'lib/msg_extractor/attachment.rb', line 21

def attach_method = properties[Mapi::PR_ATTACH_METHOD] || BY_VALUE

#content_idObject



20
# File 'lib/msg_extractor/attachment.rb', line 20

def content_id = properties[Mapi::PR_ATTACH_CONTENT_ID]

#dataObject

Bytes are memoized on first read and pinned until this Attachment is GC’d. That is deliberate: size, save, and data all reuse the same single read.



30
31
32
33
34
# File 'lib/msg_extractor/attachment.rb', line 30

def data
  return nil if embedded_message?
  return @data if defined?(@data)
  @data = properties.raw(Mapi::PR_ATTACH_DATA)
end

#embedded_message?Boolean

Returns:

  • (Boolean)


22
# File 'lib/msg_extractor/attachment.rb', line 22

def embedded_message? = attach_method == EMBEDDED_MSG

#filenameObject



15
16
17
# File 'lib/msg_extractor/attachment.rb', line 15

def filename
  properties[Mapi::PR_ATTACH_LONG_FILENAME] || properties[Mapi::PR_ATTACH_FILENAME]
end

#inline?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/msg_extractor/attachment.rb', line 24

def inline?
  properties[Mapi::PR_ATTACHMENT_HIDDEN] == true || !content_id.nil?
end

#messageObject

The parsed embedded message, when this attachment is a nested .msg. Always lenient (strict: false): raising lazily from an accessor would surprise callers, and embedded items are often non-email types.



41
42
43
44
45
46
47
# File 'lib/msg_extractor/attachment.rb', line 41

def message
  return @message if defined?(@message)
  @message =
    if embedded_message? && (sub = @storage.children["__SUBSTG1.0_3701000D"]) && sub.storage?
      MsgExtractor.from_storage(@cfbf, sub, named: @named, kind: :embedded, strict: false)
    end
end

#mime_typeObject



19
# File 'lib/msg_extractor/attachment.rb', line 19

def mime_type = properties[Mapi::PR_ATTACH_MIME_TAG]

#save(dir: ".") ⇒ Object

Raises:



49
50
51
52
53
54
55
# File 'lib/msg_extractor/attachment.rb', line 49

def save(dir: ".")
  raise Error, "cannot save an embedded message attachment as a file" if embedded_message?
  raise Error, "attachment #{filename.inspect} has no data stream" if data.nil?
  path = Util.dedupe_path(::File.join(dir, Util.sanitize_filename(filename || "attachment")))
  ::File.binwrite(path, data)
  path
end

#sizeObject



36
# File 'lib/msg_extractor/attachment.rb', line 36

def size = data&.bytesize