pluto-news 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pluto/news.rb +100 -24
- data/lib/pluto/news/version.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a014d89094549725b6cbd78214ee882094a0aeb3
|
4
|
+
data.tar.gz: f7cae9d5c36c7bb69ec34f276cce937639097bac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3244fbe52589e3ae1c9a5aadb06b2050b7e8382f2b9f0f68854b419852f9d5ed45cf056f54185485ffae975dde0e18f21db314b260df49aa4d05928139f76896
|
7
|
+
data.tar.gz: a92e359f7776f47f520b920931d069176c67f1cde6cf957e1d5f9085df4ce3f1136e61cf9be1a51e5262939ee229c4b8c848a164790453716366a819bb7d0ea3
|
data/lib/pluto/news.rb
CHANGED
@@ -8,6 +8,8 @@ require 'time'
|
|
8
8
|
require 'cgi'
|
9
9
|
require 'uri'
|
10
10
|
require 'digest'
|
11
|
+
require 'yaml' ## check - already included upstream?
|
12
|
+
require 'json' ## check - already included upstream?
|
11
13
|
|
12
14
|
require 'erb'
|
13
15
|
require 'ostruct'
|
@@ -54,36 +56,110 @@ require 'pluto/news/version'
|
|
54
56
|
|
55
57
|
module News
|
56
58
|
|
59
|
+
##
|
60
|
+
## todo/check: allow (add) site = nil for no site "filter" (all items / feeds) - why? why not?
|
57
61
|
def self.site=(value) @site = value; end
|
58
62
|
def self.site() @site ||= 'news'; end ## note: defaults to news
|
59
63
|
|
60
64
|
|
65
|
+
####
|
66
|
+
# helpers
|
67
|
+
|
68
|
+
def self.autogen_feed_key( feed_url )
|
69
|
+
## note:
|
70
|
+
## use a "fingerprint" hash digest as key
|
71
|
+
## do NOT include scheme (e.g. https or http)
|
72
|
+
## do NOT include port
|
73
|
+
## so you can change it without "breaking" the key - why? why not?
|
74
|
+
##
|
75
|
+
## e.g. u = URI( 'https://example.com:333/a/b?f=xml'
|
76
|
+
## u.host+u.request_uri
|
77
|
+
## #=> example.com/a/b?f=xml
|
78
|
+
uri = URI( feed_url )
|
79
|
+
## note: add host in "plain" text - making errors and the key more readable
|
80
|
+
## note: cut-off www. if leading e.g. www.ruby-lang.org => ruby-lang.org
|
81
|
+
host = uri.host.downcase.sub( /^www\./, '' )
|
82
|
+
# use a differt separator e.g _ or ~ and NOT $ - why? why not?
|
83
|
+
key = "#{host}$#{Digest::MD5.hexdigest( uri.request_uri )}"
|
84
|
+
key
|
85
|
+
end
|
61
86
|
|
62
|
-
def self.
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
def self.norm_feed_hash( old_h ) ## todo/check: rename to normalize/unify_feeds or resolve_feedlist or something?
|
88
|
+
## unify feed list entries
|
89
|
+
## case 1) if section name is some thing like [Andrew Kane]
|
90
|
+
## and NO title/name key than assume it's the title/name
|
91
|
+
## and auto-generated key/id
|
92
|
+
|
93
|
+
## move all "global" settings to [planet] section - why? why not?
|
94
|
+
## e.g.
|
95
|
+
## title = Planet Open Data News
|
96
|
+
## becomes
|
97
|
+
## [planet]
|
98
|
+
## title = Planet Open Data News
|
99
|
+
|
100
|
+
h = {}
|
101
|
+
old_h.each do |k,v|
|
102
|
+
if v.is_a?( String )
|
103
|
+
h[ k ] = v ## pass along as-is (assume "top-level" / global setting)
|
104
|
+
elsif v.is_a?( Hash )
|
105
|
+
## puts "#{k}:"
|
106
|
+
## pp v
|
107
|
+
## todo/fix: use "proper" ident e.g. allow 0-9 and .-_ too? why? why not?
|
108
|
+
if k =~ /^[a-z_][a-z0-9$_.]*$/ ## all lower case; assume id - add 0-9 and .-_ - why? why not?
|
109
|
+
h[ k ] = v
|
110
|
+
else
|
111
|
+
## puts "bingo! section name shortcut - #{k}"
|
112
|
+
if k.start_with?( 'http' )
|
113
|
+
if v.has_key?( 'feed' ) then raise ArgumentError.new( "duplicate >feed< hash table entry in section >#{k}<; cannot autogen key" ); end
|
114
|
+
|
115
|
+
new_k = autogen_feed_key( k )
|
116
|
+
# note: use merge - why? why not? to NOT overwrite existing entry - why? why not?
|
117
|
+
h[ new_k ] = { 'feed' => k }.merge( v )
|
118
|
+
else
|
119
|
+
## transform key to title and auto-generate id (new key)
|
120
|
+
if v.has_key?( 'title' ) || v.has_key?( 'name' ) then raise ArgumentError.new( "duplicate >name< or >title< hash table entry in section >#{k}<; cannot autogen key" ); end
|
121
|
+
if v.has_key?( 'feed' ) == false then raise ArgumentError.new( "expected / required >feed< hash table entry missing for section >#{k}<"); end
|
122
|
+
|
123
|
+
new_k = autogen_feed_key( v['feed'] )
|
124
|
+
# note: use merge - why? why not? to NOT overwrite existing entry - why? why not?
|
125
|
+
h[ new_k ] = { 'title' => k }.merge( v )
|
126
|
+
end
|
127
|
+
end
|
128
|
+
else
|
129
|
+
raise ArgumentError.new( "expected String or Hash for value (in hash table) but got >#{v.class.name}< for key >#{k}<" )
|
130
|
+
end
|
85
131
|
end
|
86
132
|
|
133
|
+
## todo/check - auto-add required (?) missing title if missing - why? why not?
|
134
|
+
h['title'] = 'Untitled' if h.has_key?( 'title' ) == false
|
135
|
+
|
136
|
+
h
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
def self.subscribe( *feeds )
|
141
|
+
|
142
|
+
site_hash = if feeds.size == 1 && feeds[0].is_a?( Hash )
|
143
|
+
## puts "bingo! it's a hash"
|
144
|
+
norm_feed_hash( feeds[0] )
|
145
|
+
elsif feeds.size == 1 && feeds[0].is_a?( String ) && feeds[0] =~ /\n/
|
146
|
+
## string includes newline (e.g. more than a single line?)
|
147
|
+
## if yes, parse and assume ini (config) format
|
148
|
+
norm_feed_hash( INI.load( feeds[0] ))
|
149
|
+
else ## assume list / array of strings (feed_urls)
|
150
|
+
## puts "bingo! it's a string list"
|
151
|
+
## auto-build a (simple) site hash
|
152
|
+
feeds.reduce( { ## note: keys are strings (NOT symbols) for now
|
153
|
+
'title' => 'Untitled'
|
154
|
+
## todo/check: remove title? required? check in model update if missing?
|
155
|
+
} ) do |h, feed|
|
156
|
+
key = autogen_feed_key( feed )
|
157
|
+
|
158
|
+
h[ key ] = { 'feed' => feed }
|
159
|
+
h
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
87
163
|
connection ## make sure we have a database connection (and setup) up-and-running
|
88
164
|
## note: always use "multi-site" setup; defaults to 'news' site key
|
89
165
|
Pluto::Model::Site.deep_create_or_update_from_hash!( site, site_hash )
|
@@ -118,7 +194,7 @@ module News
|
|
118
194
|
## note: always use "multi-site" setup; defaults to 'news' site key
|
119
195
|
## note: add "default" scope - orders (sorts) by latest / time
|
120
196
|
rec = Pluto::Model::Site.where(key: site).first
|
121
|
-
if rec.nil?
|
197
|
+
if rec.nil?
|
122
198
|
Pluto::Model::Item.none ## use null (relation) pattern to avoid crash on nil - why? why not?
|
123
199
|
else
|
124
200
|
rec.items.order(
|
data/lib/pluto/news/version.rb
CHANGED
@@ -3,20 +3,20 @@ module PlutoNews
|
|
3
3
|
|
4
4
|
MAJOR = 1
|
5
5
|
MINOR = 1
|
6
|
-
PATCH =
|
6
|
+
PATCH = 1
|
7
7
|
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
8
|
-
|
8
|
+
|
9
9
|
def self.version
|
10
10
|
VERSION
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def self.banner
|
14
14
|
### todo: add RUBY_PATCHLEVEL or RUBY_PATCH_LEVEL e.g. -p124
|
15
15
|
"pluto-news/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def self.root
|
19
19
|
"#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
end # module PlutoNews
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pluto-news
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pluto-models
|