service_disruption 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in service_disruption.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,38 @@
1
+ Service Disruption
2
+ =============
3
+
4
+ A little library to easily tell you when the Tube has problems
5
+
6
+ ## Install
7
+
8
+ gem install service_disruption
9
+
10
+
11
+ ## Running
12
+
13
+ $: service_disruption start
14
+
15
+ Extra arguments are: `-d` to deamonise and `-i` to change the polling time, defaults to once every 30 seconds
16
+
17
+ Alternatively if you'd like to see some pretty colours on your command line you can run
18
+
19
+ $: service_disruption status
20
+
21
+ That will tell you the current state of the tube network, you can also incude it as any other ruby library. It exposes the following API:
22
+
23
+ network = ServiceDisruption.network
24
+
25
+ network.lines # Array of lines
26
+ bakerloo = network.find_by_name('Bakerloo') # Line object
27
+
28
+ bakerloo.status # Status object
29
+
30
+ network.update! # Updates all of the lines status information if it has changed
31
+
32
+ ## Who?
33
+
34
+ [Adam Carlile](http://adamcarlile.com) built this. Ping me on Twitter —
35
+ [@frozenproduce](http://twitter.com/frozenproduce).
36
+
37
+ NOTE: Not to be used for mission critical service monitoring!
38
+
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :spec
6
+
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.rspec_opts = "--colour --format Fuubar"
10
+ end
11
+
12
+ desc "Generate code coverage"
13
+ RSpec::Core::RakeTask.new(:coverage) do |t|
14
+ t.rcov = true
15
+ t.rcov_opts = ['--exclude', 'spec']
16
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
3
+
4
+ require 'service_disruption'
5
+
6
+ ServiceDisruption::Command.start
@@ -0,0 +1,22 @@
1
+ module ServiceDisruption
2
+ class Command < Thor
3
+
4
+ desc "start", "Run the monitor"
5
+ method_option :daemonize, :aliases => "-d", :default => false, :type => :boolean, :banner => "Run as daemon"
6
+ method_option :interval, :aliases => "-i", :default => 30, :type => :numeric, :banner => "Interval to wait to poll in seconds"
7
+ def start
8
+ network = ServiceDisruption.network
9
+ EventMachine::run do
10
+ EventMachine::add_periodic_timer(options[:interval]) do
11
+ network.update!
12
+ end
13
+ end
14
+ end
15
+
16
+ desc "status", "Show the current line status"
17
+ def status
18
+ puts ServiceDisruption.network
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ class Hash
2
+
3
+ def rubyfy_keys!
4
+ keys.each do |key|
5
+ self[(key.underscore rescue key) || key] = delete(key)
6
+ end
7
+ self
8
+ end
9
+
10
+ def recursive_rubyfy_keys!
11
+ rubyfy_keys!
12
+ values.each{|h| h.recursive_rubyfy_keys! if h.is_a?(Hash) }
13
+ values.select{|v| v.is_a?(Array) }.flatten.each{|h| h.recursive_rubyfy_keys! if h.is_a?(Hash) }
14
+ self
15
+ end
16
+
17
+ def recursive_symbolize_keys!
18
+ symbolize_keys!
19
+ values.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) }
20
+ values.select{|v| v.is_a?(Array) }.flatten.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) }
21
+ self
22
+ end
23
+
24
+ def recursive_rubyfy_and_symbolize_keys!
25
+ recursive_rubyfy_keys!
26
+ recursive_symbolize_keys!
27
+ self
28
+ end
29
+
30
+ end
@@ -0,0 +1,35 @@
1
+ module ServiceDisruption
2
+ class DataSource
3
+ include HTTParty
4
+
5
+ def initialize(url)
6
+ @url = URI.parse(url)
7
+ end
8
+
9
+ def get_latest_dataset
10
+ response = self.class.get(@url.to_s)
11
+ if response.success?
12
+ response.recursive_rubyfy_and_symbolize_keys!
13
+ else
14
+ false
15
+ end
16
+ rescue
17
+ false
18
+ end
19
+
20
+ def parse_data_set
21
+ lines_array = []
22
+ if get_latest_dataset
23
+ get_latest_dataset[:array_of_line_status][:line_status].each do |line_status|
24
+ lines_array << line_status
25
+ end
26
+ end
27
+ lines_array
28
+ end
29
+
30
+ def available_lines
31
+ parse_data_set
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ module ServiceDisruption
2
+ class Line
3
+
4
+ attr_accessor :name, :status, :id
5
+
6
+ def initialize(line)
7
+ @id = line[:line][:id]
8
+ @name = line[:line][:name]
9
+ @status = ServiceDisruption::Status.new(line[:status], line[:status_details])
10
+ ServiceDisruption.notifier.status_change(self) if @status.disrupted?
11
+ end
12
+
13
+ def to_s
14
+ "#{@name}: #{@status}"
15
+ end
16
+
17
+ def update_status(data)
18
+ old_status = @status
19
+ new_status = ServiceDisruption::Status.new(data[:status], data[:status_details])
20
+ unless old_status == new_status
21
+ @status = new_status
22
+ ServiceDisruption.notifier.status_change(self)
23
+ end
24
+ end
25
+
26
+ def disrupted?
27
+ @status.disrupted?
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,54 @@
1
+ module ServiceDisruption
2
+ class Network
3
+
4
+ attr_accessor :lines, :updated_at
5
+
6
+ def initialize(data_source)
7
+ @lines = []
8
+ @updated_at = Time.now
9
+ data_source.available_lines.each {|x| add_line ServiceDisruption::Line.new(x)}
10
+ end
11
+
12
+ def add_line(line)
13
+ @lines << line
14
+ end
15
+
16
+ def [](index)
17
+ @lines[index]
18
+ end
19
+
20
+ def find_by_name(name)
21
+ @lines.select {|x| x.name == name}
22
+ end
23
+
24
+ def find_by_id(id)
25
+ @lines.select {|x| x.id == id}
26
+ end
27
+
28
+ def update!
29
+ begin
30
+ ServiceDisruption.data_source.available_lines.each do |new_data|
31
+ line = find_by_id(new_data[:line][:id]).first
32
+ line.update_status(new_data)
33
+ end
34
+ @updated_at = Time.now
35
+ true
36
+ rescue
37
+ false
38
+ end
39
+ end
40
+
41
+ def to_s
42
+ out = []
43
+ out << ' '
44
+ out << '==========================='
45
+ out << @lines
46
+ out << '==========================='
47
+ out << "Updated at: #{@updated_at}"
48
+ out << '==========================='
49
+ out << ' '
50
+ out.join("\n")
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,35 @@
1
+ module ServiceDisruption
2
+ class Notifier
3
+
4
+ def initialize
5
+ @client = GNTP.new("Service Disruption")
6
+ register_notifications
7
+ end
8
+
9
+ def status_change(line)
10
+ @client.notify({:name => "status_change",
11
+ :title => "#{line.name} | #{line.status.status_description}",
12
+ :text => line.status.status_details,
13
+ :icon => line.status.image,
14
+ :sticky => true
15
+ })
16
+ true
17
+ rescue
18
+ false
19
+ end
20
+
21
+ private
22
+
23
+ def register_notifications
24
+ @client.register({:notifications => [{
25
+ :name => "status_change",
26
+ :enabled => true,
27
+ }]
28
+ })
29
+ true
30
+ rescue
31
+ false
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ module ServiceDisruption
2
+ class Status
3
+
4
+ COLOUR_CODES = {
5
+ :GS => :green,
6
+ :MD => :yellow,
7
+ :SD => :red,
8
+ :CS => :yellow,
9
+ :PS => :red,
10
+ :PC => :yellow
11
+ }
12
+
13
+ attr_accessor :id, :status_details, :status_description, :active
14
+
15
+ def initialize(status, status_details)
16
+ @id = status[:id].upcase.to_sym
17
+ @status_details = status_details
18
+ @status_description = status[:description]
19
+ @active = status[:is_active]
20
+ @updated_at = Time.now
21
+ end
22
+
23
+ def image
24
+ "#{ROOT_PATH}/static/#{@id.to_s.downcase}.png"
25
+ end
26
+
27
+ def to_s
28
+ out = [@status_description]
29
+ out << @status_details unless @status_details.nil?
30
+ out.join(' ').color(COLOUR_CODES[@id])
31
+ end
32
+
33
+ def disrupted?
34
+ [:MD, :SD, :CS, :PS, :PC].include? @id
35
+ end
36
+
37
+ def ==(another_status)
38
+ (self.id == another_status.id) && (self.status_details == another_status.status_details)
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,45 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue LoadError
4
+ end
5
+
6
+ require 'uri'
7
+ require 'thor'
8
+ require 'httparty'
9
+ require 'eventmachine'
10
+ require 'rainbow'
11
+ require 'ruby_gntp'
12
+ require 'active_support/core_ext'
13
+
14
+ #Redefine runtime loadpath
15
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
16
+
17
+ require "service_disruption/command"
18
+ require "service_disruption/data_source"
19
+ require "service_disruption/line"
20
+ require "service_disruption/status"
21
+ require "service_disruption/network"
22
+ require "service_disruption/notifier"
23
+
24
+ require "service_disruption/core_ext/hash"
25
+
26
+ module ServiceDisruption
27
+ VERSION = '0.0.1'
28
+ TFL_ENDPOINT = 'http://cloud.tfl.gov.uk/TrackerNet/LineStatus'
29
+ ROOT_PATH = File.dirname(File.dirname(__FILE__))
30
+
31
+ extend self
32
+
33
+ def notifier
34
+ @notifier ||= ServiceDisruption::Notifier.new
35
+ end
36
+
37
+ def data_source
38
+ @data_source ||= ServiceDisruption::DataSource.new(TFL_ENDPOINT)
39
+ end
40
+
41
+ def network
42
+ @network ||= ServiceDisruption::Network.new(data_source)
43
+ end
44
+
45
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "service_disruption"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "service_disruption"
7
+ s.version = ServiceDisruption::VERSION
8
+ s.authors = ["Adam Carlile"]
9
+ s.email = ["adam@benchmedia.co.uk"]
10
+ s.homepage = "http://adamcarlile.com"
11
+ s.summary = %q{
12
+ A simple gem to track the current status of London Underground services
13
+ }
14
+ s.description = %q{
15
+ BOOM!
16
+ }
17
+
18
+ s.rubyforge_project = "service_disruption"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ # specify any dependencies here; for example:
26
+ s.add_development_dependency 'rake', '~> 0.9.2'
27
+ s.add_development_dependency 'rspec', '~> 2.9.0'
28
+ s.add_development_dependency 'fakeweb', '~> 1.3.0'
29
+ s.add_development_dependency 'fuubar', '~> 1.0.0'
30
+
31
+ s.add_runtime_dependency "thor", '~> 0.14.6'
32
+ s.add_runtime_dependency "httparty", '~> 0.8.3'
33
+ s.add_runtime_dependency "eventmachine", '~> 0.12.10'
34
+ s.add_runtime_dependency "rainbow", '~> 1.1.3'
35
+ s.add_runtime_dependency "activesupport", '~> 3.2.0'
36
+ s.add_runtime_dependency "ruby_gntp", '~> 0.3.4'
37
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Service Disruption / Data Source" do
4
+
5
+ context 'with a successful HTTP request' do
6
+
7
+ before(:each) do
8
+ @data_source = ServiceDisruption::DataSource.new(ServiceDisruption::TFL_ENDPOINT)
9
+ end
10
+
11
+ it 'should return an array of available lines' do
12
+ @data_source.available_lines.class.should eq(Array)
13
+ end
14
+
15
+ it 'should return an aray with more then one line' do
16
+ @data_source.available_lines.should_not be_empty
17
+ end
18
+
19
+ end
20
+
21
+ context 'with an unsuccessful HTTP request' do
22
+
23
+ before(:each) do
24
+ @data_source = ServiceDisruption::DataSource.new('http://cloud.tfl.gov.uk/unsuccessful.xml')
25
+ end
26
+
27
+ it 'should return an empty array' do
28
+ @data_source.available_lines.should be_empty
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,103 @@
1
+
2
+ <?xml version="1.0" encoding="utf-8"?>
3
+ <ArrayOfLineStatus xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://webservices.lul.co.uk/">
4
+ <LineStatus ID="0" StatusDetails="">
5
+ <BranchDisruptions />
6
+ <Line ID="1" Name="Bakerloo" />
7
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
8
+ <StatusType ID="1" Description="Line" />
9
+ </Status>
10
+ </LineStatus>
11
+ <LineStatus ID="1" StatusDetails="">
12
+ <BranchDisruptions />
13
+ <Line ID="2" Name="Central" />
14
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
15
+ <StatusType ID="1" Description="Line" />
16
+ </Status>
17
+ </LineStatus>
18
+ <LineStatus ID="10" StatusDetails="">
19
+ <BranchDisruptions />
20
+ <Line ID="7" Name="Circle" />
21
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
22
+ <StatusType ID="1" Description="Line" />
23
+ </Status>
24
+ </LineStatus>
25
+ <LineStatus ID="2" StatusDetails="No service between Turnham Green and Richmond due to planned engineering work. GOOD SERVICE on the rest of the line.">
26
+ <BranchDisruptions>
27
+ <BranchDisruption>
28
+ <StationTo ID="190" Name="Richmond" />
29
+ <StationFrom ID="238" Name="Turnham Green" />
30
+ </BranchDisruption>
31
+ </BranchDisruptions>
32
+ <Line ID="9" Name="District" />
33
+ <Status ID="PC" CssClass="DisruptedService" Description="Part Closure" IsActive="true">
34
+ <StatusType ID="1" Description="Line" />
35
+ </Status>
36
+ </LineStatus>
37
+ <LineStatus ID="8" StatusDetails="">
38
+ <BranchDisruptions />
39
+ <Line ID="8" Name="Hammersmith and City" />
40
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
41
+ <StatusType ID="1" Description="Line" />
42
+ </Status>
43
+ </LineStatus>
44
+ <LineStatus ID="4" StatusDetails="">
45
+ <BranchDisruptions />
46
+ <Line ID="4" Name="Jubilee" />
47
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
48
+ <StatusType ID="1" Description="Line" />
49
+ </Status>
50
+ </LineStatus>
51
+ <LineStatus ID="9" StatusDetails="">
52
+ <BranchDisruptions />
53
+ <Line ID="11" Name="Metropolitan" />
54
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
55
+ <StatusType ID="1" Description="Line" />
56
+ </Status>
57
+ </LineStatus>
58
+ <LineStatus ID="5" StatusDetails="">
59
+ <BranchDisruptions />
60
+ <Line ID="5" Name="Northern" />
61
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
62
+ <StatusType ID="1" Description="Line" />
63
+ </Status>
64
+ </LineStatus>
65
+ <LineStatus ID="6" StatusDetails="">
66
+ <BranchDisruptions />
67
+ <Line ID="6" Name="Piccadilly" />
68
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
69
+ <StatusType ID="1" Description="Line" />
70
+ </Status>
71
+ </LineStatus>
72
+ <LineStatus ID="7" StatusDetails="">
73
+ <BranchDisruptions />
74
+ <Line ID="3" Name="Victoria" />
75
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
76
+ <StatusType ID="1" Description="Line" />
77
+ </Status>
78
+ </LineStatus>
79
+ <LineStatus ID="11" StatusDetails="Train service will resume at 06.15 on Monday.">
80
+ <BranchDisruptions />
81
+ <Line ID="12" Name="Waterloo and City" />
82
+ <Status ID="CS" CssClass="DisruptedService" Description="Planned Closure" IsActive="true">
83
+ <StatusType ID="1" Description="Line" />
84
+ </Status>
85
+ </LineStatus>
86
+ <LineStatus ID="82" StatusDetails="No service between Willesden Junction and Richmond. No service between Euston and Watford Junction due to planned works. GOOD SERVICE on other routes.">
87
+ <BranchDisruptions>
88
+ <BranchDisruption />
89
+ <BranchDisruption />
90
+ </BranchDisruptions>
91
+ <Line ID="82" Name="Overground" />
92
+ <Status ID="PC" CssClass="DisruptedService" Description="Part Closure" IsActive="true">
93
+ <StatusType ID="1" Description="Line" />
94
+ </Status>
95
+ </LineStatus>
96
+ <LineStatus ID="81" StatusDetails="">
97
+ <BranchDisruptions />
98
+ <Line ID="81" Name="DLR" />
99
+ <Status ID="GS" CssClass="GoodService" Description="Good Service" IsActive="true">
100
+ <StatusType ID="1" Description="Line" />
101
+ </Status>
102
+ </LineStatus>
103
+ </ArrayOfLineStatus>
data/spec/line_spec.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Service Disruption / Line" do
4
+
5
+ before(:all) do
6
+ @bakerloo = {
7
+ :line => {:id => "1", :name => "Bakerloo"},
8
+ :status => {
9
+ :id => "GS",
10
+ :description => "Good Service",
11
+ :is_active => true
12
+ },
13
+ :status_details => ""
14
+ }
15
+ end
16
+
17
+ context "Line with good service" do
18
+
19
+ before(:each) do
20
+ @line = ServiceDisruption::Line.new(@bakerloo)
21
+ end
22
+
23
+ it "should not be disrupted" do
24
+ @line.disrupted?.should be_false
25
+ end
26
+
27
+ it "should return it's name and status" do
28
+ @line.to_s.should be_an_instance_of String
29
+ end
30
+
31
+ end
32
+
33
+ context "Line with minor disruptions" do
34
+
35
+ before(:each) do
36
+ @broken_bakerloo = @bakerloo.merge({
37
+ :status_details => "Oops, looks like the Bakerloo line is broken again",
38
+ :status => {
39
+ :id => "MD",
40
+ :description => "Minor Delays"
41
+ }})
42
+ @line = ServiceDisruption::Line.new(@broken_bakerloo)
43
+ end
44
+
45
+ it "should be disrupted" do
46
+ @line.disrupted?.should be_true
47
+ end
48
+
49
+ it "should allow me to change the lines status" do
50
+ @line.disrupted?.should be_true
51
+ @line.update_status(@bakerloo)
52
+ @line.disrupted?.should be_false
53
+ end
54
+
55
+ it "shouldn't create a new status object if the line status hasn't changed" do
56
+ old_status = @line.status
57
+ @line.update_status(@broken_bakerloo)
58
+ @line.status.object_id.should eq(old_status.object_id)
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Service Disruption / Network" do
4
+
5
+ before(:each) do
6
+ @network = ServiceDisruption::Network.new(ServiceDisruption.data_source)
7
+ end
8
+
9
+ it "should return a list of available lines" do
10
+ @network.lines.should_not be_empty
11
+ end
12
+
13
+ it "should allow me to find lines by position" do
14
+ @network[0].class.should eq(ServiceDisruption::Line)
15
+ end
16
+
17
+ it "should allow me to find lines by name" do
18
+ @network.find_by_name('Bakerloo').should_not be_empty
19
+ end
20
+
21
+ it "should allow me to find lines by id" do
22
+ @network.find_by_id('1').should_not be_empty
23
+ end
24
+
25
+ it "should be able to update it's list" do
26
+ old_time = @network.updated_at
27
+ @network.update!
28
+ @network.updated_at.should_not eq(old_time)
29
+ end
30
+
31
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Service Disruption" do
4
+
5
+ it "should return a network object" do
6
+ ServiceDisruption.network.class.should eq(ServiceDisruption::Network)
7
+ end
8
+
9
+ it "should return a datasource" do
10
+ ServiceDisruption.data_source.class.should eq(ServiceDisruption::DataSource)
11
+ end
12
+
13
+ it "should return a notifier" do
14
+ ServiceDisruption.notifier.class.should eq(ServiceDisruption::Notifier)
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
2
+ require 'service_disruption'
3
+ require 'fakeweb'
4
+
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:suite) do
8
+ FakeWeb.allow_net_connect = false
9
+
10
+ FakeWeb.register_uri(:get, ServiceDisruption::TFL_ENDPOINT,
11
+ :body => File.read(File.join(File.dirname(__FILE__), 'fixtures', 'line_status.xml')),
12
+ :content_type => "text/xml")
13
+
14
+ FakeWeb.register_uri(:get, 'http://cloud.tfl.gov.uk/unsuccessful.xml',
15
+ :status => ['500', 'Internal Server Error'])
16
+ end
17
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Service Disruption / Status" do
4
+
5
+ before(:all) do
6
+ @good_status = {
7
+ :id => "GS",
8
+ :description => "Good Service",
9
+ :is_active => true
10
+ }
11
+ @severe_delays = {
12
+ :id => "SD",
13
+ :description => "Severe Delays",
14
+ :is_active => true
15
+ }
16
+ end
17
+
18
+ context "Status with good service" do
19
+ before(:each) do
20
+ @status = ServiceDisruption::Status.new(@good_status, "Everything is running great")
21
+ end
22
+
23
+ it "shouldn't be disrupted" do
24
+ @status.disrupted?.should be_false
25
+ end
26
+
27
+ end
28
+
29
+ context "Status with severe delays" do
30
+ before(:each) do
31
+ @status = ServiceDisruption::Status.new(@severe_delays, "It's all horribly broken")
32
+ end
33
+
34
+ it "should be disrupted" do
35
+ @status.disrupted?.should be_true
36
+ end
37
+
38
+ end
39
+
40
+ it "should be equal when two statuses with the same attributes are compared" do
41
+ status = ServiceDisruption::Status.new(@good_status, "It's going great")
42
+ status.should == status
43
+ end
44
+
45
+ it "shouldn't be equal when two statuses with the same attributes are compared" do
46
+ good_status = ServiceDisruption::Status.new(@good_status, "It's going great")
47
+ bad_status = ServiceDisruption::Status.new(@severe_delays, "Oh dear")
48
+ good_status.should_not == bad_status
49
+ end
50
+
51
+ end
data/static/cs.png ADDED
Binary file
data/static/gs.png ADDED
Binary file
data/static/md.png ADDED
Binary file
data/static/ps.png ADDED
Binary file
data/static/sd.png ADDED
Binary file
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: service_disruption
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Adam Carlile
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70126178324100 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.2
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70126178324100
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70126178339920 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.9.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70126178339920
36
+ - !ruby/object:Gem::Dependency
37
+ name: fakeweb
38
+ requirement: &70126178339400 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.3.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70126178339400
47
+ - !ruby/object:Gem::Dependency
48
+ name: fuubar
49
+ requirement: &70126178338900 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70126178338900
58
+ - !ruby/object:Gem::Dependency
59
+ name: thor
60
+ requirement: &70126178338400 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.14.6
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70126178338400
69
+ - !ruby/object:Gem::Dependency
70
+ name: httparty
71
+ requirement: &70126178337940 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 0.8.3
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70126178337940
80
+ - !ruby/object:Gem::Dependency
81
+ name: eventmachine
82
+ requirement: &70126178337480 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: 0.12.10
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *70126178337480
91
+ - !ruby/object:Gem::Dependency
92
+ name: rainbow
93
+ requirement: &70126178337020 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 1.1.3
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: *70126178337020
102
+ - !ruby/object:Gem::Dependency
103
+ name: activesupport
104
+ requirement: &70126178336560 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 3.2.0
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: *70126178336560
113
+ - !ruby/object:Gem::Dependency
114
+ name: ruby_gntp
115
+ requirement: &70126178336080 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ version: 0.3.4
121
+ type: :runtime
122
+ prerelease: false
123
+ version_requirements: *70126178336080
124
+ description: ! "\n BOOM!\n "
125
+ email:
126
+ - adam@benchmedia.co.uk
127
+ executables:
128
+ - service_disruption
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - .gitignore
133
+ - Gemfile
134
+ - README.markdown
135
+ - Rakefile
136
+ - bin/service_disruption
137
+ - lib/service_disruption.rb
138
+ - lib/service_disruption/command.rb
139
+ - lib/service_disruption/core_ext/hash.rb
140
+ - lib/service_disruption/data_source.rb
141
+ - lib/service_disruption/line.rb
142
+ - lib/service_disruption/network.rb
143
+ - lib/service_disruption/notifier.rb
144
+ - lib/service_disruption/status.rb
145
+ - service_disruption.gemspec
146
+ - spec/data_source_spec.rb
147
+ - spec/fixtures/line_status.xml
148
+ - spec/line_spec.rb
149
+ - spec/network_spec.rb
150
+ - spec/service_disruption_spec.rb
151
+ - spec/spec_helper.rb
152
+ - spec/status_spec.rb
153
+ - static/cs.png
154
+ - static/gs.png
155
+ - static/md.png
156
+ - static/ps.png
157
+ - static/sd.png
158
+ homepage: http://adamcarlile.com
159
+ licenses: []
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ segments:
171
+ - 0
172
+ hash: -2835984172953313753
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ segments:
180
+ - 0
181
+ hash: -2835984172953313753
182
+ requirements: []
183
+ rubyforge_project: service_disruption
184
+ rubygems_version: 1.8.17
185
+ signing_key:
186
+ specification_version: 3
187
+ summary: A simple gem to track the current status of London Underground services
188
+ test_files:
189
+ - spec/data_source_spec.rb
190
+ - spec/fixtures/line_status.xml
191
+ - spec/line_spec.rb
192
+ - spec/network_spec.rb
193
+ - spec/service_disruption_spec.rb
194
+ - spec/spec_helper.rb
195
+ - spec/status_spec.rb