shipindo 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +77 -0
- data/Rakefile +55 -0
- data/lib/shipindo.rb +4 -0
- data/lib/shipindo/carriers.rb +29 -0
- data/lib/shipindo/carriers/jne.rb +85 -0
- data/lib/shipindo/helpers/rupiah_to_float.rb +29 -0
- data/lib/shipindo/version.rb +14 -0
- data/test/fixtures/jne.html +369 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/carriers_test.rb +31 -0
- data/test/unit/jne_test.rb +42 -0
- data/test/unit/rupiah_to_float_test.rb +26 -0
- data/test/unit/shipindo_test.rb +14 -0
- metadata +102 -0
data/README.rdoc
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= Shipindo
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
Library that scrapes rates from various Indonesian shipping carriers web 1.0 sites.
|
6
|
+
API is similar in those of ActiveShipping.
|
7
|
+
|
8
|
+
== Supported Shipping Carriers
|
9
|
+
|
10
|
+
* JNE -- http://jne.co.id
|
11
|
+
* more if you send patch
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
gem install shipindo
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
# use them all
|
20
|
+
require 'shipindo'
|
21
|
+
|
22
|
+
Shipindo.find_rates(
|
23
|
+
:origin => "MEDAN",
|
24
|
+
:destination => "TANGERANG",
|
25
|
+
:weight => 2)
|
26
|
+
|
27
|
+
=> {
|
28
|
+
:origin => "MEDAN",
|
29
|
+
:destination => "TANGERANG",
|
30
|
+
:weight => 2,
|
31
|
+
:carrier => "jne",
|
32
|
+
:origin_code => "TUVTMTAwMDBK",
|
33
|
+
:destination_code => "VEdSMTAwMDBK",
|
34
|
+
:from => "MEDAN",
|
35
|
+
:to => "TANGERANG",
|
36
|
+
:response => {
|
37
|
+
:rates => [
|
38
|
+
[0] {
|
39
|
+
:service_name => "SS",
|
40
|
+
:service_type => "Dokumen/Paket",
|
41
|
+
:rate => 330000.0
|
42
|
+
},
|
43
|
+
[1] {
|
44
|
+
:service_name => "YES",
|
45
|
+
:service_type => "Dokumen/Paket",
|
46
|
+
:rate => 39000.0
|
47
|
+
},
|
48
|
+
[2] {
|
49
|
+
:service_name => "REG",
|
50
|
+
:service_type => "Dokumen/Paket",
|
51
|
+
:rate => 32000.0
|
52
|
+
},
|
53
|
+
[3] {
|
54
|
+
:service_name => "OKE",
|
55
|
+
:service_type => "Dokumen/Paket",
|
56
|
+
:rate => 30000.0
|
57
|
+
}
|
58
|
+
],
|
59
|
+
:origin => "MEDAN",
|
60
|
+
:destination => "TANGERANG",
|
61
|
+
:weight => "2"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
# or only a single carrier
|
66
|
+
require 'shipindo/carriers/jne'
|
67
|
+
|
68
|
+
jne = Shipindo::Carrier::Jne.new
|
69
|
+
jne.find_rates(
|
70
|
+
:origin => "JAKARTA",
|
71
|
+
:destination => "MEDAN",
|
72
|
+
:weight => 2)
|
73
|
+
|
74
|
+
== Copyright
|
75
|
+
|
76
|
+
See MIT-LICENSE for details.
|
77
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), %w(lib shipindo version))
|
6
|
+
|
7
|
+
spec = Gem::Specification.new do |s|
|
8
|
+
s.name = 'shipindo'
|
9
|
+
s.version = Shipindo::Version.to_s
|
10
|
+
s.has_rdoc = true
|
11
|
+
s.extra_rdoc_files = %w(README.rdoc)
|
12
|
+
s.rdoc_options = %w(--main README.rdoc)
|
13
|
+
s.summary = "Library that scrapes rates from various Indonesian shipping carriers web 1.0 sites."
|
14
|
+
s.author = 'wynst'
|
15
|
+
s.email = 'wynst.uei@gmail.com'
|
16
|
+
s.homepage = 'http://github.com/wynst/shipindo'
|
17
|
+
s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
|
18
|
+
# s.executables = ['shipindo']
|
19
|
+
|
20
|
+
s.add_dependency('nokogiri', '>= 0')
|
21
|
+
s.add_dependency('rest-client', '>= 0')
|
22
|
+
end
|
23
|
+
|
24
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
25
|
+
pkg.gem_spec = spec
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::TestTask.new do |t|
|
29
|
+
t.libs << 'test'
|
30
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
begin
|
35
|
+
require 'rcov/rcovtask'
|
36
|
+
|
37
|
+
exclude_paths = %w(/Library/Ruby /usr/lib/ruby)
|
38
|
+
exclude_paths += Array(Gem.path)
|
39
|
+
|
40
|
+
options = ['--text-report'] + exclude_paths.map {|p| "-x '#{p}'" }
|
41
|
+
|
42
|
+
Rcov::RcovTask.new(:coverage) do |t|
|
43
|
+
t.libs = ['test']
|
44
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
45
|
+
t.verbose = true
|
46
|
+
t.rcov_opts = options
|
47
|
+
end
|
48
|
+
|
49
|
+
task :default => :coverage
|
50
|
+
|
51
|
+
rescue LoadError
|
52
|
+
warn "\n**** Install rcov (gem install rcov) to get coverage stats ****\n"
|
53
|
+
task :default => :test
|
54
|
+
end
|
55
|
+
|
data/lib/shipindo.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'shipindo/carriers/jne'
|
2
|
+
|
3
|
+
module Shipindo
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def find_rates(options)
|
8
|
+
# jne is default for 99% Indonesia online shop..
|
9
|
+
options[:carrier] ||= 'jne'
|
10
|
+
|
11
|
+
klass = find_carrier(options[:carrier])
|
12
|
+
klass.new.find_rates(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_carrier(name)
|
16
|
+
case name.downcase
|
17
|
+
when 'jne'
|
18
|
+
Shipindo::Carrier::Jne
|
19
|
+
else
|
20
|
+
raise(NameError, "unknown carrier #{name}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
extend ClassMethods
|
27
|
+
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'restclient'
|
3
|
+
|
4
|
+
require 'shipindo/helpers/rupiah_to_float'
|
5
|
+
|
6
|
+
module Shipindo::Carrier
|
7
|
+
|
8
|
+
class Jne
|
9
|
+
|
10
|
+
def list_city(query, limit=1)
|
11
|
+
# bug in JNE server, limit parameter is ignored
|
12
|
+
resp = RestClient.get "http://www.jne.co.id/tariff.php?q=#{ query }&limit=#{ limit }"
|
13
|
+
|
14
|
+
resp.body.split("\r\n").map do |item|
|
15
|
+
city, code = item.split("|")
|
16
|
+
{ :city => city, :code => code }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def find_rates(options)
|
21
|
+
if options[:origin] && options[:destination]
|
22
|
+
options[:origin_code] = list_city(options[:origin]).first[:code]
|
23
|
+
options[:destination_code] = list_city(options[:destination]).first[:code]
|
24
|
+
# another jne server flunk, response city name is from request parameters,
|
25
|
+
# if there isn't any eg. using only code if cities, then it's displayed as empty.
|
26
|
+
options[:from] = options[:origin]
|
27
|
+
options[:to] = options[:destination]
|
28
|
+
end
|
29
|
+
|
30
|
+
unless options[:origin_code] && options[:destination_code]
|
31
|
+
raise(ArgumentError, "origin & destination or code must be defined")
|
32
|
+
end
|
33
|
+
|
34
|
+
options[:weight] ||= 1
|
35
|
+
|
36
|
+
resp = RestClient.post "http://www.jne.co.id/index.php?mib=tariff&lang=IN", options
|
37
|
+
|
38
|
+
doc = Nokogiri::HTML.parse(resp.body)
|
39
|
+
|
40
|
+
options[:response] = parse_rates(doc)
|
41
|
+
options
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def parse_rates(doc)
|
47
|
+
h = {}
|
48
|
+
h[:rates] = []
|
49
|
+
|
50
|
+
# get estimates information
|
51
|
+
l = doc.css("tr.trfH")
|
52
|
+
if l.length >= 4
|
53
|
+
|
54
|
+
get_info = Proc.new do |doc|
|
55
|
+
td = doc.css('td')
|
56
|
+
if td.length >= 3
|
57
|
+
td[2].inner_html
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
h[:origin] = get_info.call(l[0])
|
62
|
+
h[:destination] = get_info.call(l[1])
|
63
|
+
h[:weight] = get_info.call(l[2])
|
64
|
+
end
|
65
|
+
|
66
|
+
# get rates estimates
|
67
|
+
doc.css("tr.trfC").each do |tr|
|
68
|
+
t = tr.css("td")
|
69
|
+
|
70
|
+
if t.length == 3
|
71
|
+
h[:rates] << {
|
72
|
+
:service_name => t[0].inner_html.strip,
|
73
|
+
:service_type => t[1].inner_html,
|
74
|
+
:rate => t[2].inner_html.rp_to_f(
|
75
|
+
:thousand_separator => ",",
|
76
|
+
:cent_separator => ".")
|
77
|
+
}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
h
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Shipindo
|
2
|
+
module Helpers
|
3
|
+
module RupiahToFloat
|
4
|
+
# convert rupiah string to float
|
5
|
+
# @param [Hash] options conversion options
|
6
|
+
# @option options [String] :prefix ("Rp.") prefix to remove
|
7
|
+
# @option options [String] :thousand_separator (".") separator for thousands
|
8
|
+
# @option options [String] :cent_separator (",") separator for cents
|
9
|
+
def rupiah_to_float(options={})
|
10
|
+
options[:prefix] ||= "Rp."
|
11
|
+
options[:thousand_separator] ||= "."
|
12
|
+
options[:cent_separator] ||= ","
|
13
|
+
|
14
|
+
text = self.gsub(options[:prefix],"").gsub(options[:thousand_separator],"")
|
15
|
+
if text.include?(options[:cent_separator]) && options[:cent_separator] != "."
|
16
|
+
text = text.gsub(options[:cent_separator], ".")
|
17
|
+
end
|
18
|
+
text.to_f
|
19
|
+
end
|
20
|
+
|
21
|
+
alias :rp_to_f :rupiah_to_float
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class String
|
27
|
+
include Shipindo::Helpers::RupiahToFloat
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,369 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
|
5
|
+
<title>JNE - Express Across Nations</title>
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
7
|
+
<meta name="author" content="City Web Indonesia" />
|
8
|
+
<meta name="description" content="JNE, Express Across Nations" />
|
9
|
+
<meta name="keyword" content="JNE,TIKIJNE,TARIF TIKIJNE,TRACKING,KURIR,Pengiriman " />
|
10
|
+
<meta name="copyright" content="Copyright 2008 by TIKI JNE" />
|
11
|
+
<meta name="language" content="Indonesian" />
|
12
|
+
<meta name="distribution" content="Global" />
|
13
|
+
<meta name="rating" content="General" />
|
14
|
+
<meta name="robots" content="index,follow" />
|
15
|
+
<meta name="googlebot" content="index,follow" />
|
16
|
+
<meta name="revisit-after" content="1 days" />
|
17
|
+
<meta name="expires" content="never" />
|
18
|
+
<meta name="dc.title" content="TIKI JNE" />
|
19
|
+
<meta name="dc.creator.e-mail" content="sales@citywebindo.com" />
|
20
|
+
<meta name="dc.creator.name" content="City Web Indonesia" />
|
21
|
+
<meta name="dc.creator.website" content="http://www.citywebindo.com" />
|
22
|
+
<meta name="tgn.name" content="Jakarta" />
|
23
|
+
<meta name="tgn.nation" content="Indonesia" />
|
24
|
+
|
25
|
+
<script type="text/javascript" src="js/script.js.js"></script>
|
26
|
+
<script type="text/javascript" src="js/calendar.js"></script>
|
27
|
+
<script type="text/javascript" src="js/lang/calendar-en.js"></script>
|
28
|
+
<script type="text/javascript" src="js/calendar-setup.js"></script>
|
29
|
+
<script language="javascript">AC_FL_RunContent = 0;</script>
|
30
|
+
<script src="AC_RunActiveContent.js" language="javascript"></script>
|
31
|
+
<!-- jQuery -->
|
32
|
+
<script type="text/javascript" src="js/jquery-1.2.6.pack.js"></script>
|
33
|
+
<script type="text/javascript" src="js/jquery.autocomplete.js"></script>
|
34
|
+
<script type="text/javascript" src="js/jquery.alphanumeric.pack.js"></script>
|
35
|
+
<script type="text/javascript" src="js/jquery.rsv.js"></script>
|
36
|
+
|
37
|
+
<script type="text/javascript" src="js/tariff.js"></script>
|
38
|
+
<script type="text/javascript" src="js/tracking.js"></script>
|
39
|
+
<script type="text/javascript" src="js/pickup.js"></script>
|
40
|
+
<script type="text/javascript" src="js/opportunity.js"></script>
|
41
|
+
<script language="javascript">
|
42
|
+
<!--
|
43
|
+
jQuery.noConflict();
|
44
|
+
-->
|
45
|
+
</script>
|
46
|
+
|
47
|
+
<script type="text/javascript">
|
48
|
+
function cari()
|
49
|
+
{
|
50
|
+
text = document.getElementById('txtCari').value;
|
51
|
+
if(text == '')
|
52
|
+
{
|
53
|
+
alert("Search text can't be empty !");
|
54
|
+
return;
|
55
|
+
}
|
56
|
+
|
57
|
+
document.location = 'index.php?mib=search&lang=IN&txt='+text;
|
58
|
+
}
|
59
|
+
</script>
|
60
|
+
|
61
|
+
<link href="css/calendar-blue.css" rel="stylesheet" type="text/css" media="all" title="winter" />
|
62
|
+
<link rel="stylesheet" href="tiki.css" type="text/css" media="screen" />
|
63
|
+
<link rel="stylesheet" href="css/jquery.autocomplete.css" type="text/css" />
|
64
|
+
<link rel="shortcut icon" href="images/favicon.ico" >
|
65
|
+
|
66
|
+
</head>
|
67
|
+
|
68
|
+
<body>
|
69
|
+
|
70
|
+
<div id="container">
|
71
|
+
|
72
|
+
<table width="852" border="0" cellspacing="0" cellpadding="0">
|
73
|
+
<tr>
|
74
|
+
<td width="852" height="92" align="left" valign="top"><table width="852" border="0" cellspacing="0" cellpadding="0">
|
75
|
+
<tr>
|
76
|
+
<td width="164" height="92" rowspan="5" align="left" valign="top"><span style="width:164px;height:92px;display:inline-block; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/logo.png');"><img style="filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0); " src="images/logo.png" alt="tiki jne" width="164" height="92" /></span></td>
|
77
|
+
<td width="688" height="3" align="right" valign="top"></td>
|
78
|
+
</tr>
|
79
|
+
<tr>
|
80
|
+
<td width="688" align="right" valign="bottom" class="bahasa"><a href="index.php?lang=IN">Indonesia</a> | <a href="index.php?lang=EN">English</a></td>
|
81
|
+
</tr>
|
82
|
+
<tr>
|
83
|
+
<td width="688" height="2" align="right" valign="top"></td>
|
84
|
+
</tr>
|
85
|
+
<tr>
|
86
|
+
<td width="688" align="right" valign="top" class="menutop"><a href="index.php?lang=IN">home</a> | <a href="index.php?mib=contact&lang=IN">contact us</a> | <a href="#">search</a>
|
87
|
+
<input type="text" name="txtCari" id="txtCari" class="inputsearch" value="JNE Branch" onFocus="this.value=''" /> <input type="submit" name="submitsearch" class="btnsearch" value="GO" onclick="cari()" /></td>
|
88
|
+
</tr>
|
89
|
+
<tr>
|
90
|
+
<td width="688" align="right" valign="top"> </td>
|
91
|
+
</tr>
|
92
|
+
</table></td>
|
93
|
+
</tr>
|
94
|
+
<tr>
|
95
|
+
<td width="852" height="15" align="left" valign="top"></td>
|
96
|
+
</tr>
|
97
|
+
<tr>
|
98
|
+
<td width="852" align="left" valign="top"><table width="852" border="0" cellspacing="0" cellpadding="0">
|
99
|
+
<tr>
|
100
|
+
<td width="106" align="left" valign="top"><a id="company" href="index.php?mib=pages&id=2008072315125002&lang=IN">COMPANY</a></td>
|
101
|
+
<td width="10" align="left" valign="top"> </td>
|
102
|
+
<td width="130" align="left" valign="top"><a id="services" href="index.php?mib=testimonial&lang=IN">SERVICES</a></td>
|
103
|
+
<td width="10" align="left" valign="top"> </td>
|
104
|
+
<td width="108" align="left" valign="top"><a id="network" href="index.php?mib=propinsi&lang=IN">NETWORK</a></td>
|
105
|
+
<td width="9" align="left" valign="top"> </td>
|
106
|
+
<td width="179" align="left" valign="top"><a id="newspromo" href="index.php?mib=berita&lang=IN">NEWS & PROMO</a></td>
|
107
|
+
<td width="10" align="left" valign="top"> </td>
|
108
|
+
<td width="190" align="left" valign="top"><a id="business" href="index.php?mib=opportunity&lang=IN">BUSINESS OPPORTUNITY</a></td>
|
109
|
+
<td width="10" align="left" valign="top"> </td>
|
110
|
+
<td width="90" align="left" valign="top"><a id="clients" href="index.php?mib=client&lang=IN">CLIENTS</a></td>
|
111
|
+
</tr>
|
112
|
+
</table></td>
|
113
|
+
</tr>
|
114
|
+
<tr>
|
115
|
+
<td width="852" height="15" align="left" valign="top"></td>
|
116
|
+
</tr>
|
117
|
+
<tr>
|
118
|
+
<td width="852" height="207" align="left" valign="top">
|
119
|
+
<script language="javascript">
|
120
|
+
if (AC_FL_RunContent == 0) {
|
121
|
+
alert("This page requires AC_RunActiveContent.js.");
|
122
|
+
} else {
|
123
|
+
AC_FL_RunContent(
|
124
|
+
'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
|
125
|
+
'width', '852',
|
126
|
+
'height', '207',
|
127
|
+
'src', 'jnecard',
|
128
|
+
'quality', 'high',
|
129
|
+
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
|
130
|
+
'align', 'middle',
|
131
|
+
'play', 'true',
|
132
|
+
'loop', 'true',
|
133
|
+
'scale', 'showall',
|
134
|
+
'wmode', 'window',
|
135
|
+
'devicefont', 'false',
|
136
|
+
'id', 'jnecard',
|
137
|
+
'bgcolor', '#ffffff',
|
138
|
+
'name', 'jnecard',
|
139
|
+
'menu', 'true',
|
140
|
+
'allowFullScreen', 'false',
|
141
|
+
'allowScriptAccess','sameDomain',
|
142
|
+
'movie', 'jnecard',
|
143
|
+
'salign', ''
|
144
|
+
); //end AC code
|
145
|
+
}
|
146
|
+
</script>
|
147
|
+
<noscript>
|
148
|
+
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="852" height="207" id="banner_tiki" align="middle">
|
149
|
+
<param name="allowScriptAccess" value="sameDomain" />
|
150
|
+
<param name="allowFullScreen" value="false" />
|
151
|
+
<param name="movie" value="jnecard.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /> <embed src="jnecard.swf" quality="high" bgcolor="#ffffff" width="852" height="207" name="jnecard" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
|
152
|
+
</object>
|
153
|
+
</noscript></td>
|
154
|
+
</tr>
|
155
|
+
<tr>
|
156
|
+
<td width="852" height="15" align="left" valign="top"></td>
|
157
|
+
</tr>
|
158
|
+
<tr>
|
159
|
+
<td width="852" align="left" valign="top"><table width="852" border="0" cellspacing="0" cellpadding="0">
|
160
|
+
<tr>
|
161
|
+
<td width="277" align="left" valign="top">
|
162
|
+
<table width="277" border="0" cellspacing="0" cellpadding="0">
|
163
|
+
<tr>
|
164
|
+
<td width="277" align="left" valign="top"><table width="277" border="0" cellspacing="0" cellpadding="0">
|
165
|
+
<tr>
|
166
|
+
<td width="277" align="left" valign="top" class="lengkungatas1"> </td>
|
167
|
+
</tr>
|
168
|
+
<tr>
|
169
|
+
<td width="277" align="left" valign="top" class="bg1"><table width="262" border="0" cellspacing="0" cellpadding="0">
|
170
|
+
<tr>
|
171
|
+
<td width="15" align="left" valign="top"> </td>
|
172
|
+
<td width="232" align="left" valign="top"><div class="subtitle">TRACE & TRACKING</div>
|
173
|
+
<div class="content">Please enter JNE Airwaybill Number (one Per line). Then Click 'Search'<br />
|
174
|
+
<em>Available up to 20 Airwaybill </em></div>
|
175
|
+
<form action="index.php?mib=tracking&lang=IN" method="POST">
|
176
|
+
<table width="232" border="0" cellspacing="0" cellpadding="0">
|
177
|
+
<tr>
|
178
|
+
<td class="lengkungatas3"> </td>
|
179
|
+
</tr>
|
180
|
+
<tr>
|
181
|
+
<td class="bg3"><table width="232" border="0" cellspacing="0" cellpadding="0">
|
182
|
+
<tr>
|
183
|
+
<td width="15" align="left" valign="top"> </td>
|
184
|
+
<td width="202" height="75" align="left" valign="top">
|
185
|
+
<textarea name="awbnum" id="awbnum" cols="25" rows="3" autocomplete="off" style="border:0px solid"></textarea>
|
186
|
+
</td>
|
187
|
+
<td width="15" align="left" valign="top"> </td>
|
188
|
+
</tr>
|
189
|
+
</table></td>
|
190
|
+
</tr>
|
191
|
+
<tr>
|
192
|
+
<td class="lengkungbawah3"> </td>
|
193
|
+
</tr>
|
194
|
+
</table>
|
195
|
+
<div style="border:0px solid;" id="tempty"></div>
|
196
|
+
<div style="text-align:right;">
|
197
|
+
<input type="submit" name="submittracking" class="btnsearch2" value="" id="trksubmit" />
|
198
|
+
</div>
|
199
|
+
</form>
|
200
|
+
</td>
|
201
|
+
<td width="15" align="left" valign="top"> </td>
|
202
|
+
</tr>
|
203
|
+
</table></td>
|
204
|
+
</tr>
|
205
|
+
<tr>
|
206
|
+
<td width="277" align="left" valign="top" class="lengkungbawah1"> </td>
|
207
|
+
</tr>
|
208
|
+
</table></td>
|
209
|
+
</tr>
|
210
|
+
<tr>
|
211
|
+
<td width="277" height="15" align="left" valign="top"></td>
|
212
|
+
</tr>
|
213
|
+
<tr>
|
214
|
+
<td width="277" height="15" align="left" valign="top"><table width="277" border="0" cellspacing="0" cellpadding="0">
|
215
|
+
<tr>
|
216
|
+
<td width="277" align="left" valign="top" class="lengkungatas5"> </td>
|
217
|
+
</tr>
|
218
|
+
<tr>
|
219
|
+
<td width="277" align="left" valign="top" class="bg1"><table width="277" border="0" cellspacing="0" cellpadding="0">
|
220
|
+
<tr>
|
221
|
+
<td width="15" align="left" valign="top"> </td>
|
222
|
+
<td align="left" valign="top"><div class="subtitle">CHECK OUR TARIFF NOW</div>
|
223
|
+
<form action="index.php?mib=tariff&lang=IN" method="POST">
|
224
|
+
<table width="247" border="0" cellspacing="0" cellpadding="0">
|
225
|
+
<tr>
|
226
|
+
<td width="67" align="left" valign="middle">FROM</td>
|
227
|
+
<td width="180" align="left" valign="middle">
|
228
|
+
<input type="text" name="from" id="origin" class="inputcheck" />
|
229
|
+
<input type="hidden" name="origin_code" id="origin_code" />
|
230
|
+
</td>
|
231
|
+
</tr>
|
232
|
+
<tr>
|
233
|
+
<td height="5" colspan="2" align="left" valign="middle"></td>
|
234
|
+
</tr>
|
235
|
+
<tr>
|
236
|
+
<td width="67" align="left" valign="middle">TO</td>
|
237
|
+
<td width="180" align="left" valign="middle">
|
238
|
+
<input type="text" name="to" id="destination" class="inputcheck" />
|
239
|
+
<input type="hidden" name="destination_code" id="destination_code" />
|
240
|
+
</td>
|
241
|
+
</tr>
|
242
|
+
<tr>
|
243
|
+
<td height="5" colspan="2" align="left" valign="middle"></td>
|
244
|
+
</tr>
|
245
|
+
<tr>
|
246
|
+
<td width="67" align="left" valign="middle">WEIGHT(Kg/s)</td>
|
247
|
+
<td width="180" align="left" valign="middle"><input type="text" name="weight" id="weight" class="inputcheck" /></td>
|
248
|
+
</tr>
|
249
|
+
<tr>
|
250
|
+
<td height="7" colspan="2" align="left" valign="top"></td>
|
251
|
+
</tr>
|
252
|
+
<tr>
|
253
|
+
<td colspan="2" align="right" valign="top"><input type="submit" name="checktariff" class="btnsubmit" value="" id="checktariff" /></td>
|
254
|
+
</tr>
|
255
|
+
<tr>
|
256
|
+
<td colspan="2" align="left" valign="top"> </td>
|
257
|
+
</tr>
|
258
|
+
<tr>
|
259
|
+
<td colspan="2" align="left" valign="top" class="content"><div align="justify">for further information please <a href="mailto:customercare@jne.co.id?subject=Checking Tariff">contact us</a>.</div></td>
|
260
|
+
</tr>
|
261
|
+
</table>
|
262
|
+
</form>
|
263
|
+
</td>
|
264
|
+
<td width="15" align="left" valign="top"> </td>
|
265
|
+
</tr>
|
266
|
+
</table></td>
|
267
|
+
</tr>
|
268
|
+
<tr>
|
269
|
+
<td width="277" align="left" valign="top" class="lengkungbawah1"> </td>
|
270
|
+
</tr>
|
271
|
+
</table></td>
|
272
|
+
</tr>
|
273
|
+
<tr>
|
274
|
+
<td width="277" height="15" align="left" valign="top"></td>
|
275
|
+
</tr>
|
276
|
+
<tr>
|
277
|
+
<td width="277" align="left" valign="top"><a href="index.php?mib=pickup&lang=IN" id="pickuporder" title="pick up order">CLICK HERE FOR PICK UP ORDER</a></td>
|
278
|
+
</tr>
|
279
|
+
</table>
|
280
|
+
</td>
|
281
|
+
<td width="18" align="left" valign="top"> </td>
|
282
|
+
<td align="left" valign="top"><table width="557" border="0" cellspacing="0" cellpadding="0">
|
283
|
+
<tr>
|
284
|
+
<td width="557" align="left" valign="top" class="lengkungatas4"> </td>
|
285
|
+
</tr>
|
286
|
+
<tr>
|
287
|
+
<td width="557" align="left" valign="top" class="bg4"><table width="557" border="0" cellspacing="0" cellpadding="0">
|
288
|
+
<tr>
|
289
|
+
<td width="15" rowspan="3" align="left" valign="top"> </td>
|
290
|
+
<td width="527" align="left" valign="top" class="subtitle">TARIFF</td>
|
291
|
+
<td width="15" rowspan="3" align="left" valign="top"> </td>
|
292
|
+
</tr>
|
293
|
+
<tr>
|
294
|
+
<td width="527" height="11" align="left" valign="top"></td>
|
295
|
+
</tr>
|
296
|
+
<tr>
|
297
|
+
<td width="527" align="left" valign="top" class="content"></td>
|
298
|
+
</tr>
|
299
|
+
<tr>
|
300
|
+
<td align="left" valign="top"> </td>
|
301
|
+
<td align="left" valign="top" class="content">
|
302
|
+
<table border="0" width="60%" cellspacing=0>
|
303
|
+
<tr class="trfH"><td width="100">Dari</td><td>:</td><td>MEDAN</td></tr>
|
304
|
+
<tr class="trfH"><td>Tujuan</td><td>:</td><td>TANGERANG</td></tr>
|
305
|
+
<tr class="trfH"><td>Berat (Kg)</td><td>:</td><td>1</td></tr>
|
306
|
+
</table>
|
307
|
+
<p></p>
|
308
|
+
<table border="0" bgcolor="#fff" cellspacing="1">
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
<tr class="trfH">
|
314
|
+
<td width="100">Nama Layanan</td><td width="120">Jenis Kiriman</td><td width="100">Tarif</td>
|
315
|
+
</tr>
|
316
|
+
<tr class='trfC'><td>SS </td><td>Dokumen/Paket</td><td>Rp. 300,000.00</td></tr><tr class='trfC'><td>YES </td><td>Dokumen/Paket</td><td>Rp. 19,500.00</td></tr><tr class='trfC'><td>REG </td><td>Dokumen/Paket</td><td>Rp. 16,000.00</td></tr><tr class='trfC'><td>OKE </td><td>Dokumen/Paket</td><td>Rp. 15,000.00</td></tr>
|
317
|
+
</table>
|
318
|
+
</td>
|
319
|
+
<td align="left" valign="top"> </td>
|
320
|
+
</tr>
|
321
|
+
</table></td>
|
322
|
+
</tr>
|
323
|
+
<tr>
|
324
|
+
<td width="557" align="left" valign="top" class="lengkungbawah4"> </td>
|
325
|
+
</tr>
|
326
|
+
</table>
|
327
|
+
|
328
|
+
</td>
|
329
|
+
</tr>
|
330
|
+
</table></td>
|
331
|
+
</tr>
|
332
|
+
<tr>
|
333
|
+
<td width="852" height="15" align="left" valign="top"></td>
|
334
|
+
</tr>
|
335
|
+
</table>
|
336
|
+
|
337
|
+
</div>
|
338
|
+
|
339
|
+
<div id="footer">
|
340
|
+
|
341
|
+
<table width="852" border="0" align="center" cellpadding="0" cellspacing="0">
|
342
|
+
<tr>
|
343
|
+
<td width="435" height="113" align="left" valign="top"><table width="435" border="0" cellspacing="0" cellpadding="0">
|
344
|
+
<tr>
|
345
|
+
<td width="435" height="35" align="left" valign="middle" class="menutop"> <a href="index.php?lang=IN">home</a>
|
346
|
+
|
|
347
|
+
<a href="index.php?mib=contact&lang=IN">contact us</a></td>
|
348
|
+
</tr>
|
349
|
+
<tr>
|
350
|
+
<td width="435" align="left" valign="top" class="copyright">Copyright © 2008 <strong>JNE</strong>. All Rights Reserved.<br />
|
351
|
+
<!--Powered by <a href="http://www.citywebindo.com" title="Cityweb Indonesia" target="_blank">Citywebindo</a>.--></td>
|
352
|
+
</tr>
|
353
|
+
</table></td>
|
354
|
+
<td width="417" height="113" align="right" valign="bottom" class="logologo"> </td>
|
355
|
+
</tr>
|
356
|
+
</table>
|
357
|
+
|
358
|
+
</div>
|
359
|
+
<script type="text/javascript">
|
360
|
+
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
361
|
+
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
362
|
+
</script>
|
363
|
+
<script type="text/javascript">
|
364
|
+
var pageTracker = _gat._getTracker("UA-5433111-1");
|
365
|
+
pageTracker._trackPageview();
|
366
|
+
</script>
|
367
|
+
</body>
|
368
|
+
|
369
|
+
</html>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w(.. test_helper)))
|
2
|
+
|
3
|
+
require 'shipindo'
|
4
|
+
|
5
|
+
class CarriersTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "A Shipindo class" do
|
8
|
+
|
9
|
+
should "find class" do
|
10
|
+
assert_equal("Shipindo::Carrier::Jne", Shipindo.find_carrier('jne').name)
|
11
|
+
assert_raises(NameError) { Shipindo.find_carrier('kantor-pos') }
|
12
|
+
end
|
13
|
+
|
14
|
+
should "display valid rate" do
|
15
|
+
data = Shipindo.find_rates(
|
16
|
+
:origin => "MEDAN",
|
17
|
+
:destination => "TANGERANG",
|
18
|
+
:weight => 2)
|
19
|
+
|
20
|
+
assert_equal "jne", data[:carrier]
|
21
|
+
assert_equal "MEDAN", data[:response][:origin]
|
22
|
+
assert_equal "TANGERANG", data[:response][:destination]
|
23
|
+
assert_equal 4, data[:response][:rates].length
|
24
|
+
assert_equal "SS", data[:response][:rates][0][:service_name]
|
25
|
+
assert_equal 330_000, data[:response][:rates][0][:rate]
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w(.. test_helper)))
|
2
|
+
|
3
|
+
require 'shipindo/carriers/jne'
|
4
|
+
|
5
|
+
class Shipindo::Carrier::Jne
|
6
|
+
public :parse_rates
|
7
|
+
end
|
8
|
+
|
9
|
+
class JneTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
context "A Jne class" do
|
12
|
+
setup do
|
13
|
+
@jne = Shipindo::Carrier::Jne.new
|
14
|
+
end
|
15
|
+
|
16
|
+
should "raise ArgumentError when no destination_code defined" do
|
17
|
+
assert_raises(ArgumentError) { @jne.find_rates(:origin => "Jakarta") }
|
18
|
+
end
|
19
|
+
|
20
|
+
should "parse rates" do
|
21
|
+
doc = Nokogiri::HTML.parse File.read('test/fixtures/jne.html')
|
22
|
+
resp = @jne.parse_rates(doc)
|
23
|
+
assert_equal "MEDAN", resp[:origin]
|
24
|
+
assert_equal "TANGERANG", resp[:destination]
|
25
|
+
assert_equal 4, resp[:rates].length
|
26
|
+
assert_equal "REG", resp[:rates][2][:service_name]
|
27
|
+
assert_equal 15_000, resp[:rates][3][:rate]
|
28
|
+
end
|
29
|
+
|
30
|
+
should "parse city list" do
|
31
|
+
list = @jne.list_city('JAKARTA')
|
32
|
+
assert_equal 6, list.length
|
33
|
+
assert_equal "JAKARTA BARAT", list[1][:city]
|
34
|
+
assert_equal "Q0dLMTAxMDBK", list[1][:code]
|
35
|
+
assert_equal "JAKARTA TIMUR", list[4][:city]
|
36
|
+
assert_equal "Q0dLMTA1MDBK", list[4][:code]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w(.. test_helper)))
|
2
|
+
|
3
|
+
require 'shipindo/helpers/rupiah_to_float'
|
4
|
+
|
5
|
+
class RupiahToFloatTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "A RupiahToFloat string extension" do
|
8
|
+
|
9
|
+
should "define aliases" do
|
10
|
+
assert "TEST".respond_to? :rupiah_to_float
|
11
|
+
assert "TEST".respond_to? :rp_to_f
|
12
|
+
end
|
13
|
+
|
14
|
+
should "parse rupiah" do
|
15
|
+
assert_equal 16_000, " 16.000,00 ".rupiah_to_float
|
16
|
+
assert_equal 16_000.50, " 16000,50 ".rupiah_to_float
|
17
|
+
assert_equal 1_600_000, " 1600000 ".rupiah_to_float
|
18
|
+
assert_equal 16_000, " Rp. 16,000.00 ".rupiah_to_float(
|
19
|
+
:thousand_separator => ",",
|
20
|
+
:cent_separator => ".")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w(.. test_helper)))
|
2
|
+
|
3
|
+
#class ShipindoTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
# context "An instance of the Shipindo class" do
|
6
|
+
|
7
|
+
# should "flunk" do
|
8
|
+
# flunk "Please provide some tests"
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# end
|
12
|
+
|
13
|
+
#end
|
14
|
+
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shipindo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- wynst
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-29 00:00:00 +07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: nokogiri
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rest-client
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description:
|
47
|
+
email: wynst.uei@gmail.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- README.rdoc
|
54
|
+
files:
|
55
|
+
- README.rdoc
|
56
|
+
- Rakefile
|
57
|
+
- lib/shipindo.rb
|
58
|
+
- lib/shipindo/carriers.rb
|
59
|
+
- lib/shipindo/carriers/jne.rb
|
60
|
+
- lib/shipindo/version.rb
|
61
|
+
- lib/shipindo/helpers/rupiah_to_float.rb
|
62
|
+
- test/fixtures/jne.html
|
63
|
+
- test/test_helper.rb
|
64
|
+
- test/unit/carriers_test.rb
|
65
|
+
- test/unit/shipindo_test.rb
|
66
|
+
- test/unit/jne_test.rb
|
67
|
+
- test/unit/rupiah_to_float_test.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://github.com/wynst/shipindo
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options:
|
74
|
+
- --main
|
75
|
+
- README.rdoc
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.3.7
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: Library that scrapes rates from various Indonesian shipping carriers web 1.0 sites.
|
101
|
+
test_files: []
|
102
|
+
|