]> code.delx.au - monosys/commitdiff
Virgin mobile credit checking
authorJames Bunton <jamesbunton@fastmail.fm>
Mon, 1 Dec 2008 15:33:07 +0000 (02:33 +1100)
committerJames Bunton <jamesbunton@fastmail.fm>
Mon, 1 Dec 2008 15:33:07 +0000 (02:33 +1100)
scripts/virginmobile.rb [new file with mode: 0755]

diff --git a/scripts/virginmobile.rb b/scripts/virginmobile.rb
new file mode 100755 (executable)
index 0000000..8a6cc87
--- /dev/null
@@ -0,0 +1,192 @@
+#!/usr/bin/env ruby
+
+# # Sample config file
+# ROOTCA = "/etc/ssl/certs/ca-certificates.crt"
+# SMTPSERVER = "mail.example.com"
+# FROMADDR = "cron@example.com"
+# SLEEPTIME = 15
+# ACCOUNTS = [
+#      ["person1@example.com", "0499999999", "000000", 100, 30],
+#      ["person2@example.com", "0499999998", "000000", 100, 30],
+# ]
+
+require 'optparse'
+require 'net/http'
+require 'net/https'
+require 'net/smtp'
+require 'uri'
+
+class VirginMobile
+       def initialize(sleep_time, username, password)
+               @sleep_time = sleep_time
+               @username = username
+               @password = password
+               @cookie = nil
+       end
+
+       def do_request(path, form_data=nil)
+               sleep(@sleep_time) # Don't look like a bot
+               http = Net::HTTP.new("www.virginmobile.com.au", 443)
+               http.use_ssl = true
+               if File.exist? ROOTCA
+                       http.ca_file = ROOTCA
+                       http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+                       http.verify_depth = 5
+               end
+               if @cookie
+                       req = Net::HTTP::Get.new(path)
+                       req["Cookie"] = @cookie
+               end
+               if form_data
+                       req = Net::HTTP::Post.new(path)
+                       req.form_data = form_data
+               end
+               return http.request(req)
+       end
+
+       def do_login
+               form_data = {
+                       "username" => @username,
+                       "password" => @password,
+               }
+               res = do_request("/selfcare/MyAccount/LogoutLoginPre.jsp", form_data)
+               @cookie = res.fetch("Set-Cookie")
+
+               while location = res.get_fields("Location")
+                       location = URI.parse(location[0])
+                       res = do_request(location.path)
+               end
+       end
+
+       def do_logout
+               do_request("/selfcare/dispatch/Logout")
+       end
+
+       def request_bill_preview
+               res = do_request("/selfcare/dispatch/PostPayUnbilledUsage")
+               usage = res.body.scan(/\$([\d\.]*)/).flatten
+               last_bill_date = res.body.gsub(/\n/, '').scan(/Last bill date:.*(\d\d?\/\d\d?\/\d\d\d\d)/).flatten
+               return usage, last_bill_date
+       end
+
+       def request_mobile_browsing
+               res = do_request("/selfcare/dispatch/DataUsageRequest")
+               data_usage = res.body.scan(/USAGE: ([\d\.]*)MB/).flatten
+               return data_usage
+       end
+
+       def dump_result(res)
+               res.each_capitalized do |key, value|
+                       print "#{key}: #{value}\n"
+               end
+               print res.body + "\n"
+       end
+end
+
+def check_usage(sleep_time, ignore_limits, destination, username, password, usageLimit, dataLimit)
+       message = ""
+       data = VirginMobile.new(sleep_time, username, password)
+       data.do_login
+
+       usage, last_bill_date = data.request_bill_preview
+       usage.each do |x|
+               if ignore_limits or (usageLimit >= 0 and x.to_f >= usageLimit)
+                       message += "Unbilled usage: $#{x}\n"
+               end
+       end
+
+       data_usage = data.request_mobile_browsing
+       data_usage.each do |x|
+               if ignore_limits or (dataLimit >= 0 and x.to_f >= dataLimit)
+                       message += "Data usage: #{x} MiB\n"
+               end
+       end
+
+       data.do_logout
+
+       if message.length > 0
+               return destination, <<EOT
+From: #{FROMADDR}
+To: #{destination}
+Subject: Virgin Mobile Usage
+
+Virgin Mobile Usage
+-------------------
+
+Previous bill: #{last_bill_date}
+#{message}
+
+https://www.virginmobile.com.au/selfcare/MyAccount/login.jsp
+
+EOT
+
+       end
+end
+
+def send_emails(emails)
+       Net::SMTP.start(SMTPSERVER, 25) do |smtp|
+               emails.each do |destination, message|
+                       smtp.send_message(message, FROMADDR, destination)
+               end
+       end
+end
+
+def do_email(sleep_time, ignore_limits)
+       emails = []
+       ACCOUNTS.each do |args|
+               if ret = check_usage(sleep_time, ignore_limits, *args)
+                       emails.push(ret)
+               end
+       end
+       send_emails(emails)
+end
+
+def do_print(sleep_time, ignore_limits)
+       emails = []
+       ACCOUNTS.each do |args|
+               if ret = check_usage(sleep_time, ignore_limits, *args)
+                       print ret[1]
+               end
+       end
+end
+
+def main
+       ignore_limits = dry_run = fast = false
+       OptionParser.new do |opts|
+               opts.banner = "Usage: #{$0} [options] config\n"
+               opts.on("--fast", "Don't sleep between connections") do |v|
+                       fast = v
+               end
+               opts.on("--dry-run", "Don't send emails, just print them") do |v|
+                       dry_run = v
+               end
+               opts.on("--ignore-limits", "Treat all limits as 0") do |v|
+                       ignore_limits = v
+               end
+       end.parse!
+
+       config = ARGV[0]
+       begin
+               eval File.open(config).read
+       rescue
+               $stderr.print "Error parsing config file!\n\n"
+               raise
+       end
+
+       if fast
+               sleep_time = 0
+       else
+               sleep_time = SLEEPTIME
+       end
+
+       if dry_run
+               do_print(sleep_time, ignore_limits)
+       else
+               do_email(sleep_time, ignore_limits)
+       end
+end
+
+if __FILE__ == $0
+       main
+end
+