kuroneko 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bf2d1cc3857d488435e9c5efa8ce9b6523e848ad
4
+ data.tar.gz: 272673dc919d28a7577b4ef66b4b7cd320401c5c
5
+ SHA512:
6
+ metadata.gz: 93cd11cea58a67c145aa1e415e5b9355d3ea6c262aa81f058ad09d9e302121838ec7114f348128119d3cdbed7c36192aa686115e2238e3ff437aec3c38f8121a
7
+ data.tar.gz: 35bdec0ab36607c3eaa837d73ece53cd1b561837be441b003d6d543c68d991e3ef4ab362f4e3c1d5e29293dbe9443055ebc37287d4a88456c02b7e5a6288f271
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kuroneko.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 wktk
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Kuroneko
2
+
3
+ クロネコヤマトの荷物追跡を照会する
4
+
5
+ See also: http://toi.kuronekoyamato.co.jp/cgi-bin/tneko
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'kuroneko'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install kuroneko
20
+
21
+ ## Usage
22
+
23
+ ``` ruby
24
+ require "kuroneko"
25
+
26
+ neko = Kuroneko.new
27
+
28
+ # 1 つの荷物の状態履歴
29
+ history = neko.history("1234-5678-9012")
30
+
31
+ # 複数の荷物の状態履歴
32
+ histories = neko.histories("1234-5678-9012", "1234-5678-9013", ... )
33
+
34
+ # 1 つの荷物の最新状態
35
+ status = neko.status("1234-5678-9012")
36
+ # OR
37
+ status = history.latest
38
+ status = history.find(&:latest?)
39
+
40
+ # 複数の荷物の最新状態
41
+ statuses = neko.statuses("1234-5678-9012", "1234-5678-9013", ... )
42
+
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/kuroneko.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kuroneko/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kuroneko"
8
+ spec.version = Kuroneko::VERSION
9
+ spec.authors = ["wktk"]
10
+ spec.email = ["mail@wktk.jp"]
11
+ spec.description = %q{クロネコヤマトの荷物追跡を照会する}
12
+ spec.summary = spec.description
13
+ spec.homepage = "https://github.com/wktk/kuroneko"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "mechanize", "~> 2.7"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,65 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ class Kuroneko
4
+ # 状態情報
5
+ Status = Struct.new(:number, :status, :date, :time, :branch, :branch_code)
6
+
7
+ class Status
8
+ # @!attribute number
9
+ # @return [String] 伝票番号
10
+ # @example
11
+ # "123456789012"
12
+ # @note 数字以外 (ハイフン等) は含まない
13
+
14
+ # @!attribute status
15
+ # @return [String] 状態名
16
+ # @example
17
+ # "配達完了"
18
+
19
+ # @!attribute date
20
+ # @return [String] 状態発生日
21
+ # @example
22
+ # "12/31"
23
+
24
+ # @!attribute time
25
+ # @return [String] 状態発生時刻
26
+ # @example
27
+ # "12:59"
28
+
29
+ # @!attribute branch
30
+ # @return [String] 担当店
31
+ # @example
32
+ # "北東京ベース店"
33
+
34
+ # @!attribute branch_code
35
+ # @return [String] 担当店コード
36
+ # @example
37
+ # "030990"
38
+
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
+ # @return [Boolean] 最新の状態であるか
48
+ def latest?
49
+ @latest
50
+ end
51
+
52
+ private
53
+
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! { |elem| elem.text.encode('utf-8') }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
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
@@ -0,0 +1,4 @@
1
+ class Kuroneko
2
+ # @return [String] バージョン
3
+ VERSION = '0.0.1'
4
+ end
data/lib/kuroneko.rb ADDED
@@ -0,0 +1,110 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'mechanize'
4
+ require 'kuroneko/status'
5
+ require 'kuroneko/status_history'
6
+ require 'kuroneko/version'
7
+
8
+ # クロネコヤマトの荷物を追跡する
9
+ #
10
+ # @see http://toi.kuronekoyamato.co.jp/cgi-bin/tneko
11
+ class Kuroneko
12
+ # @return [Mechanize] 使用する Mechanize インスタンス
13
+ attr_accessor :agent
14
+
15
+ # @return [String] 問い合わせフォームの URL
16
+ attr_accessor :url
17
+
18
+ # インスタンスを初期化する
19
+ #
20
+ # @param [Hash] options
21
+ # @option options [Mechanize] :agent 使用する Mechanize インスタンス
22
+ # @option options [String] :url 問い合わせフォームの URL
23
+ def initialize(options={})
24
+ @agent = options[:agent] || Mechanize.new
25
+ @url = options[:url] || 'http://toi.kuronekoyamato.co.jp/cgi-bin/tneko'
26
+ end
27
+
28
+ # 1 つの荷物の状態履歴を照会する
29
+ #
30
+ # @param [String, #to_s] number 伝票番号
31
+ # @return [Kuroneko::StatusHistory<Kuroneko::Status>] 状態履歴
32
+ def history(number)
33
+ histories(number).first
34
+ end
35
+
36
+ # 複数の荷物の状態履歴を照会する
37
+ #
38
+ # @param [Array<String, #to_s>] numbers 伝票番号
39
+ # @return [Array<Kuroneko::StatusHistory<Kuroneko::Status>>] 状態履歴
40
+ def histories(*numbers)
41
+ numbers.flatten!
42
+ results = []
43
+ results.concat(query(numbers.shift(10))) until numbers.empty?
44
+ results
45
+ end
46
+
47
+ # 1 つの荷物の最新状態を照会する
48
+ #
49
+ # @param [String, #to_s] number 伝票番号
50
+ # @return [Kuroneko::Status] 最新状態
51
+ def status(number)
52
+ history(number).latest
53
+ end
54
+
55
+ # 複数の荷物の最新状態を取得する
56
+ #
57
+ # @param [Array<String, #to_s>] numbers 伝票番号
58
+ # @return [Array<Kuroneko::Status>] 最新状態
59
+ def statuses(*numbers)
60
+ histories(*numbers).map(&:latest)
61
+ end
62
+
63
+ private
64
+
65
+ # ページをから情報を抽出する
66
+ #
67
+ # @param [Mechanize::Page] page 照会結果のページ
68
+ # @return [Array<Kuroneko::StatusHistory<Kuroneko::Status>>] 状態履歴
69
+ def parse(page)
70
+ page.parser.css('table.saisin').map do |summary|
71
+ rows = summary.css('tr')
72
+ number = rows[0].css('td')[2].text.gsub(/\D/, '')
73
+ status = rows[1].css('td')[2].text
74
+
75
+ history = summary.parent.css('table.meisai').first
76
+ history ||= [Status.new(number, [status], true)] # 伝票番号誤りなど
77
+ StatusHistory.new(number, history)
78
+ end
79
+ end
80
+
81
+ # フォームパラメータをセットする
82
+ #
83
+ # @param [Mechanize::Form] form
84
+ # @param [Array<String, #to_s>] numbers 伝票番号
85
+ # @return [void]
86
+ def prepare_form(form, numbers)
87
+ numbers.each.with_index(1) do |number, index|
88
+ form["number%02d" % index] = number
89
+ end
90
+ end
91
+
92
+ # リクエストを送信して状態を抽出する
93
+ #
94
+ # @param [Array<String, #to_s>] numbers 伝票番号
95
+ # @return [Array<Kuroneko::StatusHistory<Kuroneko::Status>>] 状態履歴
96
+ def query(numbers)
97
+ result_page = request(numbers)
98
+ parse(result_page)
99
+ end
100
+
101
+ # 照会リクエストを送る
102
+ #
103
+ # @param [Array<String, #to_s>] numbers 伝票番号、1 度に 10 件まで
104
+ # @return [Mechanize::Page] 照会結果のページ
105
+ def request(numbers)
106
+ form = agent.get(url).form
107
+ prepare_form(form, numbers)
108
+ form.submit
109
+ end
110
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kuroneko
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - wktk
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mechanize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: "クロネコヤマトの荷物追跡を照会する"
56
+ email:
57
+ - mail@wktk.jp
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - kuroneko.gemspec
68
+ - lib/kuroneko.rb
69
+ - lib/kuroneko/status.rb
70
+ - lib/kuroneko/status_history.rb
71
+ - lib/kuroneko/version.rb
72
+ homepage: https://github.com/wktk/kuroneko
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.0.3
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: "クロネコヤマトの荷物追跡を照会する"
96
+ test_files: []
97
+ has_rdoc: