mail2frontmatter 0.0.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.
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: []