mail2frontmatter 0.1.0 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 050bf37a3ad7a9d3207ce8ffb89c1b204c69e90a
4
- data.tar.gz: 4658ee6d6a02c3a7746824d9dfcd0d1a38f9db0f
3
+ metadata.gz: 0ca545c2952a483060ba2c7b90aa0aeed1c85891
4
+ data.tar.gz: 96be89bc2de5e5cc89d2daecd2cf0633a8d0fdcd
5
5
  SHA512:
6
- metadata.gz: a5114ef331caf20a530462e41730ae61a2bf02bd43cf97ccfa23816a88efc7ac5409a6c50eb2e7d44997105bedbbeb125c59357a116083c8379d36d9f71d0dc0
7
- data.tar.gz: b6f0d9125761f73d4a3aa8f94899f2c25301cea925a367971267e974a99dcd6fe25f1daeea5aab4e0ddc5b779e9bf1290438fa63eec0b7f0123cd29137368942
6
+ metadata.gz: 2af70109d10996401cb9b20bf429af5493ef41da128352350d5e31a793aa7a5cc8cf3dfe1b5ef3d824936f57742325e706163df48bb1fdc81990bfd8f3b18e39
7
+ data.tar.gz: 124aa40da8be4e7bb23199384b0b375046c4f057ca0355999ac1f7a7d4f2f863307946db6b9c76ea25d150d2e59ad740142367ed9b97815d6830c1b98245f366
data/.gitignore CHANGED
@@ -14,3 +14,5 @@
14
14
  mkmf.log
15
15
  /source/
16
16
  .DS_Store
17
+ /fixtures/data/*.yml
18
+ /fixtures/media/*/*
@@ -1,5 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.3
4
3
  - 2.2.0
5
4
  script: bundle exec rake
data/README.md CHANGED
@@ -4,7 +4,9 @@
4
4
 
5
5
  Email-to-blog parser which creates YAML FrontMatter and saves your attachments.
6
6
 
7
- Designed to be used with either Middleman or Jekyll
7
+ Designed to be used with either Middleman or Jekyll.
8
+
9
+ This project is actively being developed. I wrap the executable with the [eye](https://github.com/kostya/eye) gem at the moment.
8
10
 
9
11
  ## Installation
10
12
 
@@ -147,6 +149,27 @@ You should always always return metadata and body as shown since this will be pa
147
149
 
148
150
  ### TODO
149
151
 
150
- * White list sanitization by default
151
- * defaults for Jekyll out of the box
152
+ * core plugins
153
+
154
+ Core plugins should be included out of the box and disabled upon request. It's just simpler to use
155
+
156
+ * zero config for Jekyll
157
+
158
+ current we 'detect' the directory structure to see if the executable is run from Middleman,
159
+ do the same for Jekyll in order to support it out of the box with zero configuration
160
+
161
+ * remove dependency on Mailman, use Mail directly
162
+
163
+ no need to use Mailman if I intend to manage the process myself. Use Mail directly
164
+
165
+ * detach runner
166
+
167
+ incoming mail checks in the main thread, processing, writing, commiting should be handled in a separate process to discard leaks
168
+
169
+
170
+
171
+
172
+
173
+
174
+
152
175
 
data/Rakefile CHANGED
@@ -1,9 +1,5 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
2
3
 
3
4
  task default: 'spec'
4
-
5
- begin
6
- require 'rspec/core/rake_task'
7
- RSpec::Core::RakeTask.new(:spec)
8
- rescue LoadError
9
- end
5
+ RSpec::Core::RakeTask.new(:spec)
@@ -13,34 +13,34 @@ options = {
13
13
  }
14
14
 
15
15
  OptionParser.new do |opts|
16
- opts.banner = "Usage: mail2frontmatter [options]"
16
+ opts.banner = 'Usage: mail2frontmatter [options]'
17
17
 
18
- opts.on("-k", "--stop", "stop the running process if any") do
18
+ opts.on('-k', '--stop', 'stop the running process if any') do
19
19
  stop = true
20
20
  end
21
21
 
22
- opts.on("-cCONFIG", "--config=CONFIG", "path to configuration file, defaults to ./data/mail2frontmatter.yml") do |config_file|
22
+ opts.on('-cCONFIG', '--config=CONFIG', 'path to configuration file, defaults to ./data/mail2frontmatter.yml') do |config_file|
23
23
  config = config_file
24
24
  end
25
25
 
26
- opts.on("-d", "--detach", "detach process and run in the background") do
26
+ opts.on('-d', '--detach', 'detach process and run in the background') do
27
27
  options[:background] = true
28
28
  end
29
29
 
30
- opts.on("-lLOGFILE", "--log=LOGFILE", "path to log file, defaults to STDOUT in the foreground or ./log/mail2frontmatter.log when daemonized") do |log_file|
30
+ opts.on('-lLOGFILE', '--log=LOGFILE', 'path to log file, defaults to STDOUT in the foreground or ./log/mail2frontmatter.log when daemonized') do |log_file|
31
31
  config[:log_file] = log_file
32
32
  end
33
33
 
34
- opts.on("-pPIDFILE", "--pid=PIDFILE", "path to pid file, defaults to ./tmp/pids/mail2frontmatter.pid") do |pid_file|
34
+ opts.on('-pPIDFILE', '--pid=PIDFILE', 'path to pid file, defaults to ./tmp/pids/mail2frontmatter.pid') do |pid_file|
35
35
  options[:pid_file] = pid_file
36
36
  end
37
37
 
38
- opts.on("-h", "--help", "Prints this help") do
38
+ opts.on('-h', '--help', 'Prints this help') do
39
39
  puts opts
40
40
  exit
41
41
  end
42
42
 
43
- opts.on_tail("-v", "--version", "Prints version") do
43
+ opts.on_tail('-v', '--version', 'Prints version') do
44
44
  require File.join(File.dirname(__FILE__), '..', 'lib', 'mail2frontmatter', 'version')
45
45
  puts Mail2FrontMatter::VERSION
46
46
  exit
@@ -50,8 +50,8 @@ end.parse!
50
50
  # TRY TO KILL
51
51
  if stop
52
52
 
53
- if !File.exist?(options[:pid_file])
54
- puts "no pidfile! are you sure mail2frontmatter is running?"
53
+ unless File.exist?(options[:pid_file])
54
+ puts 'no pidfile! are you sure mail2frontmatter is running?'
55
55
  exit 1
56
56
  end
57
57
 
@@ -63,13 +63,13 @@ if stop
63
63
  Process.kill('TERM', pid)
64
64
  exit 0
65
65
 
66
- # FUTURE: library intercepts TERM,
67
- # waits to finish processing if it is
68
- # or if kill exits dirty.
66
+ # FUTURE: library intercepts TERM,
67
+ # waits to finish processing if it is
68
+ # or if kill exits dirty.
69
69
 
70
70
  # CATCH STALE PID
71
71
  rescue Errno::ESRCH
72
- puts "stale pidfile... cleaning"
72
+ puts 'stale pidfile... cleaning'
73
73
 
74
74
  # also exit here! but don't move exit 0 to ensure block
75
75
  # because "in the future" we may intelligently intercept pkill above
@@ -90,7 +90,7 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'mail2frontmatter')
90
90
  if options[:background]
91
91
 
92
92
  # CHECKING ALREADY RUNNING / CHECK STALE
93
- if File.exists?(options[:pid_file])
93
+ if File.exist?(options[:pid_file])
94
94
  pid = File.read(options[:pid_file]).to_i
95
95
 
96
96
  begin
@@ -99,12 +99,12 @@ if options[:background]
99
99
  exit 1
100
100
 
101
101
  rescue Errno::ESRCH
102
- puts "stale pidfile... cleaning"
102
+ puts 'stale pidfile... cleaning'
103
103
  File.delete(options[:pid_file])
104
104
  end
105
105
  end
106
106
 
107
- puts "daemonizing..."
107
+ puts 'daemonizing...'
108
108
 
109
109
  # SET CONFIG...
110
110
  Mail2FrontMatter.set_config(config)
@@ -1,8 +1,8 @@
1
1
  module Mail2FrontMatter
2
2
  class BrokenProcessor < PreProcessor
3
3
  def self.run(metadata, body)
4
- raise NoMethodError, "because this is a test"
5
- return metadata, body
4
+ fail NoMethodError, 'because this is a test'
5
+ [metadata, body]
6
6
  end
7
7
  end
8
8
  end
@@ -1,7 +1,7 @@
1
1
  module Mail2FrontMatter
2
2
  class FakeProcessorWithOptions < PreProcessor
3
3
  def self.run(metadata, body)
4
- return metadata, body
4
+ [metadata, body]
5
5
  end
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module Mail2FrontMatter
2
2
  class FakeProcessor < PreProcessor
3
3
  def self.run(metadata, body)
4
- return metadata, body
4
+ [metadata, body]
5
5
  end
6
6
  end
7
7
  end
@@ -2,5 +2,6 @@ require 'mail2frontmatter/version'
2
2
  require 'mail2frontmatter/configuration'
3
3
  require 'mail2frontmatter/watcher'
4
4
  require 'mail2frontmatter/parser'
5
- require 'mail2frontmatter/writer'
6
5
  require 'mail2frontmatter/preprocessor'
6
+ require 'mail2frontmatter/writer'
7
+ require 'mail2frontmatter/committer'
@@ -0,0 +1,68 @@
1
+
2
+ # Commits Changes to git
3
+ #
4
+ module Mail2FrontMatter
5
+ class Committer
6
+ begin
7
+ require 'rugged'
8
+ @@available = true
9
+
10
+ rescue LoadError
11
+ @@available = false
12
+ end
13
+
14
+ def self.available?
15
+ @@available
16
+ end
17
+
18
+ def self.commit(metadata, _body)
19
+ repo = Rugged::Repository.new(Mail2FrontMatter.config[:git][:path])
20
+ index = repo.index
21
+
22
+ # stage frontmatter/erb
23
+ relative_path = metadata[:filepath].gsub(Mail2FrontMatter.config[:git][:path] + '/', '')
24
+
25
+ index.add(path: relative_path,
26
+ oid: (Rugged::Blob.from_workdir repo, relative_path),
27
+ mode: 0100644)
28
+
29
+ # stage attachments
30
+ metadata[:attachments].each_pair do |_k, filemeta|
31
+ relative_path = filemeta[:filepath].gsub(Mail2FrontMatter.config[:git][:path] + '/', '')
32
+
33
+ index.add(path: relative_path,
34
+ oid: (Rugged::Blob.from_workdir repo, relative_path),
35
+ mode: 0100644)
36
+ end
37
+
38
+ # commit
39
+ tree = index.write_tree(repo)
40
+ index.write
41
+
42
+ author = {
43
+ email: Mail2FrontMatter.config[:git][:email] || metadata[:from].match(/\<(.*)\>/)[1],
44
+ name: Mail2FrontMatter.config[:git][:name] || metadata[:from].match(/(.*) \<.*\>/)[1],
45
+ time: Time.now
46
+ }
47
+
48
+ Rugged::Commit.create(repo, author: author,
49
+ committer: author,
50
+ message: "post via email, #{metadata[:subject]}",
51
+ parents: [repo.head.target],
52
+ tree: tree,
53
+ update_ref: 'HEAD')
54
+
55
+ # push
56
+ begin
57
+ credentials = Rugged::Credentials::SshKeyFromAgent.new(username: 'git')
58
+ repo.push 'origin', ['refs/heads/master'], { credentials: credentials }
59
+ rescue StandardError => e
60
+ Mail2FrontMatter.logger.info("Could not push!")
61
+ Mail2FrontMatter.logger.error(e)
62
+ end
63
+
64
+ # return sha
65
+ repo.references['refs/heads/master'].target_id
66
+ end
67
+ end
68
+ end
@@ -3,15 +3,11 @@ module Mail2FrontMatter
3
3
  require 'active_support/inflector'
4
4
 
5
5
  class << self
6
- def logger
7
- @logger
8
- end
6
+ attr_reader :logger
9
7
 
10
- def config
11
- @config
12
- end
8
+ attr_reader :config
13
9
 
14
- def set_config(passed_config = nil, &block)
10
+ def set_config(passed_config = nil, &_block)
15
11
  # load config from file
16
12
  if passed_config.is_a?(String)
17
13
  @config = YAML.load_file(passed_config).deep_symbolize_keys!
@@ -24,14 +20,14 @@ module Mail2FrontMatter
24
20
  if File.exist?(default_config)
25
21
  @config = YAML.load_file(default_config).deep_symbolize_keys!
26
22
  else
27
- raise LoadError, 'no configuration given or found at ./data/mail2frontmatter.yml'
23
+ fail LoadError, 'no configuration given or found at ./data/mail2frontmatter.yml'
28
24
  end
29
25
 
30
26
  elsif passed_config.is_a?(Hash)
31
27
  @config = passed_config
32
28
 
33
29
  else
34
- raise ArgumentError, 'not a valid configuration type'
30
+ fail ArgumentError, 'not a valid configuration type'
35
31
  end
36
32
 
37
33
  # setup logger, use provided location
@@ -47,6 +43,10 @@ module Mail2FrontMatter
47
43
  @logger = Logger.new(STDOUT)
48
44
  end
49
45
 
46
+ @config[:git] ||= {
47
+ path: Dir.pwd
48
+ }
49
+
50
50
  # set default for data directory unless already specified
51
51
  # the data directory is where the posts will be written to
52
52
  unless @config[:data_directory]
@@ -83,9 +83,8 @@ module Mail2FrontMatter
83
83
  raise e
84
84
  end
85
85
 
86
- klass = "Mail2FrontMatter::#{processor[:key].underscore.camelize}".constantize.register(processor[:options] || {})
86
+ "Mail2FrontMatter::#{processor[:key].underscore.camelize}".constantize.register(processor[:options] || {})
87
87
  end
88
-
89
88
  end
90
89
  end
91
90
  end
@@ -8,19 +8,19 @@ module Mail2FrontMatter
8
8
  attr_accessor :message, :metadata, :body
9
9
 
10
10
  ALLOWED_TYPES = {
11
- "audio" => "audio",
12
- "video" => "videos",
13
- "image" => "images"
11
+ 'audio' => 'audio',
12
+ 'video' => 'videos',
13
+ 'image' => 'images'
14
14
  }
15
15
 
16
16
  def initialize(message)
17
17
  @message = message
18
18
  raw_parsed_html = Nokogiri::HTML.parse(@message.html_part.decoded.strip)
19
19
 
20
- @body = raw_parsed_html.at("body")
20
+ @body = raw_parsed_html.at('body')
21
21
 
22
22
  # remove extraneous nesting
23
- while(@body.children.count == 1 && @body.children.first.name == "div") do
23
+ while @body.children.count == 1 && @body.children.first.name == 'div'
24
24
  @body = @body.children.first
25
25
  end
26
26
 
@@ -33,10 +33,10 @@ module Mail2FrontMatter
33
33
  media_type_directory = File.join(Mail2FrontMatter.config[:media_directory], Parser::ALLOWED_TYPES[attachment.main_type])
34
34
  FileUtils.mkdir_p(media_type_directory)
35
35
 
36
- filepath = File.join(media_type_directory, attachment.filename)
36
+ filepath = File.join(media_type_directory, attachment.filename)
37
37
 
38
38
  # save attachment
39
- File.open(filepath, "w+b", 0644) { |f| f.write attachment.body.decoded }
39
+ File.open(filepath, 'w+b', 0644) { |f| f.write attachment.body.decoded }
40
40
 
41
41
  # retain metadata
42
42
  attachments[attachment.cid] = {
@@ -67,7 +67,6 @@ module Mail2FrontMatter
67
67
  subject: message.subject,
68
68
  attachments: attachments
69
69
  }
70
-
71
70
  end
72
71
  end
73
72
  end
@@ -1,11 +1,10 @@
1
-
2
1
  # Pre-processes blog data, allows hooks
3
2
 
4
3
  module Mail2FrontMatter
5
4
  class PreProcessor
6
5
  require 'set'
7
6
 
8
- class InvalidProcessor < StandardError ; end
7
+ class InvalidProcessor < StandardError; end
9
8
 
10
9
  @@processors = Set.new
11
10
 
@@ -14,8 +13,8 @@ module Mail2FrontMatter
14
13
  end
15
14
 
16
15
  def self.register(options = {})
17
- raise InvalidProcessor, "run method not defined on #{self}" if !self.respond_to?(:run)
18
- raise ArgumentError, "options must be a hash" unless options.is_a? Hash
16
+ fail InvalidProcessor, "run method not defined on #{self}" unless self.respond_to?(:run)
17
+ fail ArgumentError, 'options must be a hash' unless options.is_a? Hash
19
18
  @options = options
20
19
 
21
20
  @@processors << self
@@ -26,13 +25,12 @@ module Mail2FrontMatter
26
25
  begin
27
26
  metadata, body = processor.run(metadata, body)
28
27
  rescue StandardError => e
29
- Mail2FrontMatter.logger.error("processor failed!")
28
+ Mail2FrontMatter.logger.error('processor failed!')
30
29
  Mail2FrontMatter.logger.error(e)
31
30
  end
32
31
  end
33
32
 
34
- return metadata, body
33
+ [metadata, body]
35
34
  end
36
-
37
35
  end
38
36
  end
@@ -1,3 +1,3 @@
1
1
  module Mail2FrontMatter
2
- VERSION = "0.1.0"
2
+ VERSION = '0.1.2'
3
3
  end
@@ -4,24 +4,22 @@ module Mail2FrontMatter
4
4
  require 'mailman'
5
5
 
6
6
  class Watcher
7
-
8
7
  def self.run
9
8
  mail_protocol = Mail2FrontMatter.config[:protocol] || :imap
10
9
  poll_interval = Mail2FrontMatter.config[:interval] || 60
11
10
 
12
- @receiver = Mail2FrontMatter.config[:receiver]
13
- @senders = Mail2FrontMatter.config[:senders]
14
-
15
11
  Mailman.config.poll_interval = poll_interval
16
12
  Mailman.config.ignore_stdin = true
17
13
 
18
14
  Mailman.config.send("#{mail_protocol}=", Mail2FrontMatter.config[:mailman])
19
15
  Mailman.config.logger = Mail2FrontMatter.logger
20
16
 
17
+ Mail2FrontMatter.logger.info("Mail2FrontMatter v#{Mail2FrontMatter::VERSION} is starting...")
18
+
21
19
  Mailman::Application.run do
22
- from(@senders).to(@receiver) do
23
- logger = Mailman.config.logger
20
+ logger = Mail2FrontMatter.logger
24
21
 
22
+ from(Mail2FrontMatter.config[:senders]).to(Mail2FrontMatter.config[:receiver]) do
25
23
  logger.info('parsing message...')
26
24
  parser = Mail2FrontMatter::Parser.new(message)
27
25
 
@@ -30,9 +28,17 @@ module Mail2FrontMatter
30
28
 
31
29
  logger.info('saving processed post...')
32
30
  Mail2FrontMatter::Writer.write(metadata, body)
31
+
32
+ logger.info('commiting written post and attachments...')
33
+ Mail2FrontMatter::Committer.commit(metadata, body)
34
+
35
+ logger.info('done...')
36
+ end
37
+
38
+ default do
39
+ logger.error("received and discarded email from unknown address!")
33
40
  end
34
41
  end
35
42
  end
36
-
37
43
  end
38
44
  end
@@ -1,20 +1,19 @@
1
1
 
2
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?
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
7
  # --- probably just let anyone specify the extension.. keep it simple
8
- #
8
+ #
9
9
  module Mail2FrontMatter
10
10
  class Writer
11
-
12
11
  require 'yaml'
13
12
  require 'active_support/inflector'
14
13
 
15
14
  def self.write(metadata, body)
16
15
  # MAPPINGS!
17
- #
16
+ #
18
17
  # Play nice with programs which will read this data
19
18
  # And set sensible defaults as fall throughs
20
19
 
@@ -22,12 +21,12 @@ module Mail2FrontMatter
22
21
  metadata[:title] ||= metadata[:subject]
23
22
 
24
23
  # make a sensible standard blog filename unless one is given
25
- metadata[:filename] ||= [metadata[:received].strftime("%Y-%m-%d"), '-', metadata[:subject].parameterize, '.html.erb'].join
24
+ metadata[:filename] ||= [metadata[:received].strftime('%Y-%m-%d'), '-', metadata[:subject].parameterize, '.html.erb'].join
25
+ metadata[:filepath] ||= File.join(Mail2FrontMatter.config[:data_directory], metadata[:filename])
26
26
 
27
27
  data = metadata.to_yaml + "---\n" + body
28
28
 
29
- File.write(File.join(Mail2FrontMatter.config[:data_directory], metadata[:filename]), data)
29
+ File.write(metadata[:filepath], data)
30
30
  end
31
-
32
31
  end
33
32
  end
@@ -4,26 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'mail2frontmatter/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "mail2frontmatter"
7
+ spec.name = 'mail2frontmatter'
8
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"
9
+ spec.authors = ['Kunal Shah']
10
+ spec.email = ['me@kunalashah.com']
11
+ spec.summary = 'email-in for static blogs like Middleman'
12
+ spec.description = spec.summary + '. Uses Mailman to poll an account. '
13
+ spec.homepage = 'https://github.com/whistlerbrk/Mail2FrontMatter'
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "mailman", "~> 0.7"
22
- spec.add_dependency "nokogiri", "~> 1.6"
23
- spec.add_dependency "activesupport", "~> 4"
21
+ spec.add_dependency 'mailman', '~> 0.7.3'
22
+ spec.add_dependency 'nokogiri', '~> 1.6'
23
+ spec.add_dependency 'activesupport', '~> 4'
24
+ spec.add_dependency 'rugged', '~> 0.21'
24
25
 
25
- spec.add_development_dependency "rspec", "~> 3.1"
26
- spec.add_development_dependency "byebug", "~> 3.5" unless RUBY_VERSION =~ /1.9/
27
- spec.add_development_dependency "bundler", "~> 1.7"
28
- spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency 'rspec', '~> 3.1'
27
+ spec.add_development_dependency 'byebug', '~> 3.5'
28
+ spec.add_development_dependency 'bundler', '~> 1.7'
29
+ spec.add_development_dependency 'rake', '~> 10.0'
29
30
  end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mail2FrontMatter::Committer, 'committing' do
4
+ require 'rugged'
5
+
6
+ let(:config) { File.join(M2FM_GEM_PATH, 'fixtures', 'mail2frontmatter.simple.yml') }
7
+ let(:message_one) { Mail::Message.new(File.read(File.join(M2FM_GEM_PATH, 'fixtures', 'attachments.eml'))) }
8
+
9
+ it 'should commit new posts' do
10
+ Mail2FrontMatter.set_config(config) do |config|
11
+ config[:data_directory] = File.join(M2FM_GEM_PATH, 'spec', 'installation', 'data')
12
+ config[:media_directory] = File.join(M2FM_GEM_PATH, 'spec', 'installation', 'media')
13
+ config[:git] = { path: File.join(M2FM_GEM_PATH, 'spec', 'installation') }
14
+ end
15
+
16
+ repo = Rugged::Repository.new(Mail2FrontMatter.config[:git][:path])
17
+ opening_sha = repo.references['refs/heads/master'].target_id
18
+
19
+ parser = Mail2FrontMatter::Parser.new(message_one)
20
+ Mail2FrontMatter::Writer.write(parser.metadata, parser.body)
21
+ Mail2FrontMatter::Committer.commit(parser.metadata, parser.body)
22
+
23
+ closing_sha = repo.references['refs/heads/master'].target_id
24
+
25
+ expect(opening_sha == closing_sha).to be(false)
26
+ end
27
+ end
@@ -1,42 +1,40 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Mail2FrontMatter, "configuration" do
4
-
3
+ describe Mail2FrontMatter, 'configuration' do
5
4
  let(:simple_config) { File.join(M2FM_GEM_PATH, 'fixtures', 'mail2frontmatter.simple.yml') }
6
5
  let(:complex_config) { File.join(M2FM_GEM_PATH, 'fixtures', 'mail2frontmatter.complex.yml') }
7
6
  let(:malformed_config) { File.join(M2FM_GEM_PATH, 'fixtures', 'mail2frontmatter.malformed.yml') }
8
7
 
9
- it "should load a configuration by passing a YAML file location" do
10
- expect {
8
+ it 'should load a configuration by passing a YAML file location' do
9
+ expect do
11
10
  Mail2FrontMatter.set_config(simple_config)
12
- }.to_not raise_error
11
+ end.to_not raise_error
13
12
  end
14
13
 
15
- it "should load a configuration by passing a hash" do
16
- expect {
17
- Mail2FrontMatter.set_config({foo: 'bar'})
18
- }.to_not raise_error
14
+ it 'should load a configuration by passing a hash' do
15
+ expect do
16
+ Mail2FrontMatter.set_config(foo: 'bar')
17
+ end.to_not raise_error
19
18
  end
20
19
 
21
- it "should raise an error for other types" do
22
- expect {
20
+ it 'should raise an error for other types' do
21
+ expect do
23
22
  Mail2FrontMatter.set_config([])
24
- }.to raise_error
23
+ end.to raise_error
25
24
  end
26
25
 
27
- it "should fail loading malformed configs" do
28
- expect {
26
+ it 'should fail loading malformed configs' do
27
+ expect do
29
28
  Mail2FrontMatter.set_config(malformed_config)
30
- }.to raise_error
29
+ end.to raise_error
31
30
  end
32
31
 
33
- it "should attempt to load the default configuration if nothing is passed" do
32
+ it 'should attempt to load the default configuration if nothing is passed' do
34
33
  # this should attempt and fail because there is no ./data/mail2frontmatter.yml
35
- expect {
34
+ expect do
36
35
  Mail2FrontMatter.set_config do |config|
37
36
  config[:foo] = 'bar'
38
37
  end
39
- }.to raise_error(LoadError)
38
+ end.to raise_error(LoadError)
40
39
  end
41
-
42
- end
40
+ end
File without changes
File without changes
@@ -1,43 +1,41 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Mail2FrontMatter::Parser, "parsing" do
4
-
3
+ describe Mail2FrontMatter::Parser, 'parsing' do
5
4
  let(:message_one) { Mail::Message.new(File.read(File.join(M2FM_GEM_PATH, 'fixtures', 'attachments.eml'))) }
6
5
 
7
- it "should parse HTML email" do
8
- expect {
6
+ it 'should parse HTML email' do
7
+ expect do
9
8
  Mail2FrontMatter::Parser.new(message_one)
10
- }.to_not raise_error
9
+ end.to_not raise_error
11
10
  end
12
11
 
13
- it "should return an html body as a string" do
12
+ it 'should return an html body as a string' do
14
13
  body = Mail2FrontMatter::Parser.new(message_one).body
15
14
  expect(body).to match(/Charlie<br>/)
16
15
  end
17
16
 
18
- it "should return have an email metadata hash with a from key" do
17
+ it 'should return have an email metadata hash with a from key' do
19
18
  from = Mail2FrontMatter::Parser.new(message_one).metadata[:from]
20
- expect(from).to eq("Kunal Shah <kunalashokshah@gmail.com>")
19
+ expect(from).to eq('Kunal Shah <kunalashokshah@gmail.com>')
21
20
  end
22
21
 
23
- it "should return have an email metadata hash with a to key" do
22
+ it 'should return have an email metadata hash with a to key' do
24
23
  to = Mail2FrontMatter::Parser.new(message_one).metadata[:to]
25
- expect(to).to eq("stream@kunalashah.com")
24
+ expect(to).to eq('stream@kunalashah.com')
26
25
  end
27
26
 
28
- it "should return have an email metadata hash with a received key" do
27
+ it 'should return have an email metadata hash with a received key' do
29
28
  received = Mail2FrontMatter::Parser.new(message_one).metadata[:received]
30
29
  expect(received.class).to eq(DateTime)
31
30
  end
32
31
 
33
- it "should return have an email metadata hash with a subject key" do
32
+ it 'should return have an email metadata hash with a subject key' do
34
33
  subject = Mail2FrontMatter::Parser.new(message_one).metadata[:subject]
35
- expect(subject).to eq("295 Abandoned Elevator Shaft")
34
+ expect(subject).to eq('295 Abandoned Elevator Shaft')
36
35
  end
37
36
 
38
- it "should save attachments to disk" do
37
+ it 'should save attachments to disk' do
39
38
  attachment_path = Mail2FrontMatter::Parser.new(message_one).metadata[:attachments].first[1][:filepath]
40
39
  expect(File.exist?(attachment_path)).to eq(true)
41
40
  end
42
-
43
- end
41
+ end
@@ -7,56 +7,55 @@ describe Mail2FrontMatter::PreProcessor do
7
7
 
8
8
  let(:message_one) { Mail::Message.new(File.read(File.join(M2FM_GEM_PATH, 'fixtures', 'attachments.eml'))) }
9
9
 
10
- let(:invalidly_defined_preprocessor) {
10
+ let(:invalidly_defined_preprocessor) do
11
11
  class MyInvalidProcessor < Mail2FrontMatter::PreProcessor
12
12
  # note, instanced not class
13
13
  def run(metadata, body)
14
14
  # some modification
15
- return metadata, body
15
+ [metadata, body]
16
16
  end
17
17
  end
18
18
 
19
19
  return MyInvalidProcessor
20
- }
20
+ end
21
21
 
22
- let(:validly_defined_preprocessor) {
22
+ let(:validly_defined_preprocessor) do
23
23
  class MyValidProcessor < Mail2FrontMatter::PreProcessor
24
24
  def self.run(metadata, body)
25
25
  # some modification
26
- return metadata, body
26
+ [metadata, body]
27
27
  end
28
28
  end
29
29
 
30
30
  return MyValidProcessor
31
- }
32
-
33
- context "registration" do
31
+ end
34
32
 
35
- it "should raise errors for invalid processors" do
36
- expect {
33
+ context 'registration' do
34
+ it 'should raise errors for invalid processors' do
35
+ expect do
37
36
  invalidly_defined_preprocessor.register({})
38
- }.to raise_error
37
+ end.to raise_error
39
38
  end
40
39
 
41
- it "should not raise errors for valid processors" do
42
- expect {
40
+ it 'should not raise errors for valid processors' do
41
+ expect do
43
42
  validly_defined_preprocessor.register({})
44
- }.to_not raise_error
43
+ end.to_not raise_error
45
44
  end
46
45
 
47
- it "should raise an error when registered without a hash" do
48
- expect {
46
+ it 'should raise an error when registered without a hash' do
47
+ expect do
49
48
  validly_defined_preprocessor.register(nil)
50
- }.to raise_error(ArgumentError)
49
+ end.to raise_error(ArgumentError)
51
50
  end
52
51
 
53
- it "should not raise an error when registered with a hash" do
54
- expect {
55
- validly_defined_preprocessor.register({ foo: 'bar' })
56
- }.to_not raise_error
52
+ it 'should not raise an error when registered with a hash' do
53
+ expect do
54
+ validly_defined_preprocessor.register(foo: 'bar')
55
+ end.to_not raise_error
57
56
  end
58
57
 
59
- it "should load preprocessors" do
58
+ it 'should load preprocessors' do
60
59
  Mail2FrontMatter.set_config(complex_config)
61
60
  processors = Mail2FrontMatter::PreProcessor.processors
62
61
 
@@ -64,23 +63,23 @@ describe Mail2FrontMatter::PreProcessor do
64
63
  expect(processors).to include(Mail2FrontMatter::FakeProcessorWithOptions)
65
64
  end
66
65
 
67
- it "should provide preprocessors with passed options" do
66
+ it 'should provide preprocessors with passed options' do
68
67
  Mail2FrontMatter.set_config(complex_config)
69
68
  options = Mail2FrontMatter::FakeProcessorWithOptions.instance_variable_get(:@options)
70
69
 
71
70
  expect(options.class).to eq(Hash)
72
- expect(options[:foo]).to eq("bar")
71
+ expect(options[:foo]).to eq('bar')
73
72
  end
74
73
  end
75
74
 
76
- context "operation" do
77
- it "should continue processing if an individual processor fails" do
75
+ context 'operation' do
76
+ it 'should continue processing if an individual processor fails' do
78
77
  Mail2FrontMatter.set_config(broken_config)
79
78
  parser = Mail2FrontMatter::Parser.new(message_one)
80
79
 
81
- expect {
82
- metadata, body = Mail2FrontMatter::PreProcessor.process(parser.metadata, parser.body)
83
- }.to_not raise_error
80
+ expect do
81
+ Mail2FrontMatter::PreProcessor.process(parser.metadata, parser.body)
82
+ end.to_not raise_error
84
83
  end
85
84
  end
86
85
  end
File without changes
@@ -1,6 +1,67 @@
1
1
 
2
2
  M2FM_GEM_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
- $: << File.join(M2FM_GEM_PATH, 'fixtures')
3
+ $LOAD_PATH << File.join(M2FM_GEM_PATH, 'fixtures')
4
4
 
5
5
  require 'yaml'
6
+ require 'fileutils'
6
7
  require File.join(M2FM_GEM_PATH, 'lib', 'mail2frontmatter')
8
+
9
+ module RSpec
10
+ # remove any data hanging around from spec runs...
11
+ def self.clean_testbed
12
+ FileUtils.rm_rf(Dir[File.join(M2FM_GEM_PATH, 'spec', 'remote', '*')])
13
+ FileUtils.rm_rf(Dir[File.join(M2FM_GEM_PATH, 'spec', 'installation', 'data', '*')])
14
+ FileUtils.rm_rf(Dir[File.join(M2FM_GEM_PATH, 'spec', 'installation', 'media', '*')])
15
+ FileUtils.rm_rf(Dir[File.join(M2FM_GEM_PATH, 'spec', 'installation', '.git')])
16
+ end
17
+ end
18
+
19
+ RSpec.configure do |config|
20
+ config.before(:suite) do
21
+ RSpec.clean_testbed
22
+
23
+ # setup a repo in spec/installation
24
+ repo = Rugged::Repository.init_at(File.join(M2FM_GEM_PATH, 'spec', 'installation', '.git'))
25
+
26
+ # setup another repo in spec/remote
27
+ Rugged::Repository.init_at(File.join(M2FM_GEM_PATH, 'spec', 'remote'), :bare)
28
+
29
+ # add the second repo as the origin of the first
30
+ repo.remotes.create('origin', File.join(M2FM_GEM_PATH, 'spec', 'remote'))
31
+
32
+ index = repo.index
33
+
34
+ # stage the blank folders
35
+ index.add(path: 'data/.gitkeep',
36
+ oid: (Rugged::Blob.from_workdir repo, 'data/.gitkeep'),
37
+ mode: 0100644)
38
+
39
+ index.add(path: 'media/.gitkeep',
40
+ oid: (Rugged::Blob.from_workdir repo, 'media/.gitkeep'),
41
+ mode: 0100644)
42
+
43
+ # commit them
44
+ tree = index.write_tree(repo)
45
+ index.write
46
+
47
+ author = {
48
+ email: 'sender@example.com',
49
+ name: 'The Sender',
50
+ time: Time.now
51
+ }
52
+
53
+ Rugged::Commit.create(repo, author: author,
54
+ committer: author,
55
+ message: 'checking in data/media empties',
56
+ parents: [],
57
+ tree: tree,
58
+ update_ref: 'HEAD')
59
+
60
+ # push
61
+ repo.push 'origin', ['refs/heads/master']
62
+ end
63
+
64
+ config.after(:suite) do
65
+ RSpec.clean_testbed
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mail2FrontMatter::Writer, 'writing' do
4
+ let(:config) { File.join(M2FM_GEM_PATH, 'fixtures', 'mail2frontmatter.simple.yml') }
5
+ let(:message_one) { Mail::Message.new(File.read(File.join(M2FM_GEM_PATH, 'fixtures', 'attachments.eml'))) }
6
+
7
+ it 'should write a parse and processed email' do
8
+ Mail2FrontMatter.set_config(config) do |config|
9
+ config[:data_directory] = File.join(M2FM_GEM_PATH, 'spec', 'installation', 'data')
10
+ config[:media_directory] = File.join(M2FM_GEM_PATH, 'spec', 'installation', 'media')
11
+ end
12
+
13
+ parser = Mail2FrontMatter::Parser.new(message_one)
14
+ metadata, body = Mail2FrontMatter::PreProcessor.process(parser.metadata, parser.body)
15
+
16
+ Mail2FrontMatter::Writer.write(metadata, body)
17
+
18
+ expect(File.exist?(File.join(Mail2FrontMatter.config[:data_directory], '2009-11-25-295-abandoned-elevator-shaft.html.erb'))).to be(true)
19
+ expect(File.exist?(File.join(Mail2FrontMatter.config[:media_directory], 'images', 'IMG_0141.JPG'))).to be(true)
20
+ end
21
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail2frontmatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kunal Shah
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-01 00:00:00.000000000 Z
11
+ date: 2016-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mailman
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.7'
19
+ version: 0.7.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0.7'
26
+ version: 0.7.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rugged
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.21'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.21'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -108,8 +122,7 @@ dependencies:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
124
  version: '10.0'
111
- description: 'Email-to-blog parser which creates YAML FrontMatter. Uses Mailman to
112
- poll an account. '
125
+ description: 'email-in for static blogs like Middleman. Uses Mailman to poll an account. '
113
126
  email:
114
127
  - me@kunalashah.com
115
128
  executables:
@@ -135,6 +148,7 @@ files:
135
148
  - fixtures/mail2frontmatter/fake-processor.rb
136
149
  - fixtures/no_attachments.eml
137
150
  - lib/mail2frontmatter.rb
151
+ - lib/mail2frontmatter/committer.rb
138
152
  - lib/mail2frontmatter/configuration.rb
139
153
  - lib/mail2frontmatter/parser.rb
140
154
  - lib/mail2frontmatter/preprocessor.rb
@@ -142,10 +156,15 @@ files:
142
156
  - lib/mail2frontmatter/watcher.rb
143
157
  - lib/mail2frontmatter/writer.rb
144
158
  - mail2frontmatter.gemspec
159
+ - spec/committer_spec.rb
145
160
  - spec/configuration_spec.rb
161
+ - spec/installation/data/.gitkeep
162
+ - spec/installation/media/.gitkeep
146
163
  - spec/parser_spec.rb
147
164
  - spec/preprocessor_spec.rb
165
+ - spec/remote/.gitkeep
148
166
  - spec/spec_helper.rb
167
+ - spec/writer_spec.rb
149
168
  homepage: https://github.com/whistlerbrk/Mail2FrontMatter
150
169
  licenses:
151
170
  - MIT
@@ -166,12 +185,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
185
  version: '0'
167
186
  requirements: []
168
187
  rubyforge_project:
169
- rubygems_version: 2.4.5
188
+ rubygems_version: 2.5.1
170
189
  signing_key:
171
190
  specification_version: 4
172
- summary: Email-to-blog parser which creates YAML FrontMatter
191
+ summary: email-in for static blogs like Middleman
173
192
  test_files:
193
+ - spec/committer_spec.rb
174
194
  - spec/configuration_spec.rb
195
+ - spec/installation/data/.gitkeep
196
+ - spec/installation/media/.gitkeep
175
197
  - spec/parser_spec.rb
176
198
  - spec/preprocessor_spec.rb
199
+ - spec/remote/.gitkeep
177
200
  - spec/spec_helper.rb
201
+ - spec/writer_spec.rb