service_disruption 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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