manga-tools 0.1.1 → 0.1.2

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: 00e79a7d0c8e37ab036decdaba2d9cd556d97256a523a59d6af0c1c63c07d2b5
4
- data.tar.gz: 46a97ec12c433b9ce51ee222d82df047edc3b8f311304149dd8d3e9a946b27d3
3
+ metadata.gz: da4ed03340c47790056a5ffeaa86a4f986010d8dfcb7c8fd87568300c9f66e30
4
+ data.tar.gz: a4f1644d7fca880a904463bf10376c86aaac49aac3a2233ec323ee8d0287bc42
5
5
  SHA512:
6
- metadata.gz: 3635bfe7dd5cd5c4093fb8281d8137e34c4a3c551c4e377e7332f6712a933190f0515d1159e56bfb78bc6ea917226b6561f1d053afdc5d1b805e4a5e417e9454
7
- data.tar.gz: 6170c78319d8e7a74ed93860dde010b87b23c9281385bb65bfeec4af5eb2c9c51f02ceb771797126c9365f9b3295d8d5b4db5b812e16dc3af3e022f33cba45bd
6
+ metadata.gz: 94e0f51017fd81f30360f03ec4c29cf82318401e507dc267cc354e6e4cba43278b5161e3b12f3af4f0ecfdc2e4dc21af6e8f0c10c0f0ea5b4fd22fb96f06e4dc
7
+ data.tar.gz: 45d686425259594ae0e45114f8e7d70970df515db271f3c3c6dee8c6316c83deaa8d844a6be9b199abe7fe1854032a127a56eed64e2da785245281b8dafbca15
data/Gemfile CHANGED
@@ -6,7 +6,6 @@ source 'https://rubygems.org'
6
6
  gemspec
7
7
 
8
8
  gem 'faraday'
9
- gem 'nokogiri'
10
9
  gem 'pry'
11
10
  gem 'rake', require: false
12
11
  gem 'rspec'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- manga-tools (0.1.1)
4
+ manga-tools (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -14,10 +14,7 @@ GEM
14
14
  multipart-post (>= 1.2, < 3)
15
15
  json (2.3.1)
16
16
  method_source (1.0.0)
17
- mini_portile2 (2.4.0)
18
17
  multipart-post (2.1.1)
19
- nokogiri (1.10.10)
20
- mini_portile2 (~> 2.4.0)
21
18
  parallel (1.19.2)
22
19
  parser (2.7.1.4)
23
20
  ast (~> 2.4.1)
@@ -67,7 +64,6 @@ PLATFORMS
67
64
  DEPENDENCIES
68
65
  faraday
69
66
  manga-tools!
70
- nokogiri
71
67
  pry
72
68
  rake
73
69
  rspec
data/README.md CHANGED
@@ -1,13 +1,10 @@
1
1
  # Manga::Tools
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/manga-tools.svg)](https://badge.fury.io/rb/manga-tools)
3
4
  ![Ruby](https://github.com/yagihiro/manga-tools/workflows/Ruby/badge.svg)
4
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/e2797c91a0bd6f521905/maintainability)](https://codeclimate.com/github/yagihiro/manga-tools/maintainability)
5
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/e2797c91a0bd6f521905/test_coverage)](https://codeclimate.com/github/yagihiro/manga-tools/test_coverage)
6
7
 
7
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/manga/tools`. To experiment with that code, run `bin/console` for an interactive prompt.
8
-
9
- TODO: Delete this and the text above, and describe your gem
10
-
11
8
  ## Installation
12
9
 
13
10
  Add this line to your application's Gemfile:
@@ -26,7 +23,11 @@ Or install it yourself as:
26
23
 
27
24
  ## Usage
28
25
 
29
- TODO: Write usage instructions here
26
+ * A search command to find out the release date of a manga
27
+
28
+ ```
29
+ $ manga-tools search "ONE PIECE"
30
+ ```
30
31
 
31
32
  ## Development
32
33
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'tools/cache'
4
3
  require_relative 'tools/cli'
5
4
  require_relative 'tools/http'
6
5
  require_relative 'tools/version'
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
- require 'nokogiri'
5
- require 'stringio'
6
4
  require 'thor'
5
+ require_relative 'http'
7
6
 
8
7
  module Manga
9
8
  module Tools
@@ -13,150 +12,18 @@ module Manga
13
12
  true
14
13
  end
15
14
 
16
- # desc "pub {name}", "publication date of {name}"
17
- # def pub(name)
18
- # doc = Nokogiri::HTML(
19
- # URI.open('https://tsutaya.tsite.jp/feature/book/release/comic/index', 'User-Agent' => UserAgent)
20
- # )
21
- #
22
- # File.open('.index.txt', 'w') {|f| f.write doc }
23
- #
24
- # results = {}
25
- #
26
- # current_date = ''
27
- # state = :title
28
- # current_data = {}
29
- # doc.css('h3, div.comic_list div.c_cols-1of3 span').each do |element|
30
- # case element.name
31
- # when 'h3'
32
- # results[element.content] = []
33
- # current_date = element.content
34
- # when 'span'
35
- # current_data[state] = element.content
36
- # case state
37
- # when :title
38
- # state = :author
39
- # when :author
40
- # state = :label
41
- # when :label
42
- # state = :title
43
- # results[current_date] << current_data
44
- # current_data = {}
45
- # end
46
- # end
47
- # end
48
- #
49
- # puts JSON.pretty_generate(results)
50
- # end
51
-
52
- desc 'search WORD', 'Search for a given WORD'
15
+ desc 'search WORD', 'Search titles for a given WORD'
53
16
  def search(word)
54
- Manga::Tools::Cache.init
55
-
56
- t = Time.now
57
- url = "https://calendar.gameiroiro.com/manga.php?year=#{t.year}&month=#{t.month}"
58
- data = Manga::Tools::Cache.fetch(key: url) do |cache|
59
- res = Manga::Tools::Http.get(url)
60
- cache.expires_in = Manga::Tools::Http.seconds_to_cache(res)
61
- results = generate_internal_data(t, res.body)
62
- results.to_json
63
- end
64
-
65
- hash = JSON.parse(data)
17
+ url = "https://manga-tools-server.herokuapp.com/publications?keyword=#{CGI.escape(word)}"
18
+ res = Manga::Tools::Http.get(url)
19
+ results = JSON.parse(res.body)
66
20
 
67
21
  puts "Searching '#{word}' ..."
68
- hash.each do |date, items|
69
- next if items.empty?
70
-
71
- items.each do |item|
72
- puts "Found: #{date}, #{item['title']}" if item['title'].index(word)
73
- end
22
+ results.each do |item|
23
+ puts "#{item['published_at']}: #{item['title']}"
74
24
  end
75
25
  puts 'Finished.'
76
26
  end
77
-
78
- private
79
-
80
- # @param time [Time] a target time
81
- # @param data [String] a string of HTTP response body.
82
- def generate_internal_data(time, data)
83
- doc = Nokogiri::HTML(StringIO.open(data))
84
-
85
- results = {}
86
- current_date = nil
87
- state = :genre
88
- data = {}
89
- doc.css(targets.join(', ')).each do |element|
90
- value = rm_spaces(element.content)
91
- case element.name
92
- when 'td'
93
- current_date = format('%<ym>s/%<day>02d', ym: time.strftime('%Y/%m'), day: value.to_i)
94
- results[current_date] = []
95
- when 'p', 'a'
96
- case state
97
- when :genre
98
- guard_genre(element)
99
- data[state] = value
100
- state = :title
101
- when :title
102
- guard_title(element)
103
- data[state] = value
104
- data[:link] = element['href']
105
- state = :company
106
- when :company
107
- guard_company(element)
108
- data[state] = value
109
- state = :authors
110
- when :authors
111
- guard_authors(element)
112
- data[state] = value
113
- state = :genre
114
- results[current_date] << data
115
- data = {}
116
- end
117
- end
118
- rescue StandardError
119
- # when authors, authors may not be present.
120
- if state == :authors
121
- data[state] = ''
122
- state = :genre
123
- results[current_date] << data
124
- data = {}
125
- end
126
- retry
127
- end
128
-
129
- results
130
- end
131
-
132
- def targets
133
- @targets ||= [
134
- 'td.day-td',
135
- 'div.product-description-right p.p-genre',
136
- 'div.product-description-right a',
137
- 'div.product-description-right p.p-company'
138
- ]
139
- end
140
-
141
- # Remove HTML spaces (&nbsp;) and white spaces.
142
- # @param str [String] a string
143
- def rm_spaces(str)
144
- str.gsub("\u00A0", '').strip
145
- end
146
-
147
- def guard_genre(element)
148
- raise 'invalid state' unless element.name == 'p' && element['class'] == 'p-genre'
149
- end
150
-
151
- def guard_title(element)
152
- raise 'invalid state' unless element.name == 'a'
153
- end
154
-
155
- def guard_company(element)
156
- raise 'invalid state' unless element.name == 'p' && element['class'] == 'p-company'
157
- end
158
-
159
- alias guard_authors guard_company
160
27
  end
161
28
  end
162
29
  end
@@ -2,23 +2,20 @@
2
2
 
3
3
  require 'faraday'
4
4
  require 'uri'
5
+ require_relative 'version'
5
6
 
6
7
  module Manga
7
8
  module Tools
8
9
  # HTTP client class
9
10
  module Http
10
- # rubocop:disable Layout/LineLength
11
- UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'
12
- # rubocop:enable Layout/LineLength
13
-
14
11
  # @param url [String] an url string, eg: `https://example.com`
15
12
  # @return [Faraday::Connection] a connection object
16
13
  def self.connection(url)
17
14
  @connection ||= Faraday.new(
18
15
  url: url,
19
- headers: { 'User-Agent' => UA }
16
+ headers: { 'User-Agent' => user_agent }
20
17
  ) do |f|
21
- f.response :logger
18
+ # f.response :logger
22
19
  end
23
20
  end
24
21
 
@@ -40,6 +37,10 @@ module Manga
40
37
 
41
38
  Regexp.last_match(1).to_i
42
39
  end
40
+
41
+ def self.user_agent
42
+ @user_agent ||= "manga-tools #{Manga::Tools::VERSION}"
43
+ end
43
44
  end
44
45
  end
45
46
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Manga
4
4
  module Tools
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: manga-tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroki Yagita
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-09 00:00:00.000000000 Z
11
+ date: 2020-08-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Tools to support the automation of daily manga-related activities.
14
14
  email:
@@ -34,7 +34,6 @@ files:
34
34
  - bin/setup
35
35
  - exe/manga-tools
36
36
  - lib/manga/tools.rb
37
- - lib/manga/tools/cache.rb
38
37
  - lib/manga/tools/cli.rb
39
38
  - lib/manga/tools/http.rb
40
39
  - lib/manga/tools/version.rb
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'digest/md5'
4
- require 'fileutils'
5
-
6
- module Manga
7
- module Tools
8
- # Cache class
9
- class Cache
10
- class << self
11
- # Initialize cache
12
- def init
13
- FileUtils.mkdir_p(cache_current_year_dir)
14
- end
15
-
16
- def root_dir
17
- @root_dir ||= "#{Dir.home}/.manga-tools"
18
- end
19
-
20
- def cache_root_dir
21
- @cache_root_dir ||= "#{root_dir}/cache"
22
- end
23
-
24
- def cache_current_year_dir
25
- @cache_current_year_dir ||= "#{cache_root_dir}/#{Time.now.year}"
26
- end
27
-
28
- # @return [Integer] default expires in seconds (1day)
29
- def default_expires_in
30
- @default_expires_in ||= 1 * 24 * 60 * 60
31
- end
32
-
33
- # @param key [String] A key to generate a key for the cache
34
- # @return [String] string of cached data
35
- def fetch(key:)
36
- raise ArgumentError, 'mast pass a block' unless block_given?
37
-
38
- cache = new(key)
39
- # cache.clear
40
- return cache.load_data if cache.available?
41
-
42
- result = yield(cache)
43
- cache.save_meta_data
44
- cache.save_data(result)
45
- result
46
- end
47
- end
48
-
49
- # @return [Integer|nil] A cache deadline in seconds.
50
- attr_accessor :expires_in
51
- # @return [String] A key to generate a key for the cache.
52
- attr_reader :key
53
- # @return [String] A key for the cache.
54
- attr_reader :cache_key
55
- # @return [String] A path to the cache metadata file.
56
- attr_reader :meta_file_path
57
- # @return [String] A path to the cached data file.
58
- attr_reader :data_file_path
59
-
60
- # @param key [String] A key to generate a key for the cache.
61
- def initialize(key)
62
- raise ArgumentError, 'mast pass the key param' unless key
63
-
64
- @expires_in = self.class.default_expires_in
65
- @key = key
66
- @cache_key = Digest::MD5.hexdigest(key)
67
- @meta_file_path = "#{self.class.cache_current_year_dir}/#{@cache_key}"
68
- @data_file_path = "#{@meta_file_path}.data"
69
- end
70
-
71
- # @return [Boolean] True if a cache is available, otherwise return false.
72
- def available?
73
- t = File.mtime(meta_file_path)
74
- saved_expires_in = File.read(meta_file_path).strip.to_i
75
-
76
- Time.now <= (t + saved_expires_in)
77
- rescue StandardError
78
- false
79
- end
80
-
81
- # @return [String] Reads and returns the cache data.
82
- def load_data
83
- File.read(data_file_path)
84
- end
85
-
86
- # Save the metadata for the cache.
87
- def save_meta_data
88
- @expires_in = self.class.default_expires_in unless expires_in
89
-
90
- File.open(meta_file_path, 'w') do |f|
91
- f.write(expires_in.to_s)
92
- end
93
-
94
- self
95
- end
96
-
97
- # @param str [String] Save the specified cache data
98
- def save_data(str)
99
- File.open(data_file_path, 'w') do |f|
100
- f.write(str.force_encoding('utf-8'))
101
- end
102
-
103
- self
104
- end
105
-
106
- # for debug
107
- def clear
108
- File.delete(meta_file_path) if File.exist?(meta_file_path)
109
- File.delete(data_file_path) if File.exist?(data_file_path)
110
- end
111
- end
112
- end
113
- end