mail2frontmatter 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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