Skip to content

Commit

Permalink
Slight modification to mapi requires.
Browse files Browse the repository at this point in the history
  • Loading branch information
aquasync committed Jul 29, 2014
1 parent 2487d0a commit fa01e1d
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 106 deletions.
1 change: 0 additions & 1 deletion bin/mapitool
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require 'optparse'
require 'rubygems'
require 'mapi/msg'
require 'mapi/pst'
require 'mapi/convert'
require 'time'

class Mapitool
Expand Down
107 changes: 2 additions & 105 deletions lib/mapi.rb
Original file line number Diff line number Diff line change
@@ -1,108 +1,5 @@
require 'mapi/version'
require 'mapi/base'
require 'mapi/types'
require 'mapi/property_set'

module Mapi
#
# Mapi::Item is the base class used for all mapi objects, and is purely a
# property set container
#
class Item
attr_reader :properties
alias props properties

# +properties+ should be a PropertySet instance.
def initialize properties
@properties = properties
end
end

# a general attachment class. is subclassed by Msg and Pst attachment classes
class Attachment < Item
def filename
props.attach_long_filename || props.attach_filename
end

def data
@embedded_msg || @embedded_ole || props.attach_data
end

# with new stream work, its possible to not have the whole thing in memory at one time,
# just to save an attachment
#
# a = msg.attachments.first
# a.save open(File.basename(a.filename || 'attachment'), 'wb')
def save io
raise "can only save binary data blobs, not ole dirs" if @embedded_ole
data.each_read { |chunk| io << chunk }
end

def inspect
"#<#{self.class.to_s[/\w+$/]}" +
(filename ? " filename=#{filename.inspect}" : '') +
(@embedded_ole ? " embedded_type=#{@embedded_ole.embedded_type.inspect}" : '') + ">"
end
end

class Recipient < Item
# some kind of best effort guess for converting to standard mime style format.
# there are some rules for encoding non 7bit stuff in mail headers. should obey
# that here, as these strings could be unicode
# email_address will be an EX:/ address (X.400?), unless external recipient. the
# other two we try first.
# consider using entry id for this too.
def name
name = props.transmittable_display_name || props.display_name
# dequote
name[/^'(.*)'/, 1] or name rescue nil
end

def email
props.smtp_address || props.org_email_addr || props.email_address
end

RECIPIENT_TYPES = { 0 => :orig, 1 => :to, 2 => :cc, 3 => :bcc }
def type
RECIPIENT_TYPES[props.recipient_type]
end

def to_s
if name = self.name and !name.empty? and email && name != email
%{"#{name}" <#{email}>}
else
email || name
end
end

def inspect
"#<#{self.class.to_s[/\w+$/]}:#{self.to_s.inspect}>"
end
end

# i refer to it as a message (as does mapi), although perhaps Item is better, as its a more general
# concept than a message, as used in Pst files. though maybe i'll switch to using
# Mapi::Object as the base class there.
#
# IMessage essentially, but there's also stuff like IMAPIFolder etc. so, for this to form
# basis for PST Item, it'd need to be more general.
class Message < Item
# these 2 collections should be provided by our subclasses
def attachments
raise NotImplementedError
end

def recipients
raise NotImplementedError
end

def inspect
str = %w[message_class from to subject].map do |key|
" #{key}=#{props.send(key).inspect}"
end.compact.join
str << " recipients=#{recipients.inspect}"
str << " attachments=#{attachments.inspect}"
"#<#{self.class.to_s[/\w+$/]}#{str}>"
end
end
end

require 'mapi/convert'
103 changes: 103 additions & 0 deletions lib/mapi/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
module Mapi
#
# Mapi::Item is the base class used for all mapi objects, and is purely a
# property set container
#
class Item
attr_reader :properties
alias props properties

# +properties+ should be a PropertySet instance.
def initialize properties
@properties = properties
end
end

# a general attachment class. is subclassed by Msg and Pst attachment classes
class Attachment < Item
def filename
props.attach_long_filename || props.attach_filename
end

def data
@embedded_msg || @embedded_ole || props.attach_data
end

# with new stream work, its possible to not have the whole thing in memory at one time,
# just to save an attachment
#
# a = msg.attachments.first
# a.save open(File.basename(a.filename || 'attachment'), 'wb')
def save io
raise "can only save binary data blobs, not ole dirs" if @embedded_ole
data.each_read { |chunk| io << chunk }
end

def inspect
"#<#{self.class.to_s[/\w+$/]}" +
(filename ? " filename=#{filename.inspect}" : '') +
(@embedded_ole ? " embedded_type=#{@embedded_ole.embedded_type.inspect}" : '') + ">"
end
end

class Recipient < Item
# some kind of best effort guess for converting to standard mime style format.
# there are some rules for encoding non 7bit stuff in mail headers. should obey
# that here, as these strings could be unicode
# email_address will be an EX:/ address (X.400?), unless external recipient. the
# other two we try first.
# consider using entry id for this too.
def name
name = props.transmittable_display_name || props.display_name
# dequote
name[/^'(.*)'/, 1] or name rescue nil
end

def email
props.smtp_address || props.org_email_addr || props.email_address
end

RECIPIENT_TYPES = { 0 => :orig, 1 => :to, 2 => :cc, 3 => :bcc }
def type
RECIPIENT_TYPES[props.recipient_type]
end

def to_s
if name = self.name and !name.empty? and email && name != email
%{"#{name}" <#{email}>}
else
email || name
end
end

def inspect
"#<#{self.class.to_s[/\w+$/]}:#{self.to_s.inspect}>"
end
end

# i refer to it as a message (as does mapi), although perhaps Item is better, as its a more general
# concept than a message, as used in Pst files. though maybe i'll switch to using
# Mapi::Object as the base class there.
#
# IMessage essentially, but there's also stuff like IMAPIFolder etc. so, for this to form
# basis for PST Item, it'd need to be more general.
class Message < Item
# these 2 collections should be provided by our subclasses
def attachments
raise NotImplementedError
end

def recipients
raise NotImplementedError
end

def inspect
str = %w[message_class from to subject].map do |key|
" #{key}=#{props.send(key).inspect}"
end.compact.join
str << " recipients=#{recipients.inspect}"
str << " attachments=#{attachments.inspect}"
"#<#{self.class.to_s[/\w+$/]}#{str}>"
end
end
end

0 comments on commit fa01e1d

Please sign in to comment.