Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/tracker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require 'tracker/api/corporations/sagawa'
require 'tracker/api/corporations/yuusei'
require 'tracker/api/corporations/seinou'
require 'tracker/api/corporations/delivery_provider'

module Tracker # :nodoc:
# 荷物追跡
Expand All @@ -16,7 +17,7 @@ class Base
# @todo クラス名を変える
# @todo validationの改修
# @param no [String] 追跡番号
# @param company [String] 運送会社 (yamato, sawaga, yuusei, seinou)
# @param company [String] 運送会社 (yamato, sawaga, yuusei, seinou, delivery_provider)
# @param format [Symbol] (nil[:hash], :json)
# @param validation [Symbol] バリーデーションの利用 default: false
# @return [Array]
Expand All @@ -30,12 +31,12 @@ def self.execute(no: nil, company: nil, format: nil, validation: false)
end

data = []
# 運送各社を追加する場合はここ(現状は3社のみ)
coms = ["yamato", "sagawa", "yuusei"]
# 運送各社を追加する場合はここ(現状は4社のみ)
coms = ["yamato", "sagawa", "yuusei", "delivery_provider"]
companies = company.to_s.empty? ? coms : [company]

companies.each do |c|
str = "Tracker::Api::#{c.capitalize}"
str = "Tracker::Api::#{c.split("_").map(&:capitalize).join}"
klass = Object.const_get(str)
a = klass.new
a.no = no
Expand Down
133 changes: 133 additions & 0 deletions lib/tracker/api/corporations/delivery_provider.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
require 'tracker/api/builder'
require 'tracker/api/formatter'
require 'tracker/api/implementation'
require 'nokogiri'
require 'net/http'

module Tracker
module Api
# デリバリープロバイダー
# @see http://track-a.tmg-group.jp/cts/TmgCargoSearchAction.do?method_id=INIT
# Cookieが必要なことや一回検索結果ページを経由して詳細画面に遷移するため他の業者と実装が微妙に変わる
class DeliveryProvider
include Tracker::Api::Implementation

def build_param
@data = []
@data << ["method_id", "POPUPSEA"]
@data << ["inputData[0].inq_no", @no]

self
end

def create_form
@uri = URI.encode_www_form(@data)

self
end

def send_data
# cookieがないと情報取得できない模様
host = "track-a.tmg-group.jp"
http = Net::HTTP.new(host)
path = "/cts/TmgCargoSearchAction.do"

# cookie取得のための通信
res = http.get("#{path}?method_id=INIT")
@cookie = res.get_fields("set-cookie").first.match(/(JSESSIONID=.*);/)[1]

# 検索のための通信
res = http.get("#{path}?#{@uri}", {"Cookie" => @cookie})

# 検索結果画面
@url = "http://#{host}#{path}?#{@uri}"
@html = res.body

self
end

def parse_data
@build = Tracker::Api::Builder.new
@doc = Nokogiri::HTML.parse(@html) do |config|
config.noblanks
end

@doc.search('table[@id="list"]').each do |node|
node.css('tr').each_with_index do |tr, i|
next if i != 1
@build.no = tr.search('td[@class="inq_list_input"]').text.strip
@build.status = tr.search('td[@class="inq_list_status"]').text.strip
unless @build.status == ""
# 詳細はformボタンを押して別ページに表示される
detail_info = tr.search('td[@class="inq_list_dtl"]').first
params = detail_info.children.search("input")[0].attributes["onclick"].value.match(/(\(.*\))/)[1].split(',')
doc = Nokogiri::HTML.parse(detail_html(params: params)) do |config|
config.noblanks
end

doc.search('table[@class="dtl2"]').each do |node|
node.css('tr').each_with_index do |tr, i|

build = Tracker::Api::Builder.new
build.no = @no

tr.css('td').each_with_index do |n, j|
case j
when 0 #日付
build.date = n.text
when 1 #商品所在地
build.place = n.text
when 2 #状態
build.status = n.text
end
end
build.company = "delivery_provider"
build.order_no = i
@details << build.object_to_hash unless i == 0
end
end
else
# 検索結果がないときの文言にお問い合わせ番号がまじるため、"未登録"に書き換える
@build.status = "未登録"
if @build.no == ""
@build.no = @no
end
end
end
end

self
end

def insert_latest_data
@build.company = "delivery_provider"
@details << @build.object_to_hash
self
end

private
def detail_html(params:)
# formで使っているパラメーターを切り出す
tmp_mani_num = params[1].gsub(/\'/, '')
tmp_trk_id = params[2].gsub(/\'/, '')
tmp_item_num = params[3].gsub(/\'/, '')
tmp_cust_ord_num = params[4].gsub(/(\'|\))/, '')

data = []
data << ["method_id", "DTL_SHOW"]
data << ["tmp_mani_num", tmp_mani_num]
data << ["tmp_trk_id", tmp_trk_id]
data << ["tmp_item_num", tmp_item_num]
data << ["tmp_cust_ord_num", tmp_cust_ord_num]

host = "track-a.tmg-group.jp"
http = Net::HTTP.new(host)
path = "/cts/TmgCargoSearchAction.do"

res = http.get("#{path}?#{URI.encode_www_form(data)}", {"Cookie" => @cookie})

res.body
end
end
end
end
14 changes: 14 additions & 0 deletions lib/tracker/api/formatter/status.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,17 @@ seinou:
"配達": :entry
#完了
"配達済みです": :complete

delivery_provider:
#未登録
"未登録": :noentry
#引受(受付)
"配送センターからデータを受信しました。": :entry
#配送中
"近くの配達店まで輸送中です": :entry
#不在
"ご不在のため、持ち帰りました。再配達をお申込みください。": :reject
#配達中
"配達中です": :entry
#完了
"配達完了しました": :complete
38 changes: 38 additions & 0 deletions spec/api/delivery_provider_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'spec_helper'

describe Tracker::Api::DeliveryProvider do
let(:delivery_provider) { Tracker::Api::DeliveryProvider.new no: "123412341231" }

describe ".new" do
subject { delivery_provider.no }
it { should eq "123412341231" }
end

describe "#execute" do
context "データがある" do
subject { delivery_provider.execute }
it { expect(subject.data).not_to be_empty }
it { expect(subject.details).not_to be_empty }
end
end

describe "#make" do
context "オリジナルデータをもっている" do
subject { delivery_provider.execute.make.details[0]["origin"] }
it { expect(subject).to_not be_empty }
end
end

describe "#result" do
context "Hash配列を返す" do
subject { delivery_provider.execute.make.result }
it { should be_a Array }
it { expect(subject[0]).to be_key "no" }
it { expect(subject[0]).to be_key "company" }
it { expect(subject[0]).to be_key "status" }
it { expect(subject[0]).to be_value "123412341231" }
it { expect(subject[0]).to be_value "delivery_provider" }
end
end

end