Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
471 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
package couriers | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"log" | ||
"net/http" | ||
"strings" | ||
|
||
"time" | ||
|
||
"github.com/PuerkitoBio/goquery" | ||
"github.com/purpleworks/delibird" | ||
"golang.org/x/text/encoding/korean" | ||
"golang.org/x/text/transform" | ||
) | ||
|
||
type Slx struct{} | ||
|
||
func init() { | ||
RegisterCourier("SLX", &Slx{}) | ||
} | ||
|
||
func (t Slx) Code() string { | ||
return "SLX" | ||
} | ||
|
||
func (t Slx) Name() string { | ||
return "SLX" | ||
} | ||
|
||
func (t Slx) TrackingUrl() string { | ||
return "http://aladin.slx.co.kr/Tracking.slx?param1=%s" | ||
} | ||
|
||
func (t Slx) Parse(trackingNumber string) (delibird.Track, *delibird.ApiError) { | ||
track := delibird.Track{} | ||
|
||
body, err := t.getHtml(trackingNumber) | ||
|
||
if err != nil { | ||
return track, delibird.NewApiError(delibird.RequestPageError, err.Error()) | ||
} | ||
|
||
doc, err := goquery.NewDocumentFromReader(body) | ||
if err != nil { | ||
return track, delibird.NewApiError(delibird.ParseError, err.Error()) | ||
} | ||
|
||
hasTrainNo := strings.TrimSpace(doc.Find(".train_no span").First().Text()) | ||
if len(hasTrainNo) == 0 { | ||
return track, delibird.NewApiError(delibird.NoTrackingInfo, "등록되지 않은 운송장이거나 배송준비중입니다.") | ||
} | ||
|
||
track = delibird.Track{ | ||
TrackingNumber: trackingNumber, | ||
CompanyCode: t.Code(), | ||
CompanyName: t.Name(), | ||
//document.querySelectorAll("table")[1].querySelectorAll("td")[1]; | ||
Sender: strings.TrimSpace(doc.Find("table").Eq(1).Find("td").Eq(1).Text()), | ||
Receiver: strings.TrimSpace(doc.Find("table").Eq(1).Find("td").Eq(5).Text()), | ||
Signer: strings.TrimSpace(doc.Find("table").Eq(1).Find("td").Eq(7).Text()), | ||
} | ||
|
||
history := []delibird.History{} | ||
|
||
//배송정보 | ||
//document.querySelectorAll("table")[2].querySelectorAll("tr")[1]; | ||
doc.Find("table").Eq(2).Find("tr").Each(func(i int, s *goquery.Selection) { | ||
if i > 0 { | ||
dateText := strings.TrimSpace(s.Find("td").Eq(0).Text()) | ||
if dateText == "" { | ||
return | ||
} | ||
|
||
timeText := strings.TrimSpace(s.Find("td").Eq(1).Text()) | ||
if timeText == "" { | ||
return | ||
} | ||
|
||
date, err := time.Parse("2006/01/02 15:04", dateText+" "+timeText) | ||
if err != nil { | ||
log.Printf("%s - %s", dateText, err) | ||
} else { | ||
statusText := strings.TrimSpace(s.Find("td").Eq(4).Text()) | ||
history = append(history, | ||
delibird.History{ | ||
Date: date.Add(-time.Hour * 9).Unix(), | ||
DateText: date.Format("2006-01-02 15:04"), | ||
Area: strings.TrimSpace(s.Find("td").Eq(2).Text()), | ||
StatusCode: t.getStatus(statusText), | ||
StatusText: statusText, | ||
}) | ||
|
||
track.StatusCode = t.getStatus(statusText) | ||
track.StatusText = statusText | ||
} | ||
} | ||
}) | ||
track.History = history | ||
|
||
return track, nil | ||
} | ||
|
||
func (t Slx) getHtml(trackingNumber string) (io.Reader, error) { | ||
url := fmt.Sprintf(t.TrackingUrl(), trackingNumber) | ||
res, err := http.Get(url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer res.Body.Close() | ||
|
||
body, err := ioutil.ReadAll(res.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
convertedBody := transform.NewReader(bytes.NewReader(body), korean.EUCKR.NewDecoder()) | ||
|
||
return convertedBody, nil | ||
} | ||
|
||
func (t Slx) getStatus(status_text string) delibird.TrackingStatus { | ||
switch status_text { | ||
case "집하": | ||
return delibird.Ready | ||
case "입고": | ||
return delibird.Loading | ||
case "배송 출발": | ||
return delibird.DeleveryStart | ||
case "배송 완료": | ||
return delibird.DeleveryComplete | ||
} | ||
|
||
return delibird.UnknownStatus | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package couriers | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/jarcoal/httpmock" | ||
"github.com/purpleworks/delibird" | ||
. "github.com/smartystreets/goconvey/convey" | ||
) | ||
|
||
func TestSlxCourier(t *testing.T) { | ||
// create slx courier | ||
courier, _ := New("SLX") | ||
|
||
// create http mock | ||
httpmock.Activate() | ||
defer httpmock.DeactivateAndReset() | ||
|
||
invalidTrackingNumber := "slx_invalid" | ||
//startTrackingNumber := "slx_start" | ||
completeTrackingNumber := "slx_complete" | ||
|
||
httpmock.RegisterResponder("GET", fmt.Sprintf(Slx{}.TrackingUrl(), invalidTrackingNumber), | ||
httpmock.NewStringResponder(200, readTestResponseFile(invalidTrackingNumber+".html"))) | ||
//httpmock.RegisterResponder("GET", fmt.Sprintf(Slx{}.TrackingUrl(), startTrackingNumber), | ||
// httpmock.NewStringResponder(200, readTestResponseFile(startTrackingNumber+".html"))) | ||
httpmock.RegisterResponder("GET", fmt.Sprintf(Slx{}.TrackingUrl(), completeTrackingNumber), | ||
httpmock.NewStringResponder(200, readTestResponseFile(completeTrackingNumber+".html"))) | ||
|
||
Convey("SLX test", t, func() { | ||
Convey("Invalid tracking number test", func() { | ||
_, err := courier.Parse(invalidTrackingNumber) | ||
So(err, ShouldNotBeNil) | ||
}) | ||
|
||
//Convey("Start courier test", func() { | ||
// data, _ := courier.Parse(startTrackingNumber) | ||
// | ||
// So(data.StatusCode, ShouldEqual, delibird.Ready) | ||
// So(data.Sender, ShouldEqual, "홈*럼") | ||
// So(data.Receiver, ShouldEqual, "테*트") | ||
// So(data.Signer, ShouldEqual, "") | ||
// So(data.CompanyCode, ShouldEqual, "CJ") | ||
//}) | ||
|
||
Convey("Complete courier test", func() { | ||
data, _ := courier.Parse(completeTrackingNumber) | ||
|
||
So(data.StatusCode, ShouldEqual, delibird.DeleveryComplete) | ||
So(data.Sender, ShouldEqual, "홈*럼") | ||
So(data.Receiver, ShouldEqual, "테*트") | ||
So(data.Signer, ShouldEqual, "본인") | ||
So(data.CompanyCode, ShouldEqual, "SLX") | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | ||
<!-- saved from url=(0099)http://localhost:63342/delibird/couriers/testhtml/slx_complete.html?_ijt=fcc5icfqihdtodos56um7iu5s7 --> | ||
<html xmlns="http://www.w3.org/1999/xhtml"><link rel="stylesheet" type="text/css" href="chrome-extension://bmhcbmnbenmcecpmpepghooflbehcack/styles/tooltip.css"><head><meta http-equiv="Content-Type" content="text/html; charset=EUC-KR"><!-- Google Tag Manager --><script async="" src="./slx_complete_files/gtm.js"></script><script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-N6WTLHM');</script><!-- End Google Tag Manager --><link rel="stylesheet" type="text/css" href="chrome-extension://bmhcbmnbenmcecpmpepghooflbehcack/styles/tooltip.css"><!-- Google Tag Manager --><script async="" src="./slx_complete_files/gtm.js"></script><script async="" src="./slx_complete_files/gtm(1).js"></script><script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','GTM-N6WTLHM');</script><!-- End Google Tag Manager --> | ||
|
||
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, width=device-width"> | ||
<title>SLX-ALADIN</title> | ||
<style> | ||
tr, td, body { font-family: 돋움; font-size: 9pt; color: #444444; line-height: 18px;} | ||
.title{ font-size:13px; font-weight:bold; } | ||
.train_no{ font-size:13px; font-weight:bold; color:#386da1;} | ||
.t_on{ color:#cc338c; font-size:14px;} | ||
.basic_tex{font-size:13px; font-weight:bold; color:#386da1; padding-left:10px; } | ||
.basic_tex2{font-size:13px; font-weight:bold; color:#386da1; } | ||
.notic{ font-weight:bold; font-size:12px;} | ||
.noti_table{ border:2px solid #3399FF; padding:20px 0 20px 10px; font-size:11px;} | ||
.add{ padding-left:10px;} | ||
|
||
.no_tit{ font-weight:bold; color:#009933;} | ||
.t_dot{ color:#FF0000;} | ||
.spac{color:#FF0000; text-decoration:underline;} | ||
</style> | ||
<style type="text/css"> | ||
<!-- | ||
a:link {text-decoration:none;color:#f48727} | ||
a:active {text-decoration:underline;color:#f48727} | ||
a:visited {text-decoration:none;color:#f48727} | ||
a:hover {text-decoration:underline;color:#f48727} | ||
//--> | ||
</style> | ||
</head> | ||
|
||
<body cz-shortcut-listen="true" style=""><!-- Google Tag Manager (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N6WTLHM"height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><!-- End Google Tag Manager (noscript) --><!-- Google Tag Manager (noscript) --><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-N6WTLHM"height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><!-- End Google Tag Manager (noscript) --> | ||
<div style="width:100%; margin:0 auto;"> | ||
<div style=" margin:35px 0 25px 0;"><div align="center"><img src="./slx_complete_files/tracking_tit.jpg" alt="배송조회"></div> | ||
</div> | ||
|
||
<!-- 기본정보--> | ||
<div> | ||
<table width="100%" border="0" cellspacing="0"> | ||
<tbody><tr> | ||
<td width="70%"><img src="./slx_complete_files/dot_star.gif" width="17" height="18" align="absmiddle"><span class="title">기본정보</span></td> | ||
<td width="30%"><span class="train_no">운송장번호 : <span class="t_on"> 980067198106</span></span></td> | ||
</tr> | ||
</tbody></table> | ||
</div> | ||
|
||
<div style="margin-bottom:25px;"> | ||
<table width="100%" cellspacing="1" cellpadding="3" bgcolor="#83b8c2" border="0" align="center"> | ||
<tbody><tr> | ||
<td width="25%" bgcolor="#edf5fc"><span class="basic_tex">보내는분</span></td> | ||
<td width="25%" align="center" bgcolor="#ffffff">홈*럼</td> | ||
<td width="25%" bgcolor="#edf5fc"> <span class="basic_tex">배송상태</span></td> | ||
<td width="25%" align="center" bgcolor="#ffffff">배송완료</td> | ||
</tr> | ||
<tr> | ||
<td bgcolor="#edf5fc"><span class="basic_tex">받는 분</span></td> | ||
<td align="center" bgcolor="#ffffff">테*트</td> | ||
<td bgcolor="#edf5fc"> <span class="basic_tex">인수자</span></td> | ||
<td align="center" bgcolor="#ffffff">본인</td> | ||
</tr> | ||
<tr> | ||
<td bgcolor="#edf5fc"> <span class="basic_tex">주소</span></td> | ||
<td colspan="3" bgcolor="#ffffff"><span class="add">경기도 안양시</span></td> | ||
</tr> | ||
</tbody></table> | ||
|
||
</div> | ||
|
||
|
||
<!-- 추적현황--> | ||
<div><img src="./slx_complete_files/dot_star.gif" width="17" height="18" align="absmiddle"><span class="title">추적현황</span></div> | ||
<div style="margin-bottom:25px;"> | ||
<table width="100%" cellspacing="1" cellpadding="3" bgcolor="#83b8c2" border="0" align="center"> | ||
<tbody><tr> | ||
<td width="15%" align="center" bgcolor="#edf5fc"> <span class="basic_tex2">날짜</span></td> | ||
<td width="15%" align="center" bgcolor="#edf5fc"><span class="basic_tex2">시간</span></td> | ||
<td width="35%" align="center" bgcolor="#edf5fc"><span class="basic_tex2">위치</span></td> | ||
<td width="23%" align="center" bgcolor="#edf5fc"><span class="basic_tex2">연락처</span></td> | ||
<td width="12%" align="center" bgcolor="#edf5fc"><span class="basic_tex2">진행현황</span></td> | ||
</tr> | ||
<tr> | ||
<td align="center" bgcolor="#ffffff">2019/03/20</td> | ||
<td align="center" bgcolor="#ffffff">10:50</td> | ||
<td align="center" bgcolor="#ffffff">집하전담집하전담</td> | ||
<td align="center" bgcolor="#ffffff">0000-0000</td> | ||
<td align="center" bgcolor="#ffffff">집하</td> | ||
</tr> | ||
<tr> | ||
<td align="center" bgcolor="#ffffff">2019/03/20</td> | ||
<td align="center" bgcolor="#ffffff">14:42</td> | ||
<td align="center" bgcolor="#ffffff">통합물류센터 </td> | ||
<td align="center" bgcolor="#ffffff"> </td> | ||
<td align="center" bgcolor="#ffffff">입고</td> | ||
</tr> | ||
<tr> | ||
<td align="center" bgcolor="#ffffff">2019/03/21</td> | ||
<td align="center" bgcolor="#ffffff">08:25</td> | ||
<td align="center" bgcolor="#ffffff">안양(대)테스트</td> | ||
<td align="center" bgcolor="#ffffff">010-0000-0000</td> | ||
<td align="center" bgcolor="#ffffff">배송 출발</td> | ||
</tr> | ||
<tr> | ||
<td align="center" bgcolor="#ffffff">2019/03/21</td> | ||
<td align="center" bgcolor="#ffffff">10:53</td> | ||
<td align="center" bgcolor="#ffffff">안양(대)테스트</td> | ||
<td align="center" bgcolor="#ffffff">010-0000-0000</td> | ||
<td align="center" bgcolor="#ffffff">배송 완료</td> | ||
</tr> | ||
</tbody></table> | ||
|
||
</div> | ||
|
||
<div style="color:#f48727; margin-bottom:18px;"> | ||
<span class="notic">※ 배송완료 시간은 실제 받으신 시간과 다를 수 있습니다.</span><br> | ||
<span class="notic">※ 고객센터 :</span> <a href="http://www.doortodoor.co.kr/jsp/cmn/Tracking.jsp?QueryType=3&pTdNo=980067198106">CJ대한통운택배(하루배송)</a> 1588-1255 / SLX택배(당일배송) 1544-6482<br> | ||
</div> | ||
|
||
|
||
<!-- 주의사항--> | ||
<div class="noti_table"> | ||
<table width="100%" border="0" cellspacing="0"> | ||
<tbody><tr> | ||
<td> | ||
<span class="no_tit">1. 아래와 같이 배송이 진행됩니다.</span> <br> | ||
<span class="t_dot">*</span> 집하 : 알라딘 물류센터에서 포장상품 인수 후 차량적재 -> 물품 분류장(터미널)으로 이동중 <br> | ||
<span class="t_dot">*</span> 입고/출고 : 1차 분류장(터미널) 도착 후 각 권역별 분류장 혹은 배송 영업소*대리점으로 이동중 <br> | ||
<span class="t_dot">*</span> 도착 : 배송 영업소*대리점 도착 완료<br> | ||
<span class="t_dot">*</span> 출발 : 배송 영업소*대리점의 구역별 담당기사 차량 적재 후 배송출발 <br> | ||
<span class="t_dot">*</span> 완료 : 고객님(혹은 대리수령인)께 인계 혹은 부재시 경비실 등 위탁 완료 <br> | ||
</td> | ||
</tr> | ||
|
||
<tr> | ||
<td> | ||
<br> | ||
<span class="no_tit">2. 알라딘 출고*집하 후 통상 익일(월-토), ' 당일배송' 상품은 출고 당일(17-21시 사이) 배송됩니다.</span> <br> | ||
<span class="t_dot">*</span> <span class="spac">당일배송</span> 상품은, 대부분 야간 시간대 배송되므로 <span class="spac">가급적 '회사 외 주소'로 지정</span> 해 주십시오. <br> | ||
<span class="t_dot">*</span> 배송기사별 동선에 따라 다르나, 회사 주소지의 경우 당일배송 가능성이 적어 통상 익일 오전 중 배송됩니다. <br> | ||
<span class="t_dot">*</span> 연말 연초,명절 연휴 전후 및 신학기 시즌 등에는 배송물량 증가로 예상일 보다 지연 배송 가능성이 있습니다. <br> | ||
<span class="t_dot">*</span> 1588-1255로 기사 연락처가 표시되는 경우에는 배송진행 현황표 하단의 고객센터 정보 중 '하루배송' 부분 클릭하시면, 상세 페이지 이동 후 기사 연락처 확인이 가능합니다. <br> | ||
(단, 계속 차량운행 또는 배송상품 전달 등 상황으로 배송기사와의 통화가 원활하지 않음) <br> | ||
</td> | ||
</tr> | ||
</tbody></table> | ||
|
||
</div> | ||
|
||
</div> | ||
|
||
|
||
|
||
<div class="liner-mini-button" style="display: none;"><a class="liner-mb liner-save-button"></a></div><div class="liner-mini-tooltip" style="display: none;"><span class="liner-color-yellow liner-mini-color-circle liner-save-button"></span><span class="liner-color-green liner-mini-color-circle liner-save-button"></span><span class="liner-color-orange liner-mini-color-circle liner-save-button"></span><span class="liner-color-violet liner-mini-color-circle liner-save-button"></span><span class="liner-color-blue liner-mini-color-circle liner-save-button"></span><span class="liner-color-pink liner-mini-color-circle liner-save-button"></span></div><div class="liner-tooltip-wrap"><div class="liner-tooltip-menu"><span class="liner-tooltip-color liner-tooltip-icon"></span><span class="liner-tooltip-comment liner-tooltip-icon"></span><span class="liner-tooltip-undo liner-tooltip-icon"></span></div><div class="liner-color-picker"><span class="liner-color-yellow liner-color-circle"></span><span class="liner-color-green liner-color-circle"></span><span class="liner-color-orange liner-color-circle"></span><span class="liner-color-violet liner-color-circle"></span><span class="liner-color-blue liner-color-circle"></span><span class="liner-color-pink liner-color-circle"></span></div><div class="liner-tooltip-arrow"><span class="liner-arrow-down"></span></div></div><div class="liner-comment-box"><div class="liner-comment-line"></div><div class="liner-comment-area"><textarea class="liner-comment-input" placeholder="Write a comment"></textarea><div class="liner-comment-saving"><p class="liner-comment-status"></p></div></div></div><iframe name="liner-extension" id="liner-extension" src="./slx_complete_files/popup.html" style="opacity: 0; top: -130px;"></iframe></body></html> |
Oops, something went wrong.