rail_feeds 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +6 -0
- data/Guardfile +25 -0
- data/LICENSE.md +32 -0
- data/README.md +77 -0
- data/Rakefile +3 -0
- data/doc/guides/Logging.md +13 -0
- data/doc/guides/Network Rail/CORPUS.md +34 -0
- data/doc/guides/Network Rail/SMART.md +39 -0
- data/doc/guides/Network Rail/Schedule.md +138 -0
- data/file +0 -0
- data/lib/rail_feeds/credentials.rb +45 -0
- data/lib/rail_feeds/logging.rb +51 -0
- data/lib/rail_feeds/network_rail/corpus.rb +77 -0
- data/lib/rail_feeds/network_rail/credentials.rb +22 -0
- data/lib/rail_feeds/network_rail/http_client.rb +57 -0
- data/lib/rail_feeds/network_rail/schedule/association.rb +208 -0
- data/lib/rail_feeds/network_rail/schedule/data.rb +215 -0
- data/lib/rail_feeds/network_rail/schedule/days.rb +95 -0
- data/lib/rail_feeds/network_rail/schedule/fetcher.rb +193 -0
- data/lib/rail_feeds/network_rail/schedule/header/cif.rb +102 -0
- data/lib/rail_feeds/network_rail/schedule/header/json.rb +79 -0
- data/lib/rail_feeds/network_rail/schedule/header.rb +22 -0
- data/lib/rail_feeds/network_rail/schedule/parser/cif.rb +141 -0
- data/lib/rail_feeds/network_rail/schedule/parser/json.rb +87 -0
- data/lib/rail_feeds/network_rail/schedule/parser.rb +108 -0
- data/lib/rail_feeds/network_rail/schedule/stp_indicator.rb +72 -0
- data/lib/rail_feeds/network_rail/schedule/tiploc.rb +100 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/change_en_route.rb +158 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/intermediate.rb +119 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/origin.rb +91 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location/terminating.rb +72 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule/location.rb +76 -0
- data/lib/rail_feeds/network_rail/schedule/train_schedule.rb +392 -0
- data/lib/rail_feeds/network_rail/schedule.rb +33 -0
- data/lib/rail_feeds/network_rail/smart.rb +186 -0
- data/lib/rail_feeds/network_rail/stomp_client.rb +77 -0
- data/lib/rail_feeds/network_rail.rb +16 -0
- data/lib/rail_feeds/version.rb +14 -0
- data/lib/rail_feeds.rb +10 -0
- data/rail_feeds.gemspec +32 -0
- data/spec/fixtures/network_rail/schedule/data/full.yaml +60 -0
- data/spec/fixtures/network_rail/schedule/data/starting.yaml +131 -0
- data/spec/fixtures/network_rail/schedule/data/update-gap.yaml +10 -0
- data/spec/fixtures/network_rail/schedule/data/update-next.yaml +13 -0
- data/spec/fixtures/network_rail/schedule/data/update-old.yaml +10 -0
- data/spec/fixtures/network_rail/schedule/data/update.yaml +112 -0
- data/spec/fixtures/network_rail/schedule/parser/train_create.json +1 -0
- data/spec/fixtures/network_rail/schedule/parser/train_delete.json +1 -0
- data/spec/fixtures/network_rail/schedule/train_schedule/json-data.yaml +67 -0
- data/spec/rail_feeds/credentials_spec.rb +46 -0
- data/spec/rail_feeds/logging_spec.rb +81 -0
- data/spec/rail_feeds/network_rail/corpus_spec.rb +92 -0
- data/spec/rail_feeds/network_rail/credentials_spec.rb +22 -0
- data/spec/rail_feeds/network_rail/http_client_spec.rb +88 -0
- data/spec/rail_feeds/network_rail/schedule/association_spec.rb +205 -0
- data/spec/rail_feeds/network_rail/schedule/data_spec.rb +219 -0
- data/spec/rail_feeds/network_rail/schedule/days_shared.rb +99 -0
- data/spec/rail_feeds/network_rail/schedule/days_spec.rb +4 -0
- data/spec/rail_feeds/network_rail/schedule/fetcher_spec.rb +228 -0
- data/spec/rail_feeds/network_rail/schedule/header/cif_spec.rb +72 -0
- data/spec/rail_feeds/network_rail/schedule/header/json_spec.rb +51 -0
- data/spec/rail_feeds/network_rail/schedule/header_spec.rb +19 -0
- data/spec/rail_feeds/network_rail/schedule/parser/cif_spec.rb +197 -0
- data/spec/rail_feeds/network_rail/schedule/parser/json_spec.rb +172 -0
- data/spec/rail_feeds/network_rail/schedule/parser_spec.rb +34 -0
- data/spec/rail_feeds/network_rail/schedule/stp_indicator_shared.rb +49 -0
- data/spec/rail_feeds/network_rail/schedule/stp_indicator_spec.rb +4 -0
- data/spec/rail_feeds/network_rail/schedule/tiploc_spec.rb +77 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/change_en_route_spec.rb +121 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/intermediate_spec.rb +95 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/origin_spec.rb +87 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location/terminating_spec.rb +81 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule/location_spec.rb +35 -0
- data/spec/rail_feeds/network_rail/schedule/train_schedule_spec.rb +284 -0
- data/spec/rail_feeds/network_rail/schedule_spec.rb +41 -0
- data/spec/rail_feeds/network_rail/smart_spec.rb +194 -0
- data/spec/rail_feeds/network_rail/stomp_client_spec.rb +151 -0
- data/spec/rail_feeds/network_rail_spec.rb +7 -0
- data/spec/rail_feeds_spec.rb +11 -0
- data/spec/spec_helper.rb +47 -0
- metadata +282 -0
@@ -0,0 +1,186 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
module RailFeeds
|
7
|
+
module NetworkRail
|
8
|
+
# rubocop:disable Metrics/ModuleLength
|
9
|
+
# A module for getting information out of the SMART data.
|
10
|
+
module SMART
|
11
|
+
Step = Struct.new(
|
12
|
+
:td_area, :from_berth, :to_berth, :step_type, :event_direction, :from_line,
|
13
|
+
:to_line, :trust_offset, :platform, :event_type, :route, :stanox,
|
14
|
+
:stanox_name, :comment
|
15
|
+
) do
|
16
|
+
def from_direction
|
17
|
+
return :up if event_direction.eql?(:down)
|
18
|
+
return :down if event_direction.eql?(:up)
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_direction
|
23
|
+
event_direction
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Berth = Struct.new(
|
28
|
+
:id, :up_steps, :down_steps, :up_berths, :down_berths
|
29
|
+
)
|
30
|
+
|
31
|
+
# Download the current SMART data.
|
32
|
+
# @param [RailFeeds::NetworkRail::Credentials] credentials
|
33
|
+
# @param [String] file
|
34
|
+
# The path to the file to save the .json.gz download in.
|
35
|
+
def self.download(file, credentials: Credentials)
|
36
|
+
client = HTTPClient.new(credentials: credentials)
|
37
|
+
client.download 'ntrod/SupportingFileAuthenticate?type=SMART', file
|
38
|
+
end
|
39
|
+
|
40
|
+
# Fetch the current SMART data.
|
41
|
+
# @param [RailFeeds::NetworkRail::Credentials] credentials
|
42
|
+
# @return [Tempfile]
|
43
|
+
def self.fetch(credentials: Credentials)
|
44
|
+
client = HTTPClient.new(credentials: credentials)
|
45
|
+
client.fetch 'ntrod/SupportingFileAuthenticate?type=SMART'
|
46
|
+
end
|
47
|
+
|
48
|
+
# Load SMART data from either a .json or .json.gz file.
|
49
|
+
# @param [String] file The path of the file to open.
|
50
|
+
# @return [Array<RailFeeds::NetworkRail::SMART::Step>]
|
51
|
+
def self.load_file(file)
|
52
|
+
Zlib::GzipReader.open(file) do |gz|
|
53
|
+
parse_json gz.read
|
54
|
+
end
|
55
|
+
rescue Zlib::GzipFile::Error
|
56
|
+
parse_json File.read(file)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Load SMART data from the internet.
|
60
|
+
# @param [RailFeeds::NetworkRail::Credentials] credentials
|
61
|
+
# The credentials to authenticate with.
|
62
|
+
# @return [Array<RailFeeds::NetworkRail::SMART::Step>]
|
63
|
+
def self.fetch_data(credentials: Credentials)
|
64
|
+
client = HTTPClient.new(credentials: credentials)
|
65
|
+
client.fetch_unzipped('ntrod/SupportingFileAuthenticate?type=SMART') do |file|
|
66
|
+
break parse_json file.read
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# rubocop:disable Metrics/AbcSize
|
71
|
+
# rubocop:disable Metrics/MethodLength
|
72
|
+
# Generate an berth data from step data.
|
73
|
+
# You'll get an array of berths which list the steps into and out of them,
|
74
|
+
# which in turn have references to other (via the to_berth attribute) to
|
75
|
+
# other berths.
|
76
|
+
# @param [Array<RailFeeds::NetworkRail::SMART::Step] steps
|
77
|
+
# The steps to build the berth information from.
|
78
|
+
# @return [Hash{String=>Hash{String=>RailFeeds::NetworkRail::SMART::Step}}
|
79
|
+
# Nested hashes which take a String for the td_area, then a String for
|
80
|
+
# the berth.id (from either step.from_berth or step.to_berth) to get a
|
81
|
+
# specific berth.
|
82
|
+
def self.build_berths(steps)
|
83
|
+
berths = Hash.new do |hash, key|
|
84
|
+
hash[key] = Hash.new do |hash2, key2|
|
85
|
+
hash2[key2] = Berth.new nil, Set.new, Set.new, Set.new, Set.new
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
steps.each do |step|
|
90
|
+
next if step.event_direction.nil?
|
91
|
+
|
92
|
+
# from_berth -> step -> to_berth ---> up
|
93
|
+
from_berth = berths.dig(step.td_area, step.from_berth)
|
94
|
+
to_berth = berths.dig(step.td_area, step.to_berth)
|
95
|
+
|
96
|
+
from_berth.id ||= step.from_berth
|
97
|
+
to_berth.id ||= step.to_berth
|
98
|
+
|
99
|
+
from_berth.send("#{step.to_direction}_steps").add step
|
100
|
+
to_berth.send("#{step.from_direction}_steps").add step
|
101
|
+
from_berth.send("#{step.to_direction}_berths").add step.to_berth
|
102
|
+
end
|
103
|
+
|
104
|
+
# Convert sets to arrays
|
105
|
+
berths.each do |_area, hash|
|
106
|
+
hash.each do |_id, value|
|
107
|
+
value.up_steps = value.up_steps.to_a
|
108
|
+
value.down_steps = value.down_steps.to_a
|
109
|
+
value.up_berths = value.up_berths.to_a
|
110
|
+
value.down_berths = value.down_berths.to_a
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
# rubocop:enable Metrics/AbcSize
|
115
|
+
# rubocop:enable Metrics/MethodLength
|
116
|
+
|
117
|
+
# private methods below
|
118
|
+
|
119
|
+
# rubocop:disable Metrics/AbcSize
|
120
|
+
# rubocop:disable Metrics/MethodLength
|
121
|
+
def self.parse_json(json)
|
122
|
+
data = JSON.parse json
|
123
|
+
data['BERTHDATA'].map do |item|
|
124
|
+
Step.new(
|
125
|
+
nilify(item['TD']&.strip),
|
126
|
+
nilify(item['FROMBERTH']&.strip),
|
127
|
+
nilify(item['TOBERTH']&.strip),
|
128
|
+
step_type(item['STEPTYPE']),
|
129
|
+
event_direction(item['EVENT']),
|
130
|
+
nilify(item['FROMLINE']&.strip),
|
131
|
+
nilify(item['TOLINE']&.strip),
|
132
|
+
(item['BERTHOFFSET']&.to_i || 0),
|
133
|
+
nilify(item['PLATFORM']&.strip),
|
134
|
+
event_type(item['EVENT']),
|
135
|
+
nilify(item['ROUTE']&.strip),
|
136
|
+
nilify(item['STANOX']&.strip)&.to_i,
|
137
|
+
nilify(item['STANME']&.strip),
|
138
|
+
nilify(item['COMMENT']&.strip)
|
139
|
+
)
|
140
|
+
# berths[step.from_berth].up_steps.push ....
|
141
|
+
# berths[step.to_berth].down_steps.push ....
|
142
|
+
end
|
143
|
+
end
|
144
|
+
# rubocop:enable Metrics/AbcSize
|
145
|
+
# rubocop:enable Metrics/MethodLength
|
146
|
+
private_class_method :parse_json
|
147
|
+
|
148
|
+
def self.nilify(value)
|
149
|
+
return nil if value.nil? || value.empty?
|
150
|
+
value
|
151
|
+
end
|
152
|
+
private_class_method :nilify
|
153
|
+
|
154
|
+
def self.event_type(value)
|
155
|
+
return :arrive if value.eql?('A') || value.eql?('C')
|
156
|
+
return :depart if value.eql?('B') || value.eql?('D')
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
private_class_method :event_type
|
160
|
+
|
161
|
+
def self.event_direction(value)
|
162
|
+
return :up if value.eql?('A') || value.eql?('B')
|
163
|
+
return :down if value.eql?('C') || value.eql?('D')
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
private_class_method :event_direction
|
167
|
+
|
168
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
169
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
170
|
+
def self.step_type(value)
|
171
|
+
return :between if value.eql?('B')
|
172
|
+
return :from if value.eql?('F')
|
173
|
+
return :to if value.eql?('T')
|
174
|
+
return :intermediate_first if value.eql?('D')
|
175
|
+
return :clearout if value.eql?('C')
|
176
|
+
return :interpose if value.eql?('I')
|
177
|
+
return :intermediate if value.eql?('E')
|
178
|
+
nil
|
179
|
+
end
|
180
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
181
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
182
|
+
private_class_method :step_type
|
183
|
+
end
|
184
|
+
# rubocop:enable Metrics/ModuleLength
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'stomp'
|
5
|
+
|
6
|
+
module RailFeeds
|
7
|
+
module NetworkRail
|
8
|
+
# A wrapper class for ::Stomp::Client which provides durable subscriptions
|
9
|
+
class StompClient
|
10
|
+
include Logging
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
HOST = 'datafeeds.networkrail.co.uk'
|
14
|
+
PORT = '61618'
|
15
|
+
|
16
|
+
# Initialize a new stomp client.
|
17
|
+
# @param [RailFeeds::NetworkRail::Credentials] credentials
|
18
|
+
# The credentials for connecting to the feed.
|
19
|
+
# @param [Logger, nil] logger
|
20
|
+
# The logger for outputting evetns, if nil the global logger will be used.
|
21
|
+
def initialize(credentials: Credentials, logger: nil)
|
22
|
+
@credentials = credentials
|
23
|
+
self.logger = logger unless logger.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable Metrics/MethodLength
|
27
|
+
# Connect to the network rail server.
|
28
|
+
def connect
|
29
|
+
return if @client && client.open?
|
30
|
+
client_options = {
|
31
|
+
hosts: [{
|
32
|
+
host: HOST,
|
33
|
+
port: PORT,
|
34
|
+
login: @credentials.username,
|
35
|
+
password: @credentials.password
|
36
|
+
}],
|
37
|
+
connect_headers: {
|
38
|
+
'host' => HOST,
|
39
|
+
'client-id' => @credentials.username,
|
40
|
+
'accept-version' => '1.1',
|
41
|
+
'heart-beat' => '5000,10000'
|
42
|
+
},
|
43
|
+
logger: logger
|
44
|
+
}
|
45
|
+
@client = Stomp::Client.new client_options
|
46
|
+
end
|
47
|
+
# rubocop:enable Metrics/MethodLength
|
48
|
+
|
49
|
+
# Disconnect from the network rail server.
|
50
|
+
def disconnect
|
51
|
+
return if @client.nil?
|
52
|
+
@client.close
|
53
|
+
end
|
54
|
+
|
55
|
+
# Subscribe to a topic.
|
56
|
+
# Will connect to the server if required.
|
57
|
+
# Must be passed a block which will be called with each message received.
|
58
|
+
# @param [String, #to_s] topic
|
59
|
+
# The topic to subscribe to (e.g. "TSR_WESS_ROUTE" or "TD_ALL_SIG_AREA").
|
60
|
+
# @param [Hash] headers
|
61
|
+
# Extra headers to pass to the server.
|
62
|
+
def subscribe(topic, headers = {}, &block)
|
63
|
+
connect if @client.nil? || @client.closed?
|
64
|
+
headers['activemq.subscriptionName'] ||= "#{::Socket.gethostname}+#{topic}"
|
65
|
+
headers['id'] ||= @client.uuid
|
66
|
+
headers['ack'] ||= 'client'
|
67
|
+
@client.subscribe "/topic/#{topic}", headers, &block
|
68
|
+
end
|
69
|
+
|
70
|
+
def_delegators :@client, :ack, :acknowledge, :nack, :unreceive,
|
71
|
+
:create_error_handler, :open?, :closed?, :join, :running?,
|
72
|
+
:begin, :abort, :commit, :unsubscribe, :uuid, :poll,
|
73
|
+
:hbsend_interval, :hbrecv_interval,
|
74
|
+
:hbsend_count, :hbrecv_count
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'network_rail/credentials'
|
4
|
+
require_relative 'network_rail/http_client'
|
5
|
+
require_relative 'network_rail/stomp_client'
|
6
|
+
require_relative 'network_rail/corpus'
|
7
|
+
require_relative 'network_rail/schedule'
|
8
|
+
require_relative 'network_rail/smart'
|
9
|
+
|
10
|
+
module RailFeeds
|
11
|
+
module NetworkRail # :nodoc:
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Add alias for module
|
16
|
+
::NetRailFeeds = RailFeeds::NetworkRail
|
data/lib/rail_feeds.rb
ADDED
data/rail_feeds.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
require File.join(File.dirname(__FILE__), 'lib', 'rail_feeds', 'version')
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'rail_feeds'
|
8
|
+
s.license = 'BSD 3 clause'
|
9
|
+
s.version = RailFeeds::Version
|
10
|
+
s.authors = ['Robert Gauld']
|
11
|
+
s.email = ['robert@robertgauld.co.uk']
|
12
|
+
s.homepage = 'https://github.com/robertgauld/rail_feeds'
|
13
|
+
s.summary = 'Make use of the various open data rails feeds in the UK.'
|
14
|
+
s.description = 'Make use of the various open data rails feeds in the UK. Currently only some from Network Rail.'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'stomp', '~> 1.4'
|
22
|
+
|
23
|
+
s.add_development_dependency 'coveralls', '~> 0.7'
|
24
|
+
s.add_development_dependency 'guard-rspec', '~> 4.2', '>= 4.2.5'
|
25
|
+
s.add_development_dependency 'guard-rubocop', '~> 1.3'
|
26
|
+
s.add_development_dependency 'rake', '~> 12.0'
|
27
|
+
s.add_development_dependency 'rb-inotify', '~> 0.9'
|
28
|
+
s.add_development_dependency 'rspec', '>= 3.7', '< 4'
|
29
|
+
s.add_development_dependency 'rubocop', '~> 0.57.1'
|
30
|
+
s.add_development_dependency 'simplecov', '~> 0.7'
|
31
|
+
s.add_development_dependency 'timecop', '~> 0.5'
|
32
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
- - :on_header
|
4
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
5
|
+
current_file_reference: DFROC2Q
|
6
|
+
update_indicator: F
|
7
|
+
extracted_at: 2018-06-18 19:45:00
|
8
|
+
start_date: 2018-06-18
|
9
|
+
end_date: 2019-06-17
|
10
|
+
|
11
|
+
- - :on_tiploc_create
|
12
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
13
|
+
tiploc: '1'
|
14
|
+
- - :on_tiploc_create
|
15
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
16
|
+
tiploc: '2'
|
17
|
+
- - :on_tiploc_create
|
18
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
19
|
+
tiploc: '3'
|
20
|
+
|
21
|
+
- - :on_association_create
|
22
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
23
|
+
tiploc: '1'
|
24
|
+
main_location_suffix: 'a'
|
25
|
+
category: JJ
|
26
|
+
days: [true, true, true, true, true, false, false]
|
27
|
+
- - :on_association_create
|
28
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
29
|
+
tiploc: '2'
|
30
|
+
main_location_suffix: 'b'
|
31
|
+
category: JJ
|
32
|
+
days: [true, true, true, true, true, true, false, false]
|
33
|
+
- - :on_association_create
|
34
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
35
|
+
tiploc: '3'
|
36
|
+
main_location_suffix: 'c'
|
37
|
+
category: JJ
|
38
|
+
days: [true, true, true, true, true, false, false]
|
39
|
+
|
40
|
+
- - :on_train_schedule_create
|
41
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
42
|
+
uid: 1
|
43
|
+
signalling_headcode: '1A11'
|
44
|
+
days: [true, true, true, true, true, false, false]
|
45
|
+
journey: []
|
46
|
+
- - :on_train_schedule_create
|
47
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
48
|
+
uid: 2
|
49
|
+
signalling_headcode: '2B22'
|
50
|
+
days: [true, true, true, true, true, false, false]
|
51
|
+
journey: []
|
52
|
+
- - :on_train_schedule_create
|
53
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
54
|
+
uid: 3
|
55
|
+
signalling_headcode: '3C33'
|
56
|
+
days: [true, true, true, true, true, false, false]
|
57
|
+
journey: []
|
58
|
+
|
59
|
+
- - :on_trailer
|
60
|
+
-
|
@@ -0,0 +1,131 @@
|
|
1
|
+
---
|
2
|
+
:last_header: !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
3
|
+
mainframe_identity: mainframe
|
4
|
+
extracted_at: 2018-06-14 19:43:37 +00:00
|
5
|
+
current_file_reference: starting-update
|
6
|
+
last_file_reference:
|
7
|
+
update_indicator: U
|
8
|
+
version: a
|
9
|
+
start_date: 2018-06-14
|
10
|
+
end_date: 2019-06-13
|
11
|
+
|
12
|
+
:associations:
|
13
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
14
|
+
main_train_uid: 1
|
15
|
+
associated_train_uid: 2
|
16
|
+
category: JJ
|
17
|
+
start_date: 2018-06-14
|
18
|
+
end_date: 2019-06-13
|
19
|
+
date_indicator: S
|
20
|
+
days: [true, true, true, true, true, true, false, false]
|
21
|
+
tiploc: 1
|
22
|
+
base_location_suffix: a
|
23
|
+
association_location_suffix: b
|
24
|
+
type: O
|
25
|
+
stp_indicator: S
|
26
|
+
transaction_type: N
|
27
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
28
|
+
main_train_uid: 3
|
29
|
+
associated_train_uid: 4
|
30
|
+
category: VV
|
31
|
+
start_date: 2018-06-14
|
32
|
+
end_date: 2019-06-13
|
33
|
+
date_indicator: S
|
34
|
+
days: [true, true, true, true, true, true, false, false]
|
35
|
+
tiploc: 2
|
36
|
+
base_location_suffix: a
|
37
|
+
association_location_suffix: b
|
38
|
+
type: O
|
39
|
+
stp_indicator: S
|
40
|
+
transaction_type: N
|
41
|
+
|
42
|
+
:tiplocs:
|
43
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
44
|
+
tiploc: '1'
|
45
|
+
nlc: 1
|
46
|
+
nlc_check_char: a
|
47
|
+
nlc_description: Nlc 1
|
48
|
+
tps_description: Tps 1
|
49
|
+
stanox: 1
|
50
|
+
crs: 1
|
51
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
52
|
+
tiploc: '2'
|
53
|
+
nlc: 2
|
54
|
+
nlc_check_char: b
|
55
|
+
nlc_description: Nlc 2
|
56
|
+
tps_description: Tps 2
|
57
|
+
stanox: 2
|
58
|
+
crs: 2
|
59
|
+
|
60
|
+
:trains:
|
61
|
+
'1':
|
62
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
63
|
+
journey:
|
64
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin
|
65
|
+
scheduled_departure: '1111'
|
66
|
+
public_departure: '1111'
|
67
|
+
tiploc_with_suffix: 1
|
68
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating
|
69
|
+
scheduled_arrival: '2222'
|
70
|
+
public_arrival: '2222'
|
71
|
+
tiploc_with_suffix: 2
|
72
|
+
uid: 1
|
73
|
+
category:
|
74
|
+
status:
|
75
|
+
stp_indicator:
|
76
|
+
portion_id:
|
77
|
+
reservation_headcode:
|
78
|
+
signalling_headcode: 1A11
|
79
|
+
service_code:
|
80
|
+
start_date: 2018-06-14
|
81
|
+
end_date: 2019-06-13
|
82
|
+
days: [true, true, true, true, true, true, false, false]
|
83
|
+
run_on_bank_holiday: ''
|
84
|
+
power_type: DMU
|
85
|
+
timing_load:
|
86
|
+
speed: 75
|
87
|
+
operating_characteristics:
|
88
|
+
seating_class: B
|
89
|
+
sleeping_class:
|
90
|
+
reservations:
|
91
|
+
catering:
|
92
|
+
branding:
|
93
|
+
uic_code:
|
94
|
+
atoc_code:
|
95
|
+
applicable_timetable: Y
|
96
|
+
transaction_type: N
|
97
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
98
|
+
journey:
|
99
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin
|
100
|
+
scheduled_departure: '1111'
|
101
|
+
public_departure: '1111'
|
102
|
+
tiploc_with_suffix: 2
|
103
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating
|
104
|
+
scheduled_arrival: '2222'
|
105
|
+
public_arrival: '2222'
|
106
|
+
tiploc_with_suffix: 1
|
107
|
+
uid: 1
|
108
|
+
category:
|
109
|
+
status:
|
110
|
+
stp_indicator:
|
111
|
+
portion_id:
|
112
|
+
reservation_headcode:
|
113
|
+
signalling_headcode: 1A11
|
114
|
+
service_code:
|
115
|
+
start_date: 2018-06-14
|
116
|
+
end_date: 2019-06-13
|
117
|
+
days: [true, true, true, true, true, true, false, false]
|
118
|
+
run_on_bank_holiday: ''
|
119
|
+
power_type: DMU
|
120
|
+
timing_load:
|
121
|
+
speed: 75
|
122
|
+
operating_characteristics:
|
123
|
+
seating_class: B
|
124
|
+
sleeping_class:
|
125
|
+
reservations:
|
126
|
+
catering:
|
127
|
+
branding:
|
128
|
+
uic_code:
|
129
|
+
atoc_code:
|
130
|
+
applicable_timetable: Y
|
131
|
+
transaction_type: N
|
@@ -0,0 +1,10 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
- - :on_header
|
4
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
5
|
+
current_file_reference: DFROC1N
|
6
|
+
previous_file_reference: DFROC1M
|
7
|
+
update_indicator: U
|
8
|
+
extracted_at: 2018-06-21 19:45:00
|
9
|
+
start_date: 2018-06-21
|
10
|
+
end_date: 2019-06-20
|
@@ -0,0 +1,13 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
- - :on_header
|
4
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
5
|
+
current_file_reference: DFROC1M
|
6
|
+
previous_file_reference: DFROC1L
|
7
|
+
update_indicator: U
|
8
|
+
extracted_at: 2018-06-19 19:45:00
|
9
|
+
start_date: 2018-06-20
|
10
|
+
end_date: 2019-06-19
|
11
|
+
|
12
|
+
- - :on_trailer
|
13
|
+
-
|
@@ -0,0 +1,10 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
- - :on_header
|
4
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
5
|
+
current_file_reference: DFROC1B
|
6
|
+
previous_file_reference: DFROC1A
|
7
|
+
update_indicator: U
|
8
|
+
extracted_at: 2018-06-12 19:45:00
|
9
|
+
start_date: 2018-06-12
|
10
|
+
end_date: 2019-06-11
|
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
|
3
|
+
- - :on_header
|
4
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Header::CIF
|
5
|
+
current_file_reference: DFROC1L
|
6
|
+
previous_file_reference: DFROC1K
|
7
|
+
update_indicator: U
|
8
|
+
extracted_at: 2018-06-18 19:45:00
|
9
|
+
start_date: 2018-06-19
|
10
|
+
end_date: 2019-06-18
|
11
|
+
|
12
|
+
# Insert new tiploc
|
13
|
+
- - :on_tiploc_create
|
14
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
15
|
+
tiploc: '4'
|
16
|
+
# Delete existing tiploc
|
17
|
+
- - :on_tiploc_delete
|
18
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
19
|
+
tiploc: '2'
|
20
|
+
# Delete nonexisting tiploc
|
21
|
+
- - :on_tiploc_delete
|
22
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
23
|
+
tiploc: '22'
|
24
|
+
# Amend existing tiploc
|
25
|
+
- - :on_tiploc_update
|
26
|
+
- - '3'
|
27
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
28
|
+
tiploc: '3a'
|
29
|
+
# Amend nonexisting tiploc
|
30
|
+
- - :on_tiploc_update
|
31
|
+
- - '5'
|
32
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Tiploc
|
33
|
+
tiploc: '5a'
|
34
|
+
|
35
|
+
# New association
|
36
|
+
- - :on_association_create
|
37
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
38
|
+
tiploc: '4'
|
39
|
+
main_location_suffix: 'd'
|
40
|
+
category: JJ
|
41
|
+
days: [true, true, true, true, true, false, false]
|
42
|
+
# Delete existing association
|
43
|
+
- - :on_association_delete
|
44
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
45
|
+
tiploc: '2'
|
46
|
+
main_location_suffix: 'b'
|
47
|
+
# Delete nonexisting association
|
48
|
+
- - :on_association_delete
|
49
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
50
|
+
tiploc: '22'
|
51
|
+
main_location_suffix: 'D'
|
52
|
+
# Revise existing association
|
53
|
+
- - :on_association_update
|
54
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
55
|
+
tiploc: '3'
|
56
|
+
main_location_suffix: 'c'
|
57
|
+
category: VV
|
58
|
+
days: [true, true, true, true, true, false, false]
|
59
|
+
# Revise nonexisting association
|
60
|
+
- - :on_association_update
|
61
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::Association
|
62
|
+
tiploc: '5'
|
63
|
+
main_location_suffix: 'e'
|
64
|
+
category: JJ
|
65
|
+
days: [true, true, true, true, true, false, false]
|
66
|
+
|
67
|
+
# New train
|
68
|
+
- - :on_train_schedule_create
|
69
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
70
|
+
uid: 4
|
71
|
+
signalling_headcode: '4D44'
|
72
|
+
days: [true, true, true, true, true, false, false]
|
73
|
+
journey:
|
74
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Origin
|
75
|
+
scheduled_departure: '1111'
|
76
|
+
public_departure: '1111'
|
77
|
+
tiploc: 1
|
78
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::ChangeEnRoute
|
79
|
+
tiploc: 2
|
80
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Intermediate
|
81
|
+
scheduled_departure: '1111'
|
82
|
+
public_departure: '1111'
|
83
|
+
tiploc: 2
|
84
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule::Location::Terminating
|
85
|
+
scheduled_arrival: '2222'
|
86
|
+
public_arrival: '2222'
|
87
|
+
tiploc: 3
|
88
|
+
# Delete existing train
|
89
|
+
- - :on_train_schedule_delete
|
90
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
91
|
+
uid: 2
|
92
|
+
# Delete nonexisting train
|
93
|
+
- - :on_train_schedule_delete
|
94
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
95
|
+
uid: 22
|
96
|
+
# Revise existing train
|
97
|
+
- - :on_train_schedule_update
|
98
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
99
|
+
uid: 3
|
100
|
+
signalling_headcode: '3c33'
|
101
|
+
days: [true, true, true, true, true, false, false]
|
102
|
+
journey: []
|
103
|
+
# Revise nonexisting train
|
104
|
+
- - :on_train_schedule_update
|
105
|
+
- !ruby/object:RailFeeds::NetworkRail::Schedule::TrainSchedule
|
106
|
+
uid: 5
|
107
|
+
signalling_headcode: '5E55'
|
108
|
+
days: [true, true, true, true, true, false, false]
|
109
|
+
journey: []
|
110
|
+
|
111
|
+
- - :on_trailer
|
112
|
+
-
|