planet 0.3.12 → 0.4.0
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.
- data/bin/planet +15 -9
- data/lib/planet.rb +24 -19
- data/lib/planet/blog.rb +3 -9
- data/lib/planet/importer.rb +9 -0
- data/lib/planet/parsers.rb +40 -41
- data/lib/planet/post.rb +51 -53
- data/lib/planet/version.rb +2 -2
- metadata +4 -19
data/bin/planet
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
2
3
|
|
3
4
|
require 'gli'
|
4
5
|
require 'planet'
|
6
|
+
require 'fileutils'
|
5
7
|
|
6
|
-
include GLI
|
8
|
+
include GLI::App
|
7
9
|
|
8
10
|
TEMPLATES = {
|
9
11
|
author: '
|
@@ -48,16 +50,20 @@ desc 'Parses planet.yml file for blogs and generates their posts in Jekyll compl
|
|
48
50
|
command :generate do |c|
|
49
51
|
|
50
52
|
c.action do |global_options,options,args|
|
51
|
-
conf = YAML.load_file('planet.yml')
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
Planet::Importer.import('planet.yml') do |planet|
|
55
|
+
|
56
|
+
posts_dir = planet.config.fetch('posts_directory', 'source/_posts/')
|
57
|
+
FileUtils.mkdir_p(posts_dir)
|
58
|
+
puts "=> Writing #{ planet.posts.size } posts to the #{ posts_dir } directory."
|
57
59
|
|
58
|
-
|
60
|
+
planet.posts.each do |post|
|
61
|
+
file_name = posts_dir + post.file_name
|
62
|
+
File.open(file_name + '.markdown', "w+") { |f| f.write(post.to_s) }
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
59
66
|
|
60
|
-
@planet.write_posts
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
@@ -147,4 +153,4 @@ on_error do |exception|
|
|
147
153
|
true
|
148
154
|
end
|
149
155
|
|
150
|
-
exit
|
156
|
+
exit run(ARGV)
|
data/lib/planet.rb
CHANGED
@@ -1,23 +1,16 @@
|
|
1
|
+
require 'yaml'
|
1
2
|
require 'planet/version'
|
2
3
|
require 'planet/blog'
|
4
|
+
require 'planet/importer'
|
3
5
|
|
4
6
|
class Planet
|
5
7
|
|
6
8
|
attr_accessor :config, :blogs
|
7
9
|
|
8
|
-
def initialize(
|
9
|
-
|
10
|
-
self.
|
11
|
-
|
12
|
-
feed: blog['feed'],
|
13
|
-
url: blog['url'],
|
14
|
-
author: blog['author'],
|
15
|
-
image: blog['image'],
|
16
|
-
posts: [],
|
17
|
-
planet: self,
|
18
|
-
twitter: blog['twitter']
|
19
|
-
)
|
20
|
-
end
|
10
|
+
def initialize(config_file_path)
|
11
|
+
config_file = read_config_file(config_file_path)
|
12
|
+
self.config = config_file[:planet]
|
13
|
+
self.blogs = config_file[:blogs]
|
21
14
|
end
|
22
15
|
|
23
16
|
def posts
|
@@ -32,14 +25,26 @@ class Planet
|
|
32
25
|
end
|
33
26
|
|
34
27
|
def write_posts
|
35
|
-
|
36
|
-
|
37
|
-
puts "=> Writing #{ self.posts.size } posts to the #{ posts_dir } directory."
|
28
|
+
Importer.import(self)
|
29
|
+
end
|
38
30
|
|
39
|
-
|
40
|
-
file_name = posts_dir + post.file_name
|
31
|
+
private
|
41
32
|
|
42
|
-
|
33
|
+
def read_config_file(config_file_path)
|
34
|
+
config = YAML.load_file(config_file_path)
|
35
|
+
planet = config.fetch('planet', {})
|
36
|
+
blogs = config.fetch('blogs', []).map do |blog|
|
37
|
+
Blog.new(
|
38
|
+
feed: blog['feed'],
|
39
|
+
url: blog['url'],
|
40
|
+
author: blog['author'],
|
41
|
+
image: blog['image'],
|
42
|
+
posts: [],
|
43
|
+
planet: self,
|
44
|
+
twitter: blog['twitter']
|
45
|
+
)
|
43
46
|
end
|
47
|
+
|
48
|
+
{ planet: planet, blogs: blogs }
|
44
49
|
end
|
45
50
|
end
|
data/lib/planet/blog.rb
CHANGED
@@ -36,22 +36,16 @@ class Planet
|
|
36
36
|
end
|
37
37
|
|
38
38
|
feed.entries.each do |entry|
|
39
|
-
content = if
|
39
|
+
content = if entry.content
|
40
40
|
self.sanitize_images(entry.content.strip)
|
41
|
-
elsif
|
41
|
+
elsif entry.summary
|
42
42
|
self.sanitize_images(entry.summary.strip)
|
43
43
|
else
|
44
44
|
abort "=> No content found on entry"
|
45
45
|
end
|
46
46
|
|
47
|
-
title = if !entry.title.nil?
|
48
|
-
entry.title.sanitize
|
49
|
-
else
|
50
|
-
self.name
|
51
|
-
end
|
52
|
-
|
53
47
|
self.posts << @post = Post.new(
|
54
|
-
title: title,
|
48
|
+
title: entry.title.nil? ? self.name : entry.title,
|
55
49
|
content: content,
|
56
50
|
date: entry.published,
|
57
51
|
url: self.url + entry.url,
|
data/lib/planet/parsers.rb
CHANGED
@@ -1,59 +1,58 @@
|
|
1
1
|
require 'feedzirra'
|
2
2
|
require 'set'
|
3
3
|
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# files located on planet/parsers are automatically loaded.
|
10
|
-
class Parsers
|
11
|
-
@@parsers = Set.new
|
4
|
+
# Parsers class - manager for the feed parsers
|
5
|
+
#
|
6
|
+
# parser classes inherit from Planet::Parsers::BaseParser
|
7
|
+
# and are added automatically to the list of available parsers.
|
8
|
+
# files located on planet/parsers are automatically loaded.
|
12
9
|
|
13
|
-
|
14
|
-
|
15
|
-
end
|
10
|
+
class Planet::Parsers
|
11
|
+
@@parsers = Set.new
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# but before it is fully defined).
|
21
|
-
def initialize
|
22
|
-
@types, @domains = {}, {}
|
13
|
+
def self.add_parser(parser)
|
14
|
+
@@parsers << parser
|
15
|
+
end
|
23
16
|
|
24
|
-
|
25
|
-
|
17
|
+
# Parser instances keep indexes of the available parsers and
|
18
|
+
# check for duplicate definitions (need to use an instance
|
19
|
+
# because #inherited gets called as soon as the class is seen
|
20
|
+
# but before it is fully defined).
|
21
|
+
def initialize
|
22
|
+
@types, @domains = {}, {}
|
26
23
|
|
27
|
-
|
28
|
-
|
24
|
+
@@parsers.each do |parser|
|
25
|
+
new_type, new_domains = parser.type, parser.domains
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
@domains[new_domain] = parser
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
27
|
+
fail("duplicate type") if new_type and @types.has_key? new_type
|
28
|
+
fail("overlapping domains") unless (@domains.keys & new_domains).empty?
|
36
29
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
return @types.fetch(type)
|
41
|
-
rescue KeyError => e
|
42
|
-
raise(ArgumentError, "No parser for type '#{ type }'", caller)
|
30
|
+
@types[new_type] = parser if new_type
|
31
|
+
new_domains.each do |new_domain|
|
32
|
+
@domains[new_domain] = parser
|
43
33
|
end
|
44
34
|
end
|
35
|
+
end
|
45
36
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
37
|
+
# returns the appropiate parser based on the type
|
38
|
+
def get_parser(type)
|
39
|
+
begin
|
40
|
+
return @types.fetch(type)
|
41
|
+
rescue KeyError => e
|
42
|
+
raise(ArgumentError, "No parser for type '#{ type }'", caller)
|
43
|
+
end
|
44
|
+
end
|
50
45
|
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
# returns any parser that can handle this feeds' domain,
|
47
|
+
# defaults to Feedzirra if none available.
|
48
|
+
def get_parser_for(feed)
|
49
|
+
feed_domain = URI(feed).host
|
54
50
|
|
55
|
-
|
51
|
+
@domains.each do |domain, parser|
|
52
|
+
return parser if feed_domain.end_with? domain
|
56
53
|
end
|
54
|
+
|
55
|
+
return Feedzirra::Feed # default generic parser
|
57
56
|
end
|
58
57
|
end
|
59
58
|
|
data/lib/planet/post.rb
CHANGED
@@ -1,58 +1,56 @@
|
|
1
1
|
require 'mustache'
|
2
2
|
|
3
|
-
class Planet
|
4
|
-
class Post
|
5
|
-
|
6
|
-
attr_accessor :title, :content, :date, :url, :blog
|
7
|
-
|
8
|
-
def initialize(attributes = {})
|
9
|
-
self.title = attributes[:title]
|
10
|
-
self.content = attributes[:content]
|
11
|
-
self.date = attributes[:date]
|
12
|
-
self.url = attributes[:url]
|
13
|
-
self.blog = attributes[:blog]
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_s
|
17
|
-
"#{ header }#{ content }#{ footer }"
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_hash
|
21
|
-
{
|
22
|
-
post_content: self.content,
|
23
|
-
post_title: self.title,
|
24
|
-
post_date: self.date,
|
25
|
-
image_url: self.blog.image,
|
26
|
-
author: self.blog.author,
|
27
|
-
blog_url: self.blog.url,
|
28
|
-
blog_name: self.blog.name,
|
29
|
-
post_url: self.url,
|
30
|
-
twitter: self.blog.twitter,
|
31
|
-
twitter_url: "http://twitter.com/#{ self.blog.twitter }"
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
|
-
def header
|
36
|
-
## TODO: We need categories/tags
|
37
|
-
file = self.blog.planet.config.fetch('templates_directory', '_layouts/') + 'header.md'
|
38
|
-
file_contents = File.read(file)
|
39
|
-
|
40
|
-
Mustache.render(file_contents, self.to_hash)
|
41
|
-
end
|
42
|
-
|
43
|
-
def footer
|
44
|
-
file = self.blog.planet.config.fetch('templates_directory', '_layouts/') + 'author.html'
|
45
|
-
file_contents = File.read(file)
|
46
|
-
|
47
|
-
Mustache.render(file_contents, self.to_hash)
|
48
|
-
end
|
49
|
-
|
50
|
-
def file_name
|
51
|
-
name_date = date ? date.strftime('%Y-%m-%d') : nil
|
52
|
-
name_title = title.downcase.scan(/\w+/).join('-')
|
53
|
-
|
54
|
-
[name_date, name_title].join('-')
|
55
|
-
end
|
3
|
+
class Planet::Post
|
56
4
|
|
5
|
+
attr_accessor :title, :content, :date, :url, :blog
|
6
|
+
|
7
|
+
def initialize(attributes = {})
|
8
|
+
self.title = attributes[:title]
|
9
|
+
self.content = attributes[:content]
|
10
|
+
self.date = attributes[:date]
|
11
|
+
self.url = attributes[:url]
|
12
|
+
self.blog = attributes[:blog]
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"#{ header }#{ content }#{ footer }"
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_hash
|
20
|
+
{
|
21
|
+
post_content: self.content,
|
22
|
+
post_title: self.title,
|
23
|
+
post_date: self.date,
|
24
|
+
image_url: self.blog.image,
|
25
|
+
author: self.blog.author,
|
26
|
+
blog_url: self.blog.url,
|
27
|
+
blog_name: self.blog.name,
|
28
|
+
post_url: self.url,
|
29
|
+
twitter: self.blog.twitter,
|
30
|
+
twitter_url: "http://twitter.com/#{ self.blog.twitter }"
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def header
|
35
|
+
## TODO: We need categories/tags
|
36
|
+
file = self.blog.planet.config.fetch('templates_directory', '_layouts/') + 'header.md'
|
37
|
+
file_contents = File.read(file)
|
38
|
+
|
39
|
+
Mustache.render(file_contents, self.to_hash)
|
57
40
|
end
|
41
|
+
|
42
|
+
def footer
|
43
|
+
file = self.blog.planet.config.fetch('templates_directory', '_layouts/') + 'author.html'
|
44
|
+
file_contents = File.read(file)
|
45
|
+
|
46
|
+
Mustache.render(file_contents, self.to_hash)
|
47
|
+
end
|
48
|
+
|
49
|
+
def file_name
|
50
|
+
name_date = date ? date.strftime('%Y-%m-%d') : nil
|
51
|
+
name_title = title.downcase.scan(/\w+/).join('-')
|
52
|
+
|
53
|
+
[name_date, name_title].join('-')
|
54
|
+
end
|
55
|
+
|
58
56
|
end
|
data/lib/planet/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: planet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,24 +9,8 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
-
- !ruby/object:Gem::Dependency
|
15
|
-
name: rake
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :development
|
23
|
-
prerelease: false
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ! '>='
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0'
|
30
14
|
- !ruby/object:Gem::Dependency
|
31
15
|
name: gli
|
32
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,6 +68,7 @@ extra_rdoc_files: []
|
|
84
68
|
files:
|
85
69
|
- bin/planet
|
86
70
|
- lib/planet/blog.rb
|
71
|
+
- lib/planet/importer.rb
|
87
72
|
- lib/planet/parsers/base_parser.rb
|
88
73
|
- lib/planet/parsers.rb
|
89
74
|
- lib/planet/post.rb
|
@@ -110,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
95
|
version: '0'
|
111
96
|
requirements: []
|
112
97
|
rubyforge_project:
|
113
|
-
rubygems_version: 1.8.
|
98
|
+
rubygems_version: 1.8.24
|
114
99
|
signing_key:
|
115
100
|
specification_version: 3
|
116
101
|
summary: An awesome rss/atom feed aggregator designed to work with Octopress/Jekyll
|