Skip to content

Instantly share code, notes, and snippets.

@christiangenco
Created March 27, 2014 05:11
Show Gist options
  • Save christiangenco/9800775 to your computer and use it in GitHub Desktop.
Save christiangenco/9800775 to your computer and use it in GitHub Desktop.
Download the swipes and flex dollars left on your SMU ID card.
#!/usr/bin/env ruby
# Author: Christian Genco (@cgenco)
# 2013-09-04
SMU_ID = "SMU STUDENT ID GOES HERE"
SMU_PW = "SMU PASSWORD GOES HERE"
require 'time'
@logfilename = "/Users/cgenco/Dropbox/flex.log"
@graphfilename = "/tmp/flex_graph.html"
require 'hpricot'
require 'rest_client'
def put(str); STDERR.puts str; end
@env = {"User-Agent"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17"}
params = {'user' => SMU_ID,'pass' => SMU_PW}
url = "https://webcardcenter.smu.edu/student/local_login.php"
# put "Getting session id"
res = RestClient.get(url, @env)
@cookies = {:cookies => res.cookies}
res.body =~ /var __sesstok = '(.*)';/
params['__sesstok'] = $1
# define "get" and "post" with the cookies
def get(url)
RestClient.get(url, @env.merge(@cookies)).body
end
def post(url, params)
RestClient.post(url, params, @env.merge(@cookies)){ |response, request, result, &block|
if [301, 302, 307].include? response.code
# follow redirects
response.follow_redirection(request, result, &block)
else
response.return!(request, result, &block)
end
}.body
end
# fun time
put "Logging in and getting data"
page = Hpricot(post(url, params))
page_text = page.inner_text
# get rid of pony
page_text["$0.00"] = ""
# when you have a problem, use regex
page_text =~ /\$(\d+\.\d{2})/
flex = $1.to_f
# then you will have two problems
page_text =~ /Block 40\s+(\d+)/
swipes = $1.to_i
graduation = Time.parse("May 19, 2013")
days = (graduation - Time.now)/(60*60*24)
# subtract spring break
spring_break_end = Time.parse("March 9, 2013")
if Time.now < spring_break_end
# put "before spring break"
days -= 9
end
puts "#{days.round(1)} days, $#{flex} flex and #{swipes} swipes left."
flex_per_day = (flex/days).round(2)
swipes_per_day = (swipes/days).round(1)
puts "That's $#{flex_per_day} flex and #{swipes_per_day} swipes per day."
put "Logout" # trying to be responsible :D
get("https://webcardcenter.smu.edu/logout.php?dir=&logout=1")
# loggin' time
require 'logger'
Logger.new(@logfilename).info("#{days.round(2)}, #{flex}, #{swipes}")
exit
#make graph!
# parse the data from the logfile
data = File.open(@logfilename).map{|line|
if line =~ /^[^\[]+\[([^\]]*)[^\:]+\: ([0-9\,\.]+)[^\(]+\(([0-9\,\.]+)/
time, total, per_day = $1, $2, $3
total = total.to_s.gsub(',','')
per_day = per_day.to_s.gsub(',','')
{
# Date.UTC(year,month,day,hours,minutes,seconds,millisec)
:time => Time.parse(time).strftime("Date.UTC(%Y,%-m-1,%-d,%-k,%-M,%-S)"),
:total => total,
:per_day => per_day
}
end
}.compact
data.map!{|h|
if h[:per_day].to_i > 5_000
h[:per_day] = 5_000.to_s
end
h
}
def make_chart(params = {})
params[:id] ||= 'chart'
params[:title] ||= 'My Chart'
params[:series_title] ||= 'My Series'
params[:y_axis] ||= 'y'
params[:data] ||= []
html=<<-END
<div id="#{params[:id]}" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
<script>
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: '#{params[:id]}',
type: 'spline'
},
title: {
text: '#{params[:title]}'
},
xAxis: {
type: 'datetime',
dateTimeLabelFormats: { // don't display the dummy year
month: '%e. %b',
year: '%b'
}
},
yAxis: {
title: {
text: '#{params[:y_axis]}'
},
min: 0
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%e. %b', this.x) +': '+ this.y +' m';
}
},
series: [{
name: '#{params[:series_title]}',
data: [
[#{params[:data].map{|d| d[0] + ',' + d[1]}.join("],\n[")}]
]
}]
});
});
});
</script>
END
end
html=<<-END
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script>google.load("jquery", "1.7.1");</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
#{make_chart(:id => 'average_use', :title => 'Internet Usage', :series_title => 'Average MB/day', :y_axis => 'MB/day', :data => data.map{|d| [d[:time], d[:per_day]]})}
#{make_chart(:id => 'total_use', :title => 'Total Internet Available', :series_title => 'Total MB', :y_axis => 'MB', :data => data.map{|d| [d[:time], d[:total]]})}
END
File.open(@graphfilename , 'w'){|f| f.puts html}
# , {
# name: 'Total MB',
# data: [
# [#{data.map{|d| d[:time] + ',' + d[:total]}.join("],\n[")}]
# ]
# }
`open /tmp/internet_graph.html` if ARGV.index("graph")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment