Skip to content
This repository has been archived by the owner on Dec 16, 2020. It is now read-only.

Commit

Permalink
Add fetching/loading of CORPUS data.
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Gauld committed Jun 25, 2018
1 parent 28a41f1 commit 6f757f1
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
31 changes: 31 additions & 0 deletions doc/guides/Network Rail/CORPUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Network Rail CORPUS (Codes for Operations, Retail & Planning – a Unified Solution)

The CORPUS data is a list of indentification information for locations around the network.
See <https://wiki.openraildata.com/index.php/Reference_Data#CORPUS:_Location_Reference_Data>
for many more details.

You'll get an array of a data struct with the following attributes:

* tiploc - TIPLOC code (e.g. "ERGNCHP")
* stanox - STANOX code (e.g. 78370)
* crs - 3 letter location code (e.g. "ECP")
* uic - UIC code (e.g. 3750)
* nlc - NLC code (e.g. "37500")
* nlc_description - Description of the NLC (e.g. "ENERGLYN & CHURCHILL PARK")
* nlc_short_description - 16 character version (e.g. "ENERGLYN & C PK")

```ruby

# Get data from a previously saved file
data = RailFeeds::NetworkRail::CORPUS.load_file('PATH TO FILE.json.gz')

# Get data from a previously saved and extracted file
data = RailFeeds::NetworkRail::CORPUS.load_file('PATH TO FILE.json')

# Get data by fetching it from the web
RailFeeds::NetworkRail::Credentials.configure(
username: 'YOUR USERNAME HERE',
password: 'YOUR PASSWORD HERE'
)
data = RailFeeds::NetworkRail::CORPUS.fetch_data
`
1 change: 1 addition & 0 deletions lib/rail_feeds/network_rail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative 'network_rail/credentials'
require_relative 'network_rail/http_client'
require_relative 'network_rail/stomp_client'
require_relative 'network_rail/corpus'
require_relative 'network_rail/schedule'

module RailFeeds
Expand Down
60 changes: 60 additions & 0 deletions lib/rail_feeds/network_rail/corpus.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

require 'json'

module RailFeeds
module NetworkRail
# A module for getting data out of the CORPUS data.
module CORPUS
Data = Struct.new(
:tiploc, :stanox, :crs, :uic, :nlc, :nlc_description, :nlc_short_description
)

# Load CORPUS data from either a .json or .json.gz file.
# @param [String] file The path of the file to open.
# @return [Array<RailFeeds::NetworkRail::CORPUS::Data>]
def self.load_file(file)
Zlib::GzipReader.open(file) do |gz|
parse_json gz.read
end
rescue Zlib::GzipFile::Error
parse_json File.read(file)
end

# Load CORPUS data from the internet.
# @param [RailFeeds::NetworkRail::Credentials] credentials
# The credentials to authenticate with.
# @return [Array<RailFeeds::NetworkRail::CORPUS::Data>]
def self.fetch_data(credentials: Credentials)
client = HTTPClient.new(credentials: credentials)
client.get_unzipped('ntrod/SupportingFileAuthenticate?type=CORPUS') do |file|
break parse_json file.read
end
end

# rubocop:disable Metrics/AbcSize
def self.parse_json(json)
data = JSON.parse json
data['TIPLOCDATA'].map do |item|
Data.new(
nilify(item['TIPLOC']&.strip),
nilify(item['STANOX']&.strip)&.to_i,
nilify(item['3ALPHA']&.strip),
nilify(item['UIC']&.strip)&.to_i,
nilify(item['NLC']&.strip),
nilify(item['NLCDESC']&.strip),
nilify(item['NLCDESC16']&.strip)
)
end
end
# rubocop:enable Metrics/AbcSize
private_class_method :parse_json

def self.nilify(item)
return nil if item.nil? || item.empty?
item
end
private_class_method :nilify
end
end
end
50 changes: 50 additions & 0 deletions spec/rail_feeds/network_rail/corpus_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

describe RailFeeds::NetworkRail::CORPUS do
let :json do
'{"TIPLOCDATA":[{"NLCDESC":"MERSEYRAIL ELECTRICS","NLC":"8","TIPLOC":"MERSELE","3A' \
'LPHA":"ABC","STANOX":"1","NLCDESC16":"MPTE HQ","UIC":"2"},{"NLCDESC":" ","NLC":" ' \
'","TIPLOC":" ","3ALPHA":" ","STANOX":" ","NLCDESC16":" ","UIC":" "}]}'
end
let(:http_client) { double RailFeeds::NetworkRail::HTTPClient }
let(:reader) { double Zlib::GzipReader }

describe '::load_file' do
it 'json file' do
expect(Zlib::GzipReader).to receive(:open).with('filename') { fail Zlib::GzipFile::Error }
expect(File).to receive(:read).with('filename').and_return(json)
data = described_class.load_file('filename')
expect(data[0].tiploc).to eq 'MERSELE'
expect(data[0].stanox).to eq 1
expect(data[0].crs).to eq 'ABC'
expect(data[0].uic).to eq 2
expect(data[0].nlc).to eq '8'
expect(data[0].nlc_description).to eq 'MERSEYRAIL ELECTRICS'
expect(data[0].nlc_short_description).to eq 'MPTE HQ'
expect(data[1].tiploc).to be_nil
expect(data[1].stanox).to be_nil
expect(data[1].crs).to be_nil
expect(data[1].uic).to be_nil
expect(data[1].nlc).to be_nil
expect(data[1].nlc_description).to be_nil
expect(data[1].nlc_short_description).to be_nil
end

it 'json.gz file' do
expect(Zlib::GzipReader).to receive(:open).with('filename')
.and_yield(StringIO.new(json))
expect(described_class.load_file('filename').count).to eq 2
end
end

it '::fetch_data' do
expect(RailFeeds::NetworkRail::HTTPClient)
.to receive(:new).with(credentials: RailFeeds::NetworkRail::Credentials)
.and_return(http_client)
expect(http_client).to receive(:get_unzipped)
.with('ntrod/SupportingFileAuthenticate?type=CORPUS')
.and_yield(reader)
expect(reader).to receive(:read).and_return(json)
expect(described_class.fetch_data.count).to eq 2
end
end

0 comments on commit 6f757f1

Please sign in to comment.