three-usage 0.0.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/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2009-02-17
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,17 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.rdoc
5
+ Rakefile
6
+ bin/three-usage
7
+ lib/three_usage.rb
8
+ lib/three_usage/cli.rb
9
+ lib/three_usage/fetcher.rb
10
+ lib/three_usage/parser.rb
11
+ lib/three_usage/usage_block.rb
12
+ test/test_helper.rb
13
+ test/test_three_usage.rb
14
+ test/fixtures/initial.html
15
+ test/test_three_usage_cli.rb
16
+ test/test_three_usage_parser.rb
17
+ test/test_three_usage_usage_block.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,11 @@
1
+
2
+ For more information on three_usage, see http://three_usage.rubyforge.org
3
+
4
+ You will want to create a ~/.three_usage.yml file for storing your settings
5
+
6
+ ================
7
+ ---
8
+ username: (three mobile phone number)
9
+ password: (account password)
10
+ pin: (account pin)
11
+ ================
data/README.rdoc ADDED
@@ -0,0 +1,42 @@
1
+ = three_usage
2
+
3
+ * http://three-usage.rubyforge.org
4
+
5
+ == DESCRIPTION:
6
+
7
+ Simple scraper to downloading remaining usage from 3 (AU)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Basic scraper is written
12
+ * No support for post paid accounts (if you have one get in touch)
13
+
14
+
15
+ == INSTALL:
16
+
17
+ * gem install three-usage
18
+
19
+ == LICENSE:
20
+
21
+ (The MIT License)
22
+
23
+ Copyright (c) 2009 Alan Harper
24
+
25
+ Permission is hereby granted, free of charge, to any person obtaining
26
+ a copy of this software and associated documentation files (the
27
+ 'Software'), to deal in the Software without restriction, including
28
+ without limitation the rights to use, copy, modify, merge, publish,
29
+ distribute, sublicense, and/or sell copies of the Software, and to
30
+ permit persons to whom the Software is furnished to do so, subject to
31
+ the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be
34
+ included in all copies or substantial portions of the Software.
35
+
36
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
37
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
38
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
39
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
40
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
41
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
42
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/three_usage'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('three-usage', ThreeUsage::VERSION) do |p|
7
+ p.developer('Alan Harper', 'alan@aussiegeek.net')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
10
+ p.rubyforge_name = p.name # TODO this is default value
11
+ # p.extra_deps = [
12
+ # ['activesupport','>= 2.0.2'],
13
+ # ]
14
+ p.extra_dev_deps = [
15
+ ['newgem', ">= #{::Newgem::VERSION}"]
16
+ ]
17
+
18
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
19
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
20
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
data/bin/three-usage ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2009-2-17.
4
+ # Copyright (c) 2009. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/three_usage")
7
+
8
+ require "three_usage/cli"
9
+
10
+ ThreeUsage::CLI.execute(STDOUT, ARGV)
@@ -0,0 +1,76 @@
1
+ require 'optparse'
2
+ require 'three_usage/fetcher'
3
+ require 'three_usage/parser'
4
+
5
+ module ThreeUsage
6
+ class CLI
7
+ def self.execute(stdout, arguments=[])
8
+ config_file = File.expand_path("~/.three_usage.yml")
9
+
10
+ if File.exist?(config_file)
11
+ yaml=YAML.load_file(config_file)
12
+ options = {
13
+ :username => yaml['username'],
14
+ :password => yaml['password'],
15
+ :pin => yaml['pin'],
16
+ :full_details => false
17
+ }
18
+ else
19
+ options = {
20
+ :username => '',
21
+ :password => '',
22
+ :pin => '',
23
+ :full_details => false
24
+ }
25
+ end
26
+
27
+ parser = OptionParser.new do |opts|
28
+ opts.banner = <<-BANNER.gsub(/^ /,'')
29
+ Retreive usage from 3 website
30
+
31
+ Usage: #{File.basename($0)} [options]
32
+
33
+ Options are:
34
+ BANNER
35
+ opts.separator ""
36
+ opts.on("-u", "--username=USERNAME", String,
37
+ "Username",
38
+ "Default from ~/.three_usage.yml") { |arg| options[:username] = arg }
39
+ opts.on("-p", "--password=PASSWORD", String,
40
+ "Password",
41
+ "Default from ~/.three_usage.yml") { |arg| options[:password] = arg }
42
+ opts.on("-n", "--pin=PIN", String,
43
+ "PIN",
44
+ "Default from ~/.three_usage.yml") { |arg| options[:pin] = arg }
45
+ opts.on("-f", "--full", "Show full usage information") { options[:full_details] = true}
46
+ opts.on("-h", "--help",
47
+ "Show this help message.") { stdout.puts opts; exit }
48
+ opts.parse!(arguments)
49
+
50
+ end
51
+
52
+ mandatory_options = %w( username password pin )
53
+ abort = false
54
+ mandatory_options.each do |field|
55
+ if options[field.to_sym].nil? || options[field.to_sym] == ""
56
+ puts "You must specify " + field
57
+ abort = true
58
+ end
59
+ end
60
+ exit(1) if abort
61
+
62
+ path = options[:path]
63
+
64
+ fetcher = Fetcher.new(options[:username],options[:password],options[:pin])
65
+ parser = Parser.new(fetcher.page)
66
+
67
+ if options[:full_details]
68
+ parser.usage_blocks.each do |usage_block|
69
+ pp usage_block
70
+ end
71
+ else
72
+ puts 'Remaining Usage: ' + parser.remaining_three_quota.to_s + ' MB'
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'mechanize'
3
+
4
+ module ThreeUsage
5
+ class Fetcher
6
+ attr_accessor :page
7
+ def initialize(username,password,pin)
8
+ agent = WWW::Mechanize.new
9
+ page = agent.get('https://www.my.three.com.au/My3/jfn')
10
+ login_form = page.form('login')
11
+ login_form.login = username
12
+ login_form.password = password
13
+ page = agent.submit(login_form, login_form.buttons.first)
14
+ pin_form = page.form('myForm')
15
+ if pin_form.nil?
16
+ puts "Authentication failure"
17
+ exit(1)
18
+ end
19
+ pin_form.pin = pin
20
+ @page = agent.submit(pin_form, pin_form.buttons.first)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ require 'three_usage/usage_block'
2
+ require 'nokogiri'
3
+
4
+ module ThreeUsage
5
+ class Parser
6
+ attr_accessor :usage_blocks
7
+ def initialize(doc)
8
+ @usage_blocks = []
9
+ rows = doc.search(".my3RemainBonusFreeUnitsTable").search("tr")
10
+ rows.each do |row|
11
+ cells = row.search("td")
12
+ usage_blocks << UsageBlock.new(:description => cells[0].inner_html.gsub(/\t/, '').strip,
13
+ :remaining => cells[1].inner_html.gsub(/\t/, '').strip,
14
+ :expires_at => cells[2].inner_html.gsub(/\t/, '').strip)
15
+ end
16
+ end
17
+
18
+ def three_usage_blocks
19
+ @usage_blocks.delete_if {|b| b.block_type != :three}
20
+ end
21
+
22
+ def remaining_three_quota
23
+ three_usage_blocks.inject(0){|sum,item| sum + item.remaining}
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,19 @@
1
+ module ThreeUsage
2
+ class UsageBlock
3
+ attr_reader :description, :remaining, :expires_at, :block_type
4
+ def initialize(options)
5
+ @description = options[:description]
6
+ @remaining = options[:remaining].to_f
7
+ @expires_at = Date.strptime(options[:expires_at], '%d/%m/%y')
8
+
9
+ @block_type = case @description
10
+ when 'Prepaid Mobile Broadband (On Net)', 'Prepaid Initial Activation Data (On Net)'
11
+ :three
12
+ when 'Prepaid Roaming Mobile Broadband'
13
+ :roaming
14
+ else
15
+ :unknown
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module ThreeUsage
5
+ VERSION = '0.0.1'
6
+ end
@@ -0,0 +1,771 @@
1
+
2
+
3
+
4
+ <?xml version="1.0" encoding="ISO-8859-1"?>
5
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
6
+ <head>
7
+ <link rel="stylesheet" type="text/css" href="include/css/rich.css" media="all" />
8
+ <link rel="stylesheet" type="text/css" href="include/css/fwk.css" media="all" />
9
+ </head>
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+ <SCRIPT LANGUAGE="JavaScript">
33
+ function showHideDetails(id1,imageName) {
34
+ if (document.getElementById) {
35
+ obj1=document.getElementById(id1);
36
+ var imageSrc=document.images[imageName].src;
37
+ var newImageSrc;
38
+ /* Toggle between the images */
39
+ if (imageSrc.search(/more_/) == -1) {
40
+ newImageSrc=imageSrc.replace(/hide_/,"more_");
41
+ } else {
42
+ newImageSrc=imageSrc.replace(/more_/,"hide_");
43
+ }
44
+ document.images[imageName].src=newImageSrc;
45
+
46
+ /* Toggle between the styles. */
47
+ if (obj1.style.display == "none") {
48
+ obj1.style.display = "inline";
49
+ } else {
50
+ obj1.style.display = "none";
51
+ }
52
+ }
53
+ return;
54
+ }
55
+
56
+ function getInfo1(rolloverAmt, InationalAmt, P3Amt ,name,pname)
57
+ {
58
+ window.open('getinfo1.jsp?RA='+rolloverAmt+'&IA='+InationalAmt+'&PA='+P3Amt+'&Name='+name+'&plan='+pname,name,'left=330,width=400,height=100,top=450');
59
+ }
60
+ function getInfo2(rolloverAmt, InationalAmt, P3Amt ,name,pname)
61
+ {
62
+ window.open('getinfo1.jsp?RA='+rolloverAmt+'&IA='+InationalAmt+'&PA='+P3Amt+'&Name='+name+'&plan='+pname,name,'left=330,width=400,height=220,top=450');
63
+ }
64
+
65
+ /* Changes Made for TOPAZ -BEGIN*/
66
+ function RemUnit(freeUnitName,AMT,Edate,rateplan)
67
+ {
68
+
69
+ window.open('Remainingunits.jsp?name='+freeUnitName+'&amt='+AMT+'&enddate='+Edate+'&rateplanname='+rateplan,"Remunit",'left=330,width=240,height=200,top=450');
70
+ }
71
+
72
+ function showdet()
73
+ {
74
+
75
+ window.open('Addon.jsp',"addOn",'left=330,width=270,height=220,top=450');
76
+ }
77
+
78
+ /* Changes made for TOPAZ ends */
79
+
80
+ </SCRIPT>
81
+
82
+
83
+
84
+
85
+ <!-- added by hari -->
86
+
87
+ <!-- end -->
88
+
89
+ <html xmlns="http://www.w3.org/1999/xhtml">
90
+ <head>
91
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
92
+ <link rel="stylesheet" type="text/css" href="include/css/rich.css" title="normal" media="all" />
93
+ <link rel="stylesheet" type="text/css" href="include/css/fwk.css" media="all" />
94
+ <link rel="alternate stylesheet" type="text/css" href="include/css/richMax.css" title="max" media="all" />
95
+ <title>Mobile Summary</title>
96
+ <script type="text/javascript" src="include/js/jsLib.js"></script>
97
+ <script type="text/javascript" src="include/js/sorttable.js"></script>
98
+ </head>
99
+ <body>
100
+ <div id="mainContainerALL">
101
+
102
+
103
+
104
+
105
+
106
+ <!-- added by hari -->
107
+ <table border="0" width=728 height="15" cellspacing="0" cellpadding="0" style="margin-left:8px;">
108
+ <tr>
109
+ <td align="left" rowspan="3" width=162> <img src="include/img/fwk/3logo-green.gif" width=59px height=75px border="0"></td>
110
+ <td colspan="2" rowspan="2" valign="top" align="left"><img src="include/img/fwk/my3_title.gif" width=200px height=38px></td>
111
+
112
+ <td> <div class="rightAlign"><div class="MyLastLoginFont"><b> Last Login: 8:12pm 16|02|2009 AEST</b></div></div> </td>
113
+ </tr>
114
+
115
+ <tr>
116
+ <td>
117
+ <div class="rightAlign">
118
+ <table cellpadding="0" cellspacing="0" border="0" style="margin-right:0px;">
119
+ <tr> <td align="right" valign="top">
120
+
121
+
122
+ </td>
123
+ <td valign="top" align="right">&nbsp;
124
+ <a href='jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=579&amp;jfnRC=1' onMouseOver="window.status='ChangePassword';return changePasswordImage('ChangePassword');return true;"
125
+ onMouseOut="window.status='';return changePasswordImage('ChangePassword');return false;" ><img border="0" name="ChangePassword" src="include/img/fwk/ChangePassword_nor.gif" /></a>
126
+ </td>
127
+ <td valign="top" align="right">
128
+ <a href="javaScript:logout()" id="logoutE" onMouseOver="window.status='Logout';return changeLogoutImage('Logout');return true;"
129
+ onMouseOut="window.status='';return changeLogoutImage('Logout');return false;" ><img border="0" name="Logout" src="include/img/fwk/Logout_nor.gif" /></a>
130
+ </td>
131
+ </tr>
132
+ </table>
133
+ </div>
134
+ </td>
135
+ </tr>
136
+ <tr>
137
+ <td colspan="3" valign="top" align="left">
138
+
139
+ <script language="JavaScript">
140
+ var scriptVar=0;
141
+ // Changing Image for Topmenu bar wben the item is to be Active
142
+ function activeImage(menuItemObj){
143
+ var imageSrc=document.images[menuItemObj].src;
144
+ if(imageSrc.search(/_act/) == -1){
145
+ if(imageSrc.search(/_nor/) == -1){
146
+ var newImageSrc=imageSrc.replace(/_ove/,"_act");
147
+ }else{
148
+ var newImageSrc=imageSrc.replace(/_nor/,"_act");
149
+ }
150
+ }else{
151
+ var newImageSrc=imageSrc;
152
+ }
153
+ document.images[menuItemObj].src=newImageSrc;
154
+ }
155
+ // Changing Image for Topmenu bar when the item is mouse over/on state
156
+ function changeImage(menuItemObj){
157
+
158
+ var imageSrc=document.images[menuItemObj].src;
159
+
160
+ if(imageSrc.search(/_ove/) == -1){
161
+ var newImageSrc=imageSrc.replace(/_nor/,"_ove");
162
+ }else{
163
+ var newImageSrc=imageSrc.replace(/_ove/,"_nor");
164
+ }
165
+ document.images[menuItemObj].src=newImageSrc;
166
+ return true;
167
+ }
168
+ function changeActiveImage(menuItemObj){
169
+
170
+ var imageSrc=document.images[menuItemObj].src;
171
+
172
+ if(imageSrc.search(/_ove/) == -1){
173
+ var newImageSrc=imageSrc.replace(/_act/,"_ove");
174
+ }else{
175
+ var newImageSrc=imageSrc.replace(/_ove/,"_act");
176
+ }
177
+ document.images[menuItemObj].src=newImageSrc;
178
+ return true;
179
+ }
180
+ function changePasswordImage(menuItemObj){
181
+
182
+ var imageSrc=document.images[menuItemObj].src;
183
+
184
+ if(imageSrc.search(/_ove/) == -1){
185
+ var newImageSrc=imageSrc.replace(/_nor/,"_ove");
186
+ }else{
187
+ var newImageSrc=imageSrc.replace(/_ove/,"_nor");
188
+ }
189
+ document.images[menuItemObj].src=newImageSrc;
190
+ return true;
191
+ }
192
+
193
+ function changeLogoutImage(menuItemObj){
194
+
195
+ var imageSrc=document.images[menuItemObj].src;
196
+
197
+ if(imageSrc.search(/_ove/) == -1){
198
+ var newImageSrc=imageSrc.replace(/_nor/,"_ove");
199
+ }else{
200
+ var newImageSrc=imageSrc.replace(/_ove/,"_nor");
201
+ }
202
+ document.images[menuItemObj].src=newImageSrc;
203
+ return true;
204
+ }
205
+
206
+
207
+ function logout(){
208
+ document.forms["Logout"].submit();
209
+ logoutE.disabled=true;
210
+ }
211
+ </script>
212
+
213
+ <!--
214
+ <div class="rightAlign">
215
+ <span class="MyLastLoginFont">
216
+ -->
217
+
218
+
219
+
220
+ <!-- span commented by hari -->
221
+ <form name="Logout" action='jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=2&amp;jfnRC=1' method=post>
222
+ <table class="my3HeaderTable">
223
+
224
+ <tr>
225
+ <td>
226
+ <!--
227
+
228
+
229
+ -->
230
+
231
+ <!-- hari -->
232
+
233
+ </td></tr>
234
+
235
+ </table>
236
+ </form>
237
+
238
+
239
+ <div id="lineHeaderID2"><img src="include/img/fwk/tp.gif" /></div>
240
+
241
+ <div id="menuLevelOneContainer">
242
+
243
+ <div id="MenuButtonLevelOne">
244
+ <ul>
245
+ <li id="currentitem">
246
+
247
+
248
+ <a href="jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1153&amp;jfnRC=1"
249
+ onMouseOver="window.status='My Summary_SSCPre';return changeActiveImage('My Summary_SSCPre');return true;"
250
+ onMouseOut="window.status='';return changeActiveImage('My Summary_SSCPre');return false;"
251
+ onClick="return activeImage('My Summary_SSCPre')"
252
+ >
253
+
254
+ <img border="0" name="My Summary_SSCPre" src="include/img/fwk/My Summary_SSCPre_act.gif"/></a> </li>
255
+
256
+
257
+ <li>
258
+
259
+
260
+ <a href="jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1260&amp;jfnRC=1"
261
+ onMouseOver="window.status='My Account_SSCPre';return changeImage('My Account_SSCPre');return true;"
262
+ onMouseOut="window.status='';return changeImage('My Account_SSCPre');return false;"
263
+ onClick="return activeImage('My Account_SSCPre')"
264
+ >
265
+ <!-- My Account_SSCPre -->
266
+
267
+ <img border="0" name="My Account_SSCPre" src="include/img/fwk/My Account_SSCPre_nor.gif"/> </a>
268
+
269
+ </li>
270
+
271
+
272
+ <li>
273
+
274
+
275
+ <a href="jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1097&amp;jfnRC=1"
276
+ onMouseOver="window.status='My Mobile_SSCPre';return changeImage('My Mobile_SSCPre');return true;"
277
+ onMouseOut="window.status='';return changeImage('My Mobile_SSCPre');return false;"
278
+ onClick="return activeImage('My Mobile_SSCPre')"
279
+ >
280
+ <!-- My Mobile_SSCPre -->
281
+
282
+ <img border="0" name="My Mobile_SSCPre" src="include/img/fwk/My Mobile_SSCPre_nor.gif"/> </a>
283
+
284
+ </li>
285
+
286
+
287
+ <li>
288
+
289
+
290
+ <a href="jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1082&amp;jfnRC=1"
291
+ onMouseOver="window.status='Recharge_SSCPre';return changeImage('Recharge_SSCPre');return true;"
292
+ onMouseOut="window.status='';return changeImage('Recharge_SSCPre');return false;"
293
+ onClick="return activeImage('Recharge_SSCPre')"
294
+ >
295
+ <!-- Recharge_SSCPre -->
296
+
297
+ <img border="0" name="Recharge_SSCPre" src="include/img/fwk/Recharge_SSCPre_nor.gif"/> </a>
298
+
299
+ </li>
300
+
301
+
302
+ <li>
303
+
304
+
305
+ <a href="jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1285&amp;jfnRC=1"
306
+ onMouseOver="window.status='RAF_SSCPre';return changeImage('RAF_SSCPre');return true;"
307
+ onMouseOut="window.status='';return changeImage('RAF_SSCPre');return false;"
308
+ onClick="return activeImage('RAF_SSCPre')"
309
+ >
310
+ <!-- RAF_SSCPre -->
311
+
312
+ <img border="0" name="RAF_SSCPre" src="include/img/fwk/RAF_SSCPre_nor.gif"/> </a>
313
+
314
+ </li>
315
+ </ul>
316
+ </div>
317
+ </div>
318
+
319
+ <div id="my3menuLevelOneContainerAA">
320
+ </div>
321
+
322
+
323
+ <div id="menuLevelOneEnd"><img style="display:block" src="include/img/fwk/tab_level1_end.gif" border="0" /></div>
324
+
325
+
326
+ <div id="lineMainMenuID4"><img src="include/img/fwk/tp.gif" /></div>
327
+
328
+
329
+ <div style="width: 650px;height:30px;float:left;margin-top:-5px;"></div>
330
+ </tr>
331
+ </table>
332
+
333
+ <!-- end -->
334
+ <div style="margin-top:-13px;margin-right:8px">
335
+
336
+
337
+
338
+
339
+
340
+
341
+
342
+
343
+
344
+
345
+ <table align="right" cellpadding="0" cellspacing="0" border=0 style="margin-top:-7px;">
346
+
347
+ <td valign="bottom" style="font-family:Trebuchet Ms; font-size: 11px; color: #000000;white-space: nowrap;">
348
+ &nbsp;
349
+ <b>You are logged in as the Account Administrator : Anonymous User</b>&nbsp;|&nbsp;</td>
350
+ <td valign="bottom" style="font-family:Trebuchet Ms; font-size: 11px; color: #000000;white-space: nowrap;">
351
+ <b>Mobile Number:</b></td>
352
+ <td valign="bottom" style="font-family:Trebuchet Ms; font-size: 11px; color: #000000;white-space: nowrap;">
353
+ <b>0400000000</b>
354
+
355
+
356
+
357
+ </td>
358
+
359
+
360
+ <td valign="bottom"><a href="javascript:chooseStyle('max',60)"><img src="include/img/fwk/Zoom_plus1.GIF" border=0 width=21x height=17px></a></td>
361
+ <td valign="bottom"><a href="javascript:chooseStyle('normal',60)"><img src="include/img/fwk/Zoom_minus1.GIF" border=0 width=20px height=18px></a></td>
362
+ <td valign="bottom"><a href="javaScript:print()"><img src="include/img/fwk/printer.gif" border=0 width=18px height=16px></a></td>
363
+ <td>&nbsp;</td>
364
+ <td valign="bottom"><a href='javaScript:helpLnk("http://www.three.com.au/my3help")'><img border=0 src="include/img/fwk/help.gif" width=23px height=19px></a></td>
365
+ </tr>
366
+ </table>
367
+
368
+
369
+
370
+
371
+ <script src="include/js/styleswitch.js" type="text/javascript">
372
+ function maxView()
373
+ {
374
+ chooseStyle("max", 60);
375
+
376
+ }
377
+ function normalView()
378
+ {
379
+
380
+ chooseStyle("normal", 60);
381
+
382
+ }
383
+ </script>
384
+ <script>
385
+ function helpLnk(link)
386
+ {
387
+ var load = window.open(link,'My3','left=0,width=1024,height=800,top=0');
388
+
389
+ }
390
+
391
+ </script>
392
+
393
+
394
+ </div>
395
+ <br>
396
+ <!--
397
+ <div id="mainContainerContentSummary">
398
+ <div id="mainMenuContainer">
399
+ <div id="workspaceContainerSummary"> -->
400
+ <!-- <h1>Mobile Summary</h1> -->
401
+ <!--
402
+ <table id="workspaceContainer" border=0>
403
+ -->
404
+
405
+
406
+ <body>
407
+ <br />
408
+ <!-- Check for contract Status-->
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+ <!-- table added by hari -->
441
+ <table border="0" cellspacing="0" cellpadding="3" style="margin-left:8px;">
442
+ <tr>
443
+ <td align="left" valign="top">
444
+ <table border="1" cellpadding="0" height=454px cellspacing="0" width="547px"
445
+ style="background-image: url(include/img/fwk/watermark_744x550.gif);
446
+ border: 4px double gray;"><!-- <fieldset class="miniDatabox">-->
447
+ <tr>
448
+ <td valign="top">
449
+ <div class="paddingText"><img src="include/img/fwk/ST_MySummary.gif" /></div>
450
+ <hr />
451
+ <div style="border:0px;height:430px;overflow:auto">
452
+ <!-- Main Div Overflow -->
453
+ <div id="DATA" style="border: 0px solid gray;height:auto">
454
+
455
+ <table border="0" cellpadding="0" cellspacing="0" style="margin-top:7px;margin-left:25px;">
456
+
457
+
458
+ <tr>
459
+ <td colspan=2 align="left" valign="top" class="my3GroupSubHeadingText">
460
+ Prepaid Mobile Broadband</td>
461
+
462
+ <td colspan=2 align="right" width="270px" class="my3GroupNormalText">
463
+
464
+
465
+ <a href='jfn?myAutoRecharge=Yes&amp;&amp;oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1325&amp;jfnRC=1' style="color:#666666;">
466
+ My auto recharge</a> |
467
+ <a href='jfn?oid=L8%3A10216202&amp;ctx=L&amp;mfunc=1325&amp;jfnRC=1' style="color:#666666;">
468
+ Set up auto recharge</a>
469
+
470
+
471
+ </td>
472
+ </tr>
473
+
474
+ <tr>
475
+ <td class="my3GroupNormalText" width="130px" align="left" style="padding-top:7px;padding-bottom:7px;">$29 - 3 Broadband 2GB</td>
476
+ </tr>
477
+
478
+ </div>
479
+ </td>
480
+ </tr>
481
+ </table>
482
+ <hr>
483
+
484
+
485
+ <!--End of BFR -->
486
+
487
+
488
+
489
+
490
+
491
+ <div id="remainUnits" class="paddingText" style="border: 0px solid gray; height:auto">
492
+ <table border="0">
493
+ <tr>
494
+ <td class="my3GroupSubHeadingText" colspan="2" align="left"><b>Remaining Units</b><br /></td>
495
+ </tr>
496
+ </table>
497
+ <div style="margin-top:5px">
498
+ <table width=100% class="my3RemainBonusFreeUnitsTable">
499
+ <thead>
500
+ <th >Type</th>
501
+ <th >Remaining</th>
502
+ <th >Expires</th>
503
+ </thead>
504
+ <tbody>
505
+
506
+ <tr>
507
+ <td>
508
+
509
+ Free Talk on 3
510
+
511
+
512
+ </td>
513
+ <td>
514
+
515
+ 0 min 0 sec
516
+ </td>
517
+ <td>
518
+
519
+ 10/03/09
520
+ </td>
521
+ <td>
522
+
523
+ </td>
524
+ </tr>
525
+
526
+ <tr>
527
+ <td>
528
+
529
+ Free SMS
530
+
531
+
532
+ </td>
533
+ <td>
534
+
535
+ 10 SMS
536
+ </td>
537
+ <td>
538
+
539
+ 10/03/09
540
+ </td>
541
+ <td>
542
+
543
+ <div>
544
+ <a href= "javascript:RemUnit('Free Prepaid SMS','0','10/03/09','$29 - 3 Broadband 2GB');">
545
+ <img align="left" src="include/img/fwk/help.gif" border="0"/>
546
+
547
+ </a>
548
+ </div>
549
+
550
+ </td>
551
+ </tr>
552
+
553
+ <tr>
554
+ <td>
555
+
556
+ Prepaid Mobile Broadband (On Net)
557
+
558
+
559
+ </td>
560
+ <td>
561
+
562
+ 2048.000MB
563
+ </td>
564
+ <td>
565
+
566
+ 10/03/09
567
+ </td>
568
+ <td>
569
+
570
+ <div>
571
+ <a href= "javascript:RemUnit('Prepaid Mobile Broadband (On Net)','0.00MB','10/03/09','$29 - 3 Broadband 2GB');">
572
+ <img align="left" src="include/img/fwk/help.gif" border="0"/>
573
+
574
+ </a>
575
+ </div>
576
+
577
+ </td>
578
+ </tr>
579
+
580
+ <tr>
581
+ <td>
582
+
583
+ Prepaid Roaming Mobile Broadband
584
+
585
+
586
+ </td>
587
+ <td>
588
+
589
+ 2.000MB
590
+ </td>
591
+ <td>
592
+
593
+ 10/03/09
594
+ </td>
595
+ <td>
596
+
597
+ <div>
598
+ <a href= "javascript:RemUnit('Prepaid Roaming Mobile Broadband','0.00MB','10/03/09','$29 - 3 Broadband 2GB');">
599
+ <img align="left" src="include/img/fwk/help.gif" border="0"/>
600
+
601
+ </a>
602
+ </div>
603
+
604
+ </td>
605
+ </tr>
606
+
607
+ <tr>
608
+ <td>
609
+
610
+ Prepaid Initial Activation Data (On Net)
611
+
612
+
613
+ </td>
614
+ <td>
615
+
616
+ 14.052MB
617
+ </td>
618
+ <td>
619
+
620
+ 07/03/09
621
+ </td>
622
+ <td>
623
+
624
+ </td>
625
+ </tr>
626
+
627
+
628
+ </table></div><br />
629
+ </div>
630
+
631
+ <hr>
632
+
633
+
634
+
635
+
636
+
637
+
638
+
639
+
640
+
641
+ </div><!-- Main Div Overflow -->
642
+ </td>
643
+ </tr>
644
+ </table>
645
+
646
+ </td><!-- main table -->
647
+
648
+ <!-- side table begin-->
649
+ <td valign="top" align="left">
650
+
651
+ <table cellpadding="0" cellspacing="1" style="float:right;width:170px;background-image: url(../img/fwk/watermark_180x550.gif);
652
+ border: 0px ridge;position:relative;font-family: Trebuchet Ms; font-size: 8px; solid gray;">
653
+ <tr>
654
+ <td valign="top" height=25>
655
+ <div><img src="include/img/fwk/packs_passes_hdr.gif"/></div>
656
+ </td>
657
+ </tr>
658
+ <tr>
659
+ <td width=159 height=425 valign="top" style="border: 0px solid #666666; background-image: url(include/img/fwk/watermark_180x550.gif);">
660
+ <table align="left" cellpadding="0" cellspacing="0" style="width:170px; height:54px;background-image: url(include/img/fwk/watermark_180x550.gif); background-repeat: no-repeat;border: 1px solid gray;">
661
+ <tr>
662
+ <td valign="top" width="100%">
663
+ <table class="my3sideDataTable" width="100%">
664
+ <tr>
665
+ <td class="alt">
666
+
667
+ <span class="my3GroupNormalText">You're signed upto </span><br />
668
+ <b>
669
+ 0&nbsp;</b><span class="my3GroupNormalText">packs/passes</span>
670
+
671
+ </td>
672
+ </tr>
673
+ </table> <!-- End of my3sideDataTable-->
674
+
675
+
676
+ <!-- </fieldset> -->
677
+ </td>
678
+ </tr>
679
+ </table>
680
+ </td>
681
+ </tr>
682
+ </table>
683
+ </td>
684
+ <!-- side table end -->
685
+
686
+ </tr>
687
+ </table>
688
+
689
+ </table>
690
+
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+ </tr>
702
+ </table>
703
+
704
+ </table>
705
+
706
+
707
+
708
+
709
+
710
+ <!--
711
+ </div> <workspaceContainer>
712
+ </div> <mainMenuContainer>
713
+ </div> <mainContainerContent>
714
+ -->
715
+ <!-- <div id="mainContainerFooter"> -->
716
+ <!-- <div id="corporatePageFooterContainer"> -->
717
+ <!-- table added hari -->
718
+ <br>
719
+ <table align="left" style="margin-left: 16px;" border="0" width="726">
720
+ <tr><td valign="top"><div id="corporatePageFooterContainer">
721
+ <b><a href="javascript:click()" style="color:black"><u>Terms of Use</u></a> &nbsp;&nbsp;|&nbsp;&nbsp;
722
+ <a href = "http://www.three.com.au/privacypolicy.html" target="_blank" style="color:black"><u>Privacy policy</u></a></b>
723
+ </div></td></tr>
724
+ </table>
725
+
726
+ <!-- </div>-->
727
+
728
+ <!--
729
+ <div style="position: absolute;left: 20px">
730
+
731
+
732
+
733
+ </div>
734
+ </div>
735
+ -->
736
+
737
+
738
+ </div> <!--mainContainerAll-->
739
+ <script type="text/javascript">
740
+ function click()
741
+ {
742
+ var load = window.open('Termofuse.html','My3',"scrollbars=1,width=650,height=600,top=100, left=300");
743
+ }
744
+
745
+
746
+ </script>
747
+
748
+
749
+
750
+
751
+ </BODY>
752
+
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+ <script src="https://ssl.google-analytics.com/urchin.js" type="text/javascript">
765
+ </script>
766
+ <script type="text/javascript">
767
+ _uacct = 'UA-939169-4';
768
+ var trackerName = 'My3AccountSummary';
769
+ urchinTracker(trackerName);
770
+ </script>
771
+
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'stringio'
3
+ require 'test/unit'
4
+ require 'shoulda'
5
+
6
+ require File.dirname(__FILE__) + '/../lib/three_usage'
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestThreeUsage < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+ require 'three_usage/cli'
3
+
4
+ class TestThreeUsageCli < Test::Unit::TestCase
5
+ def setup
6
+ ThreeUsage::CLI.execute(@stdout_io = StringIO.new, [])
7
+ @stdout_io.rewind
8
+ @stdout = @stdout_io.read
9
+ end
10
+
11
+ def test_not_print_default_output
12
+ assert_no_match(/To update this executable/, @stdout)
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+ require 'three_usage/parser'
3
+
4
+ class TestThreeUsageParser < Test::Unit::TestCase
5
+ context "initial setup" do
6
+ setup do
7
+ doc = Nokogiri::HTML(File.read(File.join(File.dirname(__FILE__), "fixtures/initial.html")))
8
+ @parser = ThreeUsage::Parser.new(doc)
9
+
10
+ end
11
+
12
+ # FIXME: this test should work but I'm not sure why it doesn't
13
+ # should "return remaining three data blocks" do
14
+ # assert_same_elements ([
15
+ # ThreeUsage::UsageBlock.new(
16
+ # :description => 'Prepaid Mobile Broadband (On Net)',
17
+ # :remaining => 2048,
18
+ # :expires_at => '10/3/09'
19
+ # ),
20
+ # ThreeUsage::UsageBlock.new(
21
+ # :description => 'Prepaid Initial Activation Data (On Net)',
22
+ # :remaining => 14.052,
23
+ # :expires_at => '7/3/09'
24
+ # )
25
+ # ], @parser.three_usage_blocks)
26
+ # end
27
+ should "return remaining three quota" do
28
+ assert_equal 2062.052, @parser.remaining_three_quota
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,164 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+ require 'three_usage/usage_block'
3
+
4
+ class TestThreeUsageUsageBlock < Test::Unit::TestCase
5
+ context "neat" do
6
+ context "prepaid on net" do
7
+ setup do
8
+ @data_block = ThreeUsage::UsageBlock.new(
9
+ :description => 'Prepaid Mobile Broadband (On Net)',
10
+ :remaining => 2048,
11
+ :expires_at => '10/03/09'
12
+ )
13
+ end
14
+
15
+ should "return description" do
16
+ assert_equal 'Prepaid Mobile Broadband (On Net)', @data_block.description
17
+ end
18
+
19
+ should "return remaining megabytes" do
20
+ assert_equal 2048, @data_block.remaining
21
+ end
22
+
23
+ should "return expiry" do
24
+ assert_equal Date.parse('2009/03/10'), @data_block.expires_at
25
+ end
26
+
27
+ should "return block_type" do
28
+ assert_equal :three, @data_block.block_type
29
+ end
30
+ end
31
+
32
+ context "prepaid roaming" do
33
+ setup do
34
+ @data_block = ThreeUsage::UsageBlock.new(
35
+ :description => 'Prepaid Roaming Mobile Broadband',
36
+ :remaining => 2,
37
+ :expires_at => '10/03/09'
38
+ )
39
+ end
40
+
41
+ should "return description" do
42
+ assert_equal 'Prepaid Roaming Mobile Broadband', @data_block.description
43
+ end
44
+
45
+ should "return remaining megabytes" do
46
+ assert_equal 2, @data_block.remaining
47
+ end
48
+
49
+ should "return expiry" do
50
+ assert_equal Date.parse('2009/03/10'), @data_block.expires_at
51
+ end
52
+
53
+ should "return block_type" do
54
+ assert_equal :roaming, @data_block.block_type
55
+ end
56
+ end
57
+
58
+ context "prepaid initial on net" do
59
+ setup do
60
+ @data_block = ThreeUsage::UsageBlock.new(
61
+ :description => 'Prepaid Initial Activation Data (On Net)',
62
+ :remaining => 14.052,
63
+ :expires_at => '7/03/09'
64
+ )
65
+ end
66
+
67
+ should "return description" do
68
+ assert_equal 'Prepaid Initial Activation Data (On Net)', @data_block.description
69
+ end
70
+
71
+ should "return remaining megabytes" do
72
+ assert_equal 14.052, @data_block.remaining
73
+ end
74
+
75
+ should "return expiry" do
76
+ assert_equal Date.parse('2009/03/7'), @data_block.expires_at
77
+ end
78
+
79
+ should "return block_type" do
80
+ assert_equal :three, @data_block.block_type
81
+ end
82
+ end
83
+ end
84
+ context "from html" do
85
+ context "prepaid on net" do
86
+ setup do
87
+ @data_block = ThreeUsage::UsageBlock.new(
88
+ :description => 'Prepaid Mobile Broadband (On Net)',
89
+ :remaining => '2048.000MB',
90
+ :expires_at => '10/03/09'
91
+ )
92
+ end
93
+
94
+ should "return description" do
95
+ assert_equal 'Prepaid Mobile Broadband (On Net)', @data_block.description
96
+ end
97
+
98
+ should "return remaining megabytes" do
99
+ assert_equal 2048, @data_block.remaining
100
+ end
101
+
102
+ should "return expiry" do
103
+ assert_equal Date.parse('2009/03/10'), @data_block.expires_at
104
+ end
105
+
106
+ should "return block_type" do
107
+ assert_equal :three, @data_block.block_type
108
+ end
109
+ end
110
+
111
+ context "prepaid roaming" do
112
+ setup do
113
+ @data_block = ThreeUsage::UsageBlock.new(
114
+ :description => 'Prepaid Roaming Mobile Broadband',
115
+ :remaining => '2.000MB',
116
+ :expires_at => '10/03/09'
117
+ )
118
+ end
119
+
120
+ should "return description" do
121
+ assert_equal 'Prepaid Roaming Mobile Broadband', @data_block.description
122
+ end
123
+
124
+ should "return remaining megabytes" do
125
+ assert_equal 2, @data_block.remaining
126
+ end
127
+
128
+ should "return expiry" do
129
+ assert_equal Date.parse('2009/03/10'), @data_block.expires_at
130
+ end
131
+
132
+ should "return block_type" do
133
+ assert_equal :roaming, @data_block.block_type
134
+ end
135
+ end
136
+
137
+ context "prepaid initial on net" do
138
+ setup do
139
+ @data_block = ThreeUsage::UsageBlock.new(
140
+ :description => 'Prepaid Initial Activation Data (On Net)',
141
+ :remaining => '14.052MB',
142
+ :expires_at => '7/03/09'
143
+ )
144
+ end
145
+
146
+ should "return description" do
147
+ assert_equal 'Prepaid Initial Activation Data (On Net)', @data_block.description
148
+ end
149
+
150
+ should "return remaining megabytes" do
151
+ assert_equal 14.052, @data_block.remaining
152
+ end
153
+
154
+ should "return expiry" do
155
+ assert_equal Date.parse('2009/03/7'), @data_block.expires_at
156
+ end
157
+
158
+ should "return block_type" do
159
+ assert_equal :three, @data_block.block_type
160
+ end
161
+ end
162
+
163
+ end
164
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: three-usage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alan Harper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-28 00:00:00 +10:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.3
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: Simple scraper to downloading remaining usage from 3 (AU)
36
+ email:
37
+ - alan@aussiegeek.net
38
+ executables:
39
+ - three-usage
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - PostInstall.txt
46
+ - README.rdoc
47
+ files:
48
+ - History.txt
49
+ - Manifest.txt
50
+ - PostInstall.txt
51
+ - README.rdoc
52
+ - Rakefile
53
+ - bin/three-usage
54
+ - lib/three_usage.rb
55
+ - lib/three_usage/cli.rb
56
+ - lib/three_usage/fetcher.rb
57
+ - lib/three_usage/parser.rb
58
+ - lib/three_usage/usage_block.rb
59
+ - test/test_helper.rb
60
+ - test/test_three_usage.rb
61
+ - test/fixtures/initial.html
62
+ - test/test_three_usage_cli.rb
63
+ - test/test_three_usage_parser.rb
64
+ - test/test_three_usage_usage_block.rb
65
+ has_rdoc: true
66
+ homepage: http://three-usage.rubyforge.org
67
+ post_install_message: PostInstall.txt
68
+ rdoc_options:
69
+ - --main
70
+ - README.rdoc
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project: three-usage
88
+ rubygems_version: 1.3.1
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Simple scraper to downloading remaining usage from 3 (AU)
92
+ test_files:
93
+ - test/test_helper.rb
94
+ - test/test_three_usage.rb
95
+ - test/test_three_usage_cli.rb
96
+ - test/test_three_usage_parser.rb
97
+ - test/test_three_usage_usage_block.rb