blog-generator 0.0.2 → 0.0.3

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: 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