sup 0.19.0 → 0.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +4 -1
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +12 -6
  5. data/CONTRIBUTORS +28 -14
  6. data/Gemfile +5 -0
  7. data/History.txt +92 -0
  8. data/README.md +26 -5
  9. data/Rakefile +41 -1
  10. data/ReleaseNotes +17 -0
  11. data/bin/sup +12 -23
  12. data/bin/sup-add +15 -16
  13. data/bin/sup-config +30 -45
  14. data/bin/sup-dump +2 -3
  15. data/bin/sup-import-dump +5 -6
  16. data/bin/sup-sync +3 -4
  17. data/bin/sup-sync-back-maildir +3 -4
  18. data/bin/sup-tweak-labels +6 -7
  19. data/contrib/colorpicker.rb +0 -2
  20. data/contrib/completion/_sup.bash +102 -0
  21. data/devel/profile.rb +0 -1
  22. data/ext/mkrf_conf_xapian.rb +47 -0
  23. data/lib/sup.rb +10 -8
  24. data/lib/sup/buffer.rb +12 -0
  25. data/lib/sup/colormap.rb +5 -2
  26. data/lib/sup/contact.rb +4 -2
  27. data/lib/sup/crypto.rb +58 -16
  28. data/lib/sup/draft.rb +8 -8
  29. data/lib/sup/hook.rb +9 -9
  30. data/lib/sup/index.rb +20 -7
  31. data/lib/sup/label.rb +1 -1
  32. data/lib/sup/logger.rb +1 -1
  33. data/lib/sup/maildir.rb +16 -5
  34. data/lib/sup/mbox.rb +13 -5
  35. data/lib/sup/message.rb +36 -12
  36. data/lib/sup/message_chunks.rb +13 -4
  37. data/lib/sup/mode.rb +34 -28
  38. data/lib/sup/modes/contact_list_mode.rb +1 -0
  39. data/lib/sup/modes/edit_message_mode.rb +3 -2
  40. data/lib/sup/modes/forward_mode.rb +22 -3
  41. data/lib/sup/modes/line_cursor_mode.rb +1 -1
  42. data/lib/sup/modes/reply_mode.rb +3 -1
  43. data/lib/sup/modes/text_mode.rb +6 -1
  44. data/lib/sup/modes/thread_index_mode.rb +12 -2
  45. data/lib/sup/modes/thread_view_mode.rb +111 -14
  46. data/lib/sup/person.rb +68 -61
  47. data/lib/sup/search.rb +1 -1
  48. data/lib/sup/sent.rb +1 -1
  49. data/lib/sup/source.rb +1 -1
  50. data/lib/sup/util.rb +15 -94
  51. data/lib/sup/util/axe.rb +17 -0
  52. data/lib/sup/util/locale_fiddler.rb +24 -0
  53. data/lib/sup/util/ncurses.rb +3 -3
  54. data/lib/sup/version.rb +10 -1
  55. data/sup.gemspec +29 -11
  56. data/test/{messages → fixtures}/bad-content-transfer-encoding-1.eml +0 -0
  57. data/test/{messages → fixtures}/binary-content-transfer-encoding-2.eml +0 -0
  58. data/test/fixtures/blank-header-fields.eml +71 -0
  59. data/test/fixtures/contacts.txt +1 -0
  60. data/test/fixtures/mailing-list-header.eml +80 -0
  61. data/test/fixtures/malicious-attachment-names.eml +55 -0
  62. data/test/fixtures/missing-from-to.eml +18 -0
  63. data/test/{messages → fixtures}/missing-line.eml +0 -0
  64. data/test/fixtures/multi-part-2.eml +72 -0
  65. data/test/fixtures/multi-part.eml +61 -0
  66. data/test/fixtures/no-body.eml +18 -0
  67. data/test/fixtures/simple-message.eml +29 -0
  68. data/test/fixtures/text-attachments-with-charset.eml +46 -0
  69. data/test/fixtures/zimbra-quote-with-bottom-post.eml +27 -0
  70. data/test/gnupg_test_home/gpg.conf +3 -1
  71. data/test/gnupg_test_home/private-keys-v1.d/306D2EE90FF0014B5B9FD07E265C751791674140.key +0 -0
  72. data/test/gnupg_test_home/pubring.gpg +0 -0
  73. data/test/gnupg_test_home/receiver_pubring.gpg +0 -0
  74. data/test/gnupg_test_home/receiver_secring.gpg +0 -0
  75. data/test/gnupg_test_home/regen_keys.sh +89 -0
  76. data/test/gnupg_test_home/secring.gpg +0 -0
  77. data/test/gnupg_test_home/sup-test-2@foo.bar.asc +20 -17
  78. data/test/integration/test_maildir.rb +75 -0
  79. data/test/integration/test_mbox.rb +69 -0
  80. data/test/test_crypto.rb +14 -2
  81. data/test/test_header_parsing.rb +1 -1
  82. data/test/test_helper.rb +6 -3
  83. data/test/test_message.rb +115 -341
  84. data/test/test_messages_dir.rb +4 -28
  85. data/test/test_yaml_regressions.rb +1 -1
  86. data/test/unit/test_contact.rb +33 -0
  87. data/test/unit/test_locale_fiddler.rb +15 -0
  88. data/test/unit/test_person.rb +37 -0
  89. data/test/unit/util/test_query.rb +10 -4
  90. data/test/unit/util/test_string.rb +6 -0
  91. metadata +137 -53
  92. data/test/gnupg_test_home/receiver_trustdb.gpg +0 -0
  93. data/test/gnupg_test_home/trustdb.gpg +0 -0
@@ -12,7 +12,7 @@ class SearchManager
12
12
  def initialize fn
13
13
  @fn = fn
14
14
  @searches = {}
15
- if File.exists? fn
15
+ if File.exist? fn
16
16
  IO.foreach(fn) do |l|
17
17
  l =~ /^([^:]*): (.*)$/ or raise "can't parse #{fn} line #{l.inspect}"
18
18
  @searches[$1] = $2
@@ -40,7 +40,7 @@ class SentLoader < MBox
40
40
 
41
41
  def initialize
42
42
  @filename = Redwood::SENT_FN
43
- File.open(@filename, "w") { } unless File.exists? @filename
43
+ File.open(@filename, "w") { } unless File.exist? @filename
44
44
  super "mbox://" + @filename, true, $config[:archive_sent]
45
45
  end
46
46
 
@@ -58,7 +58,7 @@ class Source
58
58
  attr_accessor :id
59
59
 
60
60
  def initialize uri, usual=true, archived=false, id=nil
61
- raise ArgumentError, "id must be an integer: #{id.inspect}" unless id.is_a? Fixnum if id
61
+ raise ArgumentError, "id must be an integer: #{id.inspect}" unless id.is_a? Integer if id
62
62
 
63
63
  @uri = uri
64
64
  @usual = usual
@@ -8,17 +8,9 @@ require 'set'
8
8
  require 'enumerator'
9
9
  require 'benchmark'
10
10
  require 'unicode'
11
+ require 'unicode/display_width'
11
12
  require 'fileutils'
12
13
 
13
- ## time for some monkeypatching!
14
- class Symbol
15
- unless method_defined? :to_proc
16
- def to_proc
17
- proc { |obj, *args| obj.send(self, *args) }
18
- end
19
- end
20
- end
21
-
22
14
  class Lockfile
23
15
  def gen_lock_id
24
16
  Hash[
@@ -89,7 +81,7 @@ module RMail
89
81
  end
90
82
 
91
83
  def charset
92
- if header.field?("content-type") && header.fetch("content-type") =~ /charset="?(.*?)"?(;|$)/i
84
+ if header.field?("content-type") && header.fetch("content-type") =~ /charset\s*=\s*"?(.*?)"?(;|$)/i
93
85
  $1
94
86
  end
95
87
  end
@@ -170,13 +162,6 @@ module RMail
170
162
  end
171
163
  end
172
164
 
173
- class Range
174
- ## only valid for integer ranges (unless I guess it's exclusive)
175
- def size
176
- last - first + (exclude_end? ? 0 : 1)
177
- end
178
- end
179
-
180
165
  class Module
181
166
  def bool_reader *args
182
167
  args.each { |sym| class_eval %{ def #{sym}?; @#{sym}; end } }
@@ -198,17 +183,6 @@ class Module
198
183
  end
199
184
 
200
185
  class Object
201
- def ancestors
202
- ret = []
203
- klass = self.class
204
-
205
- until klass == Object
206
- ret << klass
207
- klass = klass.superclass
208
- end
209
- ret
210
- end
211
-
212
186
  ## "k combinator"
213
187
  def returning x; yield x; x; end
214
188
 
@@ -266,21 +240,14 @@ end
266
240
 
267
241
  class String
268
242
  def display_length
269
- @display_length ||= Unicode.width(self.fix_encoding!, false)
270
-
271
- # if Unicode.width fails and returns -1, fall back to
272
- # regular String#length, see pull-request: #256.
273
- if @display_length < 0
274
- @display_length = self.length
275
- end
276
-
277
- @display_length
243
+ @display_length ||= Unicode::DisplayWidth.of(self)
278
244
  end
279
245
 
280
246
  def slice_by_display_length len
281
247
  each_char.each_with_object "" do |c, buffer|
282
- len -= c.display_length
283
- buffer << c if len >= 0
248
+ len -= Unicode::DisplayWidth.of(c)
249
+ return buffer if len < 0
250
+ buffer << c
284
251
  end
285
252
  end
286
253
 
@@ -368,13 +335,14 @@ class String
368
335
  ret = []
369
336
  s = self
370
337
  while s.display_length > len
371
- cut = s.slice_by_display_length(len).rindex(/\s/)
338
+ slice = s.slice_by_display_length(len)
339
+ cut = slice.rindex(/\s/)
372
340
  if cut
373
341
  ret << s[0 ... cut]
374
342
  s = s[(cut + 1) .. -1]
375
343
  else
376
- ret << s.slice_by_display_length(len)
377
- s = s[ret.last.length .. -1]
344
+ ret << slice
345
+ s = s[slice.length .. -1]
378
346
  end
379
347
  end
380
348
  ret << s
@@ -382,8 +350,6 @@ class String
382
350
 
383
351
  # Fix the damn string! make sure it is valid utf-8, then convert to
384
352
  # user encoding.
385
- #
386
- # Not Ruby 1.8 compatible
387
353
  def fix_encoding!
388
354
  # first try to encode to utf-8 from whatever current encoding
389
355
  encode!('UTF-8', :invalid => :replace, :undef => :replace)
@@ -406,8 +372,6 @@ class String
406
372
 
407
373
  # transcode the string if original encoding is know
408
374
  # fix if broken.
409
- #
410
- # Not Ruby 1.8 compatible
411
375
  def transcode to_encoding, from_encoding
412
376
  begin
413
377
  encode!(to_encoding, from_encoding, :invalid => :replace, :undef => :replace)
@@ -474,13 +438,6 @@ class String
474
438
  out = out.fix_encoding! # this should now be an utf-8 string of ascii
475
439
  # compat chars.
476
440
  end
477
-
478
- unless method_defined? :ascii_only?
479
- def ascii_only?
480
- size.times { |i| return false if self[i] & 128 != 0 }
481
- return true
482
- end
483
- end
484
441
  end
485
442
 
486
443
  class Numeric
@@ -498,18 +455,18 @@ class Numeric
498
455
 
499
456
  def to_human_size
500
457
  if self < 1024
501
- to_s + "b"
458
+ to_s + "B"
502
459
  elsif self < (1024 * 1024)
503
- (self / 1024).to_s + "k"
460
+ (self / 1024).to_s + "KiB"
504
461
  elsif self < (1024 * 1024 * 1024)
505
- (self / 1024 / 1024).to_s + "m"
462
+ (self / 1024 / 1024).to_s + "MiB"
506
463
  else
507
- (self / 1024 / 1024 / 1024).to_s + "g"
464
+ (self / 1024 / 1024 / 1024).to_s + "GiB"
508
465
  end
509
466
  end
510
467
  end
511
468
 
512
- class Fixnum
469
+ class Integer
513
470
  def to_character
514
471
  if self < 128 && self >= 0
515
472
  chr
@@ -518,12 +475,6 @@ class Fixnum
518
475
  end
519
476
  end
520
477
 
521
- unless method_defined?(:ord)
522
- def ord
523
- self
524
- end
525
- end
526
-
527
478
  ## hacking the english language
528
479
  def pluralize s
529
480
  to_s + " " +
@@ -607,10 +558,6 @@ module Enumerable
607
558
  end
608
559
  end
609
560
 
610
- unless Object.const_defined? :Enumerator
611
- Enumerator = Enumerable::Enumerator
612
- end
613
-
614
561
  class Array
615
562
  def flatten_one_level
616
563
  inject([]) { |a, e| a + e }
@@ -706,32 +653,6 @@ class SavingHash
706
653
  defer_all_other_method_calls_to :hash
707
654
  end
708
655
 
709
- class OrderedHash < Hash
710
- alias_method :store, :[]=
711
- alias_method :each_pair, :each
712
- attr_reader :keys
713
-
714
- def initialize *a
715
- @keys = []
716
- a.each { |k, v| self[k] = v }
717
- end
718
-
719
- def []= key, val
720
- @keys << key unless member?(key)
721
- super
722
- end
723
-
724
- def values; keys.map { |k| self[k] } end
725
- def index key; @keys.index key end
726
-
727
- def delete key
728
- @keys.delete key
729
- super
730
- end
731
-
732
- def each; @keys.each { |k| yield k, self[k] } end
733
- end
734
-
735
656
  ## easy thread-safe class for determining who's the "winner" in a race (i.e.
736
657
  ## first person to hit the finish line
737
658
  class FinishLine
@@ -0,0 +1,17 @@
1
+ require 'highline'
2
+ @cli = HighLine.new
3
+
4
+ def axe q, default=nil
5
+ question = if default && !default.empty?
6
+ "#{q} (enter for \"#{default}\"): "
7
+ else
8
+ "#{q}: "
9
+ end
10
+ ans = @cli.ask question
11
+ ans.empty? ? default : ans.to_s
12
+ end
13
+
14
+ def axe_yes q, default="n"
15
+ axe(q, default) =~ /^y|yes$/i
16
+ end
17
+
@@ -0,0 +1,24 @@
1
+ ## the following magic enables wide characters when used with a ruby
2
+ ## ncurses.so that's been compiled against libncursesw. (note the w.) why
3
+ ## this works, i have no idea. much like pretty much every aspect of
4
+ ## dealing with curses. cargo cult programming at its best.
5
+ require 'fiddle'
6
+ require 'fiddle/import'
7
+
8
+ module LocaleFiddler
9
+ extend Fiddle::Importer
10
+
11
+ SETLOCALE_LIB = case RbConfig::CONFIG['arch']
12
+ when /darwin/; "libc.dylib"
13
+ when /cygwin/; "cygwin1.dll"
14
+ when /freebsd/; "libc.so.7"
15
+ else; "libc.so.6"
16
+ end
17
+
18
+ dlload SETLOCALE_LIB
19
+ extern "char *setlocale(int, char const *)"
20
+
21
+ def setlocale(type, string)
22
+ LocaleFiddler.setlocale(type, string)
23
+ end
24
+ end
@@ -76,7 +76,7 @@ module Ncurses
76
76
  @status = status
77
77
  c = "" if c.nil?
78
78
  return super("") if status == Ncurses::ERR
79
- c = enc_char(c) if c.is_a?(Fixnum)
79
+ c = enc_char(c) if c.is_a?(Integer)
80
80
  super c.length > 1 ? c[0,1] : c
81
81
  end
82
82
 
@@ -89,7 +89,7 @@ module Ncurses
89
89
  else
90
90
  @status = Ncurses::OK
91
91
  c = "" if c.nil?
92
- c = enc_char(c) if c.is_a?(Fixnum)
92
+ c = enc_char(c) if c.is_a?(Integer)
93
93
  super c.length > 1 ? c[0,1] : c
94
94
  end
95
95
  end
@@ -260,7 +260,7 @@ module Ncurses
260
260
  ## Ncurses::Form.form_driver_w wrapper for printable characters.
261
261
  def form_driver_char c
262
262
  form_driver CharCode.character(c)
263
- #c.is_a?(Fixnum) ? c : c.ord
263
+ #c.is_a?(Integer) ? c : c.ord
264
264
  end
265
265
 
266
266
  ## Ncurses::Form.form_driver_w wrapper for charcodes.
@@ -1,3 +1,12 @@
1
+ def git_suffix
2
+ revision = `GIT_DIR=#{__dir__}/../../.git git rev-parse HEAD 2>/dev/null`
3
+ if revision.empty?
4
+ "-git-unknown"
5
+ else
6
+ "-git-#{revision[0..7]}"
7
+ end
8
+ end
9
+
1
10
  module Redwood
2
- VERSION = "0.19.0"
11
+ VERSION = "0.23"
3
12
  end
@@ -9,8 +9,8 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["William Morgan", "Gaute Hope", "Hamish Downer", "Matthieu Rakotojaona"]
10
10
  s.email = "supmua@googlegroups.com"
11
11
  s.summary = "A console-based email client with the best features of GMail, mutt and Emacs"
12
- s.homepage = "http://supmua.org"
13
- s.license = 'GPL-2'
12
+ s.homepage = "https://sup-heliotrope.github.io/"
13
+ s.license = 'GPL-2.0'
14
14
  s.description = <<-DESC
15
15
  Sup is a console-based email client for people with a lot of email.
16
16
 
@@ -25,29 +25,47 @@ DESC
25
25
  SUP: please note that our old mailing lists have been shut down,
26
26
  re-subscribe to supmua@googlegroups.com to discuss and follow
27
27
  updates on sup (send email to: supmua+subscribe@googlegroups.com).
28
+
29
+ OpenBSD users:
30
+ If your operating system is OpenBSD you have some
31
+ additional, manual steps to do before Sup will work, see:
32
+ https://github.com/sup-heliotrope/sup/wiki/Installation%3A-OpenBSD.
28
33
  EOF
29
34
 
30
35
  s.files = `git ls-files -z`.split("\x0")
31
36
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
37
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
33
38
  s.require_paths = ["lib"]
39
+ s.extra_rdoc_files = Dir.glob("man/*")
40
+
41
+ s.required_ruby_version = '>= 2.0.0'
34
42
 
35
- s.required_ruby_version = '>= 1.9.3'
43
+ # this is here to support skipping the xapian-ruby installation on OpenBSD
44
+ # because the xapian-ruby gem doesn't install on OpenBSD, you must install
45
+ # xapian-core and xapian-bindings manually on OpenBSD
46
+ # see https://github.com/sup-heliotrope/sup/wiki/Installation%3A-OpenBSD
47
+ # and https://en.wikibooks.org/wiki/Ruby_Programming/RubyGems#How_to_install_different_versions_of_gems_depending_on_which_version_of_ruby_the_installee_is_using
48
+ s.extensions = %w[ext/mkrf_conf_xapian.rb]
49
+
50
+ ## remember to update the xapian dependency in
51
+ ## ext/mkrf_conf_xapian.rb and Gemfile.
36
52
 
37
- s.add_runtime_dependency "xapian-ruby", "~> 1.2.15"
38
53
  s.add_runtime_dependency "ncursesw", "~> 1.4.0"
39
- s.add_runtime_dependency "rmail-sup", "~> 1.0.1"
54
+ s.add_runtime_dependency "rmail", "~> 1.1"
40
55
  s.add_runtime_dependency "highline"
41
- s.add_runtime_dependency "trollop", ">= 1.12"
56
+ s.add_runtime_dependency "optimist"
42
57
  s.add_runtime_dependency "lockfile"
43
- s.add_runtime_dependency "mime-types", "~> 1.0"
58
+ s.add_runtime_dependency "mime-types", "> 2.0"
44
59
  s.add_runtime_dependency "locale", "~> 2.0"
45
- s.add_runtime_dependency "chronic", "~> 0.9.1"
60
+ s.add_runtime_dependency "chronic"
46
61
  s.add_runtime_dependency "unicode", "~> 0.4.4"
62
+ s.add_runtime_dependency "unicode-display_width"
47
63
 
48
- s.add_development_dependency "bundler", "~> 1.3"
64
+ s.add_development_dependency "bundler", ">= 1.3", "< 3"
49
65
  s.add_development_dependency "rake"
50
- s.add_development_dependency "minitest", "~> 4.7"
51
- s.add_development_dependency "rr", "~> 1.0.5"
66
+ s.add_development_dependency 'minitest', '~> 5.5.1'
67
+ s.add_development_dependency "rr", "~> 1.1"
52
68
  s.add_development_dependency "gpgme", ">= 2.0.2"
69
+ s.add_development_dependency "pry"
70
+
53
71
  end
@@ -0,0 +1,71 @@
1
+ Return-Path: <monitor-list-bounces@widget.com>
2
+ X-Original-To: nobody@localhost
3
+ Delivered-To: nobody@localhost.eng.widget.com
4
+ Received: from localhost (localhost.localdomain [127.0.0.1])
5
+ by soquel.eng.widget.com (Postfix) with ESMTP id 609BC13C0DB1
6
+ for <nobody@localhost>; Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
7
+ MIME-Version: 1.0
8
+ Received: from pa-excas-vip.widget.com [10.16.67.200]
9
+ by localhost with IMAP (fetchmail-6.2.5)
10
+ for nobody@localhost (single-drop); Thu, 19 Mar 2009 13:43:21 -0700 (PDT)
11
+ Received: from pa-exht01.widget.com (10.113.81.167) by pa-excaht11.widget.com
12
+ (10.113.81.197) with Microsoft SMTP Server (TLS) id 8.1.311.2; Thu, 19 Mar
13
+ 2009 13:42:30 -0700
14
+ Received: from mailman2.widget.com (10.16.64.159) by pa-exht01.widget.com
15
+ (10.113.81.167) with Microsoft SMTP Server id 8.1.336.0; Thu, 19 Mar 2009
16
+ 13:42:30 -0700
17
+ Received: by mailman2.widget.com (Postfix) id 47095AE30856; Thu, 19 Mar 2009
18
+ 13:42:29 -0700 (PDT)
19
+ Received: from countchocula.widget.com (localhost.localdomain [127.0.0.1]) by
20
+ mailman2.widget.com (Postfix) with ESMTP id 5F782ABC5948; Thu, 19 Mar 2009
21
+ 13:42:28 -0700 (PDT)
22
+ Received: from mailhost4.widget.com (mailhost4.widget.com [10.16.67.124]) by
23
+ mailman2.widget.com (Postfix) with ESMTP id 6CDCCABC5948 for
24
+ <monitor-list@mailman2.widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
25
+ Received: by mailhost4.widget.com (Postfix) id 2364AC9AC4; Thu, 19 Mar 2009
26
+ 13:42:26 -0700 (PDT)
27
+ Received: from pa-exht01.widget.com (pa-exht01.widget.com [10.113.81.167]) by
28
+ mailhost4.widget.com (Postfix) with ESMTP id 17A68C9AC3 for
29
+ <monitor-list@widget.com>; Thu, 19 Mar 2009 13:42:26 -0700 (PDT)
30
+ Received: from PA-EXMBX04.widget.com ([10.113.81.142]) by pa-exht01.widget.com
31
+ ([10.113.81.167]) with mapi; Thu, 19 Mar 2009 13:42:26 -0700
32
+ From: Some User <someuser@widget.com>
33
+ To: "monitor-list@widget.com" <monitor-list@widget.com>
34
+ Sender: "monitor-list-bounces@widget.com" <monitor-list-bounces@widget.com>
35
+ Date: Thu, 19 Mar 2009 13:42:25 -0700
36
+ Subject: Looking for a mac
37
+ Thread-Topic: Looking for a mac
38
+ Thread-Index: AQHJqNM1xIqqjNRWuUCUBaxzPFK5eQ==
39
+ Message-ID:
40
+ <D3C12B2AD838B44DA9D6B2CA334246D011E72A73A4@PA-EXMBX04.widget.com>
41
+ List-Help: <mailto:monitor-list-request@widget.com?subject=help>
42
+ List-Subscribe: <http://mailman2.widget.com/mailman/listinfo/monitor-list>,
43
+ <mailto:monitor-list-request@widget.com?subject=subscribe>
44
+ List-Unsubscribe:
45
+ <http://mailman2.widget.com/mailman/listinfo/monitor-list>,
46
+ <mailto:monitor-list-request@widget.com?subject=unsubscribe>
47
+ Accept-Language: en-US
48
+ Content-Language: en-US
49
+ X-MS-Exchange-Organization-AuthAs: Anonymous
50
+ X-MS-Exchange-Organization-AuthSource: pa-exht01.widget.com
51
+ X-MS-Has-Attach:
52
+ X-Auto-Response-Suppress: All
53
+ X-MS-TNEF-Correlator:
54
+ acceptlanguage: en-US
55
+ delivered-to: monitor-list@widget.com
56
+ errors-to: monitor-list-bounces@widget.com
57
+ list-id: engineering monitor related <monitor-list.widget.com>
58
+ x-mailman-version: 2.1.8
59
+ x-beenthere: monitor-list@widget.com
60
+ x-original-to: monitor-list@mailman2.widget.com
61
+ list-post: <mailto:monitor-list@widget.com>
62
+ list-archive: <http://mailman2.widget.com/pipermail/monitor-list>
63
+ Content-Type: text/plain; charset="us-ascii"
64
+ Content-Transfer-Encoding: quoted-printable
65
+
66
+ Hi all,
67
+
68
+ Just wondering if anybody can lend me a mac to reproduce PR 384931 ?
69
+ Thanks.
70
+
71
+ Michael=