mako_rss 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +8 -8
- data/README.md +13 -1
- data/Rakefile +1 -1
- data/lib/mako.rb +3 -1
- data/lib/mako/cli.rb +3 -1
- data/lib/mako/commands/subscribe.rb +19 -0
- data/lib/mako/feed_finder.rb +68 -0
- data/lib/mako/feed_requester.rb +7 -5
- data/lib/mako/subscription_list_parser.rb +10 -4
- data/lib/mako/subscription_list_writer.rb +70 -0
- data/lib/mako/version.rb +1 -1
- data/lib/templates/Gemfile +1 -1
- data/mako_rss.gemspec +1 -1
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 770630990cc3595bb157dee7f3d764d6a91b4e92
|
4
|
+
data.tar.gz: add1706141f24d42b880ae7f0b2ab819c2eeed60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58295d6d252e28a6ed94bbac881d2b35ea69f81cb965ede92c3f32598fb5201596f5b610a3d1e54b0ca4c2ed1828bc08f8a05edde5d4345ce30505cf76598796
|
7
|
+
data.tar.gz: 066590c44fb0fb8a6660f8085aa9bc24cd33986f82bacb0688522a590ed1292c67f8cd1f988b59768dc81cf7c45d1ee538412c63bfcb9524db3a8e0fb62c3070
|
data/.rubocop_todo.yml
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-
|
3
|
+
# on 2017-07-11 13:25:18 -0400 using RuboCop version 0.49.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
7
7
|
# versions of RuboCop, may require this file to be generated again.
|
8
8
|
|
9
|
-
# Offense count:
|
9
|
+
# Offense count: 4
|
10
10
|
Metrics/AbcSize:
|
11
|
-
Max:
|
11
|
+
Max: 28
|
12
12
|
|
13
|
-
# Offense count:
|
14
|
-
# Configuration parameters: AllowURI, URISchemes.
|
13
|
+
# Offense count: 40
|
14
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
15
|
+
# URISchemes: http, https
|
15
16
|
Metrics/LineLength:
|
16
17
|
Max: 629
|
17
18
|
|
18
|
-
# Offense count:
|
19
|
+
# Offense count: 8
|
19
20
|
# Configuration parameters: CountComments.
|
20
21
|
Metrics/MethodLength:
|
21
22
|
Max: 25
|
@@ -25,8 +26,7 @@ Style/AccessorMethodName:
|
|
25
26
|
Exclude:
|
26
27
|
- 'lib/mako/core.rb'
|
27
28
|
|
28
|
-
# Offense count:
|
29
|
-
# Configuration parameters: Exclude.
|
29
|
+
# Offense count: 25
|
30
30
|
Style/Documentation:
|
31
31
|
Enabled: false
|
32
32
|
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ I designed Mako with the following principals in mind:
|
|
13
13
|
|
14
14
|
To install Mako, do:
|
15
15
|
|
16
|
-
$ gem install
|
16
|
+
$ gem install mako_rss
|
17
17
|
|
18
18
|
Once the gem is installed, you'll need to generate a new Mako site. You can do
|
19
19
|
this in 1 of 2 ways.
|
@@ -62,6 +62,18 @@ Whichever you choose, place the file in the root directory and be sure its name
|
|
62
62
|
is `subscriptions`. The file extension (`.xml`/`.opml`, `.json`, or `.txt`)
|
63
63
|
will tell Mako what kind of subscription file you have.
|
64
64
|
|
65
|
+
## Subscribing to Additional Feeds
|
66
|
+
|
67
|
+
If you already have imported your subscription file, and subsequently want to
|
68
|
+
subscribe to additional feeds, Mako has a handy `subscribe` command to help you
|
69
|
+
out.
|
70
|
+
|
71
|
+
$ mako subscribe [url or urls]
|
72
|
+
|
73
|
+
It's generally best if you use the root URL of the site you would like to
|
74
|
+
subscribe to, such as https://jonathanpike.net. Mako will look at the site,
|
75
|
+
find a feed URL if it can, and add that URL to your subscription file. Easy!
|
76
|
+
|
65
77
|
## Configuration
|
66
78
|
|
67
79
|
Mako has very few configuration options. You can see all of them in the
|
data/Rakefile
CHANGED
data/lib/mako.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'time'
|
4
4
|
require 'erb'
|
5
5
|
require 'logger'
|
6
|
-
require '
|
6
|
+
require 'httparty'
|
7
7
|
require 'feedjira'
|
8
8
|
require 'nokogiri'
|
9
9
|
require 'json'
|
@@ -16,10 +16,12 @@ require_relative 'mako/mako_logger'
|
|
16
16
|
require_relative 'mako/view_helpers'
|
17
17
|
require_relative 'mako/configuration'
|
18
18
|
require_relative 'mako/subscription_list_parser'
|
19
|
+
require_relative 'mako/subscription_list_writer'
|
19
20
|
require_relative 'mako/feed'
|
20
21
|
require_relative 'mako/article'
|
21
22
|
require_relative 'mako/feed_requester'
|
22
23
|
require_relative 'mako/feed_constructor'
|
24
|
+
require_relative 'mako/feed_finder'
|
23
25
|
require_relative 'mako/html_renderer'
|
24
26
|
require_relative 'mako/sass_renderer'
|
25
27
|
require_relative 'mako/writer'
|
data/lib/mako/cli.rb
CHANGED
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
require_relative 'commands/build'
|
4
4
|
require_relative 'commands/new'
|
5
|
+
require_relative 'commands/subscribe'
|
5
6
|
require_relative 'commands/version'
|
6
7
|
|
7
8
|
module Mako
|
8
9
|
class CLI
|
9
|
-
COMMANDS = %w[build new version].freeze
|
10
|
+
COMMANDS = %w[build new subscribe version].freeze
|
10
11
|
|
11
12
|
# Takes ARGV and parses the first element (command) to see if it is
|
12
13
|
# in the commands array. If not, display help.
|
@@ -24,6 +25,7 @@ module Mako
|
|
24
25
|
Subcommands:
|
25
26
|
new Create a new Mako scaffold in PATH. If no PATH provided, defaults to current directory.
|
26
27
|
build Build your Mako site. Default: only build HTML.
|
28
|
+
subscribe Subscribe to the supplied URL or URLs. Accepts a list separated by spaces.
|
27
29
|
version Display the version.
|
28
30
|
|
29
31
|
Options:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class Subscribe
|
5
|
+
def self.perform(args)
|
6
|
+
if args.empty?
|
7
|
+
Mako.errors.add_error 'No feeds to find'
|
8
|
+
return
|
9
|
+
end
|
10
|
+
feeds = Mako::FeedFinder.new(uris: args).find
|
11
|
+
write_to_subscriptions(feeds)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.write_to_subscriptions(feed_urls)
|
15
|
+
path = File.expand_path(Dir.glob('subscriptions.*').first, Dir.pwd)
|
16
|
+
Mako::SubscriptionListWriter.new(feeds: feed_urls, destination: path).append_and_write
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class FeedFinder
|
5
|
+
# Patterns for RSS, Atom, and JSON feeds
|
6
|
+
XPATHS = ["//link[@rel='alternate'][@type='application/rss+xml']/@href",
|
7
|
+
"//link[@rel='alternate'][@type='application/atom+xml']/@href",
|
8
|
+
"//link[@rel='alternate'][@type='application/json']/@href"].freeze
|
9
|
+
MIME_TYPES = ['text/xml',
|
10
|
+
'application/xml',
|
11
|
+
'application/rss+xml',
|
12
|
+
'application/atom+xml',
|
13
|
+
'application/json'].freeze
|
14
|
+
|
15
|
+
attr_reader :uris
|
16
|
+
|
17
|
+
def initialize(args)
|
18
|
+
@uris = args.fetch(:uris)
|
19
|
+
end
|
20
|
+
|
21
|
+
# From an array of supplied URIs, will request each one and attempt to
|
22
|
+
# find a feed URI on the page. If one is found, it will be added to
|
23
|
+
# an array and returned.
|
24
|
+
#
|
25
|
+
# @return [Array]
|
26
|
+
def find
|
27
|
+
request_uris.map do |request|
|
28
|
+
if request[:body].nil?
|
29
|
+
request[:uri]
|
30
|
+
else
|
31
|
+
html = Nokogiri::HTML(request[:body])
|
32
|
+
potential_feed_uris = html.xpath(XPATHS.detect { |path| !html.xpath(path).empty? })
|
33
|
+
next if potential_feed_uris.empty?
|
34
|
+
uri_string = potential_feed_uris.first.value
|
35
|
+
feed_uri = URI.parse(uri_string)
|
36
|
+
if request[:uri].host == feed_uri.host
|
37
|
+
feed_uri.to_s
|
38
|
+
else
|
39
|
+
request[:uri].merge(feed_uri).to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end.compact
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# @private
|
48
|
+
# Make requests for each URI passed in and return an array of hashes
|
49
|
+
# with either just the URI (in the case that the URI passed in was already
|
50
|
+
# a feed URI), or the URI and the response body.
|
51
|
+
#
|
52
|
+
# @return [Array]
|
53
|
+
def request_uris
|
54
|
+
uris.map do |uri|
|
55
|
+
parsed_uri = URI.parse(uri)
|
56
|
+
# Try giving the URI a scheme if one isn't passed
|
57
|
+
parsed_uri = URI.parse('http://' + uri) if parsed_uri.scheme.nil?
|
58
|
+
request = Mako::FeedRequester.new(feed_url: parsed_uri).fetch
|
59
|
+
next unless request.ok?
|
60
|
+
if MIME_TYPES.include? request.headers['content-type'].split(';').first
|
61
|
+
{ uri: parsed_uri.to_s }
|
62
|
+
else
|
63
|
+
{ uri: parsed_uri, body: request.body }
|
64
|
+
end
|
65
|
+
end.compact
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/mako/feed_requester.rb
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
module Mako
|
4
4
|
class FeedRequester
|
5
5
|
attr_reader :feed_url
|
6
|
-
attr_accessor :ok, :body
|
6
|
+
attr_accessor :ok, :body, :headers
|
7
7
|
|
8
8
|
def initialize(args)
|
9
9
|
@ok = true
|
10
10
|
@body = ''
|
11
|
+
@headers = {}
|
11
12
|
@feed_url = args.fetch(:feed_url)
|
12
13
|
end
|
13
14
|
|
@@ -18,17 +19,18 @@ module Mako
|
|
18
19
|
# @return [Mako::FeedRequester]
|
19
20
|
def fetch
|
20
21
|
begin
|
21
|
-
request =
|
22
|
-
rescue
|
22
|
+
request = HTTParty.get(feed_url)
|
23
|
+
rescue SocketError
|
23
24
|
Mako.errors.add_error "Could not complete request to #{feed_url}."
|
24
25
|
self.ok = false
|
25
26
|
return self
|
26
27
|
end
|
27
|
-
unless request.
|
28
|
-
Mako.errors.add_error "Request to #{feed_url} returned #{request.
|
28
|
+
unless request.code == 200
|
29
|
+
Mako.errors.add_error "Request to #{feed_url} returned #{request.code}."
|
29
30
|
self.ok = false
|
30
31
|
return self
|
31
32
|
end
|
33
|
+
self.headers = request.headers
|
32
34
|
self.body = request.body
|
33
35
|
self
|
34
36
|
end
|
@@ -14,15 +14,21 @@ module Mako
|
|
14
14
|
#
|
15
15
|
# @return [Array]
|
16
16
|
def parse
|
17
|
-
loaded_list = load_resource(list)
|
18
17
|
case File.extname list
|
19
18
|
when '.xml' || '.opml'
|
20
|
-
Nokogiri::XML(
|
19
|
+
Nokogiri::XML(load_list).xpath('//@xmlUrl').map(&:value)
|
21
20
|
when '.json'
|
22
|
-
JSON.parse(
|
21
|
+
JSON.parse(load_list)
|
23
22
|
when '.txt'
|
24
|
-
|
23
|
+
load_list.split("\n")
|
25
24
|
end
|
26
25
|
end
|
26
|
+
|
27
|
+
# Load the subscription list file
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
def load_list
|
31
|
+
load_resource(list)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mako
|
4
|
+
class SubscriptionListWriter
|
5
|
+
include FileOpenUtil
|
6
|
+
|
7
|
+
attr_reader :feeds, :destination
|
8
|
+
|
9
|
+
def initialize(args)
|
10
|
+
@feeds = args.fetch(:feeds)
|
11
|
+
@destination = args.fetch(:destination)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Appends the new subscriptions to the subscription list and
|
15
|
+
# writes the results out to the file.
|
16
|
+
def append_and_write
|
17
|
+
contents = append_and_render
|
18
|
+
File.open(destination, 'w+', encoding: 'utf-8') do |f|
|
19
|
+
f.write(contents)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# @private
|
26
|
+
# Returns the rendered string for the correct file type.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
def append_and_render
|
30
|
+
loaded_list = SubscriptionListParser.new(list: destination)
|
31
|
+
case File.extname destination
|
32
|
+
when '.xml' || '.opml'
|
33
|
+
render_opml(loaded_list)
|
34
|
+
when '.json'
|
35
|
+
render_json(loaded_list)
|
36
|
+
when '.txt'
|
37
|
+
render_txt(loaded_list)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Append feeds to current subscription list and return a string separated
|
42
|
+
# by \n characters
|
43
|
+
#
|
44
|
+
# @return [String]
|
45
|
+
def render_txt(list)
|
46
|
+
(list.parse + feeds).join("\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Append feeds to current subscription list and return a JSON array
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
def render_json(list)
|
53
|
+
(list.parse + feeds).to_json
|
54
|
+
end
|
55
|
+
|
56
|
+
# Append feeds to current subscription list and return XML document
|
57
|
+
#
|
58
|
+
# @return [String]
|
59
|
+
def render_opml(list)
|
60
|
+
document = Nokogiri::XML(list.load_list)
|
61
|
+
feeds.each do |feed_url|
|
62
|
+
node = "<outline xmlUrl='#{feed_url}' />\n"
|
63
|
+
document.xpath("//outline[@text='Subscriptions']").last.add_child node
|
64
|
+
end
|
65
|
+
formatted_no_decl = Nokogiri::XML::Node::SaveOptions::FORMAT +
|
66
|
+
Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
|
67
|
+
document.to_xml(encoding: 'utf-8', save_with: formatted_no_decl)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/mako/version.rb
CHANGED
data/lib/templates/Gemfile
CHANGED
data/mako_rss.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency 'coveralls', '~> 0.8'
|
31
31
|
|
32
32
|
spec.add_runtime_dependency 'feedjira', '~> 2.0'
|
33
|
-
spec.add_runtime_dependency '
|
33
|
+
spec.add_runtime_dependency 'httparty', '~> 0.15'
|
34
34
|
spec.add_runtime_dependency 'nokogiri', '~> 1.8'
|
35
35
|
spec.add_runtime_dependency 'sass', '~> 3.4'
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mako_rss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Pike
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -109,19 +109,19 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '2.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: httparty
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
117
|
+
version: '0.15'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
124
|
+
version: '0.15'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: nokogiri
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,6 +174,7 @@ files:
|
|
174
174
|
- lib/mako/commands/build.rb
|
175
175
|
- lib/mako/commands/new.rb
|
176
176
|
- lib/mako/commands/schedule.rb
|
177
|
+
- lib/mako/commands/subscribe.rb
|
177
178
|
- lib/mako/commands/version.rb
|
178
179
|
- lib/mako/configuration.rb
|
179
180
|
- lib/mako/core.rb
|
@@ -183,6 +184,7 @@ files:
|
|
183
184
|
- lib/mako/errors.rb
|
184
185
|
- lib/mako/feed.rb
|
185
186
|
- lib/mako/feed_constructor.rb
|
187
|
+
- lib/mako/feed_finder.rb
|
186
188
|
- lib/mako/feed_requester.rb
|
187
189
|
- lib/mako/file_open_util.rb
|
188
190
|
- lib/mako/html_renderer.rb
|
@@ -190,6 +192,7 @@ files:
|
|
190
192
|
- lib/mako/mako_logger.rb
|
191
193
|
- lib/mako/sass_renderer.rb
|
192
194
|
- lib/mako/subscription_list_parser.rb
|
195
|
+
- lib/mako/subscription_list_writer.rb
|
193
196
|
- lib/mako/version.rb
|
194
197
|
- lib/mako/view_helpers.rb
|
195
198
|
- lib/mako/writer.rb
|