pluto 0.0.1 → 0.1.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/Manifest.txt +10 -0
- data/README.markdown +3 -0
- data/Rakefile +1 -1
- data/bin/pluto +5 -0
- data/lib/pluto.rb +49 -2
- data/lib/pluto/fetcher.rb +124 -0
- data/lib/pluto/formatter.rb +72 -0
- data/lib/pluto/models.rb +19 -0
- data/lib/pluto/opts.rb +34 -0
- data/lib/pluto/runner.rb +121 -0
- data/lib/pluto/version.rb +4 -0
- data/templates/blank.html.erb +26 -0
- data/templates/blank.top.html.erb +10 -0
- data/templates/blank.txt +4 -0
- metadata +16 -5
data/Manifest.txt
CHANGED
@@ -2,4 +2,14 @@ History.markdown
|
|
2
2
|
Manifest.txt
|
3
3
|
README.markdown
|
4
4
|
Rakefile
|
5
|
+
bin/pluto
|
5
6
|
lib/pluto.rb
|
7
|
+
lib/pluto/fetcher.rb
|
8
|
+
lib/pluto/formatter.rb
|
9
|
+
lib/pluto/models.rb
|
10
|
+
lib/pluto/opts.rb
|
11
|
+
lib/pluto/runner.rb
|
12
|
+
lib/pluto/version.rb
|
13
|
+
templates/blank.html.erb
|
14
|
+
templates/blank.top.html.erb
|
15
|
+
templates/blank.txt
|
data/README.markdown
CHANGED
data/Rakefile
CHANGED
data/bin/pluto
ADDED
data/lib/pluto.rb
CHANGED
@@ -1,3 +1,50 @@
|
|
1
|
+
###
|
2
|
+
# NB: for local testing run like:
|
3
|
+
#
|
4
|
+
# 1.8.x: ruby -Ilib -rrubygems lib/pakman.rb
|
5
|
+
# 1.9.x: ruby -Ilib lib/pakman.rb
|
6
|
+
|
7
|
+
# core and stlibs
|
8
|
+
|
9
|
+
require 'yaml'
|
10
|
+
require 'pp'
|
11
|
+
require 'logger'
|
12
|
+
require 'optparse'
|
13
|
+
require 'fileutils'
|
14
|
+
|
15
|
+
require 'rss'
|
16
|
+
|
17
|
+
# rubygems
|
18
|
+
|
19
|
+
require 'active_record' ## todo: add sqlite3? etc.
|
20
|
+
|
21
|
+
require 'fetcher' # fetch (download) files
|
22
|
+
require 'pakman' # template pack manager
|
23
|
+
|
24
|
+
# our own code
|
25
|
+
|
26
|
+
require 'pluto/models'
|
27
|
+
require 'pluto/version'
|
28
|
+
require 'pluto/opts'
|
29
|
+
require 'pluto/runner'
|
30
|
+
require 'pluto/fetcher'
|
31
|
+
require 'pluto/formatter'
|
32
|
+
|
1
33
|
module Pluto
|
2
|
-
|
3
|
-
|
34
|
+
|
35
|
+
def self.banner
|
36
|
+
"pluto #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.root
|
40
|
+
"#{File.expand_path( File.dirname(File.dirname(__FILE__)) )}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.main
|
44
|
+
Runner.new.run(ARGV)
|
45
|
+
end
|
46
|
+
|
47
|
+
end # module Pluto
|
48
|
+
|
49
|
+
|
50
|
+
Pluto.main if __FILE__ == $0
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Pluto
|
2
|
+
|
3
|
+
|
4
|
+
class Fetcher
|
5
|
+
|
6
|
+
def initialize( logger, opts, config )
|
7
|
+
@logger = logger
|
8
|
+
@opts = opts
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :logger, :opts, :config
|
13
|
+
|
14
|
+
|
15
|
+
def run
|
16
|
+
worker = ::Fetcher::Worker.new( logger )
|
17
|
+
|
18
|
+
config[ 'feeds' ].each do |feed_key|
|
19
|
+
|
20
|
+
feed_hash = config[ feed_key ]
|
21
|
+
feed_url = feed_hash[ 'feed_url' ]
|
22
|
+
|
23
|
+
puts "Fetching feed >#{feed_key}< using >#{feed_url}<..."
|
24
|
+
|
25
|
+
feed_rec = Feed.find_by_key( feed_key )
|
26
|
+
if feed_rec.nil?
|
27
|
+
feed_rec = Feed.new
|
28
|
+
feed_rec.key = feed_key
|
29
|
+
end
|
30
|
+
feed_rec.feed_url = feed_url
|
31
|
+
feed_rec.url = feed_hash[ 'url' ]
|
32
|
+
feed_rec.title = feed_hash[ 'title' ] # todo: use title from feed?
|
33
|
+
feed_rec.save!
|
34
|
+
|
35
|
+
worker.copy( feed_url, "./#{feed_key}.xml" )
|
36
|
+
end
|
37
|
+
|
38
|
+
logger.debug "RSS::VERSION #{RSS::VERSION}"
|
39
|
+
|
40
|
+
config[ 'feeds' ].each do |feed_key|
|
41
|
+
|
42
|
+
feed_hash = config[ feed_key ]
|
43
|
+
feed_rec = Feed.find_by_key!( feed_key )
|
44
|
+
|
45
|
+
xml = File.read( "./#{feed_key}.xml" )
|
46
|
+
|
47
|
+
puts "Before parsing feed >#{feed_key}<..."
|
48
|
+
|
49
|
+
parser = RSS::Parser.new( xml )
|
50
|
+
parser.do_validate = false
|
51
|
+
parser.ignore_unknown_element = true
|
52
|
+
|
53
|
+
puts "Parsing feed >#{feed_key}<..."
|
54
|
+
feed = parser.parse
|
55
|
+
puts "After parsing feed >#{feed_key}<..."
|
56
|
+
|
57
|
+
puts "feed.class=#{feed.class.name}"
|
58
|
+
|
59
|
+
|
60
|
+
if feed.class == RSS::Atom::Feed
|
61
|
+
puts "== #{feed.title.content} =="
|
62
|
+
else # assume RSS::Rss
|
63
|
+
puts "== #{feed.channel.title} =="
|
64
|
+
end
|
65
|
+
|
66
|
+
feed.items.each do |item|
|
67
|
+
|
68
|
+
if feed.class == RSS::Atom::Feed
|
69
|
+
|
70
|
+
## todo: if content.content empty use summary for example
|
71
|
+
item_attribs = {
|
72
|
+
:title => item.title.content,
|
73
|
+
:url => item.link.href,
|
74
|
+
:published_at => item.updated.content,
|
75
|
+
# :content => item.content.content,
|
76
|
+
:feed_id => feed_rec.id
|
77
|
+
}
|
78
|
+
guid = item.id.content
|
79
|
+
|
80
|
+
puts "- #{item.title.content}"
|
81
|
+
puts " link >#{item.link.href}<"
|
82
|
+
puts " id (~guid) >#{item.id.content}<"
|
83
|
+
|
84
|
+
### todo: use/try published first? why? why not?
|
85
|
+
puts " updated (~pubDate) >#{item.updated.content}< : #{item.updated.content.class.name}"
|
86
|
+
puts
|
87
|
+
|
88
|
+
else # assume RSS::Rss
|
89
|
+
item_attribs = {
|
90
|
+
:title => item.title,
|
91
|
+
:url => item.link,
|
92
|
+
:published_at => item.pubDate,
|
93
|
+
:content => item.content_encoded,
|
94
|
+
:feed_id => feed_rec.id
|
95
|
+
}
|
96
|
+
guid = item.guid.content
|
97
|
+
|
98
|
+
puts "- #{item.title}"
|
99
|
+
puts " link (#{item.link})"
|
100
|
+
puts " guid (#{item.guid.content})"
|
101
|
+
puts " pubDate (#{item.pubDate}) : #{item.pubDate.class.name}"
|
102
|
+
puts
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
rec = Item.find_by_guid( guid )
|
107
|
+
if rec.nil?
|
108
|
+
rec = Item.new
|
109
|
+
rec.guid = guid
|
110
|
+
end
|
111
|
+
|
112
|
+
rec.update_attributes!( item_attribs )
|
113
|
+
|
114
|
+
# puts "*** dump item:"
|
115
|
+
# pp item
|
116
|
+
|
117
|
+
end # each item
|
118
|
+
end # each feed
|
119
|
+
|
120
|
+
end # method run
|
121
|
+
|
122
|
+
end # class Fetcher
|
123
|
+
|
124
|
+
end # module Pluto
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Pluto
|
2
|
+
|
3
|
+
class Formatter
|
4
|
+
|
5
|
+
def initialize( logger, opts, config )
|
6
|
+
@logger = logger
|
7
|
+
@opts = opts
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :logger, :opts
|
12
|
+
|
13
|
+
def run( arg )
|
14
|
+
manifest_name = opts.manifest
|
15
|
+
manifest_name = manifest_name.downcase.gsub('.txt', '' ) # remove .txt if present
|
16
|
+
|
17
|
+
logger.debug "manifest=#{manifest_name}"
|
18
|
+
|
19
|
+
# check for matching manifests
|
20
|
+
manifests = installed_template_manifests.select { |m| m[0] == manifest_name+'.txt' }
|
21
|
+
|
22
|
+
if manifests.empty?
|
23
|
+
puts "*** error: unknown template pack '#{manifest_name}'; use pluto -l to list installed template packs"
|
24
|
+
exit 2
|
25
|
+
end
|
26
|
+
|
27
|
+
manifestsrc = manifests[0][1]
|
28
|
+
pakpath = opts.output_path
|
29
|
+
|
30
|
+
|
31
|
+
name = arg
|
32
|
+
Pakman::Templater.new( logger ).merge_pak( manifestsrc, pakpath, binding, name )
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def installed_template_manifest_patterns
|
38
|
+
|
39
|
+
# 1) search . # that is, working/current dir
|
40
|
+
# 2) search <config_dir>
|
41
|
+
# 3) search <gem>/templates
|
42
|
+
|
43
|
+
builtin_patterns = [
|
44
|
+
"#{Pluto.root}/templates/*.txt"
|
45
|
+
]
|
46
|
+
config_patterns = [
|
47
|
+
"#{File.expand_path(opts.config_path)}/*.txt",
|
48
|
+
"#{File.expand_path(opts.config_path)}/*/*.txt"
|
49
|
+
]
|
50
|
+
current_patterns = [
|
51
|
+
"*.txt",
|
52
|
+
"*/*.txt"
|
53
|
+
]
|
54
|
+
|
55
|
+
patterns = []
|
56
|
+
patterns += current_patterns
|
57
|
+
patterns += config_patterns
|
58
|
+
patterns += builtin_patterns
|
59
|
+
end
|
60
|
+
|
61
|
+
def installed_template_manifests
|
62
|
+
excludes = [
|
63
|
+
"Manifest.txt",
|
64
|
+
"*/Manifest.txt"
|
65
|
+
]
|
66
|
+
|
67
|
+
Pakman::Finder.new( logger ).find_manifests( installed_template_manifest_patterns, excludes )
|
68
|
+
end
|
69
|
+
|
70
|
+
end # class Formatter
|
71
|
+
|
72
|
+
end # module Pluto
|
data/lib/pluto/models.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Pluto
|
2
|
+
|
3
|
+
class Feed < ActiveRecord::Base
|
4
|
+
self.table_name = 'feeds'
|
5
|
+
|
6
|
+
has_many :items
|
7
|
+
end
|
8
|
+
|
9
|
+
class Item < ActiveRecord::Base
|
10
|
+
self.table_name = 'items'
|
11
|
+
|
12
|
+
belongs_to :feed
|
13
|
+
|
14
|
+
def self.latest
|
15
|
+
self.order( 'published_at desc' ).all
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end # module Pluto
|
data/lib/pluto/opts.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pluto
|
2
|
+
|
3
|
+
class Opts
|
4
|
+
|
5
|
+
def manifest=(value)
|
6
|
+
@manifest = value
|
7
|
+
end
|
8
|
+
|
9
|
+
def manifest
|
10
|
+
@manifest || 'blank.txt'
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def config_path=(value)
|
15
|
+
@config_path = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def config_path
|
19
|
+
@config_path || '~/.pluto'
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def output_path=(value)
|
24
|
+
@output_path = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def output_path
|
28
|
+
@output_path || '.'
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end # class Opts
|
33
|
+
|
34
|
+
end # module Pluto
|
data/lib/pluto/runner.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
|
2
|
+
module Pluto
|
3
|
+
|
4
|
+
class Runner
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@logger = Logger.new(STDOUT)
|
8
|
+
@logger.level = Logger::INFO
|
9
|
+
|
10
|
+
@opts = Opts.new
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :logger, :opts
|
14
|
+
|
15
|
+
def run( args )
|
16
|
+
opt=OptionParser.new do |cmd|
|
17
|
+
|
18
|
+
cmd.banner = "Usage: pluto [options]"
|
19
|
+
|
20
|
+
cmd.on( '-t', '--template MANIFEST', 'Generate Templates' ) do |manifest|
|
21
|
+
opts.manifest = manifest
|
22
|
+
end
|
23
|
+
|
24
|
+
cmd.on( '-c', '--config PATH', "Configuration Path (default is #{opts.config_path})" ) do |path|
|
25
|
+
opts.config_path = path
|
26
|
+
end
|
27
|
+
|
28
|
+
cmd.on( '-o', '--output PATH', "Output Path (default is #{opts.output_path})" ) { |path| opts.output_path = path }
|
29
|
+
|
30
|
+
cmd.on( '-v', '--version', "Show version" ) do
|
31
|
+
puts Pluto.banner
|
32
|
+
exit
|
33
|
+
end
|
34
|
+
|
35
|
+
cmd.on( "--verbose", "Show debug trace" ) do
|
36
|
+
logger.datetime_format = "%H:%H:%S"
|
37
|
+
logger.level = Logger::DEBUG
|
38
|
+
end
|
39
|
+
|
40
|
+
cmd.on_tail( "-h", "--help", "Show this message" ) do
|
41
|
+
puts <<EOS
|
42
|
+
|
43
|
+
pluto - Lets you build web pages from published web feeds.
|
44
|
+
|
45
|
+
#{cmd.help}
|
46
|
+
|
47
|
+
Examples:
|
48
|
+
pluto ruby # to be done
|
49
|
+
|
50
|
+
Further information:
|
51
|
+
http://geraldb.github.com/pluto
|
52
|
+
|
53
|
+
EOS
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
opt.parse!( args )
|
59
|
+
|
60
|
+
puts Pluto.banner
|
61
|
+
|
62
|
+
args.each do |arg|
|
63
|
+
|
64
|
+
name = File.basename( arg, '.*' )
|
65
|
+
|
66
|
+
db_config = {
|
67
|
+
:adapter => 'sqlite3',
|
68
|
+
:database => "#{opts.output_path}/#{name}.sqlite"
|
69
|
+
}
|
70
|
+
|
71
|
+
setup_db( db_config )
|
72
|
+
|
73
|
+
config_path = arg.dup # add .yml file extension if missing (for convenience)
|
74
|
+
config_path << '.yml' unless config_path.ends_with?( '.yml' )
|
75
|
+
|
76
|
+
config = YAML.load_file( config_path )
|
77
|
+
|
78
|
+
puts "dump >#{config_path}<:"
|
79
|
+
pp config
|
80
|
+
|
81
|
+
Fetcher.new( logger, opts, config ).run
|
82
|
+
Formatter.new( logger, opts, config ).run( name )
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
puts 'Done.'
|
87
|
+
|
88
|
+
end # method run
|
89
|
+
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def setup_db( db_config )
|
94
|
+
|
95
|
+
ActiveRecord::Base.establish_connection( db_config )
|
96
|
+
|
97
|
+
unless Feed.table_exists?
|
98
|
+
ActiveRecord::Schema.define do
|
99
|
+
create_table :feeds do |t|
|
100
|
+
t.string :title, :null => false
|
101
|
+
t.string :url, :null => false
|
102
|
+
t.string :feed_url, :null => false
|
103
|
+
t.string :key, :null => false
|
104
|
+
t.timestamps
|
105
|
+
end
|
106
|
+
|
107
|
+
create_table :items do |t|
|
108
|
+
t.string :title # todo: add some :null => false ??
|
109
|
+
t.string :url
|
110
|
+
t.string :guid
|
111
|
+
t.text :content
|
112
|
+
t.datetime :published_at
|
113
|
+
t.references :feed, :null => false
|
114
|
+
t.timestamps
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end # method setup_db
|
119
|
+
|
120
|
+
end # class Runner
|
121
|
+
end # module Pakman
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
<h1>Pluto Planet Blank Template Sample</h1>
|
3
|
+
|
4
|
+
<p>Subscriptions:</p>
|
5
|
+
<ul>
|
6
|
+
<% Feed.all.each do |feed| %>
|
7
|
+
<li><%= feed.title %> (<%= feed.items.count %>)</li>
|
8
|
+
<% end %>
|
9
|
+
</ul>
|
10
|
+
|
11
|
+
|
12
|
+
<% Item.latest.each do |item| %>
|
13
|
+
|
14
|
+
<p>
|
15
|
+
<%= item.published_at %>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
<%= item.title %>
|
20
|
+
|
21
|
+
(<%= item.feed.title %>)
|
22
|
+
</p>
|
23
|
+
|
24
|
+
<hr>
|
25
|
+
|
26
|
+
<% end %>
|
data/templates/blank.txt
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Gerald Bauer
|
@@ -49,18 +49,29 @@ dependencies:
|
|
49
49
|
version_requirements: *id002
|
50
50
|
description: pluto - Another Planet Generator (Lets You Build Web Pages from Published Web Feeds)
|
51
51
|
email: webslideshow@googlegroups.com
|
52
|
-
executables:
|
53
|
-
|
52
|
+
executables:
|
53
|
+
- pluto
|
54
54
|
extensions: []
|
55
55
|
|
56
56
|
extra_rdoc_files:
|
57
57
|
- Manifest.txt
|
58
|
+
- templates/blank.txt
|
58
59
|
files:
|
59
60
|
- History.markdown
|
60
61
|
- Manifest.txt
|
61
62
|
- README.markdown
|
62
63
|
- Rakefile
|
64
|
+
- bin/pluto
|
63
65
|
- lib/pluto.rb
|
66
|
+
- lib/pluto/fetcher.rb
|
67
|
+
- lib/pluto/formatter.rb
|
68
|
+
- lib/pluto/models.rb
|
69
|
+
- lib/pluto/opts.rb
|
70
|
+
- lib/pluto/runner.rb
|
71
|
+
- lib/pluto/version.rb
|
72
|
+
- templates/blank.html.erb
|
73
|
+
- templates/blank.top.html.erb
|
74
|
+
- templates/blank.txt
|
64
75
|
homepage: http://geraldb.github.com/pluto
|
65
76
|
licenses: []
|
66
77
|
|