web_loader 1.0.0 → 1.1.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: e1fe1994ad1ca0d18274d7f0498b0ae77843add60e1df9f5a5819ac72dc01441
4
- data.tar.gz: 3ee07c0916b00959d4aa3a7dc335606f4dee1ede3145b9590033727a20cf087f
3
+ metadata.gz: 1055ef0181a8f0e5857172c56783111bff1d102686f006c001e5b4b2627e65cb
4
+ data.tar.gz: da2499a388951ecc7d0c525442b847da0be5e32ab2b478dd8ae2338e6e0772de
5
5
  SHA512:
6
- metadata.gz: c05ee95ceab00acb361428458c71129b2800b49a6208ec919213ea5f95c44ed15e8df7335e5a9239db5a70e2d2748f3ca5759f8ff947a6633c479630dde59f19
7
- data.tar.gz: ff8cf4fb8a9ace8d6831279ef2fd28eae61935e31f7653da669d5b1961212e49e63fbcda1693de92803625f019edd4fc99e1f1f606f8f3fc2d32820fe3fe9ebc
6
+ metadata.gz: 2e7e1b93c5af2ad6280843558fc89aba4014313c2fbb2999d0148749e20966bf05dcadc1e48bd8e46791feca2c7d78c6c3b99977778da667b36bd32964046ae6
7
+ data.tar.gz: 319950bb1a184a361e215805aa49b7dfa661f28bf3d98b28d6baa3124627dd2a4c217762409c75bb375f8e12494c117863b4358319fab02c4682349a79eeeaaf
data/.idea/misc.xml CHANGED
@@ -1,4 +1,3 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
1
  <project version="4">
3
2
  <component name="ProjectRootManager" version="2" project-jdk-name="rbenv: 3.1.4" project-jdk-type="RUBY_SDK">
4
3
  <output url="file://$PROJECT_DIR$/out" />
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- web_loader (1.0.0)
4
+ web_loader (1.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -9,6 +9,9 @@ module WebLoader
9
9
 
10
10
  USER_AGENT = "WebLoader"
11
11
  CACHE_DIR = './cache'
12
+ DEFAULT_RETRY = 3
13
+ DEFAULT_REDIRECT = 10
14
+ DEFAULT_SLEEP = 10
12
15
 
13
16
  def self.save_image(url, file)
14
17
  # キャッシュせず単に保存する
@@ -31,9 +34,15 @@ module WebLoader
31
34
  attr_reader :load_cache_page
32
35
  attr_accessor :use_cache, :cache_dir, :binary, :user_agent, :verbose
33
36
 
34
- def load(url, limit = 10)
35
- raise ArgumentError, 'HTTP redirect too deep' if limit == 0
37
+ def load_retry(url, retry_count = DEFAULT_RETRY)
38
+ load(url, DEFAULT_REDIRECT, retry_count)
39
+ end
40
+
41
+ def load(url, redirect_count = DEFAULT_REDIRECT, retry_count = 0)
42
+ raise ArgumentError, 'HTTP redirect too deep' if redirect_count == 0
36
43
  log("Load: #{url}", @verbose)
44
+
45
+ ##### キャッシュの読み込み
37
46
  @load_cache_page = false
38
47
  content = try_load_cache(url)
39
48
  if content
@@ -41,6 +50,8 @@ module WebLoader
41
50
  @load_cache_page = true
42
51
  return content
43
52
  end
53
+
54
+ ##### サーバーからロード
44
55
  log("Load server: #{url}", @verbose)
45
56
  uri = URI.parse(url)
46
57
  http = Net::HTTP.new(uri.host, uri.port)
@@ -48,7 +59,20 @@ module WebLoader
48
59
  http.use_ssl = true
49
60
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
50
61
  end
51
- response, = http.get(uri.request_uri, 'User-Agent' => @user_agent) # request_uri=path + '?' + query
62
+ response = nil
63
+ begin
64
+ response = http.get(uri.request_uri, 'User-Agent' => @user_agent) # request_uri=path + '?' + query
65
+ rescue Net::ReadTimeout
66
+ # タイムアウトした場合リトライ可能ならばsleepした後に再度ロード実行
67
+ log("Read timeout: #{url}", @verbose)
68
+ if retry_count > 0
69
+ sleep DEFAULT_SLEEP
70
+ return load(url, redirect_count , retry_count - 1)
71
+ end
72
+ end
73
+
74
+ ##### レスポンスの処理
75
+ result = nil
52
76
  case response
53
77
  when Net::HTTPSuccess
54
78
  # responseがNet::HTTPSuccessのサブクラスの場合成功とみなし読み込んだ内容を返す
@@ -64,14 +88,29 @@ module WebLoader
64
88
  log("Write cache: #{url}", @verbose)
65
89
  Cache.write(@cache_dir, url, response.code, body)
66
90
  end
67
- return body
91
+ result = body
68
92
  when Net::HTTPRedirection
69
- load(to_redirect_url(uri, response['location']), limit - 1)
93
+ result = load(to_redirect_url(uri, response['location']), redirect_count - 1)
70
94
  else
71
- log("error #{url}", true)
95
+ # 上記以外のレスポンスの場合、リトライ可能ならばsleepした後に再度ロード実行
96
+ if retry_count > 0
97
+ sleep_for = 10
98
+ if response.is_a?(Net::HTTPTooManyRequests)
99
+ # HTTPTooManyRequestsならばretry-afterで指定された値を取得。
100
+ sleep_for = response.header['retry-after'].to_i + 10
101
+ log("Rate limit: #{uri} #{response.header.to_hash} (429 Too Many Requests). Sleeping #{sleep_for} seconds and retry (##{retry_count}).", @verbose)
102
+ else
103
+ log("Unknown response: #{uri} #{response.inspect}. Sleeping #{sleep_for} seconds and retry (##{retry_count}).", @verbose)
104
+ end
105
+ sleep sleep_for
106
+ result = load(url, redirect_count , retry_count - 1)
107
+ end
108
+
72
109
  # それ以外は対応した例外を発生
110
+ log("error #{url}", true)
73
111
  response.value
74
112
  end
113
+ result
75
114
  end
76
115
 
77
116
  private
@@ -1,34 +1,36 @@
1
1
  module WebLoader
2
2
  module Utils
3
3
  UTF_8 = 'UTF-8'
4
- def toutf8(str, response_encoding)
4
+
5
+ def toutf8_charset(str, charset)
6
+ # charsetが指定されていない場合はnil
7
+ return nil if charset.to_s.length == 0
8
+ # 文字列のcharsetを変更する
9
+ str.force_encoding(charset)
10
+ # force_encodingが失敗した場合はnil
11
+ return nil unless str.valid_encoding?
12
+
13
+ result = nil
14
+ if charset =~ /#{UTF_8}/i
15
+ result = str
16
+ else
17
+ # エンコーディングがUTF8じゃない場合変換する
18
+ result = str.encode(UTF_8, invalid: :replace, undef: :replace)
19
+ end
20
+ result
21
+ end
22
+
23
+ def toutf8(str, charset)
5
24
  # 2022/04/04(月)
6
25
  # GITHUBのアポストロフィ(&#x2019 U+2019)が文字化け問題に対処するために新設。
7
26
  # 原因は直接Kconv.toutf8にresponse.bodyをわたしていたことなので(Kconvのguessが失敗していたと思われる)、
8
27
  # response.type_paramsを見てそれにforce_encodingすることで対処する。渡されているcharsetとWebページの文字コードが一致していればこれで問題はないはず。
9
- org_str = str.dup
10
- result = str
28
+ result = nil
11
29
  begin
12
- if response_encoding.to_s.length > 0 # nilでないかつ長さが0以上
13
- # responseで指定された文字コードであるとみなす
14
- str.force_encoding(response_encoding)
15
- if str.valid_encoding?
16
- # 指定された文字コードとみなせた場合
17
- if response_encoding != UTF_8
18
- # エンコーディングがUTF8じゃない場合返還する
19
- result = str.encode(UTF_8, invalid: :replace, undef: :replace)
20
- else
21
- # UTF8の場合そのまま
22
- result = str
23
- end
24
- else
25
- # 指定された文字コードとみなせない場合元の文字列を返す
26
- result = org_str
27
- end
28
- else
29
- # responseで文字コードが指定されていない場合Kconvを使用
30
- result = Kconv.toutf8(str)
31
- end
30
+ # 指定されたcharsetで変換する
31
+ result = toutf8_charset(str.dup, charset)
32
+ # charsetによる変換が失敗した場合Kconvを使用
33
+ result = Kconv.toutf8(str) if result.nil?
32
34
  rescue => ex
33
35
  puts ex.message
34
36
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebLoader
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
data/web_loader.iml CHANGED
@@ -7,7 +7,48 @@
7
7
  </content>
8
8
  <orderEntry type="inheritedJdk" />
9
9
  <orderEntry type="sourceFolder" forTests="false" />
10
- <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, rbenv: 3.1.4) [gem]" level="application" />
10
+ <orderEntry type="module-library">
11
+ <library name="minitest (v5.19.0) [path][gem]" type="rubylib">
12
+ <properties>
13
+ <option name="version" value="4" />
14
+ </properties>
15
+ <CLASSES>
16
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/minitest-5.19.0/lib" />
17
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/minitest-5.19.0/test" />
18
+ </CLASSES>
19
+ <JAVADOC />
20
+ <SOURCES>
21
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/minitest-5.19.0/lib" />
22
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/minitest-5.19.0/test" />
23
+ </SOURCES>
24
+ <excluded>
25
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/minitest-5.19.0/test" />
26
+ </excluded>
27
+ </library>
28
+ </orderEntry>
29
+ <orderEntry type="module-library">
30
+ <library name="rake (v13.0.6) [path][gem]" type="rubylib">
31
+ <properties>
32
+ <option name="version" value="4" />
33
+ </properties>
34
+ <CLASSES>
35
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/doc" />
36
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/exe" />
37
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib" />
38
+ </CLASSES>
39
+ <JAVADOC />
40
+ <SOURCES>
41
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/doc" />
42
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/exe" />
43
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/lib" />
44
+ </SOURCES>
45
+ <excluded>
46
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/doc" />
47
+ <root url="file://$MODULE_DIR$/vendor/bundle/ruby/3.1.0/gems/rake-13.0.6/exe" />
48
+ </excluded>
49
+ </library>
50
+ </orderEntry>
51
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v2.4.19, rbenv: 3.1.4) [gem]" level="application" />
11
52
  </component>
12
53
  <component name="RakeTasksCache">
13
54
  <option name="myRootTask">
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - src
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-09-04 00:00:00.000000000 Z
11
+ date: 2023-10-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Web loader.
14
14
  email: