mako_rss 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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