ruby-msg 1.2.17.2 → 1.2.17.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/Rakefile +1 -1
  2. data/lib/msg.rb +1 -1
  3. metadata +2 -4
  4. data/lib/blah.rb +0 -106
  5. data/lib/mime-new.rb +0 -210
data/Rakefile CHANGED
@@ -59,7 +59,7 @@ end
59
59
 
60
60
  Rake::GemPackageTask.new(spec) do |p|
61
61
  p.gem_spec = spec
62
- p.need_tar = true
62
+ # p.need_tar = true
63
63
  p.need_zip = false
64
64
  p.package_dir = 'build'
65
65
  end
data/lib/msg.rb CHANGED
@@ -20,7 +20,7 @@ require 'mime'
20
20
  #
21
21
 
22
22
  class Msg
23
- VERSION = '1.2.17.2'
23
+ VERSION = '1.2.17.3'
24
24
  # we look here for the yaml files in data/, and the exe files for support
25
25
  # decoding at the moment.
26
26
  SUPPORT_DIR = File.dirname(__FILE__) + '/..'
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby-msg
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.2.17.2
7
- date: 2007-06-27 00:00:00 +10:00
6
+ version: 1.2.17.3
7
+ date: 2007-07-12 00:00:00 +10:00
8
8
  summary: Ruby Msg library.
9
9
  require_paths:
10
10
  - lib
@@ -38,8 +38,6 @@ files:
38
38
  - bin/msgtool
39
39
  - bin/oletool
40
40
  - lib/orderedhash.rb
41
- - lib/blah.rb
42
- - lib/mime-new.rb
43
41
  - lib/rtf.rb
44
42
  - lib/support.rb
45
43
  - lib/mime.rb
data/lib/blah.rb DELETED
@@ -1,106 +0,0 @@
1
- #! /usr/bin/ruby
2
-
3
- class SimpleGrammar
4
- def initialize(grammar)
5
- @grammar = grammar
6
- end
7
- def scan(cursor,buffer)
8
- @grammar.scan(cursor,buffer)
9
- end
10
- def |(other); Code.new { |cursor,buffer|
11
- scan(cursor,buffer) || other.scan(cursor,buffer)
12
- } end
13
- def +(other); Code.new { |cursor,buffer|
14
- scan(cursor,buffer) && other.scan(cursor,buffer)
15
- } end
16
- def filter(buf0,&block); Code.new { |cursor,buffer|
17
- buf = buf0.clone
18
- scan(cursor,buf) && buffer.concat(block[buf])
19
- } end
20
- def discard; Code.new { |cursor,buffer|
21
- scan(cursor,[])
22
- } end
23
- class Code < SimpleGrammar
24
- def initialize(&block)
25
- @block = block
26
- end
27
- def scan(cursor,buffer)
28
- @block[cursor,buffer]
29
- end
30
- end
31
- class Recurse < SimpleGrammar
32
- def initialize(&block)
33
- @grammar = block[self]
34
- end
35
- def scan(cursor,buffer)
36
- @grammar.scan(cursor,buffer)
37
- end
38
- end
39
- class Element < SimpleGrammar
40
- def initialize(pattern)
41
- @pattern = pattern
42
- end
43
- def scan(cursor,buffer)
44
- c = cursor.read1after
45
- if @pattern===c
46
- buffer << c
47
- cursor.skip1next
48
- true
49
- end
50
- end
51
- end
52
- # Make methods for our classes that call new for us
53
- constants.each { |klass|
54
- eval("
55
- def #{klass}(*args,&block)
56
- #{klass}.new(*args,&block)
57
- end
58
- def self.#{klass}(*args,&block)
59
- #{klass}.new(*args,&block)
60
- end
61
- ")
62
- }
63
- NULL = Code.new { true }
64
- end
65
-
66
- class IO
67
- # implement just the methods we need to look like a cursor
68
- def read1after;c=getc;ungetc(c);c;end
69
- def skip1next;getc&&true;end
70
- end
71
-
72
- class Expression < SimpleGrammar::Recurse
73
- def initialize; super() { |expr|
74
- digit = Element(?0..?9)
75
- int = Recurse { |int| digit+(int|NULL) }
76
- number =
77
- (int + (
78
- Element(?.)+int |
79
- NULL
80
- )).filter("") { |n| [n.to_f] }
81
- primary = Recurse { |primary|
82
- number |
83
- Element(?-).discard + primary + Code { |_,b| b[-1]=-b[-1] } |
84
- Element(?().discard + expr + Element(?)).discard
85
- }
86
- product = Recurse { |product|
87
- primary + (
88
- Element(?*).discard + product + Code { |_,b|
89
- b[-2]*=b[-1];b.pop } |
90
- Element(?/).discard + product + Code { |_,b|
91
- b[-2]/=b[-1];b.pop } |
92
- NULL
93
- )
94
- }
95
- sum = Recurse { |sum|
96
- product + (
97
- Element(?+).discard + sum + Code { |_,b| b[-2]+=b[-1];b.pop } |
98
- Element(?-).discard + sum + Code { |_,b| b[-2]-=b[-1];b.pop } |
99
- NULL
100
- )
101
- }
102
- } end
103
- end
104
-
105
- Expression.new.scan(STDIN,buf=[]) && p(buf[0])
106
-
data/lib/mime-new.rb DELETED
@@ -1,210 +0,0 @@
1
- require 'stringio'
2
- require 'ole/storage'
3
-
4
- # the IO equivalent to StringScanner.
5
- # in fact its mostly scan and scan_until that are useful to me. maybe this can be
6
- # mixed in to the underlying io class, as providing a lot of stuff, like simple reads
7
- # and peeks seems redundant extra layer cruft.
8
- class IOScanner
9
- # needs seekable +io+, as we may read more than we should, and don't
10
- # have a way (that i know of?) to push back those bytes onto temporary
11
- # buffer. (ungetc?)
12
- attr_reader :io
13
- def initialize io
14
- @io = io
15
- end
16
-
17
- def pos
18
- @io.pos
19
- end
20
-
21
- def pos= pos
22
- @io.pos = pos
23
- end
24
-
25
- def scan rx
26
- rx = Regexp.new rx
27
- # now we have to see whether we match
28
- end
29
- end
30
-
31
- #
32
- # = Introduction
33
- #
34
- # A *basic* mime class for _really_ _basic_ and probably non-standard parsing
35
- # and construction of MIME messages.
36
- #
37
- # Intended for two main purposes in this project:
38
- # 1. As the container that is used to build up the message for eventual
39
- # serialization as an eml.
40
- # 2. For assistance in parsing the +transport_message_headers+ provided in .msg files,
41
- # which are then kept through to the final eml.
42
- #
43
- # = TODO
44
- #
45
- # * Better streaming support, rather than an all-in-string approach.
46
- # * Add +OrderedHash+ optionally, to not lose ordering in headers.
47
- # * A fair bit remains to be done for this class, its fairly immature. But generally I'd like
48
- # to see it be more generally useful.
49
- # * All sorts of correctness issues, encoding particular.
50
- # * Duplication of work in net/http.rb's +HTTPHeader+? Don't know if the overlap is sufficient.
51
- # I don't want to lower case things, just for starters.
52
- # * Mime was the original place I wrote #to_tree, intended as a quick debug hack.
53
- #
54
- class Mime
55
- Hash = begin
56
- require 'orderedhash'
57
- OrderedHash
58
- rescue LoadError
59
- Hash
60
- end
61
-
62
- attr_reader :headers, :body, :parts, :content_type, :preamble, :epilogue
63
-
64
- # Create a Mime object from +io+ as an initial serialization, which must contain headers
65
- # and a body (even if empty). Needs work.
66
- attr_reader :io
67
- def initialize io=nil
68
- # use a string backed io if not specified
69
- @io = io || StringIO.new('')
70
- # read headers. flexible about new line endings here
71
- headers = ''
72
- while s = @io.gets
73
- s.chomp!
74
- break if s.empty?
75
- headers << s + "\r\n"
76
- end
77
- # what remains is the body. maybe rangesio should support infinite ranges
78
- @body = RangesIO.new @io, [@io.pos...(@io.stat.size rescue @io.size)]
79
- #headers, @body = $~[1..-1] if str[/(.*?\r?\n)(?:\r?\n(.*))?\Z/m]
80
-
81
- # don't like the way i'm creatinh on access.
82
- @headers = Hash.new { |hash, key| hash[key] = [] }
83
- #@body ||= ''
84
- headers.to_s.scan(/^\S+:\s*.*(?:\n\t.*)*/).each do |header|
85
- @headers[header[/(\S+):/, 1]] << header[/\S+:\s*(.*)/m, 1].gsub(/\s+/m, ' ').strip # this is kind of wrong
86
- end
87
-
88
- # don't have to have content type i suppose
89
- @content_type, attrs = nil, {}
90
- if @headers.include? 'Content-Type'
91
- @content_type, attrs = Mime.split_header @headers['Content-Type'][0]
92
- end
93
-
94
- if multipart?
95
- # special case
96
- if body.size == 0
97
- @preamble = ''
98
- @epilogue = ''
99
- @parts = []
100
- else
101
- # we need to split the message at the boundary
102
- # instead of raising, it should just probably become a single part message.
103
- boundary = attrs['boundary'] or raise "no boundary for multipart message"
104
-
105
- # splitting the body:
106
- # talk about crap. all that work to use io, and then i do this :)
107
- # each multipart should become a sub-io, which gets passed to Mime.new
108
- parts = body.read.split(/--#{Regexp.quote boundary}/m)
109
- unless parts[-1] =~ /^--/; warn "bad multipart boundary (missing trailing --)"
110
- else parts[-1][0..1] = ''
111
- end
112
- parts.each_with_index do |part, i|
113
- part =~ /^(\r?\n)?(.*?)(\r?\n)?\Z/m
114
- part.replace $2
115
- warn "bad multipart boundary" if (1...parts.length-1) === i and !($1 && $3)
116
- end
117
- @preamble = parts.shift
118
- @epilogue = parts.pop
119
- @parts = parts.map { |part| Mime.new part }
120
- end
121
- end
122
- end
123
-
124
- def multipart?
125
- @content_type && @content_type =~ /^multipart/ ? true : false
126
- end
127
-
128
- def inspect
129
- # add some extra here.
130
- "#<Mime content_type=#{@content_type.inspect}>"
131
- end
132
-
133
- def to_tree
134
- if multipart?
135
- str = "- #{inspect}\n"
136
- parts.each_with_index do |part, i|
137
- last = i == parts.length - 1
138
- part.to_tree.split(/\n/).each_with_index do |line, j|
139
- str << " #{last ? (j == 0 ? "\\" : ' ') : '|'}" + line + "\n"
140
- end
141
- end
142
- str
143
- else
144
- "- #{inspect}\n"
145
- end
146
- end
147
-
148
- def to_s opts={}
149
- opts = {:boundary_counter => 0}.merge opts
150
- if multipart?
151
- boundary = Mime.make_boundary opts[:boundary_counter] += 1, self
152
- @body = [preamble, parts.map { |part| "\r\n" + part.to_s(opts) + "\r\n" }, "--\r\n" + epilogue].
153
- flatten.join("\r\n--" + boundary)
154
- content_type, attrs = Mime.split_header @headers['Content-Type'][0]
155
- attrs['boundary'] = boundary
156
- @headers['Content-Type'] = [([content_type] + attrs.map { |key, val| %{#{key}="#{val}"} }).join('; ')]
157
- end
158
-
159
- str = ''
160
- @headers.each do |key, vals|
161
- vals.each { |val| str << "#{key}: #{val}\r\n" }
162
- end
163
- str << "\r\n" + @body
164
- end
165
-
166
- def self.split_header header
167
- # FIXME: haven't read standard. not sure what its supposed to do with " in the name, or if other
168
- # escapes are allowed. can't test on windows as " isn't allowed anyway. can be fixed with more
169
- # accurate parser later.
170
- # maybe move to some sort of Header class. but not all headers should be of it i suppose.
171
- # at least add a join_header then, taking name and {}. for use in Mime#to_s (for boundary
172
- # rewrite), and Attachment#to_mime, among others...
173
- attrs = {}
174
- header.scan(/;\s*([^\s=]+)\s*=\s*("[^"]*"|[^\s;]*)\s*/m).each do |key, value|
175
- if attrs[key]; warn "ignoring duplicate header attribute #{key.inspect}"
176
- else attrs[key] = value[/^"/] ? value[1..-2] : value
177
- end
178
- end
179
-
180
- [header[/^[^;]+/].strip, attrs]
181
- end
182
-
183
- # +i+ is some value that should be unique for all multipart boundaries for a given message
184
- def self.make_boundary i, extra_obj = Mime
185
- "----_=_NextPart_#{'%03d' % i}_#{'%08x' % extra_obj.object_id}.#{'%08x' % Time.now}"
186
- end
187
- end
188
-
189
- =begin
190
- things to consider for header work.
191
- encoded words:
192
- Subject: =?iso-8859-1?q?p=F6stal?=
193
-
194
- and other mime funkyness:
195
- Content-Disposition: attachment;
196
- filename*0*=UTF-8''09%20%D7%90%D7%A5;
197
- filename*1*=%20%D7%A1%D7%91-;
198
- filename*2*=%D7%A7%95%A5.wma
199
- Content-Transfer-Encoding: base64
200
-
201
- and another, doing a test with an embedded newline in an attachment name, I
202
- get this output from evolution. I get the feeling that this is probably a bug
203
- with their implementation though, they weren't expecting new lines in filenames.
204
- Content-Disposition: attachment; filename="asdf'b\"c
205
- d efgh=i: ;\\j"
206
- d efgh=i: ;\\j"; charset=us-ascii
207
- Content-Type: text/plain; name="asdf'b\"c"; charset=us-ascii
208
-
209
- =end
210
-