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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bb8b5a3c394b989b9722f6ae04b6373d23ba7e08
4
- data.tar.gz: 11efdfb201da11cf3ec348d84ae41c639c7a52a8
3
+ metadata.gz: 770630990cc3595bb157dee7f3d764d6a91b4e92
4
+ data.tar.gz: add1706141f24d42b880ae7f0b2ab819c2eeed60
5
5
  SHA512:
6
- metadata.gz: a7603d695ded87c83719c2cd159d4e33f85878525fdd29c597c6a6fd033148c7e7a3add809f824c6e544634b196b109b3a1ada4d8cb0fcb5b6a44f7c93751f99
7
- data.tar.gz: 0ba4e36181aa8dd232ad7f83fb3960dba146c136095cd0e875e0547a262aee1ceb80980e2a98a886a1534bb000bfd5259df3e77815ea87c0da2f8ea1bec675d9
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-06-06 16:33:49 -0400 using RuboCop version 0.35.1.
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: 3
9
+ # Offense count: 4
10
10
  Metrics/AbcSize:
11
- Max: 26
11
+ Max: 28
12
12
 
13
- # Offense count: 37
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: 5
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: 22
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 mako
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
@@ -5,7 +5,7 @@ require 'rake/testtask'
5
5
  require 'rubocop/rake_task'
6
6
 
7
7
  Rake::TestTask.new do |t|
8
- t.pattern = 'test/*_test.rb'
8
+ t.pattern = 'test/**/*_test.rb'
9
9
  end
10
10
 
11
11
  RuboCop::RakeTask.new(:rubocop)
data/lib/mako.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'time'
4
4
  require 'erb'
5
5
  require 'logger'
6
- require 'faraday'
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
@@ -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 = Faraday.get(feed_url)
22
- rescue Faraday::Error
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.status == 200
28
- Mako.errors.add_error "Request to #{feed_url} returned #{request.status}."
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(loaded_list).xpath('//@xmlUrl').map(&:value)
19
+ Nokogiri::XML(load_list).xpath('//@xmlUrl').map(&:value)
21
20
  when '.json'
22
- JSON.parse(loaded_list)
21
+ JSON.parse(load_list)
23
22
  when '.txt'
24
- loaded_list.split("\n")
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mako
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
@@ -2,4 +2,4 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'mako'
5
+ gem 'mako_rss'
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 'faraday', '~> 0.12'
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.1.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-06-19 00:00:00.000000000 Z
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: faraday
112
+ name: httparty
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.12'
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.12'
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