shipindo 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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,4 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'shipindo/carriers'
4
+
@@ -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,14 @@
1
+ module Shipindo
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 1
6
+ TINY = 1
7
+
8
+ def self.to_s # :nodoc:
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end
14
+
@@ -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> &nbsp;&nbsp; | &nbsp;&nbsp; <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> &nbsp;&nbsp; | &nbsp;&nbsp; <a href="index.php?mib=contact&amp;lang=IN">contact us</a> &nbsp;&nbsp; | &nbsp;&nbsp; <a href="#">search</a> &nbsp;&nbsp;
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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</td>
106
+ <td width="179" align="left" valign="top"><a id="newspromo" href="index.php?mib=berita&lang=IN">NEWS &amp; PROMO</a></td>
107
+ <td width="10" align="left" valign="top">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</td>
172
+ <td width="232" align="left" valign="top"><div class="subtitle">TRACE &amp; 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">&nbsp;</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">&nbsp;</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">&nbsp;</td>
188
+ </tr>
189
+ </table></td>
190
+ </tr>
191
+ <tr>
192
+ <td class="lengkungbawah3">&nbsp;</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">&nbsp;</td>
202
+ </tr>
203
+ </table></td>
204
+ </tr>
205
+ <tr>
206
+ <td width="277" align="left" valign="top" class="lengkungbawah1">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</td>
265
+ </tr>
266
+ </table></td>
267
+ </tr>
268
+ <tr>
269
+ <td width="277" align="left" valign="top" class="lengkungbawah1">&nbsp;</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">&nbsp;</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">&nbsp;</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">&nbsp;</td>
290
+ <td width="527" align="left" valign="top" class="subtitle">TARIFF</td>
291
+ <td width="15" rowspan="3" align="left" valign="top">&nbsp;</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">&nbsp;</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">&nbsp;</td>
320
+ </tr>
321
+ </table></td>
322
+ </tr>
323
+ <tr>
324
+ <td width="557" align="left" valign="top" class="lengkungbawah4">&nbsp;</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">&nbsp;<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 &copy; 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">&nbsp;</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>
@@ -0,0 +1,7 @@
1
+ # http://sneaq.net/textmate-wtf
2
+ $:.reject! { |e| e.include? 'TextMate' }
3
+
4
+ require 'rubygems'
5
+ require 'test/unit'
6
+ require 'shoulda'
7
+
@@ -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
+