mail2frontmatter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 805544b6ae89d533ee1dd0c5d626a3cbf69ad5f2
4
+ data.tar.gz: eb23c01ec9e523c3b3714d25e0ec30ea06fabf50
5
+ SHA512:
6
+ metadata.gz: 98b0857153b18118cc9a44e29e456631f7a5bc9b7e2c79de753fc0b900721ad6c257df4b307adf1e03735b67cf16ccc706169950bda7a8bbd3c146c9a8d70562
7
+ data.tar.gz: 47ca7154d3430195d89ebbe2087eb3ca467274dcf5cf540f4bfe7a247416a8fc2022a4f6f6cdb88287f577a567a853ddd260d6cda2229647e7f9e7a33b598bd9
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mail2frontmatter.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Kunal Shah
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Mail2FrontMatter
2
+
3
+ Email-to-blog parser which creates YAML FrontMatter and saves your attachments.
4
+
5
+ Designed to be used with either Middleman or Jekyll
6
+
7
+ ## Installation
8
+
9
+ Install it yourself as:
10
+
11
+ $ gem install mail2frontmatter
12
+
13
+ Or if you do not intend to directly use the executable, you can include it in Gemfile like:
14
+
15
+ ```ruby
16
+ gem 'mail2frontmatter'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ ## Usage
24
+
25
+ To run in the foreground:
26
+
27
+ $ mail2frontmatter
28
+
29
+ To detach the process pass the ```-d``` option:
30
+
31
+ $ mail2frontmatter -d
32
+
33
+ ```mail2frontmatter``` assumes a configuration file will be present at ```./data/mail2frontmatter.yml```
34
+
35
+ You can override this by passing ```--config=CONFIG```
36
+
37
+ Furthermore, when run daemonized ```mail2frontmatter``` assumes it can:
38
+
39
+ 1. write its pidfile to ```./tmp/pids/mail2frontmatter.pid```
40
+ 2. append its log output to ```./log/mail2frontmatter.log```
41
+
42
+ You can override each of these settings as well:
43
+
44
+ To specify a pidfile location set ```--pid=PIDFILE```
45
+ Note: no pidfile is written when run in the foreground
46
+
47
+ To specify a log file location set ```--log=LOGFILE```
48
+ The default log file when detached is ```./log/mail2frontmatter.log``` (otherwise its ```STDOUT```)
49
+
50
+ Finally to stop (```SIGTERM```) the detached process call:
51
+
52
+ $ mail2frontmatter -k
53
+
54
+ ### Basic Configuration
55
+
56
+ Your configuration file should by parseable YAML.
57
+
58
+ ```yaml
59
+ protocol: imap
60
+ receiver: yourblogemail@yourdomain.com
61
+ senders: yourpersonal@yourdomain.com
62
+ mailman:
63
+ server: imap.gmail.com
64
+ port: 993
65
+ ssl: true
66
+ username: yourblogemail@yourdomain.com
67
+ password: yourpassword
68
+ ```
69
+
70
+ As shown the mailman configuration are the exact options you would pass [to that gem](https://github.com/titanous/mailman/blob/master/USER_GUIDE.md).
71
+
72
+ ### Embedded Configuration
73
+
74
+ Finally, as an alternative to using the executable and configuration you can use the watcher embedded within your own code.
75
+
76
+ Just instantiate it with an empty hash or with config options, then give it a block. You can directly access the Mailman object here as well. See the example below and look at the gem code for more details.
77
+
78
+ ```ruby
79
+ require 'mail2frontmatter'
80
+
81
+ watcher = Mail2FrontMatter::Watcher.new({}) do |config|
82
+ config[:mailman] = {
83
+ server: imap.gmail.com
84
+ port: 993
85
+ ssl: true
86
+ username: youruser@yourdomain.com
87
+ password: yourpassword
88
+ }
89
+
90
+ @receiver = "foo@bar.com"
91
+ @senders = "baz@biz.com"
92
+
93
+ ....
94
+ end
95
+
96
+ # run it
97
+ watcher.run
98
+ ```
99
+
100
+ ## Contributing
101
+
102
+ 1. Fork it ( https://github.com/whistlerbrk/mail2frontmatter/fork )
103
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
104
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
105
+ 4. Push to the branch (`git push origin my-new-feature`)
106
+ 5. Create a new Pull Request
107
+
108
+ ### TODO
109
+
110
+ * White list sanitization!
111
+ * Mail2FrontMatter::Watcher handles both configuration for the whole shebang as well as Mailman. Should be split
112
+ * Some options intended to be configurable (media directory, etc) are not yet and essentially mean you can only run this from a middleman directory installation atm.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ run_dir = Dir.pwd
6
+
7
+ # only run time options, not *configuration* options
8
+ stop = false
9
+ config = nil
10
+ options = {
11
+ background: false,
12
+ log_file: nil,
13
+ pid_file: File.join(run_dir, 'tmp', 'pids', 'mail2frontmatter.pid')
14
+ }
15
+
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: mail2frontmatter [options]"
18
+
19
+ opts.on("-k", "--stop", "stop the running process if any") do
20
+ stop = true
21
+ end
22
+
23
+ opts.on("-cCONFIG", "--config=CONFIG", "path to configuration file, defaults to ./data/mail2frontmatter.yml") do |config_file|
24
+ require 'yaml'
25
+ config = YAML.load_file(config_file).symbolize_keys!
26
+ end
27
+
28
+ opts.on("-d", "--detach", "detach process and run in the background") do
29
+ options[:background] = true
30
+ end
31
+
32
+ opts.on("-lLOGFILE", "--log=LOGFILE", "path to log file, defaults to STDOUT in the foreground or ./log/mail2frontmatter.log when daemonized") do |log_file|
33
+ options[:log_file] = log_file
34
+ end
35
+
36
+ opts.on("-pPIDFILE", "--pid=PIDFILE", "path to pid file, defaults to ./tmp/pids/mail2frontmatter.pid") do |pid_file|
37
+ options[:pid_file] = pid_file
38
+ end
39
+
40
+ opts.on("-h", "--help", "Prints this help") do
41
+ puts opts
42
+ exit
43
+ end
44
+ end.parse!
45
+
46
+ # TRY TO KILL
47
+ if stop
48
+
49
+ if !File.exist?(options[:pid_file])
50
+ puts "no pidfile! are you sure mail2frontmatter is running?"
51
+ exit 1
52
+ end
53
+
54
+ pid = File.read(options[:pid_file]).to_i
55
+ puts "stopping (#{pid})... "
56
+
57
+ # N.B / TODO - DOESN'T WAIT.. DOESN'T CHECK
58
+ begin
59
+ Process.kill('TERM', pid)
60
+ exit 0
61
+
62
+ # FUTURE: library intercepts TERM,
63
+ # waits to finish processing if it is
64
+ # or if kill exits dirty.
65
+
66
+ # CATCH STALE PID
67
+ rescue Errno::ESRCH
68
+ puts "stale pidfile... cleaning"
69
+
70
+ # ALWAYS DELETE PID FILE
71
+ ensure
72
+ File.delete(options[:pid_file])
73
+
74
+ end
75
+
76
+ end
77
+
78
+ # TRY TO START
79
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'mail2frontmatter')
80
+
81
+ # DAEMONIZE...
82
+ if options[:background]
83
+
84
+ # CHECKING ALREADY RUNNING / CHECK STALE
85
+ if File.exists?(options[:pid_file])
86
+ pid = File.read(options[:pid_file]).to_i
87
+
88
+ begin
89
+ Process.kill(0, pid)
90
+ puts "mail2frontmatter is already running (#{pid})"
91
+ exit 1
92
+
93
+ rescue Errno::ESRCH
94
+ puts "stale pidfile... cleaning"
95
+ File.delete(options[:pid_file])
96
+ end
97
+ end
98
+
99
+ puts "daemonizing..."
100
+
101
+ # SET LOG FILE INTERNAL
102
+ watcher = Mail2FrontMatter::Watcher.new(config) do |config|
103
+ if !options[:log_file]
104
+ config[:log_file] = File.join(run_dir, 'log', 'mail2frontmatter.log')
105
+ else
106
+ config[:log_file] = options[:log_file]
107
+ end
108
+ end
109
+
110
+ # FORK / DETACH
111
+ runner = fork do
112
+ File.write(options[:pid_file], Process.pid)
113
+ watcher.run
114
+ end
115
+
116
+ Process.detach(runner)
117
+
118
+ else
119
+
120
+ # SET LOG FILE INTERNAL (REDUNDANT)
121
+ watcher = Mail2FrontMatter::Watcher.new(config) do |config|
122
+ config[:log_file] = !options[:log_file] ? STDOUT : options[:log_file]
123
+ end
124
+
125
+ # FOREGROUND
126
+ watcher.run
127
+ end
@@ -0,0 +1,72 @@
1
+
2
+ # Breaks down email
3
+ module Mail2FrontMatter
4
+ class Parser
5
+ require 'nokogiri'
6
+ require 'fileutils'
7
+
8
+ attr_accessor :message, :metadata, :body
9
+
10
+ ALLOWED_TYPES = {
11
+ "audio" => "audio",
12
+ "video" => "videos",
13
+ "image" => "images"
14
+ }
15
+
16
+ def initialize(message)
17
+ @message = message
18
+ raw_parsed_html = Nokogiri::HTML.parse(@message.html_part.body.raw_source.strip)
19
+ @body = raw_parsed_html.at("body")
20
+
21
+ # remove extraneous nesting
22
+ while(@body.children.count == 1 && @body.children.first.name == "div") do
23
+ @body = @body.children.first
24
+ end
25
+
26
+ attachments = {}
27
+
28
+ @message.attachments.each do |attachment|
29
+ if Parser::ALLOWED_TYPES.keys.include?(attachment.main_type)
30
+
31
+ # save attachments
32
+ media_directory = File.join(Dir.pwd, 'source', Parser::ALLOWED_TYPES[attachment.main_type])
33
+ FileUtils.mkdir_p(media_directory)
34
+
35
+ filepath = File.join(media_directory, attachment.filename)
36
+
37
+ # save attachment
38
+ File.open(filepath, "w+b", 0644) {|f| f.write attachment.body.decoded}
39
+
40
+ # retain metadata
41
+ attachments[attachment.cid] = {
42
+ maintype: attachment.main_type,
43
+ mimetype: attachment.mime_type,
44
+ filename: attachment.filename,
45
+ filepath: filepath
46
+ }
47
+
48
+ # file type not allowed
49
+ else
50
+ # remove cooresponding node from html
51
+ @body.xpath("//*[@src='cid:#{attachment.content_id}']").remove
52
+
53
+ end
54
+ end
55
+
56
+ # convert body immediately to a string, why?
57
+ # Plugins / pre-processors may wish to manipulate the body
58
+ # however Nokogiri is strict and won't allow template tags
59
+ # for obvious good reasons
60
+ @body = @body.inner_html
61
+
62
+ @metadata = {
63
+ from: message[:to].value,
64
+ to: message[:from].value,
65
+ received: message.date,
66
+ subject: message.subject,
67
+ attachments: attachments
68
+ }
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,46 @@
1
+
2
+ # Pre-processes blog data, allows hooks
3
+ #
4
+ #
5
+ # Build a Pre-Processor that accepts two arguments
6
+ # metadata, a symbolized hash of metadata extracted from the email
7
+ # and body, a Nokogiri parsed representation of the email
8
+ #
9
+ # modify as necessary and as atomically as possible and return two arguments
10
+ #
11
+ # example:
12
+ #
13
+ # module Mail2FrontMatter
14
+ # class MyProcessor < PreProcessor
15
+ # def self.run(metadata, body)
16
+ # metadata[:some_field] = some_transformation_of(metadata[:some_field])
17
+ # return metadata, body
18
+ # end
19
+ # end
20
+ # end
21
+
22
+ module Mail2FrontMatter
23
+ class PreProcessor
24
+ require 'set'
25
+
26
+ class InvalidProcessor < StandardError ; end
27
+
28
+ @@processors = Set.new
29
+
30
+ def self.register(options = {})
31
+ raise InvalidProcessor, "run method not defined on #{self}" if !self.respond_to?(:run)
32
+ @options = options
33
+
34
+ @@processors << self
35
+ end
36
+
37
+ def self.process(metadata, body)
38
+ @@processors.each do |processor|
39
+ metadata, body = processor.run(metadata, body)
40
+ end
41
+
42
+ return metadata, body
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Mail2FrontMatter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,79 @@
1
+
2
+ # configures and runs Mailman
3
+ module Mail2FrontMatter
4
+ require 'mailman'
5
+ require 'byebug'
6
+ require 'active_support/inflector'
7
+
8
+ class Watcher
9
+
10
+ attr_accessor :logger
11
+
12
+ def initialize(config = nil, &block)
13
+ # load config from file
14
+ if config.is_a?(String)
15
+ config = YAML.load_file(config).deep_symbolize_keys!
16
+
17
+ # load config from file at default data/mail2frontmatter.yml relative from run directory
18
+ elsif config.is_a?(NilClass)
19
+
20
+ default_config = File.join(Dir.pwd, 'data', 'mail2frontmatter.yml')
21
+
22
+ if File.exist?(default_config)
23
+ config = YAML.load_file(default_config).deep_symbolize_keys!
24
+ else
25
+ raise LoadError, 'no configuration given or found at ./data/mail2frontmatter.yml'
26
+ end
27
+
28
+ elsif !config.is_a?(Hash)
29
+ raise ArgumentError, 'not a valid configuration type'
30
+ end
31
+
32
+ yield(config) if block_given?
33
+
34
+ preprocessors = config.delete(:preprocessors) || []
35
+ preprocessors.each do |processor|
36
+
37
+ begin
38
+ require "mail2frontmatter/#{processor[:key]}"
39
+ rescue LoadError => e
40
+ puts "could not require specified preprocessor '#{processor[:key]}.rb', no such file in load path. Check your configuration and try again \n\n"
41
+ raise e
42
+ end
43
+
44
+ klass = "Mail2FrontMatter::#{processor[:key].underscore.classify}".constantize.register(processor[:options])
45
+ end
46
+
47
+ mail_protocol = config.delete(:protocol) || :imap
48
+ poll_interval = config.delete(:interval) || 60
49
+
50
+ @receiver = config.delete(:receiver)
51
+ @senders = config.delete(:senders)
52
+ @logger = Logger.new(config.delete(:log_file))
53
+
54
+ Mailman.config.poll_interval = poll_interval
55
+ Mailman.config.ignore_stdin = true
56
+
57
+ Mailman.config.send("#{mail_protocol}=", config[:mailman])
58
+ Mailman.config.logger = @logger
59
+ end
60
+
61
+ def run
62
+ Mailman::Application.run do
63
+ from(@senders).to(@receiver) do
64
+ logger = Mailman.config.logger
65
+
66
+ logger.info('parsing message...')
67
+ parser = Mail2FrontMatter::Parser.new(message)
68
+
69
+ logger.info('processing body and attachments...')
70
+ metadata, body = Mail2FrontMatter::PreProcessor.process(parser.metadata, parser.body)
71
+
72
+ logger.info('saving processed post...')
73
+ Mail2FrontMatter::Writer.write(metadata, body)
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,41 @@
1
+
2
+ # Writes YAML FrontMatter & Article Content in ERB
3
+ #
4
+ # TODO How do I support other templating solutions here?
5
+ # Same plugin style as processors?
6
+ # Is processor and writer doing the same thing?
7
+ # --- probably just let anyone specify the extension.. keep it simple
8
+ #
9
+ module Mail2FrontMatter
10
+ class Writer
11
+
12
+ require 'yaml'
13
+ require 'active_support/inflector'
14
+
15
+ def self.write(metadata, body)
16
+
17
+ # TODO FIXME!
18
+ #
19
+ # this is supposed to be configurable!
20
+ # get this value from a module variable!
21
+ #
22
+ data_directory = File.join(Dir.pwd, 'source', 'blog')
23
+
24
+ # MAPPINGS!
25
+ #
26
+ # Play nice with programs which will read this data
27
+ # And set sensible defaults as fall throughs
28
+
29
+ # if there is no title set, borrow the subject lines
30
+ metadata[:title] ||= metadata[:subject]
31
+
32
+ # make a sensible standard blog filename unless one is given
33
+ metadata[:filename] ||= [metadata[:received].strftime("%Y-%m-%d"), '-', metadata[:subject].parameterize, '.html.erb'].join
34
+
35
+ data = metadata.to_yaml + "---\n" + body
36
+
37
+ File.write(File.join(data_directory, metadata[:filename]), data)
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ require 'mail2frontmatter/version'
2
+ require 'mail2frontmatter/watcher'
3
+ require 'mail2frontmatter/parser'
4
+ require 'mail2frontmatter/writer'
5
+ require 'mail2frontmatter/preprocessor'
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mail2frontmatter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mail2frontmatter"
8
+ spec.version = Mail2FrontMatter::VERSION
9
+ spec.authors = ["Kunal Shah"]
10
+ spec.email = ["me@kunalashah.com"]
11
+ spec.summary = %q{Email-to-blog parser which creates YAML FrontMatter}
12
+ spec.description = spec.summary + %q{. Uses Mailman to poll an account. }
13
+ spec.homepage = "https://github.com/whistlerbrk/Mail2FrontMatter"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "mailman"
22
+ spec.add_dependency "activesupport"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.7"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mail2frontmatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kunal Shah
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mailman
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: 'Email-to-blog parser which creates YAML FrontMatter. Uses Mailman to
70
+ poll an account. '
71
+ email:
72
+ - me@kunalashah.com
73
+ executables:
74
+ - mail2frontmatter
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/mail2frontmatter
84
+ - lib/mail2frontmatter.rb
85
+ - lib/mail2frontmatter/parser.rb
86
+ - lib/mail2frontmatter/preprocessor.rb
87
+ - lib/mail2frontmatter/version.rb
88
+ - lib/mail2frontmatter/watcher.rb
89
+ - lib/mail2frontmatter/writer.rb
90
+ - mail2frontmatter.gemspec
91
+ homepage: https://github.com/whistlerbrk/Mail2FrontMatter
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.5
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Email-to-blog parser which creates YAML FrontMatter
115
+ test_files: []