ispusage 0.4.1 → 0.4.2

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/Rakefile CHANGED
@@ -11,6 +11,7 @@ begin
11
11
  gem.homepage = "http://github.com/aussiegeek/ispusage"
12
12
  gem.authors = ["Alan Harper"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "time_travel"
14
15
  gem.add_dependency 'json'
15
16
  gem.add_dependency 'nokogiri'
16
17
  gem.add_dependency 'mechanize'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.1
1
+ 0.4.2
@@ -18,14 +18,14 @@ class IspUsage
18
18
 
19
19
  page = agent.submit(form, form.buttons.first)
20
20
 
21
+ month_start = Time.parse(page.search('/html/body/div/div[3]/div[2]/div[2]/div/p').text.match(/Usage From: (\S+)/)[0])
22
+ self.month_end = Time.local(month_start.year, month_start.month + 1, month_start.day)
21
23
  page.search('.new_usage_content').each do |usage_div|
22
- usage_period = UsagePeriod.new
23
24
  matches = usage_div.text.match(/^(\d+\.\d+)\D+(\d+)/)
24
25
  next if matches.nil?
26
+ usage_period = self.new_usage_period
25
27
  usage_period.used = matches[1].to_f * 1000
26
28
  usage_period.quota = matches[2].to_f * 1000
27
-
28
- usage_periods << usage_period
29
29
  end
30
30
 
31
31
  usage_periods.first.label = 'Peak'
@@ -27,9 +27,9 @@ class IspUsage
27
27
  plan_text = page.search("html>body>div>div>div:nth-of-type(3)>div>div:nth-of-type(2)>div:nth-of-type(4)>div>table tr:nth-of-type(5)>td>table tr:nth-of-type(2)>td>div>table tr:nth-of-type(2)>td:nth-of-type(2)").text
28
28
 
29
29
 
30
- downloads = UsagePeriod.new
31
- self.usage_periods << downloads
32
-
30
+ downloads = self.new_usage_period
31
+ start_date = Time.parse(page.form('UnbilledUsageTableForm')['fromDate'])
32
+ self.month_end = Time.local(start_date.year, start_date.day + 1, start_date.month - 1)
33
33
  downloads.label = phone_no
34
34
  downloads.quota = plan_text.match(/(\d+)MB/)[1].to_i
35
35
 
@@ -23,9 +23,8 @@ class IspUsage
23
23
  pin_form.pin = options[:pin]
24
24
  page = agent.submit(pin_form, pin_form.buttons.first)
25
25
 
26
- downloads = UsagePeriod.new
27
- self.usage_periods << downloads
28
-
26
+ downloads = self.new_usage_period
27
+ self.month_end = Time.parse(page.search("/html/body/div/div/div[3]/div/div[3]/table/tbody/tr/td[4]/p[3]").text)
29
28
  downloads.quota = page.search("td[width='190px;']").text.strip.to_i
30
29
  downloads.used = downloads.quota - page.search('br+strong.largeclass').text.strip.to_i
31
30
  end
@@ -25,12 +25,10 @@ class IspUsage
25
25
  page = agent.get('https://cyberstore.tpg.com.au/your_account/index.php?function=checkaccountusage')
26
26
 
27
27
  usage_text = page.search('table.light_box table tr').text
28
- peak = UsagePeriod.new(:label => 'Peak', :type => :balance)
29
- usage_periods << peak
28
+ peak = self.new_usage_period(:label => 'Peak', :type => :balance)
30
29
  peak.used = usage_text.match(/\dPeak Downloads used: (\d+)/)[1].to_i
31
30
 
32
- offpeak = UsagePeriod.new(:label => 'Off Peak', :type => :balance)
33
- usage_periods << offpeak
31
+ offpeak = self.new_usage_period(:label => 'Off Peak', :type => :balance)
34
32
  offpeak.used = usage_text.match(/Off-Peak Downloads used: (\d+)/)[1].to_i
35
33
 
36
34
  end
@@ -16,7 +16,7 @@ class IspUsage
16
16
  login_form.pass = self.password
17
17
  page = agent.submit(login_form, login_form.buttons.first)
18
18
 
19
- usage = UsagePeriod.new(:type => :balance)
19
+ usage = self.new_usage_period(:type => :balance)
20
20
  self.usage_periods << usage
21
21
 
22
22
  usage.used = page.search('.results_table/tr[2]/td[2]').text.match(/\d+\.\d+/)[0].to_f
@@ -4,12 +4,13 @@ require 'json'
4
4
  class IspUsage
5
5
  class Fetchers
6
6
  class Fetcher
7
- attr_accessor :usage_periods, :username, :password, :options, :error
7
+ attr_accessor :usage_periods, :username, :password, :options, :error, :month_end
8
8
 
9
9
  def initialize(options)
10
10
  @username = options[:username]
11
11
  @password = options[:password]
12
12
  self.options = options
13
+ self.month_end = options[:month_end]
13
14
  self.usage_periods = []
14
15
  end
15
16
 
@@ -20,6 +21,11 @@ class IspUsage
20
21
  :usage_periods => self.usage_periods.map(&:to_hash)
21
22
  }
22
23
 
24
+ unless month_end.nil?
25
+ hash[:month_end] = month_end
26
+ hash[:month_used] = month_used
27
+ end
28
+
23
29
  unless error.nil?
24
30
  hash[:error] = error
25
31
  end
@@ -30,6 +36,21 @@ class IspUsage
30
36
  def to_json
31
37
  to_hash.to_json
32
38
  end
39
+
40
+ def month_used
41
+ return nil if month_end.nil?
42
+ month_start = Time.local(month_end.year, month_end.month - 1, month_end.day)
43
+
44
+ month_length = month_end.to_f - month_start.to_f
45
+
46
+ (1 - (month_end.to_f - Time.now.to_f) / month_length.to_f) * 100
47
+ end
48
+
49
+ def new_usage_period(options = {})
50
+ usage_period = IspUsage::UsagePeriod.new(self, options)
51
+ self.usage_periods << usage_period
52
+ usage_period
53
+ end
33
54
  end
34
55
  end
35
56
  end
@@ -15,7 +15,8 @@ class IspUsage
15
15
  doc = Nokogiri::XML(xml)
16
16
  used = doc.search("/ii_feed[1]/volume_usage[1]/expected_traffic_types[1]/type[1]/@used").text.to_i / 998315 #best I can figure iinet uses base 2 and base 10 bytes
17
17
  quota = doc.search("/ii_feed[1]/volume_usage[1]/expected_traffic_types[1]/type[1]/quota_allocation[1]").text.to_i
18
- self.usage_periods << UsagePeriod.new(:used => used, :quota => quota)
18
+ self.month_end = Time.local(Time.now.year,Time.now.month, doc.search("//anniversary").text.to_i)
19
+ self.new_usage_period(:used => used, :quota => quota)
19
20
  end
20
21
  end
21
22
  end
@@ -40,10 +40,10 @@ class IspUsage
40
40
  }
41
41
 
42
42
  usage_doc = Nokogiri::XML(usage_xml)
43
-
43
+ self.month_end = Time.parse(usage_doc.search("//traffic/@rollover").text)
44
44
  used = usage_doc.search("/internode[1]/api[1]/traffic[1]").text.to_i / 1000000
45
45
  quota = usage_doc.search("/internode[1]/api[1]/traffic[1]/@quota").text.to_i / 1000000
46
- self.usage_periods << UsagePeriod.new(:used => used, :quota => quota)
46
+ self.new_usage_period(:used => used, :quota => quota)
47
47
  end
48
48
  end
49
49
  end
@@ -1,8 +1,9 @@
1
1
  class IspUsage
2
2
  class UsagePeriod
3
- attr_accessor :quota, :used, :label
3
+ attr_accessor :quota, :used, :label, :fetcher
4
4
  attr_reader :type
5
- def initialize(options = {})
5
+ def initialize(fetcher, options = {})
6
+ self.fetcher = fetcher
6
7
  self.type = :meter
7
8
  self.label = ''
8
9
  auto_setters = [:quota, :used, :label, :type]
@@ -29,11 +30,14 @@ class IspUsage
29
30
  :type => type
30
31
  }
31
32
 
32
- hash.merge!({
33
- :quota => quota,
34
- :total => total,
35
- }) if type == :meter
36
-
33
+ if type == :meter
34
+ hash.merge!({
35
+ :quota => quota,
36
+ :total => total
37
+ })
38
+ hash[:month_megabytes_used] = month_megabytes_used if month_megabytes_used
39
+ end
40
+
37
41
  hash
38
42
  end
39
43
 
@@ -44,5 +48,10 @@ class IspUsage
44
48
  raise IspUsage::InvalidUsagePeriodType
45
49
  end
46
50
  end
51
+
52
+ def month_megabytes_used
53
+ return nil if fetcher.month_used.nil?
54
+ fetcher.month_used / 100 * quota
55
+ end
47
56
  end
48
57
  end
@@ -17,6 +17,10 @@ describe IspUsage::Fetchers::AUExetel do
17
17
  @usage.fetch_usage
18
18
  end
19
19
 
20
+ it "should return last day of usage period" do
21
+ @usage.month_end.should == Time.parse('2010-04-01')
22
+ end
23
+
20
24
  describe "peak usage" do
21
25
  it "should return usage correctly" do
22
26
  @usage.usage_periods.first.used.should == 13150
@@ -15,6 +15,10 @@ describe IspUsage::Fetchers::AUOptus do
15
15
  @usage.fetch_usage
16
16
  end
17
17
 
18
+ it "should set month end correctly" do
19
+ @usage.month_end.should == Time.parse('2010-03-03')
20
+ end
21
+
18
22
  it "should return usage correctly" do
19
23
  @usage.usage_periods.first.used.should == 151
20
24
  end
@@ -25,5 +25,9 @@ describe IspUsage::Fetchers::AUThree do
25
25
  it "should return total correctly" do
26
26
  @usage.usage_periods.first.total.should == 500
27
27
  end
28
+
29
+ it "should set month_end" do
30
+ @usage.month_end.should == Time.parse('2010-03-06')
31
+ end
28
32
  end
29
33
  end
@@ -1,16 +1,33 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'time_travel'
2
3
 
3
4
  describe IspUsage::Fetchers::Fetcher do
4
- it "should return hash for usage information" do
5
- @usage = IspUsage::Fetchers::Fetcher.new(:username => 'bob', :password => 'xkcd')
6
- @usage.usage_periods << IspUsage::UsagePeriod.new(:used => 500, :quota => 1000, :label => 'All Day')
7
- @usage.to_hash.should == {
8
- :usage_periods => [{:used => 500, :quota => 1000, :total => 1000, :label => 'All Day', :type => :meter}],
9
- :isp => 'Fetcher',
10
- :username => 'bob'
11
- }
12
- end
5
+ describe "usage hash" do
6
+ it "without month end" do
7
+ @usage = IspUsage::Fetchers::Fetcher.new(:username => 'bob', :password => 'xkcd')
8
+ @usage.new_usage_period(:used => 500, :quota => 1000, :label => 'All Day')
9
+ @usage.to_hash.should == {
10
+ :usage_periods => [{:used => 500, :quota => 1000, :total => 1000, :label => 'All Day', :type => :meter}],
11
+ :isp => 'Fetcher',
12
+ :username => 'bob'
13
+ }
14
+ end
13
15
 
16
+ it "with month end" do
17
+ at_time '2010-02-04 12:00' do
18
+ @usage = IspUsage::Fetchers::Fetcher.new(:username => 'bob', :password => 'xkcd', :month_end => Time.parse('2010-02-20'))
19
+ @usage.new_usage_period(:used => 500, :quota => 1000, :label => 'All Day')
20
+ @usage.to_hash.should == {
21
+ :usage_periods => [{:used => 500, :quota => 1000, :total => 1000, :label => 'All Day', :type => :meter, :month_megabytes_used => 500}],
22
+ :isp => 'Fetcher',
23
+ :username => 'bob',
24
+ :month_end => Time.parse('2010-02-20'),
25
+ :month_used => 50
26
+ }
27
+ end
28
+ end
29
+ end
30
+
14
31
  it "should return an error" do
15
32
  @usage = IspUsage::Fetchers::Fetcher.new(:username => 'bob', :password => 'xkcd')
16
33
  @usage.error = "Invalid username/password"
@@ -22,4 +39,57 @@ describe IspUsage::Fetchers::Fetcher do
22
39
  :usage_periods => []
23
40
  }
24
41
  end
42
+
43
+ describe "month used" do
44
+ before do
45
+ @usage = IspUsage::Fetchers::Fetcher.new({})
46
+ @usage.month_end = Time.parse('2010-02-22')
47
+ end
48
+
49
+ it "should be 100% at the end of the month" do
50
+ at_time '2010-02-22' do
51
+ @usage.month_used.should == 100
52
+ end
53
+ end
54
+
55
+ it "should be 0% at the start of the month" do
56
+ at_time '2010-01-22' do
57
+ @usage.month_used.should == 0
58
+ end
59
+ end
60
+
61
+ it "should be 50% in the middle of the month" do
62
+ at_time '2010-02-6 12:00' do
63
+ @usage.month_used.should == 50
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "month megabytes used" do
69
+ before do
70
+ @usage = IspUsage::Fetchers::Fetcher.new({})
71
+ @usage_period = IspUsage::UsagePeriod.new(@usage)
72
+ @usage_period.quota = 50000
73
+ @usage.usage_periods << @usage_period
74
+ @usage.month_end = Time.parse('2010-02-22')
75
+ end
76
+
77
+ it "should be 50000MB at the end of the month" do
78
+ at_time '2010-02-22' do
79
+ @usage_period.month_megabytes_used.should == 50000
80
+ end
81
+ end
82
+
83
+ it "should be 0MB at the start of the month" do
84
+ at_time '2010-01-22' do
85
+ @usage_period.month_megabytes_used.should == 0
86
+ end
87
+ end
88
+
89
+ it "should be 25000MB in the middle of the month" do
90
+ at_time '2010-02-6 12:00' do
91
+ @usage_period.month_megabytes_used.should == 25000
92
+ end
93
+ end
94
+ end
25
95
  end
@@ -7,7 +7,10 @@ describe IspUsage::Fetchers::AUIinet do
7
7
  FakeWeb.register_uri(:get, 'https://toolbox.iinet.net.au/cgi-bin/new/volume_usage_xml.cgi?action=login&username=user&password=password', :body => fixture)
8
8
  options = {:username => 'user', :password => 'password'}
9
9
  @usage = IspUsage::Fetchers::AUIinet.new(options)
10
- @usage.fetch_usage
10
+ # xml says end date relative to this month
11
+ at_time '2010-02-06' do
12
+ @usage.fetch_usage
13
+ end
11
14
  end
12
15
 
13
16
  it "should return usage correctly" do
@@ -17,5 +20,9 @@ describe IspUsage::Fetchers::AUIinet do
17
20
  it "should return quota correctly" do
18
21
  @usage.usage_periods.first.quota.should == 100000
19
22
  end
23
+
24
+ it "should return last day of usage period" do
25
+ @usage.month_end.should == Time.parse('2010-02-28')
26
+ end
20
27
  end
21
28
  end
@@ -25,6 +25,10 @@ describe IspUsage::Fetchers::AUInternode do
25
25
  it "should return total correctly" do
26
26
  @usage.usage_periods.first.total.should == 50000
27
27
  end
28
+
29
+ it "should return last day of usage period" do
30
+ @usage.month_end.should == Date.parse('2010-02-21')
31
+ end
28
32
  end
29
33
 
30
34
  describe "single usage period over limit" do
@@ -3,41 +3,48 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
  describe IspUsage::UsagePeriod do
4
4
  describe "should return hash for usage period" do
5
5
  it "should describe a meter" do
6
- @usage_period = IspUsage::UsagePeriod.new(:quota => 1000, :used => 500, :label => 'All Day', :type => :meter)
6
+ @usage = IspUsage::Fetchers::Fetcher.new({})
7
+ @usage_period = @usage.new_usage_period(:quota => 1000, :used => 500, :label => 'All Day', :type => :meter)
7
8
  @usage_period.to_hash.should == {:quota => 1000, :used => 500, :total => 1000, :label => 'All Day', :type => :meter}
8
9
  end
9
10
 
10
11
  it "should describe a balance" do
11
- @usage_period = IspUsage::UsagePeriod.new(:used => 500, :label => 'Freezone', :type => :balance)
12
+ @usage = IspUsage::Fetchers::Fetcher.new({})
13
+ @usage_period = @usage.new_usage_period(:used => 500, :label => 'Freezone', :type => :balance)
12
14
  @usage_period.to_hash.should == {:used => 500, :label => 'Freezone', :type => :balance}
13
15
  end
14
16
  end
15
17
 
16
18
  describe "calculate totals" do
17
19
  it "when under quota" do
18
- @usage_period = IspUsage::UsagePeriod.new(:quota => 1000, :used => 500)
20
+ @usage = IspUsage::Fetchers::Fetcher.new({})
21
+ @usage_period = @usage.new_usage_period(:quota => 1000, :used => 500)
19
22
  @usage_period.total.should == 1000
20
23
  end
21
24
 
22
25
  it "when over quota" do
23
- @usage_period = IspUsage::UsagePeriod.new(:quota => 1000, :used => 1500)
26
+ @usage = IspUsage::Fetchers::Fetcher.new({})
27
+ @usage_period = @usage.new_usage_period(:quota => 1000, :used => 1500)
24
28
  @usage_period.total.should == 1500
25
29
  end
26
30
 
27
31
  it "when its a balance" do
28
- @usage_period = IspUsage::UsagePeriod.new(:used => 1500, :type => :balance)
32
+ @usage = IspUsage::Fetchers::Fetcher.new({})
33
+ @usage_period = @usage.new_usage_period(:used => 1500, :type => :balance)
29
34
  @usage_period.total.should be_nil
30
35
  end
31
36
  end
32
37
 
33
38
  describe "type" do
34
39
  before do
35
- @usage_period = IspUsage::UsagePeriod.new(:quota => 500, :used => 250)
40
+ @usage = IspUsage::Fetchers::Fetcher.new({})
41
+ @usage_period = @usage.new_usage_period(:quota => 500, :used => 250)
36
42
  end
37
43
 
38
44
  it "should set type correctly in initialize" do
39
- usage_period = IspUsage::UsagePeriod.new(:type => :balance)
40
- usage_period.type.should == :balance
45
+ @usage = IspUsage::Fetchers::Fetcher.new({})
46
+ @usage_period = @usage.new_usage_period(:type => :balance)
47
+ @usage_period.type.should == :balance
41
48
  end
42
49
 
43
50
  it "should default to meter" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ispusage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alan Harper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-10 00:00:00 +10:00
12
+ date: 2010-03-14 00:00:00 +10:00
13
13
  default_executable: ispusage
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -22,6 +22,16 @@ dependencies:
22
22
  - !ruby/object:Gem::Version
23
23
  version: 1.2.9
24
24
  version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: time_travel
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
25
35
  - !ruby/object:Gem::Dependency
26
36
  name: json
27
37
  type: :runtime