weneedfeed 0.4.0 → 0.7.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
  SHA256:
3
- metadata.gz: adfe67e7ae534a35ab0e8c7ae33272c9046187564304700e7b6eec52dd671d03
4
- data.tar.gz: f4081b96371d71f0833ae6bf16e63d2719e4d341c9d23f8e17ab543f538ba6ac
3
+ metadata.gz: e666f142f72459d43fd7c6fe071740d1fce11dbac4605bcd1d7fbcc8766187ab
4
+ data.tar.gz: a6fdf6ce28e9c610d9f47fa747eaedc4d0198c59c70fd5b736d99dbeaf90d7df
5
5
  SHA512:
6
- metadata.gz: e58d4b58d0813ecdbe5c995acbf8e4a2b55c3598fb81967b0a169fcdb72ebc7ee6717bd39fcc95c043b88345cb6396f2221aa507a0cae2a0a07b1936f3442751
7
- data.tar.gz: b521aba54d499732ec09fc93de7d77ed642de53aaf828f49683b5f66c3616c781ed79675fbfb0df7a6aca4854897f57c92d2da09c0ad0f375bab12f71cdff7dd
6
+ metadata.gz: e07f3fe6d8d712e20384310e1bee1eca48065ccf2c0a400aaccd6e9d0f0d219b011f7944c34d11870bb5e3b83750f17de267d8eff260926916daaff1b9f08f35
7
+ data.tar.gz: 792f22dbcda78c4df3f0d738fe6dee28dae5a64eb075f8a1603da6d0c9d5ca68bba3337374f3f2d6dd93e798a6c1f57c4436a9ff34425ee84366d94b56c89903
@@ -5,16 +5,16 @@ on:
5
5
  push:
6
6
  branches:
7
7
  - master
8
+
8
9
  jobs:
9
10
  build:
10
11
  runs-on: ubuntu-18.04
11
12
  steps:
12
13
  - uses: actions/checkout@v2
13
- - uses: actions/setup-ruby@v1
14
+ - uses: ruby/setup-ruby@v1
14
15
  with:
15
- ruby-version: '2.7.2'
16
- - run: bundle install --jobs=$(($(nproc) - 1)) --retry=3
17
- - run: bundle exec rubocop --color --parallel
16
+ bundler-cache: true
17
+ ruby-version: 2.7.2
18
+ - uses: r7kamura/rubocop-problem-matchers-action@v1
19
+ - run: bundle exec rubocop --parallel
18
20
  - run: bundle exec rspec --force-color
19
-
20
-
data/.rspec CHANGED
@@ -1 +1,2 @@
1
+ --format doc
1
2
  --require spec_helper
@@ -1,4 +1,8 @@
1
+ require:
2
+ - rubocop-rspec
3
+
1
4
  AllCops:
5
+ NewCops: enable
2
6
  TargetRubyVersion: 2.5
3
7
 
4
8
  Lint/SuppressedException:
@@ -7,5 +11,20 @@ Lint/SuppressedException:
7
11
  Metrics:
8
12
  Enabled: false
9
13
 
14
+ RSpec/ImplicitSubject:
15
+ Enabled: false
16
+
17
+ RSpec/MultipleExpectations:
18
+ Enabled: false
19
+
20
+ RSpec/NamedSubject:
21
+ Enabled: false
22
+
10
23
  Style/Documentation:
11
24
  Enabled: false
25
+
26
+ Style/TrailingCommaInArguments:
27
+ Enabled: false
28
+
29
+ Style/TrailingCommaInHashLiteral:
30
+ Enabled: false
@@ -7,6 +7,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## 0.7.0 - 2020-11-23
11
+
12
+ ### Added
13
+
14
+ - Convert JSON response into XML.
15
+
16
+ ### Fixed
17
+
18
+ - Fix bug that item_description_selector is not used.
19
+
20
+ ## 0.6.1 - 2020-11-15
21
+
22
+ ### Changed
23
+
24
+ - Require hibana 0.2 or later.
25
+
26
+ ### Fixed
27
+
28
+ - Fix installation error caused by hanami-router version restriction.
29
+
30
+ ### Removed
31
+
32
+ - Remove direct dependency on hanami-router.
33
+
34
+ ## 0.6.0 - 2020-11-15
35
+
36
+ ### Changed
37
+
38
+ - Change pages schema from Hash to Array.
39
+ - Require hanami-router 2.0.0.alpha3 or later versions.
40
+ - Ignore pubDate when item.time is not found.
41
+ - Make some item_description_selector and item_time_selector optional.
42
+
43
+ ## 0.5.0 - 2020-11-14
44
+
45
+ ### Added
46
+
47
+ - Add datetime attribute support on time element.
48
+
49
+ ### Changed
50
+
51
+ - Change schema format about selectors.
52
+
53
+ ## 0.4.1 - 2020-11-08
54
+
55
+ ### Fixed
56
+
57
+ - Fix error when item description is not found.
58
+
10
59
  ## 0.4.0 - 2020-11-08
11
60
 
12
61
  ### Added
data/Gemfile CHANGED
@@ -9,4 +9,5 @@ gem 'rack-test'
9
9
  gem 'rake', '~> 12.0'
10
10
  gem 'rspec'
11
11
  gem 'rubocop'
12
+ gem 'rubocop-rspec'
12
13
  gem 'webmock'
@@ -1,9 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- weneedfeed (0.4.0)
4
+ weneedfeed (0.7.0)
5
+ activesupport
6
+ builder
5
7
  faraday
6
- hibana
8
+ faraday_middleware
9
+ hibana (>= 0.2)
7
10
  nokogiri
8
11
  rack-capture (>= 0.4.0)
9
12
  thor
@@ -11,35 +14,47 @@ PATH
11
14
  GEM
12
15
  remote: https://rubygems.org/
13
16
  specs:
17
+ activesupport (6.0.3.4)
18
+ concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ i18n (>= 0.7, < 2)
20
+ minitest (~> 5.1)
21
+ tzinfo (~> 1.1)
22
+ zeitwerk (~> 2.2, >= 2.2.2)
14
23
  addressable (2.7.0)
15
24
  public_suffix (>= 2.0.2, < 5.0)
16
25
  ast (2.4.1)
26
+ builder (3.2.4)
17
27
  concurrent-ruby (1.1.7)
18
28
  crack (0.4.4)
19
29
  diff-lcs (1.4.4)
20
30
  faraday (1.1.0)
21
31
  multipart-post (>= 1.2, < 3)
22
32
  ruby2_keywords
23
- hanami-router (1.3.2)
24
- hanami-utils (~> 1.3)
25
- http_router (= 0.11.2)
33
+ faraday_middleware (1.0.0)
34
+ faraday (~> 1.0)
35
+ hanami-router (2.0.0.alpha3)
36
+ mustermann (~> 1.0)
37
+ mustermann-contrib (~> 1.0)
26
38
  rack (~> 2.0)
27
- hanami-utils (1.3.6)
28
- concurrent-ruby (~> 1.0)
29
- transproc (~> 1.0)
39
+ hansi (0.2.0)
30
40
  hashdiff (1.0.1)
31
- hibana (0.1.1)
32
- hanami-router
41
+ hibana (0.2.0)
42
+ hanami-router (>= 2.0.0.alpha3)
33
43
  rack
34
44
  tilt
35
- http_router (0.11.2)
36
- rack (>= 1.0.0)
37
- url_mount (~> 0.2.1)
45
+ i18n (1.8.5)
46
+ concurrent-ruby (~> 1.0)
38
47
  mini_portile2 (2.4.0)
48
+ minitest (5.14.2)
39
49
  multipart-post (2.1.1)
50
+ mustermann (1.1.1)
51
+ ruby2_keywords (~> 0.0.1)
52
+ mustermann-contrib (1.1.1)
53
+ hansi (~> 0.2.0)
54
+ mustermann (= 1.1.1)
40
55
  nokogiri (1.10.10)
41
56
  mini_portile2 (~> 2.4.0)
42
- parallel (1.19.2)
57
+ parallel (1.20.1)
43
58
  parser (2.7.2.0)
44
59
  ast (~> 2.4.1)
45
60
  public_suffix (4.0.6)
@@ -65,29 +80,33 @@ GEM
65
80
  diff-lcs (>= 1.2.0, < 2.0)
66
81
  rspec-support (~> 3.9.0)
67
82
  rspec-support (3.9.4)
68
- rubocop (1.0.0)
83
+ rubocop (1.4.0)
69
84
  parallel (~> 1.10)
70
85
  parser (>= 2.7.1.5)
71
86
  rainbow (>= 2.2.2, < 4.0)
72
87
  regexp_parser (>= 1.8)
73
88
  rexml
74
- rubocop-ast (>= 0.6.0)
89
+ rubocop-ast (>= 1.1.1)
75
90
  ruby-progressbar (~> 1.7)
76
91
  unicode-display_width (>= 1.4.0, < 2.0)
77
- rubocop-ast (1.1.0)
92
+ rubocop-ast (1.1.1)
78
93
  parser (>= 2.7.1.5)
94
+ rubocop-rspec (2.0.0)
95
+ rubocop (~> 1.0)
96
+ rubocop-ast (>= 1.1.0)
79
97
  ruby-progressbar (1.10.1)
80
98
  ruby2_keywords (0.0.2)
81
99
  thor (1.0.1)
100
+ thread_safe (0.3.6)
82
101
  tilt (2.0.10)
83
- transproc (1.1.1)
102
+ tzinfo (1.2.8)
103
+ thread_safe (~> 0.1)
84
104
  unicode-display_width (1.7.0)
85
- url_mount (0.2.1)
86
- rack
87
105
  webmock (3.9.3)
88
106
  addressable (>= 2.3.6)
89
107
  crack (>= 0.3.2)
90
108
  hashdiff (>= 0.4.0, < 2.0.0)
109
+ zeitwerk (2.4.1)
91
110
 
92
111
  PLATFORMS
93
112
  ruby
@@ -97,6 +116,7 @@ DEPENDENCIES
97
116
  rake (~> 12.0)
98
117
  rspec
99
118
  rubocop
119
+ rubocop-rspec
100
120
  webmock
101
121
  weneedfeed!
102
122
 
data/README.md CHANGED
@@ -25,34 +25,90 @@ Or install it yourself as:
25
25
  gem install weneedfeed
26
26
  ```
27
27
 
28
- ## Usage
28
+ ## Schema
29
29
 
30
- ### Schema
30
+ You need to write a schema file named with `weneedfeed.yml` to use this gem.
31
31
 
32
- Write `weneedfeed.yml`.
32
+ ### Example
33
33
 
34
34
  ```yaml
35
35
  pages:
36
- example1:
37
- title: example site 1
36
+ - id: example1
37
+ title: Example feed with CSS Selector
38
38
  url: http://example.com/1
39
- selectors:
40
- item: li
41
- item_description: p:nth-child(3)
42
- item_link: a
43
- item_time: time[datetime]
44
- item_title: p:nth-child(2)
45
- example2:
46
- title: example site 2
39
+ item_selector: li
40
+ item_description_selector: p:nth-child(3)
41
+ item_link_selector: a
42
+ item_time_selector: time
43
+ item_title_selector: p:nth-child(2)
44
+ - id: example2
45
+ title: Example feed with XPath
47
46
  url: http://example.com/2
48
- selectors:
49
- item: //li
50
- item_description: .//p[3]
51
- item_link: .//a/@href
52
- item_time: .//time/@datetime
53
- item_title: .//p[2]
47
+ item_selector: //li
48
+ item_description_selector: .//p[3]
49
+ item_link_selector: .//a
50
+ item_time_selector: .//time
51
+ item_title_selector: .//p[2]
54
52
  ```
55
53
 
54
+ ### `id`
55
+
56
+ Feed ID.
57
+
58
+ - required
59
+ - Used for feed URL.
60
+
61
+ ### `title`
62
+
63
+ Feed title.
64
+
65
+ - required
66
+ - Used for RSS `<title>` element in `<channel>` element.
67
+
68
+ ### `url`
69
+
70
+ HTML source URL.
71
+
72
+ - required
73
+ - Used to fetch HTML page for building feed.
74
+
75
+ ### `item_selector`
76
+
77
+ CSS or XPath selector to search each item.
78
+
79
+ - required
80
+ - Equivalent unit to RSS `<item>` element.
81
+
82
+ ### `item_link_selector`
83
+
84
+ CSS or XPath selector to find `<a>` element in each item.
85
+
86
+ - required
87
+ - Used for `<link>` in `<item>`.
88
+
89
+ ### `item_title_selector`
90
+
91
+ CSS or XPath selector to find element with title information in each item.
92
+
93
+ - required
94
+ - Used for `<title>` in `<item>`.
95
+
96
+ ### `item_description_selector`
97
+
98
+ CSS or XPath selector to find element with description information in each item.
99
+
100
+ - optional
101
+ - Used for `<description>` in `<item>`.
102
+
103
+ ### `item_time_selector`
104
+
105
+ CSS or XPath selector to find element with datetime information in each item.
106
+
107
+ - optional
108
+ - Used for `<pubDate>` in `<item>`. Its `datetime` attribute or its inner HTML is used to calculate datetime.
109
+
110
+ ## Usage
111
+
56
112
  ### Build
57
113
 
58
114
  Run `weneedfeed build` to build static files.
@@ -7,8 +7,12 @@ module Weneedfeed
7
7
  autoload :Capture, 'weneedfeed/capture'
8
8
  autoload :Command, 'weneedfeed/command'
9
9
  autoload :Controllers, 'weneedfeed/controllers'
10
+ autoload :FaradayResponseMiddleware, 'weneedfeed/faraday_response_middleware'
11
+ autoload :Helpers, 'weneedfeed/helpers'
10
12
  autoload :Item, 'weneedfeed/item'
11
13
  autoload :Page, 'weneedfeed/page'
14
+ autoload :PageSchema, 'weneedfeed/page_schema'
15
+ autoload :Schema, 'weneedfeed/schema'
12
16
  autoload :Scraping, 'weneedfeed/scraping'
13
17
  autoload :Views, 'weneedfeed/views'
14
18
  end
@@ -6,12 +6,12 @@ module Weneedfeed
6
6
  class Application < ::Hibana::Application
7
7
  route do
8
8
  get '/', to: ::Weneedfeed::Controllers::ShowTopPage, as: :top_page
9
- get '/feeds/:page_name.xml', to: ::Weneedfeed::Controllers::ShowFeed, as: :feed
9
+ get '/feeds/:page_id.xml', to: ::Weneedfeed::Controllers::ShowFeed, as: :feed
10
10
  end
11
11
 
12
12
  # @param [Hash] schema
13
13
  def initialize(schema:)
14
- @schema = schema
14
+ @schema = ::Weneedfeed::Schema.new(schema)
15
15
  super()
16
16
  end
17
17
 
@@ -23,8 +23,8 @@ module Weneedfeed
23
23
 
24
24
  # @return [Array<String>]
25
25
  def paths
26
- ['/'] + @schema['pages'].keys.map do |page_name|
27
- "/feeds/#{page_name}.xml"
26
+ ['/'] + @schema.page_ids.map do |page_id|
27
+ "/feeds/#{page_id}.xml"
28
28
  end
29
29
  end
30
30
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Weneedfeed
4
4
  module Controllers
5
+ autoload :Base, 'weneedfeed/controllers/base'
5
6
  autoload :ShowFeed, 'weneedfeed/controllers/show_feed'
6
7
  autoload :ShowTopPage, 'weneedfeed/controllers/show_top_page'
7
8
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weneedfeed
4
+ module Controllers
5
+ class Base < ::Hibana::Controller
6
+ include ::Weneedfeed::Helpers::Parameters
7
+
8
+ private
9
+
10
+ # @return [Weneedfeed::Schema]
11
+ def schema
12
+ request.env['weneedfeed.schema']
13
+ end
14
+ end
15
+ end
16
+ end
@@ -2,31 +2,22 @@
2
2
 
3
3
  module Weneedfeed
4
4
  module Controllers
5
- class ShowFeed < ::Hibana::Controller
5
+ class ShowFeed < ::Weneedfeed::Controllers::Base
6
6
  def call
7
- env = request.env
8
- page_name = env.dig(
9
- 'router.params',
10
- :page_name
11
- )
12
- properties = env.dig(
13
- 'weneedfeed.schema',
14
- 'pages',
15
- page_name
16
- )
17
- unless properties
7
+ page_schema = schema.find_page_schema(path_parameters[:page_id])
8
+ unless page_schema
18
9
  response.status = 404
19
10
  return
20
11
  end
21
12
 
22
13
  scraping = ::Weneedfeed::Scraping.new(
23
- item_description_selector: properties['selectors']['item_description'],
24
- item_link_selector: properties['selectors']['item_link'],
25
- item_time_selector: properties['selectors']['item_time'],
26
- item_title_selector: properties['selectors']['item_title'],
27
- item_selector: properties['selectors']['item'],
28
- title: properties['title'],
29
- url: properties['url']
14
+ item_description_selector: page_schema.item_description_selector,
15
+ item_link_selector: page_schema.item_link_selector,
16
+ item_time_selector: page_schema.item_time_selector,
17
+ item_title_selector: page_schema.item_title_selector,
18
+ item_selector: page_schema.item_selector,
19
+ title: page_schema.title,
20
+ url: page_schema.url,
30
21
  )
31
22
  page = scraping.call
32
23
 
@@ -2,18 +2,13 @@
2
2
 
3
3
  module Weneedfeed
4
4
  module Controllers
5
- class ShowTopPage < ::Hibana::Controller
5
+ class ShowTopPage < ::Weneedfeed::Controllers::Base
6
6
  def call
7
- pages = request.env.dig(
8
- 'weneedfeed.schema',
9
- 'pages'
10
- ).sort_by do |_key, value|
11
- value['title']
12
- end
7
+ page_schemata = schema.page_schemata.sort_by(&:title)
13
8
  response.content_type = 'text/html'
14
9
  response.write(
15
10
  ::Weneedfeed::Views::ShowTopPage.new(
16
- pages: pages,
11
+ page_schemata: page_schemata,
17
12
  partial_template_path: ::File.expand_path(
18
13
  'templates/show_top_page.html.erb',
19
14
  "#{__dir__}/../../.."
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/array/conversions'
4
+ require 'active_support/core_ext/hash/conversions'
5
+ require 'faraday'
6
+ require 'faraday_middleware/response_middleware'
7
+ require 'json'
8
+
9
+ module Weneedfeed
10
+ class FaradayResponseMiddleware < ::FaradayMiddleware::ResponseMiddleware
11
+ define_parser do |body, options|
12
+ options ||= {}
13
+ options = { dasherize: false }.merge(options)
14
+ object = ::JSON.parse(body)
15
+ object.to_xml(options)
16
+ end
17
+
18
+ # @note Overriding.
19
+ def parse_response?(env)
20
+ env.response.headers['Content-Type'].to_s.include?('application/json')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weneedfeed
4
+ module Helpers
5
+ autoload :Parameters, 'weneedfeed/helpers/parameters'
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weneedfeed
4
+ module Helpers
5
+ module Parameters
6
+ private
7
+
8
+ # @return [Hash]
9
+ def path_parameters
10
+ request.env['router.params']
11
+ end
12
+ end
13
+ end
14
+ end
@@ -15,8 +15,8 @@ module Weneedfeed
15
15
  end
16
16
  end
17
17
 
18
- # @param [String] description_selector
19
- # @param [String] link_selector
18
+ # @param [String, nil] description_selector
19
+ # @param [String, nil] link_selector
20
20
  # @param [Nokogiri::Node] node
21
21
  # @param [String] time_selector
22
22
  # @param [String] title_selector
@@ -39,32 +39,58 @@ module Weneedfeed
39
39
 
40
40
  # @return [String, nil]
41
41
  def description
42
- @node.at(@description_selector).inner_html
42
+ return unless @description_selector
43
+
44
+ @node.at(@description_selector)&.inner_html
43
45
  end
44
46
 
45
47
  # @return [String]
46
48
  def link
47
49
  ::URI.join(
48
50
  @url,
49
- @node.at(@link_selector)['href']
51
+ link_path_or_url
50
52
  ).to_s
51
53
  end
52
54
 
55
+ # @return [Nokogiri::Node, nil]
56
+ def link_node
57
+ @node.at(@link_selector)
58
+ end
59
+
60
+ # @return [String, nil]
61
+ def link_path_or_url
62
+ node = link_node
63
+ node['href'] || node.inner_text
64
+ end
65
+
53
66
  # @return [Time, nil]
54
67
  def time
55
- self.class.parse_time(time_string)
68
+ return unless @time_selector
69
+
70
+ string = time_string
71
+ return unless string
72
+
73
+ self.class.parse_time(string)
56
74
  end
57
75
 
58
- # @return [String, nil]
76
+ # @return [String]
59
77
  def title
60
78
  @node.at(@title_selector).inner_text
61
79
  end
62
80
 
63
81
  private
64
82
 
65
- # @return [String]
83
+ # @return [Nokogiri::Node, nil]
84
+ def time_node
85
+ @node.at(@time_selector)
86
+ end
87
+
88
+ # @return [String, nil]
66
89
  def time_string
67
- @node.at(@time_selector).inner_html
90
+ node = time_node
91
+ return unless node
92
+
93
+ node['datetime'] || node.inner_html
68
94
  end
69
95
  end
70
96
  end
@@ -8,9 +8,9 @@ module Weneedfeed
8
8
  # @return [String]
9
9
  attr_reader :url
10
10
 
11
- # @param [String] item_description_selector
11
+ # @param [String, nil] item_description_selector
12
12
  # @param [String] item_link_selector
13
- # @param [String] item_time_selector
13
+ # @param [String, nil] item_time_selector
14
14
  # @param [String] item_title_selector
15
15
  # @param [String] item_selector
16
16
  # @param [Nokogiri::Node] node
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weneedfeed
4
+ PageSchema = Struct.new(
5
+ :id,
6
+ :item_description_selector,
7
+ :item_link_selector,
8
+ :item_time_selector,
9
+ :item_title_selector,
10
+ :item_selector,
11
+ :title,
12
+ :url,
13
+ keyword_init: true,
14
+ )
15
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Weneedfeed
4
+ class Schema
5
+ # @param [Hash] raw
6
+ def initialize(raw)
7
+ @raw = raw
8
+ end
9
+
10
+ # @param [String, nl] page_schema_id
11
+ # @return [Weneedfeed::PageSchema]
12
+ def find_page_schema(page_schema_id)
13
+ page_schemata.find do |page_schema|
14
+ page_schema.id == page_schema_id
15
+ end
16
+ end
17
+
18
+ # @return [Array<String>]
19
+ def page_ids
20
+ page_schemata.map(&:id)
21
+ end
22
+
23
+ # @return [Array<Weneedfeed::PageSchema>]
24
+ def page_schemata
25
+ @raw['pages'].map do |hash|
26
+ ::Weneedfeed::PageSchema.new(
27
+ id: hash['id'],
28
+ item_description_selector: hash['item_description_selector'],
29
+ item_link_selector: hash['item_link_selector'],
30
+ item_time_selector: hash['item_time_selector'],
31
+ item_title_selector: hash['item_title_selector'],
32
+ item_selector: hash['item_selector'],
33
+ title: hash['title'],
34
+ url: hash['url'],
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -5,9 +5,18 @@ require 'nokogiri'
5
5
 
6
6
  module Weneedfeed
7
7
  class Scraping
8
- # @param [String] item_description_selector
8
+ class << self
9
+ # @return [Faraday::Connection]
10
+ def faraday_connection
11
+ @faraday_connection ||= ::Faraday.new do |connection|
12
+ connection.use ::Weneedfeed::FaradayResponseMiddleware
13
+ end
14
+ end
15
+ end
16
+
17
+ # @param [String, nil] item_description_selector
9
18
  # @param [String] item_link_selector
10
- # @param [String] item_time_selector
19
+ # @param [String, nil] item_time_selector
11
20
  # @param [String] item_title_selector
12
21
  # @param [String] item_selector
13
22
  # @param [String] title
@@ -48,12 +57,12 @@ module Weneedfeed
48
57
 
49
58
  # @return [Nokogiri::Node]
50
59
  def parsed_body
51
- ::Nokogiri::HTML.parse(response.body)
60
+ ::Nokogiri::XML.parse(response.body)
52
61
  end
53
62
 
54
63
  # @return [Faraday::Response]
55
64
  def response
56
- ::Faraday.get(@url)
65
+ self.class.faraday_connection.get(@url)
57
66
  end
58
67
  end
59
68
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Weneedfeed
4
- VERSION = '0.4.0'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -3,6 +3,8 @@
3
3
  module Weneedfeed
4
4
  module Views
5
5
  class ShowFeed < ::Hibana::View
6
+ include ::Weneedfeed::Helpers::Parameters
7
+
6
8
  # @param [Weneedfeed::Page] page
7
9
  def initialize(page:, **argv)
8
10
  super(**argv)
@@ -13,7 +15,7 @@ module Weneedfeed
13
15
 
14
16
  # @return [String]
15
17
  def top_page_path
16
- request.path.delete_suffix(router.path(:feed, page_name: page_name))
18
+ request.path.delete_suffix(router.path(:feed, page_id: page_id))
17
19
  end
18
20
 
19
21
  # @return [Enumerable<Weneedfeed::Item>]
@@ -24,8 +26,8 @@ module Weneedfeed
24
26
  end
25
27
 
26
28
  # @return [String]
27
- def page_name
28
- request.env['router.params'][:page_name]
29
+ def page_id
30
+ path_parameters[:page_id]
29
31
  end
30
32
 
31
33
  # @return [Hanami::Router]
@@ -3,10 +3,10 @@
3
3
  module Weneedfeed
4
4
  module Views
5
5
  class ShowTopPage < ::Hibana::View
6
- # @param [Array<Weneedfeed::Page>] pages
7
- def initialize(pages:, **argv)
6
+ # @param [Array<Hash>] page_schemata
7
+ def initialize(page_schemata:, **argv)
8
8
  super(**argv)
9
- @pages = pages
9
+ @page_schemata = page_schemata
10
10
  end
11
11
 
12
12
  private
@@ -16,10 +16,10 @@ module Weneedfeed
16
16
  request.path.delete_suffix(router.path(:top_page))
17
17
  end
18
18
 
19
- # @param [String] page_name
19
+ # @param [String] page_id
20
20
  # @return [String]
21
- def feed_path(page_name:)
22
- "#{base_path}#{router.path(:feed, page_name: page_name)}"
21
+ def feed_path(page_id:)
22
+ "#{base_path}#{router.path(:feed, page_id: page_id)}"
23
23
  end
24
24
 
25
25
  # @return [Hanami::Router]
@@ -12,7 +12,9 @@
12
12
  <item>
13
13
  <title><![CDATA[<%= item.title %>]]></title>
14
14
  <link><%= item.link %></link>
15
- <pubDate><%= item.time.rfc822 %></pubDate>
15
+ <% if item.time %>
16
+ <pubDate><%= item.time.rfc822 %></pubDate>
17
+ <% end %>
16
18
  <description><![CDATA[<%= item.description %>]]></description>
17
19
  <content:encoded><![CDATA[<%= item.description %>]]></content:encoded>
18
20
  <guid isPermaLink="true"><%= item.link %></guid>
@@ -7,9 +7,9 @@
7
7
  </head>
8
8
  <body>
9
9
  <ul>
10
- <% @pages.each do |page_name, hash| %>
10
+ <% @page_schemata.each do |page_schema| %>
11
11
  <li>
12
- <a href="<%= feed_path(page_name: page_name) %>"><%= hash['title'] %></a>
12
+ <a href="<%= feed_path(page_id: page_schema.id) %>"><%= page_schema.title %></a>
13
13
  </li>
14
14
  <% end %>
15
15
  </ul>
@@ -25,8 +25,11 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
+ spec.add_runtime_dependency 'activesupport'
29
+ spec.add_runtime_dependency 'builder'
28
30
  spec.add_runtime_dependency 'faraday'
29
- spec.add_runtime_dependency 'hibana'
31
+ spec.add_runtime_dependency 'faraday_middleware'
32
+ spec.add_runtime_dependency 'hibana', '>= 0.2'
30
33
  spec.add_runtime_dependency 'nokogiri'
31
34
  spec.add_runtime_dependency 'rack-capture', '>= 0.4.0'
32
35
  spec.add_runtime_dependency 'thor'
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weneedfeed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryo Nakamura
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-07 00:00:00.000000000 Z
11
+ date: 2020-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: builder
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: faraday
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -25,7 +53,7 @@ dependencies:
25
53
  - !ruby/object:Gem::Version
26
54
  version: '0'
27
55
  - !ruby/object:Gem::Dependency
28
- name: hibana
56
+ name: faraday_middleware
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - ">="
@@ -38,6 +66,20 @@ dependencies:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: hibana
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0.2'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0.2'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: nokogiri
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -106,10 +148,16 @@ files:
106
148
  - lib/weneedfeed/capture.rb
107
149
  - lib/weneedfeed/command.rb
108
150
  - lib/weneedfeed/controllers.rb
151
+ - lib/weneedfeed/controllers/base.rb
109
152
  - lib/weneedfeed/controllers/show_feed.rb
110
153
  - lib/weneedfeed/controllers/show_top_page.rb
154
+ - lib/weneedfeed/faraday_response_middleware.rb
155
+ - lib/weneedfeed/helpers.rb
156
+ - lib/weneedfeed/helpers/parameters.rb
111
157
  - lib/weneedfeed/item.rb
112
158
  - lib/weneedfeed/page.rb
159
+ - lib/weneedfeed/page_schema.rb
160
+ - lib/weneedfeed/schema.rb
113
161
  - lib/weneedfeed/scraping.rb
114
162
  - lib/weneedfeed/version.rb
115
163
  - lib/weneedfeed/views.rb