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 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
+