shipindo 0.1.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.
- 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
|
+
|