Permalink
Browse files

Add smart rider info to the application

  • Loading branch information...
1 parent 4e3b416 commit 054825fe4409379b6ddb14e7c3cfc17b3b4b4d06 @Sutto committed Nov 26, 2011
View
1 .rspec
@@ -0,0 +1 @@
+--colour
View
@@ -23,6 +23,11 @@ group :test, :development do
gem 'rspec-rails'
end
+group :test do
+ gem 'webmock'
+ gem 'vcr'
+end
+
gem "slugged", :git => "git://github.com/Sutto/slugged.git"
gem "thin"
View
@@ -50,6 +50,7 @@ GEM
activesupport (= 3.1.1)
activesupport (3.1.1)
multi_json (~> 1.0)
+ addressable (2.2.6)
api_smith (1.0.0)
hashie (~> 1.0)
httparty
@@ -62,6 +63,7 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.1.3)
+ crack (0.3.1)
daemons (1.1.4)
diff-lcs (1.1.3)
erubis (2.7.0)
@@ -161,6 +163,10 @@ GEM
multi_json (>= 1.0.2)
uuid (2.3.4)
macaddr (~> 1.0)
+ vcr (1.11.3)
+ webmock (1.7.8)
+ addressable (~> 2.2, > 2.2.5)
+ crack (>= 0.1.7)
will_paginate (3.0.2)
yajl-ruby (1.1.0)
@@ -182,3 +188,5 @@ DEPENDENCIES
slugged!
thin
uglifier (>= 1.0.3)
+ vcr
+ webmock
@@ -1,5 +1,7 @@
class ApplicationController < RocketPants::Base
+ map_error! ActiveRecord::RecordNotFound, RocketPants::NotFound
+
private
# Only use timeout-based caching due to the nature of our app.
@@ -0,0 +1,9 @@
+class SmartRidersController < ApplicationController
+
+ def show
+ smart_rider = TransperthClient.smart_rider(params[:id])
+ raise RocketPants::NotFound if smart_rider.blank?
+ expose smart_rider
+ end
+
+end
@@ -9,7 +9,7 @@ def index
end
def show
- expose TrainStation.find_using_slug(params[:id])
+ expose TrainStation.find_using_slug!(params[:id])
end
private
View
@@ -2,5 +2,6 @@
api :version => 1 do
get 'train_stations', :to => 'train_stations#index'
get 'train_stations/:id', :to => 'train_stations#show', :as => :train_station
+ get 'smart_riders/:id', :to => 'smart_riders#show', :as => :smart_rider
end
end
View
@@ -1,9 +1,12 @@
require 'httparty'
require 'nokogiri'
+require 'open-uri'
class TransperthClient
URL_SCHEME = "http://www.transperth.wa.gov.au/TimetablesMaps/LiveTrainTimes/tabid/436/stationname/%s/Default.aspx"
+ # http://136213.mobi/SmartRider/SmartRiderResult.aspx?SRN=
+ SMART_RIDER_SCHEME = "http://136213.mobi/SmartRider/SmartRiderResult.aspx?SRN=%s"
class TrainTime < APISmith::Smash
@@ -17,6 +20,29 @@ class TrainTime < APISmith::Smash
end
+ class SmartRiderStatus < APISmith::Smash
+ property :balance
+ property :concession_type
+ property :concession_expires
+ property :autoload
+ end
+
+ def self.smart_rider(code)
+ code = code.to_s.gsub /\D/, ''
+ return nil unless code =~ /^\d{9}$/
+ url = SMART_RIDER_SCHEME % URI.escape(code)
+ raw = open(url).read
+ return nil if raw =~ /smartrider number not found/i
+ doc = Nokogiri::HTML raw
+ nbsp = Nokogiri::HTML("&nbsp;").text
+ SmartRiderStatus.new({
+ :balance => doc.at_css('span#lblCurrentBalance').text[/(\d+)\.(\d+)/].to_f,
+ :autoload => doc.at_css('span#lblAutoload').text.downcase.include?("true"),
+ :concession_type => doc.at_css('span#lblType').text.strip,
+ :concession_expires => doc.at_css('span#lblExpires').text.strip.presence
+ })
+ end
+
def self.live_times(station)
url = URL_SCHEME % URI.escape(station.to_s)
doc = Nokogiri::HTML HTTParty.get(url)
@@ -0,0 +1,5 @@
+require 'spec_helper'
+
+describe SmartRidersController do
+
+end
No changes.
View
@@ -0,0 +1,19 @@
+# This file is copied to spec/ when you run 'rails generate rspec:install'
+ENV["RAILS_ENV"] ||= 'test'
+require File.expand_path("../../config/environment", __FILE__)
+require 'rspec/rails'
+require 'rspec/autorun'
+
+# Requires supporting ruby files with custom matchers and macros, etc,
+# in spec/support/ and its subdirectories.
+Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+RSpec.configure do |config|
+ config.mock_with :rr
+ config.use_transactional_fixtures = true
+ config.infer_base_class_for_anonymous_controllers = false
+ config.include RocketPants::TestHelper, :type => :controller
+ config.include RocketPants::RSpecMatchers, :type => :controller
+ config.extend VCR::RSpec::Macros
+ config.extend VCRCassetteExtensions
+end
View
@@ -0,0 +1,27 @@
+VCR.config do |c|
+ c.cassette_library_dir = Rails.root.join('spec', 'fixtures')
+ c.stub_with :webmock
+end
+
+module VCRCassetteExtensions
+
+ def self.extended(parent)
+ class << parent
+ alias_method_chain :use_vcr_cassette, :suffixing
+ end
+ end
+
+ # Extends use_vcr_cassette to include support for per-test suffixed scenarios.
+ def use_vcr_cassette_with_suffixing(*args)
+ use_vcr_cassette_without_suffixing(*args)
+ before :each do
+ if example.metadata[:suffix_cassette]
+ normalized_name = Jammbox::NameNormalizer.normalize(example.description)
+ existing = VCR.eject_cassette
+ new_name = File.join(existing.name, normalized_name)
+ VCR.insert_cassette new_name, {:record => :all}.merge(example.metadata[:vcr] || {})
+ end
+ end
+ end
+
+end

0 comments on commit 054825f

Please sign in to comment.