blog-generator 0.0.2 → 0.0.3

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: 6f1d0ff16391680e7a1feb4dd62f7249ab4030e0
4
- data.tar.gz: 38bae8eb5d26ea606aeea6e0e82766da615b3159
3
+ metadata.gz: 5dd19e7d27a786670dabe4d2c0436fe0e2466baa
4
+ data.tar.gz: 39f1cc0815d6297914962be6d42ef8d031e6c2b7
5
5
  SHA512:
6
- metadata.gz: 754eafed7232e1c80bb8924e1e33dc3c7c9567231268adca87f501efc05d61b9008ee7fc8eca29d45a583c251c63f1dfbf0cf4fe2dec54ec52380b8586897c49
7
- data.tar.gz: 82700d910962e9d63d877d70531788f7d0af2eda225dd043de1dd081e64a0040bae7c778d8ee41a0ead96983769c8ef0ab99c9be9fb61a715e2a3905ecc31128
6
+ metadata.gz: 181288255dcdefc50b05b3fbbfae4887775ebfa6d49d0e93e65ea685335e4841797b9b96375782bc51252102b5ac29016c1fdf321d4f324b7a7850f608cb0191
7
+ data.tar.gz: a814a8fccc079f48b2421439431310d0045a8f0db2cd0f832453502d841fc77a293684f9ae453010a5cc1bfe390cfd688d2b238464beeaaf27b3265f8306774f
data/README.md CHANGED
@@ -42,14 +42,25 @@ tags: ['Hello world', 'Test']
42
42
  # Routes generated
43
43
 
44
44
  - `slug` and `published_on` added to metadata.
45
+ - `/metadata.json`
45
46
  - `/posts.json`
46
47
  - `/posts/:slug.json`
47
48
  - `/tags.json`
48
49
  - `/tags/:slug.json`
49
50
 
51
+ # Feeds
52
+
53
+ ```html
54
+ <!-- Global feed. -->
55
+ <link href="{{blog.feed_url}}" type="application/atom+xml" rel="alternate" title="{{blog.title}}" />
56
+
57
+ <!-- Per-tag feeds. -->
58
+ <link href="{{tag.feed_url}}" type="application/atom+xml" rel="alternate" title="{{tag.title}}" />
59
+ ```
60
+
50
61
  # Status
51
62
 
52
- It works, but it needs polishing. Integration specs are OK, unit tests are broken.
63
+ It works, but it needs polishing.
53
64
 
54
65
  # TODO
55
66
 
@@ -4,6 +4,7 @@
4
4
  #
5
5
  # blog-generator.rb [posts dir] [output base path]
6
6
 
7
+ require 'ostruct'
7
8
  require 'blog-generator'
8
9
 
9
10
  POSTS_DIR, OUTPUT_BASE_PATH = ARGV
@@ -16,23 +17,41 @@ unless File.directory?(POSTS_DIR)
16
17
  abort "Posts directory #{POSTS_DIR} doesn't exist."
17
18
  end
18
19
 
19
- # Parse the posts.
20
- generator = BlogGenerator::Generator.parse(POSTS_DIR)
21
-
22
20
  unless File.directory?(OUTPUT_BASE_PATH)
23
21
  puts "~ #{OUTPUT_BASE_PATH} doesn't exist, creating."
24
22
  Dir.mkdir(OUTPUT_BASE_PATH)
25
23
  end
26
24
 
25
+ path = File.expand_path(File.join(POSTS_DIR, '..', 'defaults.yml'))
26
+ unless File.exist?(path)
27
+ puts "~ Feed configuration file #{path} not found."
28
+ end
29
+
30
+ # Parse the posts.
31
+ site = OpenStruct.new(File.exist?(path) ? YAML.load_file(path) : Hash.new)
32
+ generator = BlogGenerator::Generator.parse(site, POSTS_DIR)
33
+
27
34
  # Generate.
28
35
 
29
36
  Dir.chdir(OUTPUT_BASE_PATH) do
37
+ # GET /metadata.json
38
+ File.open('metadata.json', 'w') do |file|
39
+ # TODO: Refactor this, it's evil.
40
+ file.puts(site.instance_variable_get(:@table).to_json)
41
+ end
42
+
30
43
  # GET /api/posts.json
31
44
  File.open('posts.json', 'w') do |file|
32
45
  # This calls PostList#to_json
33
46
  file.puts(JSON.pretty_generate(generator.posts))
34
47
  end
35
48
 
49
+ # GET /posts.atom
50
+ File.open('posts.atom', 'w') do |file|
51
+ feed = BlogGenerator::Feed.new(site, generator.posts, 'posts.atom')
52
+ file.puts(feed.render)
53
+ end
54
+
36
55
  # GET /api/posts/hello-world.json
37
56
  Dir.mkdir('posts') unless Dir.exist?('posts')
38
57
  generator.posts.each do |post|
@@ -50,11 +69,17 @@ Dir.chdir(OUTPUT_BASE_PATH) do
50
69
  file.puts(JSON.pretty_generate(tags))
51
70
  end
52
71
 
53
- # GET /api/tags/doxxu.json
54
72
  Dir.mkdir('tags') unless Dir.exist?('tags')
55
73
  generator.tags.each do |tag, posts|
74
+ # GET /api/tags/doxxu.json
56
75
  File.open("tags/#{tag[:slug]}.json", 'w') do |file|
57
76
  file.puts(JSON.pretty_generate(posts))
58
77
  end
78
+
79
+ # GET /api/tags/doxxu.atom
80
+ File.open("tags/#{tag[:slug]}.atom", 'w') do |file|
81
+ feed = BlogGenerator::Feed.new(site, posts, "#{tag[:slug]}.atom")
82
+ file.puts(feed.render)
83
+ end
59
84
  end
60
85
  end
@@ -3,30 +3,29 @@ require 'json'
3
3
  require 'blog-generator/post'
4
4
  require 'blog-generator/post_list'
5
5
 
6
+ require 'blog-generator/feed'
7
+
6
8
  module BlogGenerator
7
9
  class Generator
8
- def self.parse(posts_dir)
9
- posts = Dir.glob("#{posts_dir}/*.{html,md}").reduce(PostList.new) do |posts, path|
10
- post = Post.new(path)
10
+ def self.parse(site, posts_dir)
11
+ posts = Dir.glob("#{posts_dir}/*.{html,md}").reduce(PostList.new(site)) do |posts, path|
12
+ post = Post.new(site, path)
11
13
  puts "~ Parsing #{post.inspect}"
12
14
  posts.push(post)
13
15
  end
14
16
 
15
- self.new(posts)
17
+ self.new(site, posts)
16
18
  end
17
19
 
18
- attr_reader :posts
19
- def initialize(posts)
20
+ attr_reader :site, :posts
21
+ def initialize(site, posts)
20
22
  @posts = posts
21
23
  end
22
24
 
23
25
  def tags
24
26
  @posts.reduce(Hash.new) do |buffer, post|
25
- puts; puts
26
- p post
27
- puts; puts
28
27
  post.tags.each do |tag|
29
- buffer[tag] ||= PostList.new
28
+ buffer[tag] ||= PostList.new(site)
30
29
  buffer[tag] << post
31
30
  end
32
31
 
@@ -0,0 +1,69 @@
1
+ require 'erb'
2
+ require 'digest'
3
+ require 'forwardable'
4
+
5
+ module BlogGenerator
6
+ class Feed
7
+ extend Forwardable
8
+ def_delegators :@site, :base_url, :title, :subtitle, :author, :email
9
+
10
+ attr_reader :site, :posts
11
+ def initialize(site, posts, relative_url)
12
+ @site, @posts = site, posts
13
+ @relative_url = relative_url
14
+ end
15
+
16
+ def feed_url
17
+ [@site.base_url, @relative_url].join('/')
18
+ end
19
+
20
+ def id
21
+ digest = Digest::MD5.hexdigest(posts.each.map(&:title).join(","))
22
+ "urn:uuid:#{digest}"
23
+ end
24
+
25
+ def updated_at
26
+ self.posts.last.updated_at
27
+ end
28
+
29
+ def template
30
+ # @template ||= DATA.read # Why can't I use DATA?
31
+ @template ||= File.read(__FILE__).sub(/\A.*\n__END__\n/m, '')
32
+ end
33
+
34
+ def render
35
+ ERB.new(self.template).result(binding)
36
+ end
37
+ end
38
+ end
39
+
40
+ __END__
41
+ <?xml version="1.0" encoding="utf-8"?>
42
+
43
+ <feed xmlns="http://www.w3.org/2005/Atom">
44
+ <title><%= self.title %></title>
45
+ <subtitle><%= self.subtitle %></subtitle>
46
+ <link href="<%= self.feed_url %>" rel="self" />
47
+ <link href="<%= self.base_url %>" />
48
+ <id><%= self.id %></id>
49
+ <updated><%= self.updated_at.iso8601 %></updated>
50
+
51
+ <% posts.each do |post| %>
52
+ <entry>
53
+ <title><%= post.title %></title>
54
+ <link href="<%= post.absolute_url %>" />
55
+ <link rel="alternate" type="text/html" href="<%= post.absolute_url %>"/>
56
+ <id><%= post.id %></id>
57
+ <updated><%= post.updated_at.iso8601 %></updated>
58
+ <!-- TODO: strip HTML from excerpt -->
59
+ <summary><%= post.excerpt %></summary>
60
+ <!-- <content type="xhtml">
61
+ <%= post.body %>
62
+ </content> -->
63
+ <author>
64
+ <name><%= post.author %></name>
65
+ <email><%= post.email %></email>
66
+ </author>
67
+ </entry>
68
+ <% end %>
69
+ </feed>
@@ -7,9 +7,10 @@ module BlogGenerator
7
7
  class Post
8
8
  REGEXP = /^(\d{4}-\d{2}-\d{2})-(.+)\.(html|md)$/
9
9
 
10
- attr_reader :metadata
11
- def initialize(path)
12
- @path = path
10
+ attr_reader :site, :metadata
11
+ def initialize(site, path)
12
+ # TODO: metadata so we can construct url (base_url + relative) AND merge author
13
+ @site, @path = site, File.expand_path(path)
13
14
 
14
15
  @metadata = YAML.load_file(path).reduce(Hash.new) do |buffer, (key, value)|
15
16
  buffer.merge(key.to_sym => value)
@@ -32,10 +33,35 @@ module BlogGenerator
32
33
  @body = document.css('body').inner_html.strip
33
34
  end
34
35
 
36
+ def updated_at
37
+ File.mtime(@path).to_datetime
38
+ end
39
+
40
+ def author
41
+ self.metadata[:author] || site.author
42
+ end
43
+
44
+ def email
45
+ self.metadata[:email] || site.email
46
+ end
47
+
35
48
  def generate_slug(name)
36
49
  name.downcase.tr(' /', '-').delete('!?')
37
50
  end
38
51
 
52
+ def relative_url
53
+ "/posts/#{slug}"
54
+ end
55
+
56
+ def absolute_url
57
+ [site.base_url, self.relative_url].join('')
58
+ end
59
+
60
+ def id
61
+ digest = Digest::MD5.hexdigest(self.metadata[:slug])
62
+ "urn:uuid:#{digest}"
63
+ end
64
+
39
65
  # Maybe rename body -> raw_body and to_html -> body.
40
66
  def body
41
67
  @body ||= File.read(@path).match(/\n---\n(.+)$/m)[1].strip
@@ -5,12 +5,12 @@ module BlogGenerator
5
5
  class PostList
6
6
  extend Forwardable
7
7
 
8
- attr_reader :posts
9
- def initialize
10
- @posts = Array.new
8
+ attr_reader :site, :posts
9
+ def initialize(site)
10
+ @site, @posts = site, Array.new
11
11
  end
12
12
 
13
- def_delegators :@posts, :reduce, :each
13
+ def_delegators :@posts, :reduce, :each, :first, :last, :[]
14
14
 
15
15
  def as_json
16
16
  self.posts.map do |post|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blog-generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - James C Russell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-03 00:00:00.000000000 Z
11
+ date: 2015-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -34,6 +34,7 @@ files:
34
34
  - README.md
35
35
  - bin/blog-generator.rb
36
36
  - lib/blog-generator.rb
37
+ - lib/blog-generator/feed.rb
37
38
  - lib/blog-generator/post.rb
38
39
  - lib/blog-generator/post_list.rb
39
40
  homepage: http://github.com/botanicus/blog-generator