kuroneko 0.1.2 → 0.1.3
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 +4 -4
- data/.gitignore +2 -0
- data/README.md +3 -3
- data/kuroneko.gemspec +1 -1
- data/lib/kuroneko.rb +12 -26
- data/lib/kuroneko/history.rb +23 -0
- data/lib/kuroneko/parser.rb +65 -0
- data/lib/kuroneko/status.rb +5 -24
- data/lib/kuroneko/version.rb +1 -1
- metadata +5 -4
- data/lib/kuroneko/status_history.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77730733c3b79fe9c08030b78bdc4a6a821c4213
|
4
|
+
data.tar.gz: 3f44605098b4d5640f6061d4aff376db87ebafc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baee97d63a719bb3c804c237b7abca909e38239d6f9543c3df3771329ffcd53ae5d71d440aec24f25483897b7afeba2e32fa996034b80b3416e66f658caa981f
|
7
|
+
data.tar.gz: 9ee44da7e7b1629548e8a26c419b02522cc31012cad205ee5becbae83f0735447a7b583bf5963c1697a2030cb6dc6d6a925ca14c1d29a37a6f7c21af52816882
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -54,10 +54,10 @@ status.to_h
|
|
54
54
|
|
55
55
|
``` ruby
|
56
56
|
history = neko.history("1234-5678-9012")
|
57
|
-
#=> #<Kuroneko::
|
57
|
+
#=> #<Kuroneko::History<Kuroneko::Status>>
|
58
58
|
```
|
59
59
|
|
60
|
-
- `
|
60
|
+
- `History` は `Array` を継承していて、以下を追加で実装しています。
|
61
61
|
- 履歴のうち最新の状態を返す `#latest`
|
62
62
|
- 伝票番号を返す `#number`
|
63
63
|
- `Kuroneko#histories` で複数を一度に照会でき、結果は `Array` で返されます。
|
@@ -79,7 +79,7 @@ history = neko.history("1234-5678-9012")
|
|
79
79
|
そのまま問い合わせに使用するため、クロネコヤマト側が受け付ける形式であれば
|
80
80
|
どのようなものでも可能です。
|
81
81
|
|
82
|
-
`Kuroneko::
|
82
|
+
`Kuroneko::History`, `Kuroneko::Status` から読み取る伝票番号は
|
83
83
|
照会結果から取得し、数字のみからなる __文字列__ で返ります。
|
84
84
|
|
85
85
|
## Contributing
|
data/kuroneko.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "kuroneko"
|
8
8
|
spec.version = Kuroneko::VERSION
|
9
9
|
spec.authors = ["wktk"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["wktk30@gmail.com"]
|
11
11
|
spec.description = %q{クロネコヤマトの荷物追跡を照会する}
|
12
12
|
spec.summary = spec.description
|
13
13
|
spec.homepage = "https://github.com/wktk/kuroneko"
|
data/lib/kuroneko.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'mechanize'
|
4
|
-
require 'kuroneko/
|
5
|
-
require 'kuroneko/status_history'
|
4
|
+
require 'kuroneko/parser'
|
6
5
|
require 'kuroneko/version'
|
7
6
|
|
8
7
|
# クロネコヤマトの荷物を追跡する
|
@@ -15,6 +14,9 @@ class Kuroneko
|
|
15
14
|
# @return [Mechanize] 使用する Mechanize インスタンス
|
16
15
|
attr_accessor :agent
|
17
16
|
|
17
|
+
# @return [#parse] ページを解析するパーサ
|
18
|
+
attr_accessor :parser
|
19
|
+
|
18
20
|
# @return [String] 問い合わせフォームの URL
|
19
21
|
attr_accessor :url
|
20
22
|
|
@@ -22,16 +24,18 @@ class Kuroneko
|
|
22
24
|
#
|
23
25
|
# @param [Hash] options
|
24
26
|
# @option options [Mechanize] :agent 使用する Mechanize インスタンス
|
27
|
+
# @option options [#parse] :parser ページを解析するパーサ
|
25
28
|
# @option options [String] :url 問い合わせフォームの URL
|
26
29
|
def initialize(options={})
|
27
30
|
@agent = options[:agent] || Mechanize.new
|
31
|
+
@parser = options[:parser] || Parser
|
28
32
|
@url = options[:url] || URL.dup
|
29
33
|
end
|
30
34
|
|
31
35
|
# 1 つの荷物の状態履歴を照会する
|
32
36
|
#
|
33
37
|
# @param [String, #to_s] number 伝票番号
|
34
|
-
# @return [Kuroneko::
|
38
|
+
# @return [Kuroneko::History<Kuroneko::Status>] 状態履歴
|
35
39
|
def history(number)
|
36
40
|
histories(number).first
|
37
41
|
end
|
@@ -39,12 +43,9 @@ class Kuroneko
|
|
39
43
|
# 複数の荷物の状態履歴を照会する
|
40
44
|
#
|
41
45
|
# @param [Array<String, #to_s>] numbers 伝票番号
|
42
|
-
# @return [Array<Kuroneko::
|
46
|
+
# @return [Array<Kuroneko::History<Kuroneko::Status>>] 状態履歴
|
43
47
|
def histories(*numbers)
|
44
|
-
numbers.flatten
|
45
|
-
results = []
|
46
|
-
results.concat(query(numbers.shift(10))) until numbers.empty?
|
47
|
-
results
|
48
|
+
numbers.flatten.each_slice(10).map { |n| query(n) }.flatten(1)
|
48
49
|
end
|
49
50
|
|
50
51
|
# 1 つの荷物の最新状態を照会する
|
@@ -65,22 +66,6 @@ class Kuroneko
|
|
65
66
|
|
66
67
|
private
|
67
68
|
|
68
|
-
# ページをから情報を抽出する
|
69
|
-
#
|
70
|
-
# @param [Mechanize::Page] page 照会結果のページ
|
71
|
-
# @return [Array<Kuroneko::StatusHistory<Kuroneko::Status>>] 状態履歴
|
72
|
-
def parse(page)
|
73
|
-
page.parser.css('table.saisin').map do |summary|
|
74
|
-
rows = summary.css('tr')
|
75
|
-
number = rows[0].css('td')[2].text.gsub(/\D/, '')
|
76
|
-
status = rows[1].css('td')[2].text
|
77
|
-
|
78
|
-
history = summary.parent.css('table.meisai').first
|
79
|
-
history ||= [Status.new(number, [status], true)] # 伝票番号誤りなど
|
80
|
-
StatusHistory.new(number, history)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
69
|
# フォームパラメータをセットする
|
85
70
|
#
|
86
71
|
# @param [Mechanize::Form] form
|
@@ -95,10 +80,10 @@ private
|
|
95
80
|
# リクエストを送信して状態を抽出する
|
96
81
|
#
|
97
82
|
# @param [Array<String, #to_s>] numbers 伝票番号
|
98
|
-
# @return [Array<Kuroneko::
|
83
|
+
# @return [Array<Kuroneko::History<Kuroneko::Status>>] 状態履歴
|
99
84
|
def query(numbers)
|
100
85
|
result_page = request(numbers)
|
101
|
-
parse(result_page)
|
86
|
+
parser.parse(result_page)
|
102
87
|
end
|
103
88
|
|
104
89
|
# 照会リクエストを送る
|
@@ -110,4 +95,5 @@ private
|
|
110
95
|
prepare_form(form, numbers)
|
111
96
|
form.submit
|
112
97
|
end
|
98
|
+
|
113
99
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class Kuroneko
|
4
|
+
# 状態履歴
|
5
|
+
class History < Array
|
6
|
+
# @return [String] 伝票番号
|
7
|
+
# @note 数字以外 (ハイフン等) は含まない
|
8
|
+
attr_reader :number
|
9
|
+
|
10
|
+
# @param [String] number 伝票番号
|
11
|
+
# @param [Array<Kuroneko::Status>] history 状態履歴
|
12
|
+
def initialize(number, history)
|
13
|
+
@number = number
|
14
|
+
super(history)
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Kuroneko::Status] 履歴のうち最新の状態
|
18
|
+
def latest
|
19
|
+
find(&:latest?) || last
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'kuroneko/history'
|
3
|
+
require 'kuroneko/status'
|
4
|
+
|
5
|
+
class Kuroneko
|
6
|
+
# ページからデータを抽出する
|
7
|
+
module Parser
|
8
|
+
class << self
|
9
|
+
# ページをから情報を抽出する
|
10
|
+
#
|
11
|
+
# @param [Mechanize::Page] page 照会結果のページ
|
12
|
+
# @return [Array<Kuroneko::History<Kuroneko::Status>>] 状態履歴
|
13
|
+
def parse_page(page)
|
14
|
+
page.parser.css('table.saisin').map(&method(:parse_history))
|
15
|
+
end
|
16
|
+
|
17
|
+
alias parse parse_page
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# 履歴情報を解析する
|
22
|
+
#
|
23
|
+
# @param [Nokogiri::XML::Element] summary <table class="saisin">
|
24
|
+
# @return [Kuroneko::History<Kuroneko::Status>] 状態履歴
|
25
|
+
def parse_history(summary)
|
26
|
+
number, status = parse_meta(summary)
|
27
|
+
statuses = summary.parent.css('table.meisai').first
|
28
|
+
statuses = statuses ? parse_statuses(statuses) : [[true, status]]
|
29
|
+
History.new(number, statuses.map { |s| Status.new(number, *s) })
|
30
|
+
end
|
31
|
+
|
32
|
+
# 伝票番号と最新状態名を抽出する
|
33
|
+
#
|
34
|
+
# @param [Nokogiri::XML::Element] summary <table class="saisin">
|
35
|
+
# @return [Array] 伝票番号, 最新状態名
|
36
|
+
def parse_meta(summary)
|
37
|
+
rows = summary.css('tr')
|
38
|
+
number = rows[0].css('td')[2].text.gsub(/\D/, '')
|
39
|
+
status = rows[1].css('td')[2].text
|
40
|
+
[number, status]
|
41
|
+
end
|
42
|
+
|
43
|
+
# 状態を解析する
|
44
|
+
#
|
45
|
+
# @param [Nokogiri::XML::Element] status 状態情報のテーブル行
|
46
|
+
# @return [Array] Kuroneko::Status への引数
|
47
|
+
def parse_status(status)
|
48
|
+
attrs = status.css('td').to_a
|
49
|
+
latest = attrs.shift.css('img').attribute('alt').value == '最新'
|
50
|
+
[latest] + attrs.map(&:text)
|
51
|
+
end
|
52
|
+
|
53
|
+
# 状態履歴テーブルを解析する
|
54
|
+
#
|
55
|
+
# @param [Nokogiri::XML::Element] table <table class="meisai">
|
56
|
+
# @return [Array<Array>] Kuroneko::Status への引数
|
57
|
+
def parse_statuses(table)
|
58
|
+
statuses = table.css('tr').to_a
|
59
|
+
statuses.shift
|
60
|
+
statuses.map(&method(:parse_status))
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/kuroneko/status.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class Kuroneko
|
4
4
|
# 状態情報
|
5
|
-
Status = Struct.new(:number, :status, :date, :time, :branch, :branch_code)
|
5
|
+
Status = Struct.new(:number, :latest, :status, :date, :time, :branch, :branch_code)
|
6
6
|
|
7
7
|
class Status
|
8
8
|
# @!attribute number
|
@@ -11,6 +11,9 @@ class Kuroneko
|
|
11
11
|
# "123456789012"
|
12
12
|
# @note 数字以外 (ハイフン等) は含まない
|
13
13
|
|
14
|
+
# @!attribute latest
|
15
|
+
# @return [Boolean] 最新の状態であるか
|
16
|
+
|
14
17
|
# @!attribute status
|
15
18
|
# @return [String] 状態名
|
16
19
|
# @example
|
@@ -36,30 +39,8 @@ class Kuroneko
|
|
36
39
|
# @example
|
37
40
|
# "030990"
|
38
41
|
|
39
|
-
# @param [String] number 伝票番号
|
40
|
-
# @param [Nokogiri::XML::Element] status 状態情報のテーブル行
|
41
|
-
# @param [Boolean] latest 最新の状態であるか
|
42
|
-
def initialize(number, status, latest=nil)
|
43
|
-
super(number, *parse(status))
|
44
|
-
@latest = latest unless latest.nil?
|
45
|
-
end
|
46
|
-
|
47
42
|
# @return [Boolean] 最新の状態であるか
|
48
|
-
|
49
|
-
@latest
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
43
|
+
alias latest? latest
|
53
44
|
|
54
|
-
# 状態を解析する
|
55
|
-
#
|
56
|
-
# @param [Nokogiri::XML::Element] status 状態情報のテーブル行
|
57
|
-
# @return [Array<String>] 状態
|
58
|
-
def parse(status)
|
59
|
-
return status unless status.is_a?(Nokogiri::XML::Element)
|
60
|
-
attrs = status.css('td').to_a
|
61
|
-
@latest = attrs.shift.css('img').attribute('alt').value == '最新'
|
62
|
-
attrs.map!(&:text)
|
63
|
-
end
|
64
45
|
end
|
65
46
|
end
|
data/lib/kuroneko/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kuroneko
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- wktk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
description: "クロネコヤマトの荷物追跡を照会する"
|
56
56
|
email:
|
57
|
-
-
|
57
|
+
- wktk30@gmail.com
|
58
58
|
executables: []
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
@@ -67,8 +67,9 @@ files:
|
|
67
67
|
- kuroneko.gemspec
|
68
68
|
- lib/kuroneko.rb
|
69
69
|
- lib/kuroneko/en.rb
|
70
|
+
- lib/kuroneko/history.rb
|
71
|
+
- lib/kuroneko/parser.rb
|
70
72
|
- lib/kuroneko/status.rb
|
71
|
-
- lib/kuroneko/status_history.rb
|
72
73
|
- lib/kuroneko/version.rb
|
73
74
|
homepage: https://github.com/wktk/kuroneko
|
74
75
|
licenses:
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
class Kuroneko
|
4
|
-
# 状態履歴
|
5
|
-
class StatusHistory < Array
|
6
|
-
# @return [String] 伝票番号
|
7
|
-
# @note 数字以外 (ハイフン等) は含まない
|
8
|
-
attr_reader :number
|
9
|
-
|
10
|
-
# @param [String] number 伝票番号
|
11
|
-
# @param [Nokogiri::XML::Element] table 状態履歴テーブル
|
12
|
-
def initialize(number, table)
|
13
|
-
@number = number
|
14
|
-
super(parse(table))
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Kuroneko::Status] 履歴のうち最新の状態
|
18
|
-
def latest
|
19
|
-
find(&:latest?) || last
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
# 状態履歴テーブルを解析する
|
25
|
-
#
|
26
|
-
# @param [Nokogiri::XML::Element] table 状態履歴テーブル
|
27
|
-
# @return [Array<Kuroneko::Status>] 状態
|
28
|
-
def parse(table)
|
29
|
-
return table unless table.is_a?(Nokogiri::XML::Element)
|
30
|
-
statuses = table.css('tr').to_a
|
31
|
-
statuses.shift
|
32
|
-
statuses.map! { |status| Status.new(number, status) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|