pluto 0.8.1 → 0.8.2

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 CHANGED
@@ -15,5 +15,6 @@ lib/pluto/lister.rb
15
15
  lib/pluto/manifest_helpers.rb
16
16
  lib/pluto/models.rb
17
17
  lib/pluto/schema.rb
18
+ lib/pluto/template_helpers.rb
18
19
  lib/pluto/updater.rb
19
20
  lib/pluto/version.rb
data/README.md CHANGED
@@ -106,11 +106,6 @@ EXAMPLE
106
106
  ```
107
107
  title: Planet Ruby
108
108
 
109
- feeds:
110
- - rubyflow
111
- - edgerails
112
- - rubyonrails
113
- - railstutorial
114
109
 
115
110
  rubyflow:
116
111
  title: Ruby Flow
data/lib/pluto.rb CHANGED
@@ -11,6 +11,8 @@ require 'uri'
11
11
  require 'pp'
12
12
  require 'optparse'
13
13
  require 'fileutils'
14
+ require 'logger'
15
+ require 'date'
14
16
 
15
17
 
16
18
  # 3rd party ruby gems/libs
@@ -37,6 +39,7 @@ require 'pluto/installer'
37
39
  require 'pluto/updater'
38
40
  require 'pluto/fetcher'
39
41
  require 'pluto/lister'
42
+ require 'pluto/template_helpers'
40
43
  require 'pluto/formatter'
41
44
 
42
45
  require 'pluto/cli/opts' ## fix: make sure fetcher/updater etc. do not depend on cli/opts
@@ -72,6 +75,46 @@ module Pluto
72
75
  end # module Pluto
73
76
 
74
77
 
78
+ ######
79
+ # todo - move to utils or similar
80
+
81
+ class Array
82
+
83
+ ## todo: check if there's already a builtin method for this
84
+ #
85
+ # note:
86
+ # in rails ary.in_groups(3) results in
87
+ # top-to-bottom, left-to-right.
88
+ # and not left-to-right first and than top-to-bottom.
89
+ #
90
+ # rename to in_groups_vertical(3) ???
91
+
92
+ def in_columns( cols ) # alias for convenience for chunks - needed? why? why not?
93
+ chunks( cols )
94
+ end
95
+
96
+ def chunks( number_of_chunks )
97
+ ## NB: use chunks - columns might be in use by ActiveRecord!
98
+ ###
99
+ # e.g.
100
+ # [1,2,3,4,5,6,7,8,9,10].columns(3)
101
+ # becomes:
102
+ # [[1,4,7,10],
103
+ # [2,5,8],
104
+ # [3,6,9]]
105
+
106
+ ## check/todo: make a copy of the array first??
107
+ # for now reference to original items get added to columns
108
+ chunks = (1..number_of_chunks).collect { [] }
109
+ each_with_index do |item,index|
110
+ chunks[ index % number_of_chunks ] << item
111
+ end
112
+ chunks
113
+ end
114
+
115
+ end
116
+
117
+
75
118
  if __FILE__ == $0
76
119
  Pluto.main
77
120
  else
@@ -80,6 +80,114 @@ default_value opts.config_path
80
80
  flag [:c, :config]
81
81
 
82
82
 
83
+ ## note: same as build (but without step 1) fetch)
84
+ desc 'Merge planet template pack'
85
+ arg_name 'FILE', multiple: true ## todo/fix: check multiple will not print typeo???
86
+ command [:merge, :m] do |c|
87
+
88
+ c.desc 'Output Path'
89
+ c.arg_name 'PATH'
90
+ c.default_value opts.output_path
91
+ c.flag [:o,:output]
92
+
93
+ c.desc 'Template Manifest'
94
+ c.arg_name 'MANIFEST'
95
+ c.default_value opts.manifest
96
+ c.flag [:t, :template]
97
+
98
+
99
+ c.action do |g,o,args|
100
+ logger.debug 'hello from merge command'
101
+
102
+ if args.length == 0
103
+ if File.exists?( 'pluto.yml' ) # check if pluto.yml exists, if yes add/use it
104
+ args = ['pluto.yml'] # create a new args w/ one item
105
+ elsif File.exists?( 'planet.yml' ) # check if planet.yml exists, if yes add/use it
106
+ args = ['planet.yml'] # create a new args w/ one item
107
+ else
108
+ puts '*** note: no arg passed in; no pluto.yml or planet.yml found in working folder'
109
+ end
110
+ end
111
+
112
+ args.each do |arg|
113
+ name = File.basename( arg, '.*' )
114
+
115
+ #####
116
+ # todo: add into method for reuse for build/merge/fetch
117
+ # all use the same code
118
+
119
+ db_config = {
120
+ adapter: 'sqlite3',
121
+ database: "#{opts.output_path}/#{name}.db"
122
+ }
123
+
124
+ Pluto::Connecter.new.connect!( db_config )
125
+
126
+ config_path = arg.dup # add .yml file extension if missing (for convenience)
127
+ config_path << '.yml' unless config_path.ends_with?( '.yml' )
128
+
129
+ config = YAML.load_file( config_path )
130
+
131
+ puts "dump >#{config_path}<:"
132
+ pp config
133
+
134
+ Pluto::Formatter.new( opts, config ).run( name )
135
+ end
136
+
137
+ puts 'Done.'
138
+ end
139
+ end # command merge
140
+
141
+
142
+ ## note: same as build (but without step 2) merge)
143
+ desc 'Fetch planet feeds'
144
+ arg_name 'FILE', multiple: true ## todo/fix: check multiple will not print typeo???
145
+ command [:fetch, :f] do |c|
146
+
147
+ c.action do |g,o,args|
148
+ logger.debug 'hello from fetch command'
149
+
150
+ if args.length == 0
151
+ if File.exists?( 'pluto.yml' ) # check if pluto.yml exists, if yes add/use it
152
+ args = ['pluto.yml'] # create a new args w/ one item
153
+ elsif File.exists?( 'planet.yml' ) # check if planet.yml exists, if yes add/use it
154
+ args = ['planet.yml'] # create a new args w/ one item
155
+ else
156
+ puts '*** note: no arg passed in; no pluto.yml or planet.yml found in working folder'
157
+ end
158
+ end
159
+
160
+ args.each do |arg|
161
+ name = File.basename( arg, '.*' )
162
+
163
+ #####
164
+ # todo: add into method for reuse for build/merge/fetch
165
+ # all use the same code
166
+
167
+ db_config = {
168
+ adapter: 'sqlite3',
169
+ database: "#{opts.output_path}/#{name}.db"
170
+ }
171
+
172
+ Pluto::Connecter.new.connect!( db_config )
173
+
174
+ config_path = arg.dup # add .yml file extension if missing (for convenience)
175
+ config_path << '.yml' unless config_path.ends_with?( '.yml' )
176
+
177
+ config = YAML.load_file( config_path )
178
+
179
+ puts "dump >#{config_path}<:"
180
+ pp config
181
+
182
+ Pluto::Fetcher.new( opts, config ).run
183
+ end
184
+
185
+ puts 'Done.'
186
+ end
187
+ end # command fetch
188
+
189
+
190
+
83
191
  desc 'Build planet'
84
192
  arg_name 'FILE', multiple: true ## todo/fix: check multiple will not print typeo???
85
193
  command [:build, :b] do |c|
@@ -97,7 +205,17 @@ command [:build, :b] do |c|
97
205
 
98
206
  c.action do |g,o,args|
99
207
  logger.debug 'hello from build command'
100
-
208
+
209
+ if args.length == 0
210
+ if File.exists?( 'pluto.yml' ) # check if pluto.yml exists, if yes add/use it
211
+ args = ['pluto.yml'] # create a new args w/ one item
212
+ elsif File.exists?( 'planet.yml' ) # check if planet.yml exists, if yes add/use it
213
+ args = ['planet.yml'] # create a new args w/ one item
214
+ else
215
+ puts '*** note: no arg passed in; no pluto.yml or planet.yml found in working folder'
216
+ end
217
+ end
218
+
101
219
  args.each do |arg|
102
220
 
103
221
  name = File.basename( arg, '.*' )
data/lib/pluto/fetcher.rb CHANGED
@@ -14,7 +14,6 @@ class Fetcher
14
14
 
15
15
 
16
16
  def run
17
-
18
17
  updater = Updater.new
19
18
 
20
19
  # pass along debug/verbose setting/switch
@@ -22,7 +21,6 @@ class Fetcher
22
21
 
23
22
  updater.update_subscriptions( config )
24
23
  updater.update_feeds
25
-
26
24
  end # method run
27
25
 
28
26
 
@@ -6,6 +6,8 @@ class Formatter
6
6
 
7
7
  include Models
8
8
  include ManifestHelper
9
+
10
+ include TemplateHelper # e.g. lets us use time_ago_in_words, strip_tags, etc.
9
11
 
10
12
  def initialize( opts, config )
11
13
  @opts = opts
@@ -15,6 +17,8 @@ class Formatter
15
17
  attr_reader :opts
16
18
 
17
19
  def site
20
+ ### fix !!!!!!!!!!
21
+ ## fix/todo: change to db record for site
18
22
  @config
19
23
  end
20
24
 
data/lib/pluto/models.rb CHANGED
@@ -14,7 +14,8 @@ class Feed < ActiveRecord::Base
14
14
  # coalesce - supported by sqlite (yes), postgres (yes)
15
15
 
16
16
  # note: if not published_at,touched_at or built_at use hardcoded 1999-01-01 for now
17
- order( "coalesce(published_at,touched_at,built_at,'1999-01-01') desc" )
17
+ ## order( "coalesce(published_at,touched_at,built_at,'1999-01-01') desc" )
18
+ order( "coalesce(latest_published_at,'1999-01-01') desc" )
18
19
  end
19
20
 
20
21
 
data/lib/pluto/schema.rb CHANGED
@@ -31,6 +31,8 @@ class CreateDb < ActiveRecord::Migration
31
31
  t.datetime :touched_at # from feed updated(atom)
32
32
 
33
33
  # -- our own (meta) fields
34
+ t.datetime :latest_published_at # cache latest item published_at
35
+
34
36
  t.string :key, :null => false
35
37
  t.string :format # e.g. atom (1.0), rss 2.0, rss 0.7 etc.
36
38
  t.string :etag # last etag
@@ -0,0 +1,49 @@
1
+ module Pluto
2
+
3
+ ####
4
+ # fix: rename to DateHelper
5
+
6
+ module TemplateHelper
7
+
8
+ def strip_tags( hypertext )
9
+ ### tobe done
10
+ ## strip markup tags; return plain text
11
+ hypertext.gsub( /<[^>]+>/, '' )
12
+ end
13
+
14
+
15
+ def time_ago_in_words( from_time )
16
+ from_time = from_time.to_time
17
+ to_time = Time.now
18
+
19
+ ### todo: will not handle future dates??
20
+ ## what todo do??
21
+ ## use -1..-50000000000 ?? "future"
22
+
23
+ ## from_time, to_time = to_time, from_time if from_time > to_time
24
+
25
+ distance_in_minutes = ((to_time - from_time)/60.0).round
26
+
27
+ case distance_in_minutes
28
+ when 0..1 then "just now"
29
+ when 2...45 then "%d minutes ago" % distance_in_minutes
30
+ when 45...90 then "about 1 hour ago" ## use one instead of 1 ?? why? why not?
31
+ # 90 mins up to 24 hours
32
+ when 90...1440 then "about %d hours ago" % (distance_in_minutes.to_f / 60.0).round
33
+ # 24 hours up to 42 hours
34
+ when 1440...2520 then "1 day ago" ## use one day ago - why? why not?
35
+ # 42 hours up to 30 days
36
+ when 2520...43200 then "%d days ago" % (distance_in_minutes.to_f / 1440.0).round
37
+ # 30 days up to 60 days
38
+ # fix: use pluralize for months
39
+ when 43200...86400 then "about %d months ago" % (distance_in_minutes.to_f / 43200.0).round
40
+ # 60 days up to 365 days
41
+ when 86400...525600 then "%d months ago" % (distance_in_minutes.to_f / 43200.0).round
42
+ ## fix - add number of years ago
43
+ else "about a year ago" #todo: use over a year ago???
44
+ end
45
+ end
46
+
47
+
48
+ end # module TemplateHelper
49
+ end # module Pluto
data/lib/pluto/updater.rb CHANGED
@@ -111,6 +111,11 @@ class Updater
111
111
 
112
112
  def update_feeds( opts={} )
113
113
 
114
+ if debug?
115
+ ## turn on logging for sql too
116
+ ActiveRecord::Base.logger = Logger.new( STDOUT )
117
+ end
118
+
114
119
  ### move to feedutils
115
120
  ### logger.debug "using stdlib RSS::VERSION #{RSS::VERSION}"
116
121
 
@@ -157,17 +162,34 @@ class Updater
157
162
  # generator
158
163
  # published_at,built_at,touched_at,fetched_at
159
164
  # summary,title2
165
+
166
+ ## fix:
167
+ ## weird rss exception error on windows w/ dates
168
+ # e.g. /lib/ruby/1.9.1/rss/rss.rb:37:in `w3cdtf': wrong number of arguments (1 for 0) (ArgumentError)
169
+ #
170
+ # move to_datetime to feedutils!! if it works
171
+
172
+
160
173
  feed_attribs = {
161
174
  fetched_at: feed_fetched_at,
162
175
  format: feed.format,
163
- published_at: feed.published? ? feed.published : nil,
164
- touched_at: feed.updated? ? feed.updated : nil,
165
- built_at: feed.built? ? feed.built : nil,
176
+ published_at: feed.published? ? feed.published.to_datetime : nil,
177
+ touched_at: feed.updated? ? feed.updated.to_datetime : nil,
178
+ built_at: feed.built? ? feed.built.to_datetime : nil,
166
179
  summary: feed.summary? ? feed.summary : nil,
167
180
  title2: feed.title2? ? feed.title2 : nil,
168
181
  generator: feed.generator
169
182
  }
170
183
 
184
+ if debug?
185
+ ## puts "*** dump feed_attribs:"
186
+ ## pp feed_attribs
187
+ puts "*** dump feed_attribs w/ class types:"
188
+ feed_attribs.each do |key,value|
189
+ puts " #{key}: >#{value}< : #{value.class.name}"
190
+ end
191
+ end
192
+
171
193
  feed_rec.update_attributes!( feed_attribs )
172
194
 
173
195
 
@@ -179,11 +201,20 @@ class Updater
179
201
  url: item.url,
180
202
  summary: item.summary? ? item.summary : nil,
181
203
  content: item.content? ? item.content : nil,
182
- published_at: item.published? ? item.published : nil,
183
- touched_at: item.updated? ? item.updated : nil,
204
+ published_at: item.published? ? item.published.to_datetime : nil,
205
+ touched_at: item.updated? ? item.updated.to_datetime : nil,
184
206
  feed_id: feed_rec.id # add feed_id fk_ref
185
207
  }
186
208
 
209
+ if debug?
210
+ puts "*** dump item_attribs w/ class types:"
211
+ item_attribs.each do |key,value|
212
+ next if [:summary,:content].include?( key ) # skip summary n content
213
+ puts " #{key}: >#{value}< : #{value.class.name}"
214
+ end
215
+ end
216
+
217
+
187
218
  rec = Item.find_by_guid( item.guid )
188
219
  if rec.nil?
189
220
  rec = Item.new
@@ -197,11 +228,21 @@ class Updater
197
228
  rec.update_attributes!( item_attribs )
198
229
  end # each item
199
230
 
231
+ # update cached value latest published_at for item
232
+ item_recs = feed_rec.items.latest.limit(1).all
233
+ unless item_recs.empty?
234
+ if item_recs[0].published_at?
235
+ feed_rec.latest_published_at = item_recs[0].published_at
236
+ else # try touched_at
237
+ feed_rec.latest_published_at = item_recs[0].touched_at
238
+ end
239
+ feed_rec.save!
240
+ end
241
+
200
242
  end # each feed
201
243
 
202
244
  end # method run
203
245
 
204
-
205
246
 
206
247
  end # class Fetcher
207
248
 
data/lib/pluto/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
2
  module Pluto
3
- VERSION = '0.8.1'
3
+ VERSION = '0.8.2'
4
4
  end
5
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pluto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 0.8.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-23 00:00:00.000000000 Z
12
+ date: 2013-09-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: pakman
16
- requirement: &78500880 !ruby/object:Gem::Requirement
16
+ requirement: &83915310 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.5'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *78500880
24
+ version_requirements: *83915310
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: fetcher
27
- requirement: &78500610 !ruby/object:Gem::Requirement
27
+ requirement: &83914830 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0.3'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *78500610
35
+ version_requirements: *83914830
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: logutils
38
- requirement: &78500310 !ruby/object:Gem::Requirement
38
+ requirement: &83914450 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0.6'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *78500310
46
+ version_requirements: *83914450
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: feedutils
49
- requirement: &78500050 !ruby/object:Gem::Requirement
49
+ requirement: &83914160 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0.3'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *78500050
57
+ version_requirements: *83914160
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: props
60
- requirement: &78499760 !ruby/object:Gem::Requirement
60
+ requirement: &83913880 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *78499760
68
+ version_requirements: *83913880
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: textutils
71
- requirement: &78499510 !ruby/object:Gem::Requirement
71
+ requirement: &83913580 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.6.8
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *78499510
79
+ version_requirements: *83913580
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: gli
82
- requirement: &78499200 !ruby/object:Gem::Requirement
82
+ requirement: &83913340 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 2.5.6
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *78499200
90
+ version_requirements: *83913340
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rdoc
93
- requirement: &78498960 !ruby/object:Gem::Requirement
93
+ requirement: &83913010 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '3.10'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *78498960
101
+ version_requirements: *83913010
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: hoe
104
- requirement: &78498660 !ruby/object:Gem::Requirement
104
+ requirement: &83912770 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: '3.3'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *78498660
112
+ version_requirements: *83912770
113
113
  description: pluto - Another Planet Generator (Lets You Build Web Pages from Published
114
114
  Web Feeds)
115
115
  email: webslideshow@googlegroups.com
@@ -136,6 +136,7 @@ files:
136
136
  - lib/pluto/manifest_helpers.rb
137
137
  - lib/pluto/models.rb
138
138
  - lib/pluto/schema.rb
139
+ - lib/pluto/template_helpers.rb
139
140
  - lib/pluto/updater.rb
140
141
  - lib/pluto/version.rb
141
142
  homepage: https://github.com/feedreader/pluto