irasutoya 0.1.0 → 1.0.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
  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