mailfakk2 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Sean Treadway
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,52 @@
1
+ MailFaKK2
2
+ =========
3
+
4
+ A email to fax gateway for asterisk. It will work as a procmail filter.
5
+
6
+
7
+ Motivation
8
+ ==========
9
+
10
+ After trying out several other email to fax gateways we came to the conclusion that not any of them
11
+
12
+ * does not need java
13
+ * is compatible with asterisk 1.6
14
+ * does not cost money
15
+ * has tests
16
+ * just works
17
+
18
+ MailFaKK2 tries to live up to all these requirements.
19
+
20
+
21
+ Installation
22
+ ============
23
+
24
+ Debian / Ubuntu
25
+ ---------------
26
+
27
+ * sudo apt-get install ruby ruby-dev gs unoconv openoffice.org-headless rubygems xvfb librmagick-ruby
28
+ * sudo gem install activesupport andand mail prawn
29
+
30
+ Cons
31
+ ====
32
+
33
+ If you plan to spam by fax you should consider another product. MailFaKK2 is
34
+ kind of slow. This is caused by launching OpenOffice.org for every conversion.
35
+ Speed is not a priority for us (yet).
36
+
37
+ TODO
38
+ ====
39
+
40
+ * [x] generate cover sheet TIFF frame from email body
41
+ * [x] append OpenOffice.org documents
42
+ * [ ] append MS Office documents
43
+ * [ ] write TIFF and callfile
44
+ * [-] procmail mode (untested)
45
+ * [ ] header and footer for every frame
46
+ * [ ] gemspec
47
+ * [ ] check if fax was delivered (callfile moved to outgoing_done)
48
+
49
+ Meta
50
+ ====
51
+
52
+ This product is proudly presented to you by [Planetary Networks](http://planetary-networks.de).
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ begin
2
+ require 'rubygems'
3
+ require 'jeweler'
4
+ Jeweler::Tasks.new do |gemspec|
5
+ gemspec.name = %q{mailfakk2}
6
+ gemspec.summary = %q{email to fax gateway in ruby}
7
+ gemspec.description = %q{
8
+ MailFaKK2 acts as a fax gateway. With the proper setup you can send
9
+ an email to <number>@fax.local and it generates a multipage tiff and
10
+ a callfile for asterisk
11
+ }
12
+ gemspec.email = %q{niklas+mailfakk2@lanpartei.de}
13
+ gemspec.homepage = %q{http://github.com/niklas/MailFaKK2/}
14
+ gemspec.authors = ["Niklas Hofer"]
15
+ gemspec.executables = %w{mailfakk2}
16
+
17
+ gemspec.has_rdoc = false
18
+ gemspec.files = %w{
19
+ README.mardown
20
+ Rakefile
21
+
22
+ bin/mailfakk2
23
+
24
+ config/env.rb
25
+ config/forward
26
+ config/procmail
27
+
28
+ lib/logging.rb
29
+ lib/configuration.rb
30
+ lib/facsimile.rb
31
+ lib/mailfakk2.rb
32
+
33
+ MIT-LICENSE
34
+ }
35
+
36
+ gemspec.add_dependency('activesupport', '>=2.3.5')
37
+ gemspec.add_dependency('andand', '>=1.3.1')
38
+ gemspec.add_dependency('mail', '>=2.2.0')
39
+ gemspec.add_dependency('prawn', '>=0.8.4')
40
+ end
41
+ Jeweler::GemcutterTasks.new
42
+ rescue LoadError
43
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
44
+ end
data/bin/mailfakk2 ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','config','env'))
4
+
5
+
6
+ include Logging
7
+ begin
8
+ fakk = MailFakk2.deliver!(STDIN)
9
+ rescue Exception => e
10
+ log(e.message, :err)
11
+ STDERR.puts e.message
12
+ end
data/config/env.rb ADDED
@@ -0,0 +1,14 @@
1
+ APP_ROOT = File.join File.basename(__FILE__), '..'
2
+ require 'rubygems'
3
+ require 'active_support'
4
+ require 'fileutils'
5
+ require 'andand'
6
+ require 'mail'
7
+ require 'prawn'
8
+ require 'RMagick'
9
+ require 'tempfile'
10
+
11
+ require 'logging'
12
+ require 'facsimile'
13
+ require 'configuration'
14
+ require 'mailfakk2'
data/config/forward ADDED
@@ -0,0 +1,2 @@
1
+ # put this in ~/.forward
2
+ "|/usr/bin/procmail"
data/config/procmail ADDED
@@ -0,0 +1,3 @@
1
+ # put this into ~fax/.procmailrc
2
+ :0
3
+ | mailfakk2
@@ -0,0 +1,50 @@
1
+ require 'ostruct'
2
+ class Configuration < Hash
3
+ Defaults = {
4
+ 'outgoing_call_dir' => '/var/spool/asterisk/outgoing',
5
+ 'archive_path' => File.join(ENV['HOME'], 'facsimiles')
6
+ }
7
+
8
+ # Config files are read in this order
9
+ Sources = [
10
+ '/etc/mailfakk2.yml',
11
+ File.join( ENV['HOME'], '.mailfakk2.yml')
12
+ ]
13
+
14
+ def method_missing(methname, *args, &block)
15
+ methname = methname.to_s
16
+ if has_key?(methname)
17
+ self[methname]
18
+ else
19
+ if !block_given? && args.empty?
20
+ raise NoMethodError, "unknown configuration field: #{methname}"
21
+ else
22
+ super
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.load
28
+ conf = returning(Defaults) do |h|
29
+ Sources.each do |source|
30
+
31
+ if File.file?(source) && File.readable?(source)
32
+ loaded = YAML.load_file source
33
+ if loaded.is_a?(Hash)
34
+ h.merge! loaded
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ build conf
41
+ end
42
+
43
+ def self.default
44
+ build Defaults
45
+ end
46
+
47
+ def self.build(hash)
48
+ new.update(Defaults).update(hash)
49
+ end
50
+ end
data/lib/facsimile.rb ADDED
@@ -0,0 +1,170 @@
1
+ class Facsimile
2
+ include Logging
3
+
4
+ Width = 1728
5
+ Height = 2156
6
+
7
+ #include ActiveSupport::Memoization
8
+
9
+ class NoPhoneNumberFound < Exception; end
10
+ class NoContentFound < Exception; end
11
+
12
+ attr_reader :frames
13
+ attr_reader :mail
14
+
15
+ def initialize(source)
16
+ if source.is_a?(IO)
17
+ @mail = Mail.new(source.read)
18
+ else
19
+ @mail = Mail.read(source)
20
+ end
21
+ @frames = Magick::ImageList.new
22
+ @tempfiles = []
23
+ end
24
+
25
+ def number
26
+ n = mail.header['X-Original-To'].andand.to_s || mail.to.andand.first
27
+ if n.present? && n.to_s =~ /^(\d{5,})/
28
+ return $1
29
+ else
30
+ raise NoPhoneNumberFound, "could not find any phone number"
31
+ end
32
+ end
33
+
34
+ #memoize :number
35
+
36
+ def render
37
+
38
+ if mail.multipart?
39
+
40
+ mail.parts.each do |part|
41
+ case part.content_type
42
+ when %r'text/plain'
43
+ add_frames text2tiff( part.decoded )
44
+ when %r'opendocument\.text'
45
+ add_frames oo2tiff( part.decoded )
46
+ when %r'text/html'
47
+ # FIXME ignore html, let's hope a plain text contained everything important
48
+ else
49
+ STDERR.puts "unsupported content type: #{part.content_type}"
50
+ end
51
+ end
52
+
53
+ else
54
+
55
+ unless mail.body.decoded.blank?
56
+ text2tiff( mail.body.decoded ).each do |tiff|
57
+ frames << tiff
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ def write(path)
66
+ render
67
+ raise NoContentFound if frames.empty?
68
+ path = File.expand_path path
69
+ log("writing facsimile to #{path}")
70
+ path += '.tiff' unless path.ends_with?('.tiff')
71
+ dir = File.dirname path
72
+ FileUtils.mkdir_p(dir) unless File.directory?(dir)
73
+ frames.write(path)
74
+ end
75
+
76
+ def filename
77
+ "#{id}.tiff"
78
+ end
79
+
80
+ def callfile_name
81
+ "#{id}.call"
82
+ end
83
+
84
+ def id
85
+ unless mail.has_message_id?
86
+ mail.add_message_id("#{Time.now.iso8601}-#{Process.pid}")
87
+ end
88
+ mail.message_id
89
+ end
90
+
91
+ private
92
+
93
+ def add_frames(tiffs=nil)
94
+ return unless tiffs
95
+ tiffs.each do |tiff|
96
+ frames << tiff
97
+ end
98
+ end
99
+
100
+ def text2tiff(text)
101
+ pdf = text2pdf(text)
102
+ pdf2tiff(pdf)
103
+ end
104
+
105
+ def pdf2tiff(source)
106
+ dest = mktemp('tiff')
107
+ command = returning ['gs'] do |gs|
108
+ gs << '-dQUIET'
109
+ gs << '-sDEVICE=tiffg3'
110
+ gs << "-sPAPERSIZE=#{pagesize}"
111
+ gs << '-r204x196'
112
+ gs << '-dNOPAUSE'
113
+ gs << "-sOutputFile=#{dest.path}"
114
+ gs << '-c save pop'
115
+ gs << '-c "<< /Policies << /PageSize 5 >> /PageSize [595 842] /InputAttributes << 0 << /PageSize [595 842] >> >> >> setpagedevice"'
116
+ gs << "-f #{source}"
117
+ gs << '-c quit'
118
+ end.join(' ')
119
+ system(command)
120
+ read_frame dest.path
121
+ end
122
+
123
+ def oo2tiff(source_data)
124
+ source = mktemp('oo', false)
125
+ source.write source_data
126
+ source.close
127
+
128
+ dest = mktemp('pdf')
129
+ xvfb("unoconv -f pdf #{source.path}")
130
+ FileUtils.mv source.path + '.pdf', dest.path
131
+ pdf2tiff(dest.path)
132
+ end
133
+
134
+ def text2pdf(source)
135
+ document = Prawn::Document.new(:page_size => pagesize.upcase)
136
+ document.text source
137
+
138
+ dest = mktemp('pdf')
139
+ document.render_file dest.path
140
+
141
+ dest.path
142
+ end
143
+
144
+ def new_frame
145
+ tiff = Magick::Image.new(Width, Height) do
146
+ self.background_color = 'white'
147
+ end
148
+ tiff
149
+ end
150
+
151
+ def read_frame(source)
152
+ Magick::Image.read(source)
153
+ end
154
+
155
+ def mktemp(name,close=true)
156
+ tmp = Tempfile.new(name)
157
+ tmp.close if close
158
+ tmp
159
+ end
160
+
161
+ def pagesize
162
+ 'a4'
163
+ end
164
+
165
+ def xvfb(command)
166
+ system("xvfb-run --auto-servernum --server-num=23 #{command}")
167
+ end
168
+
169
+
170
+ end
data/lib/logging.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'syslog'
2
+ module Logging
3
+ def log(message, severity=:warning)
4
+ Syslog.open('mailfakk2', Syslog::LOG_PID | Syslog::LOG_CONS) { |s| s.send(severity, message) }
5
+ end
6
+ end
data/lib/mailfakk2.rb ADDED
@@ -0,0 +1,53 @@
1
+ class MailFakk2
2
+ include Logging
3
+
4
+ def self.deliver!(source)
5
+ new(source).deliver!
6
+ end
7
+
8
+ attr_reader :fax
9
+
10
+ def initialize(source)
11
+ @fax = Facsimile.new(source)
12
+ end
13
+
14
+ def deliver!
15
+ log("sending fax to #{@fax.number}")
16
+ @fax.write( archive_path )
17
+ write_callfile
18
+ self
19
+ end
20
+
21
+ def archive_path
22
+ File.expand_path File.join( config.archive_path, @fax.filename)
23
+ end
24
+
25
+ def callfile_path
26
+ File.join( config.outgoing_call_dir, @fax.callfile_name)
27
+ end
28
+
29
+ def config
30
+ @config ||= Configuration.load
31
+ end
32
+
33
+ def write_callfile
34
+ tmp = Tempfile.new('call')
35
+ tmp.puts callfile_contents
36
+ tmp.close
37
+ FileUtils.mkdir_p config.outgoing_call_dir
38
+ FileUtils.mv tmp.path, callfile_path
39
+ FileUtils.chmod 0666, callfile_path
40
+ end
41
+
42
+ def callfile_contents
43
+ <<-EOCALL
44
+ Channel: DAHDI/g0/#{@fax.number}
45
+ MaxRetries: 5
46
+ WaitTime: 20
47
+ Context: incoming-fax
48
+ Application: SendFax
49
+ Data:#{archive_path}
50
+ Archive: yes
51
+ EOCALL
52
+ end
53
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Configuration do
4
+ describe "loading" do
5
+ it 'should try system, then home' do
6
+ File.should_receive(:file?).ordered.with('/etc/mailfakk2.yml').and_return(false)
7
+ File.should_receive(:file?).ordered.with( File.join(ENV['HOME'], '.mailfakk2.yml') ).and_return(false)
8
+ c = Configuration.load
9
+ c.should be_a(Configuration)
10
+ end
11
+
12
+ it 'should fall back to defaults' do
13
+ File.stub!(:file?).and_return(false)
14
+ c = Configuration.load
15
+ Configuration::Defaults.each do |k,v|
16
+ c[k].should == v
17
+ c.send(k).should == v
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+
3
+ describe "text only" do
4
+ before(:each) do
5
+ @mail_path = mail_path('only_text')
6
+ @fax = Facsimile.new @mail_path
7
+ end
8
+
9
+ it 'should find #number' do
10
+ @fax.number.should == '01189998819991197253'
11
+ end
12
+
13
+ it 'should render 1 frame from body' do
14
+ @fax.write result_path('only_text')
15
+ @fax.frames.should be_an(Magick::ImageList)
16
+ @fax.should have(1).frame
17
+ end
18
+
19
+ it 'should add footer and header'
20
+ end
21
+
22
+ describe "text only as IO (like STDIN)" do
23
+ before(:each) do
24
+ @fax = Facsimile.new File.open( mail_path('only_text') )
25
+ end
26
+
27
+ it 'should find #number' do
28
+ @fax.number.should == '01189998819991197253'
29
+ end
30
+
31
+ it 'should provide id (even if no message_id in mail)' do
32
+ @fax.id.should_not be_blank
33
+ end
34
+
35
+ it 'should provide filename' do
36
+ @fax.filename.should =~ /.{10,}\.tiff/
37
+ end
38
+
39
+ end
40
+
41
+ describe "multipart from word mail client" do
42
+ before(:each) do
43
+ @mail_path = mail_path('multipart')
44
+ @fax = Facsimile.new @mail_path
45
+ end
46
+
47
+ it 'should find #number' do
48
+ @fax.number.should == '01189998819991197253'
49
+ end
50
+
51
+ it 'should render 1 frame from parts' do
52
+ @fax.write result_path('multipart')
53
+ @fax.frames.should be_an(Magick::ImageList)
54
+ @fax.should have(1).frame
55
+ end
56
+ end
57
+
58
+
59
+ describe "text with attached OpenOffice Writer Document (2 Pages)" do
60
+ before(:each) do
61
+ @mail_path = mail_path('oo_writer_attached')
62
+ @fax = Facsimile.new @mail_path
63
+ end
64
+
65
+ it 'should produce 1+2 frames' do
66
+ @fax.write result_path('oo_writer_attached')
67
+ @fax.should have(3).frames
68
+ end
69
+
70
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe "MailFakk2" do
4
+ before(:each) do
5
+ @mail = mail_path('only_text')
6
+ @fakk = MailFakk2.new @mail
7
+ end
8
+
9
+ it 'should create a Facsimile' do
10
+ @fakk.fax.should be_a(Facsimile)
11
+ end
12
+
13
+ it 'should load configuration' do
14
+ Configuration.should_receive(:load).once.and_return('config')
15
+ @fakk.config.should == 'config'
16
+ end
17
+
18
+ describe "delivery" do
19
+
20
+ before(:each) do
21
+ @conf = test_configuration
22
+ @fax_path = File.expand_path File.join( @conf.archive_path, @fakk.fax.filename)
23
+ @fakk.stub!(:config).and_return(@conf)
24
+ @fax = @fakk.fax
25
+ @fax.stub!(:render)
26
+ frames_mock = mock(:empty? => false, :write => true)
27
+ @fakk.fax.stub!(:frames).and_return(frames_mock)
28
+ @delivering = lambda { @fakk.deliver! }
29
+ end
30
+
31
+ after(:each) do
32
+ end
33
+
34
+ it 'should render the fax' do
35
+ @fax.should_receive(:render).once
36
+ @delivering.call
37
+ end
38
+
39
+ it 'should save the tiff to the archive path' do
40
+ @fax.should_receive(:write).with( @fax_path )
41
+ @delivering.call
42
+ end
43
+
44
+ it 'should create and move a callfile with proper permissions' do
45
+ @delivering.call
46
+ callfile_path = File.join( @conf.outgoing_call_dir, @fax.callfile_name)
47
+ File.file?(callfile_path).should be_true
48
+ # TODO permissions should be 0666, just to be sure. How to test this?
49
+ end
50
+
51
+ it 'should wait for the callfile to be moved to outgoing_done'
52
+ it 'should deliver a mail if no number was found'
53
+ it 'should deliver a mail if sending the fax failed'
54
+ it 'may deliver a mail report for successfull delivery'
55
+ end
56
+ it 'maybe should detach from procmail to enhance processing speed'
57
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec/autorun'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__),'..','config','env'))
4
+
5
+ ResultsDir = File.join APP_ROOT, 'tmp', 'results'
6
+
7
+ FileUtils.rm_rf ResultsDir if File.exists?(ResultsDir)
8
+ FileUtils.mkdir_p ResultsDir
9
+
10
+ def mail_path(name)
11
+ name += '.mail' unless name.ends_with?('.mail')
12
+ File.join APP_ROOT, 'spec', 'fixtures', name
13
+ end
14
+
15
+ def result_path(name)
16
+ name += '.tiff' unless name.ends_with?('.tiff')
17
+ File.join ResultsDir, name
18
+ end
19
+
20
+ def test_configuration
21
+ @@test_configuration ||= Configuration.build({
22
+ 'outgoing_call_dir' => ResultsDir,
23
+ 'archive_path' => ResultsDir
24
+ })
25
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mailfakk2
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Niklas Hofer
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-16 00:00:00 +02:00
18
+ default_executable: mailfakk2
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 5
31
+ version: 2.3.5
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: andand
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 3
44
+ - 1
45
+ version: 1.3.1
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mail
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 2
57
+ - 2
58
+ - 0
59
+ version: 2.2.0
60
+ type: :runtime
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: prawn
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ - 8
72
+ - 4
73
+ version: 0.8.4
74
+ type: :runtime
75
+ version_requirements: *id004
76
+ description: "\n MailFaKK2 acts as a fax gateway. With the proper setup you can send\n an email to <number>@fax.local and it generates a multipage tiff and\n a callfile for asterisk\n "
77
+ email: niklas+mailfakk2@lanpartei.de
78
+ executables:
79
+ - mailfakk2
80
+ extensions: []
81
+
82
+ extra_rdoc_files:
83
+ - README.markdown
84
+ files:
85
+ - MIT-LICENSE
86
+ - Rakefile
87
+ - bin/mailfakk2
88
+ - config/env.rb
89
+ - config/forward
90
+ - config/procmail
91
+ - lib/configuration.rb
92
+ - lib/facsimile.rb
93
+ - lib/logging.rb
94
+ - lib/mailfakk2.rb
95
+ - README.markdown
96
+ has_rdoc: true
97
+ homepage: http://github.com/niklas/MailFaKK2/
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options:
102
+ - --charset=UTF-8
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 0
111
+ version: "0"
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project:
122
+ rubygems_version: 1.3.6
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: email to fax gateway in ruby
126
+ test_files:
127
+ - spec/configuration_spec.rb
128
+ - spec/spec_helper.rb
129
+ - spec/mailfakk2_spec.rb
130
+ - spec/facsimile_spec.rb