irasutoya 0.1.0 → 1.0.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: 376e462cf4cfd7638c43d9c348f14e323d22660c4c49a67e2d492f81626a68ac
4
- data.tar.gz: f5ea400bb1e6bbbd8bc24cd9127a9d8530bf9aaa72414753cee7ed6307f64b05
3
+ metadata.gz: 6f4ac16858c54920d01070181e323a18938c08ea2981dce6019c5dc37c8cc183
4
+ data.tar.gz: 76544e45266f00020e7018772b3e8b9a162059321343da1e26c80fe6e1c425ad
5
5
  SHA512:
6
- metadata.gz: b263c7177ce0b45e257ae859d985d78d5ec73017ce4eca64dcc88512b3ba6061a45f07259235715eff72ac9ce60be799746db4b8310eb0bcf23439bca04dffa4
7
- data.tar.gz: f7d8393f93e071cd7ea4e7e2448812d0b1871ab40677b17c9c39d6bbf076042af055d98bbdade65d8db75aaea325606cebd3789430ccb498ba538e13d0b6d182
6
+ metadata.gz: 8d1ae88a93ce2248b527008cfe28d28aebf99cd057c1f0f0e4830c9e4e64f02880bc87527e6747d73282d939dd7a349b6c67799fbf0a60333a3198821bf845f7
7
+ data.tar.gz: 255c1bf1b9aa948c2a6b45ceb8dc695134b5d0902edb9e064a62f445825e65e21da2d7aa2bbcae4007549d00bae8e70240faad45393bffcffb5a8a48649d9300
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- irasutoya (0.1.0)
4
+ irasutoya (1.0.0)
5
5
  nokogiri
6
6
 
7
7
  GEM
@@ -56,7 +56,7 @@ GEM
56
56
  coderay (~> 1.1.0)
57
57
  method_source (~> 0.9.0)
58
58
  rainbow (3.0.0)
59
- rake (10.5.0)
59
+ rake (12.3.3)
60
60
  rb-fsevent (0.10.3)
61
61
  rb-inotify (0.10.0)
62
62
  ffi (~> 1.0)
@@ -102,7 +102,7 @@ DEPENDENCIES
102
102
  guard-rspec
103
103
  guard-rubocop
104
104
  irasutoya!
105
- rake (~> 10.0)
105
+ rake (~> 12.3)
106
106
  rspec (~> 3.0)
107
107
  rubocop
108
108
  simplecov
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  ![](http://ruby-gem-downloads-badge.herokuapp.com/irasutoya?type=total)
8
8
  ![GitHub](https://img.shields.io/github/license/unhappychoice/irasutoya.svg)
9
9
 
10
- `Irasutoya` is ruby library and CLI tool for [いらすとや](https://www.irasutoya.com)
10
+ `Irasutoya` is ruby library for [いらすとや](https://www.irasutoya.com)
11
11
 
12
12
  ## Installation
13
13
 
@@ -19,7 +19,29 @@ gem 'irasutoya'
19
19
  ## Usage
20
20
 
21
21
  ```ruby
22
- Irasutoya.random #=> Returns a random image from irasutoya
22
+ # Irasuto
23
+ irasuto = Irasutoya::Irasuto.random #=> returns Irasuto instance
24
+ irasuto.url
25
+ irasuto.title
26
+ irasuto.description
27
+ irasuto.image_url
28
+
29
+ irasuto_links = Irasutoya::Irasuto.search(query: 'おじさん', page: 3) #=> returns array of IrasutoLink instance
30
+
31
+ # Category
32
+ categories = Irasutoya::Category.all #=> returns array of Category instance
33
+ category = categories.first
34
+ category.title
35
+ category.list_url
36
+
37
+ irasuto_links = category.fetch_irasuto_links #=> returns array of IrasutoLink instance
38
+
39
+ # IrasutoLinks
40
+ irasuto_link = irasuto_links.first
41
+ irasuto_link.title
42
+ irasuto_link.show_url
43
+
44
+ irasutos = irasuto_link.fetch_irasuto #=> returns array of Irasuto instance
23
45
  ```
24
46
 
25
47
  ## Contributing
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency 'guard'
36
36
  spec.add_development_dependency 'guard-rspec'
37
37
  spec.add_development_dependency 'guard-rubocop'
38
- spec.add_development_dependency 'rake', '~> 10.0'
38
+ spec.add_development_dependency 'rake', '~> 12.3'
39
39
  spec.add_development_dependency 'rspec', '~> 3.0'
40
40
  spec.add_development_dependency 'rubocop'
41
41
  spec.add_development_dependency 'simplecov'
@@ -1,17 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'irasutoya/modules'
4
+
5
+ require 'irasutoya/category'
3
6
  require 'irasutoya/irasuto'
4
- require 'irasutoya/random_command'
7
+ require 'irasutoya/irasuto_link'
5
8
  require 'irasutoya/version'
9
+ require 'cgi'
6
10
  require 'json'
7
11
  require 'open-uri'
8
12
  require 'net/http'
9
13
  require 'nokogiri'
10
14
 
11
15
  module Irasutoya
12
- class << self
13
- def random
14
- RandomCommand.new.run
15
- end
16
- end
17
16
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irasutoya
4
+ class Category
5
+ include Modules::HasDocumentFetcher
6
+ include Modules::HasListPageParser
7
+
8
+ attr_reader :list_url, :title
9
+
10
+ def initialize(title:, list_url:)
11
+ @title = title
12
+ @list_url = list_url
13
+ end
14
+
15
+ class << self
16
+ def all # rubocop:disable Metrics/AbcSize
17
+ fetch_page_and_parse('https://www.irasutoya.com')
18
+ .css('#sidebar-wrapper')
19
+ .css('.widget')
20
+ .select { |w| w.search('h2').text == '詳細カテゴリー' }
21
+ .first
22
+ .css('a')
23
+ .map { |a| a.attribute('href').value }
24
+ .uniq
25
+ .select { |href| href.include?('label') }
26
+ .map { |href| Category.new(title: CGI.unescape(href.split('/')[5]), list_url: href) }
27
+ end
28
+ end
29
+
30
+ def fetch_irasuto_links
31
+ document = fetch_page_and_parse(list_url)
32
+ parse_list_page(document: document).map do |parsed|
33
+ IrasutoLink.new(title: parsed[:title], show_url: parsed[:show_url])
34
+ end
35
+ end
36
+ end
37
+ end
@@ -2,6 +2,10 @@
2
2
 
3
3
  module Irasutoya
4
4
  class Irasuto
5
+ include Modules::HasDocumentFetcher
6
+ include Modules::HasListPageParser
7
+ include Modules::HasShowPageParser
8
+
5
9
  attr_reader :url, :title, :description, :image_url
6
10
 
7
11
  def initialize(url:, title:, description:, image_url:)
@@ -10,5 +14,47 @@ module Irasutoya
10
14
  @description = description
11
15
  @image_url = image_url
12
16
  end
17
+
18
+ class << self
19
+ def random
20
+ url = random_url
21
+ document = fetch_page_and_parse(url)
22
+ parsed = parse_show_page(document: document)
23
+
24
+ Irasuto.new(url: url, title: parsed[:title], description: parsed[:description], image_url: parsed[:image_url])
25
+ end
26
+
27
+ def search(query:, page: 0)
28
+ url = if page.zero?
29
+ "https://www.irasutoya.com/search?q=#{CGI.escape query}"
30
+ else
31
+ "https://www.irasutoya.com/search?q=#{CGI.escape query}&max-results=20&start=#{page * 20}&by-date=false"
32
+ end
33
+
34
+ document = fetch_page_and_parse(url)
35
+ parse_list_page(document: document).map do |parsed|
36
+ IrasutoLink.new(title: parsed[:title], show_url: parsed[:show_url])
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def random_api_path
43
+ max_index = 22_208
44
+ luck = Random.rand(max_index)
45
+ "/feeds/posts/summary?start-index=#{luck}&max-results=1&alt=json-in-script"
46
+ end
47
+
48
+ def random_url
49
+ jsonp = Net::HTTP.get('www.irasutoya.com', random_api_path)
50
+ JSON.parse(jsonp[/{.+}/])
51
+ .dig('feed', 'entry')
52
+ .first
53
+ .dig('link')
54
+ .select { |link| link['rel'] == 'alternate' }
55
+ .first
56
+ .dig('href')
57
+ end
58
+ end
13
59
  end
14
60
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irasutoya
4
+ class IrasutoLink
5
+ include Modules::HasDocumentFetcher
6
+ include Modules::HasShowPageParser
7
+
8
+ attr_reader :title, :show_url
9
+
10
+ def initialize(title:, show_url:)
11
+ @title = title
12
+ @show_url = show_url
13
+ end
14
+
15
+ def fetch_irasuto
16
+ document = fetch_page_and_parse(show_url)
17
+ parsed = parse_show_page(document: document)
18
+
19
+ Irasuto.new(
20
+ url: show_url,
21
+ title: parsed[:title],
22
+ description: parsed[:description],
23
+ image_url: parsed[:image_url]
24
+ )
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'irasutoya/modules/has_document_fetcher'
4
+ require 'irasutoya/modules/has_list_page_parser'
5
+ require 'irasutoya/modules/has_show_page_parser'
6
+
7
+ module Irasutoya
8
+ module Modules
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irasutoya
4
+ module Modules
5
+ module HasDocumentFetcher
6
+ def self.included(klass)
7
+ klass.send(:include, Irasutoya::Modules::HasDocumentFetcher::Methods)
8
+ klass.send(:extend, Irasutoya::Modules::HasDocumentFetcher::Methods)
9
+ end
10
+
11
+ module Methods
12
+ def fetch_page_and_parse(url)
13
+ charset = nil
14
+ html = URI.parse(url).open do |f|
15
+ charset = f.charset
16
+ f.read
17
+ end
18
+ Nokogiri::HTML.parse(html, nil, charset)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irasutoya
4
+ module Modules
5
+ module HasListPageParser
6
+ def self.included(klass)
7
+ klass.send(:include, Irasutoya::Modules::HasListPageParser::Methods)
8
+ klass.send(:extend, Irasutoya::Modules::HasListPageParser::Methods)
9
+ end
10
+
11
+ module Methods
12
+ def parse_list_page(document:)
13
+ document.css('.box').map do |box|
14
+ {
15
+ title: PrivateMethods.title_from(box: box),
16
+ show_url: PrivateMethods.show_url_from(box: box)
17
+ }
18
+ end
19
+ end
20
+ end
21
+
22
+ module PrivateMethods
23
+ class << self
24
+ def title_from(box:)
25
+ box.css('a')[1].text
26
+ end
27
+
28
+ def show_url_from(box:)
29
+ box.css('a').first.attribute('href').value
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irasutoya
4
+ module Modules
5
+ module HasShowPageParser
6
+ def self.included(klass)
7
+ klass.send(:include, Irasutoya::Modules::HasShowPageParser::Methods)
8
+ klass.send(:extend, Irasutoya::Modules::HasShowPageParser::Methods)
9
+ end
10
+
11
+ module Methods
12
+ def parse_show_page(document:)
13
+ {
14
+ title: PrivateMethods.title_from(document: document),
15
+ description: PrivateMethods.description_from(document: document),
16
+ image_url: PrivateMethods.image_url_from(document: document)
17
+ }
18
+ end
19
+ end
20
+
21
+ module PrivateMethods
22
+ class << self
23
+ def title_from(document:)
24
+ document.css('.post').css('.title').search('h2').text.strip
25
+ end
26
+
27
+ def description_from(document:)
28
+ document.css('.entry').css('.separator')[1].text.strip
29
+ end
30
+
31
+ def image_url_from(document:)
32
+ image = document.css('.entry').search('img').attribute('src').value
33
+ image.chars.first == '/' ? 'http:' + image : image
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Irasutoya
4
- VERSION = '0.1.0'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: irasutoya
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuji Ueki
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '10.0'
103
+ version: '12.3'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '10.0'
110
+ version: '12.3'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: rspec
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -170,8 +170,13 @@ files:
170
170
  - Rakefile
171
171
  - irasutoya.gemspec
172
172
  - lib/irasutoya.rb
173
+ - lib/irasutoya/category.rb
173
174
  - lib/irasutoya/irasuto.rb
174
- - lib/irasutoya/random_command.rb
175
+ - lib/irasutoya/irasuto_link.rb
176
+ - lib/irasutoya/modules.rb
177
+ - lib/irasutoya/modules/has_document_fetcher.rb
178
+ - lib/irasutoya/modules/has_list_page_parser.rb
179
+ - lib/irasutoya/modules/has_show_page_parser.rb
175
180
  - lib/irasutoya/version.rb
176
181
  homepage: https://github.com/unhappychoice/irasutoya
177
182
  licenses:
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Irasutoya
4
- class RandomCommand
5
- MAX_INDEX = 22_208
6
-
7
- def run
8
- url = random_url
9
- document = fetch_page_and_parse(url)
10
-
11
- Irasuto.new(
12
- url: url,
13
- title: title_from(document: document),
14
- description: description_from(document: document),
15
- image_url: image_url_from(document: document)
16
- )
17
- end
18
-
19
- private
20
-
21
- def random_api_path
22
- luck = Random.rand(MAX_INDEX)
23
- "/feeds/posts/summary?start-index=#{luck}&max-results=1&alt=json-in-script"
24
- end
25
-
26
- def random_url
27
- jsonp = Net::HTTP.get('www.irasutoya.com', random_api_path)
28
- JSON.parse(jsonp[/{.+}/])
29
- .dig('feed', 'entry')
30
- .first
31
- .dig('link')
32
- .select { |link| link['rel'] == 'alternate' }
33
- .first
34
- .dig('href')
35
- end
36
-
37
- def fetch_page_and_parse(url)
38
- charset = nil
39
- html = URI.parse(url).open do |f|
40
- charset = f.charset
41
- f.read
42
- end
43
- Nokogiri::HTML.parse(html, nil, charset)
44
- end
45
-
46
- def title_from(document:)
47
- document.css('.post').css('.title').search('h2').text.strip
48
- end
49
-
50
- def description_from(document:)
51
- document.css('.entry').css('.separator')[1].text
52
- end
53
-
54
- def image_url_from(document:)
55
- image = document.css('.entry').search('img').attribute('src').value
56
- image.chars.first == '/' ? 'http:' + image : image
57
- end
58
- end
59
- end