ispusage 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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