kuroneko 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|