atco 0.0.2 → 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 91d4d697f6d487218aa3def133f0104257141ed8fb18b93be2c3f0c52ac92a6e
4
+ data.tar.gz: 213d51b686a0076c69f26b6d18173dd2b767eaf24db17f7e0cdc011406b94705
5
+ SHA512:
6
+ metadata.gz: fb0ccef50c6a0490c9b87b0b01a7179bec8ca755d594f52193ef6220ef6733e2c8ed600f46043c3a0a38038f3290a8687f1828adfe893dac7dad5c7413b23c89
7
+ data.tar.gz: 6ba15c31b4cfb1873577af0fe50c62c6325780d9f9c3c6ddb124cfe91397dd2808382757f1198f492ea6fbbe2a21131e010b49ac80a757f33041a3ff57db1d9f
@@ -2,11 +2,14 @@
2
2
 
3
3
  ATCO-CIF is the format of choice for UK public transport authorities. This is a ruby library that reads **.cif** files and gives you JSON back.
4
4
 
5
+ * ATCO (Association of Transport Coordinating Officers)
6
+ * CIF (Common Interface File)
7
+
5
8
  * **Official spec:** [http://www.pti.org.uk/CIF/atco-cif-spec.pdf](http://www.pti.org.uk/CIF/atco-cif-spec.pdf)
6
9
 
7
10
  ### USAGE
8
11
 
9
- Currently this library is under-development and has several things left to do before it is perfect (see the [todo.mdown](http://github.com/davidjrice/atco/blob/master/todo.mdown) list ).
12
+ Currently this library is under-development and has several things left to do before it is perfect (see the [todo.md](http://github.com/davidjrice/atco/blob/master/TODO.md) list ).
10
13
 
11
14
  * clone this library
12
15
  * start an irb session
@@ -14,14 +17,21 @@ Currently this library is under-development and has several things left to do be
14
17
 
15
18
  Code example, for more detailed internal api usage see the spec files.
16
19
 
17
- require 'lib/atco'
18
-
19
- result = Atco.parse('filename.cif')
20
- result = Atco.parse('SVRTMAO009A-20091005.cif) # an example data file
21
-
22
- => {
23
- :header => {...},
24
- :locations => [...],
25
- :journies => {...}
26
- }
27
-
20
+
21
+ ```ruby
22
+ gem install atco
23
+ irb
24
+
25
+
26
+ require 'rubygems
27
+ require 'atco'
28
+
29
+ result = Atco.parse('filename.cif')
30
+ result = Atco.parse('SVRTMAO009A-20091005.cif) # an example data file in the repo
31
+
32
+ => {
33
+ header: {…},
34
+ locations: […],
35
+ journies: {…}
36
+ }
37
+ ```
data/Rakefile CHANGED
@@ -1,14 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
1
6
  begin
2
- require 'jeweler'
3
- Jeweler::Tasks.new do |s|
4
- s.name = "atco"
5
- s.summary = "Simple and opinionated library for parsing ATCO-CIF files with Ruby."
6
- s.email = "me@davidjrice.co.uk"
7
- s.homepage = "http://github.com/davidjrice/atco"
8
- s.description = "Simple and opinionated library for parsing ATCO-CIF files with Ruby."
9
- s.authors = ["David Rice"]
10
- s.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
11
- end
7
+ RSpec::Core::RakeTask.new(:spec)
12
8
  rescue LoadError
13
- puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
14
- end
9
+ puts 'RSpec, or one of its dependencies, is not available. Install it with: bundle install'
10
+ end
11
+
12
+ task default: :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 1.0.0
data/lib/atco/journey.rb CHANGED
@@ -1,11 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Atco
2
-
3
4
  class Journey
4
-
5
- attr_accessor :vehicle_type, :registration_number, :identifier, :operator, :route_number,
6
- :first_date_of_operation, :running_board, :last_date_of_operation, :school_term_time, :route_direction, :bank_holidays
7
-
8
- attr_accessor :stops
5
+ attr_accessor :vehicle_type, :registration_number, :identifier, :operator, :route_number, :first_date_of_operation,
6
+ :running_board, :last_date_of_operation, :school_term_time, :route_direction, :bank_holidays, :stops
9
7
 
10
8
  def initialize(data)
11
9
  @mondays = parse_boolean_int data[:operates_on_mondays]
@@ -15,7 +13,7 @@ module Atco
15
13
  @fridays = parse_boolean_int data[:operates_on_fridays]
16
14
  @saturdays = parse_boolean_int data[:operates_on_saturdays]
17
15
  @sundays = parse_boolean_int data[:operates_on_sundays]
18
-
16
+
19
17
  @vehicle_type = data[:vehicle_type]
20
18
  @registration_number = data[:registration_number]
21
19
  @identifier = data[:unique_journey_identifier]
@@ -27,40 +25,60 @@ module Atco
27
25
  @running_board = data[:running_board]
28
26
  @school_term_time = data[:school_term_time]
29
27
  @bank_holidays = data[:bank_holidays]
30
-
28
+
31
29
  @stops = []
32
- #stops.each do |s|
33
- # @stops << Stop.new(s)
34
- #end
30
+ # stops.each do |s|
31
+ # @stops << Stop.new(s)
32
+ # end
33
+ end
34
+
35
+ def mondays?
36
+ @mondays
37
+ end
38
+
39
+ def tuesdays?
40
+ @tuesdays
41
+ end
42
+
43
+ def wednesdays?
44
+ @wednesdays
45
+ end
46
+
47
+ def thursdays?
48
+ @thursdays
49
+ end
50
+
51
+ def fridays?
52
+ @fridays
53
+ end
54
+
55
+ def saturdays?
56
+ @saturdays
57
+ end
58
+
59
+ def sundays?
60
+ @sundays
35
61
  end
36
62
 
37
- def mondays?; @mondays; end
38
- def tuesdays?; @tuesdays; end
39
- def wednesdays?; @wednesdays; end
40
- def thursdays?; @thursdays; end
41
- def fridays?; @fridays; end
42
- def saturdays?; @saturdays; end
43
- def sundays?; @sundays; end
44
-
45
63
  def parse_boolean_int(string)
46
- (string && string == "1") ? true : false
64
+ string && string == '1' ? true : false
47
65
  end
48
-
66
+
49
67
  def to_json(*args)
50
68
  {
51
- :vehicle_type => @vehicle_type,
52
- :registration_number => @registration_number,
53
- :identifier => @identifier,
54
- :operator => @operator,
55
- :route_number => @route_number,
56
- :first_date_of_operation => @first_date_of_operation,
57
- :running_board => @running_board,
58
- :last_date_of_operation => @last_date_of_operation,
59
- :school_term_time => @school_term_time,
60
- :route_direction => @route_direction,
61
- :bank_holidays => @bank_holidays,
62
- :stops => @stops
69
+ vehicle_type: @vehicle_type,
70
+ registration_number: @registration_number,
71
+ identifier: @identifier,
72
+ operator: @operator,
73
+ route_number: @route_number,
74
+ first_date_of_operation: @first_date_of_operation,
75
+ running_board: @running_board,
76
+ last_date_of_operation: @last_date_of_operation,
77
+ school_term_time: @school_term_time,
78
+ route_direction: @route_direction,
79
+ bank_holidays: @bank_holidays,
80
+ stops: @stops
63
81
  }.to_json(*args)
64
82
  end
65
83
  end
66
- end
84
+ end
data/lib/atco/location.rb CHANGED
@@ -1,7 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Atco
2
-
3
4
  class Location
4
-
5
5
  attr_accessor :name, :identifier, :easting, :northing, :gazeteer_code
6
6
 
7
7
  def initialize(location_header, additional_location_information)
@@ -13,15 +13,13 @@ module Atco
13
13
  end
14
14
 
15
15
  def to_json(*a)
16
- {
17
- :name => @name,
18
- :identifier => @identifier,
19
- :easting => @easting,
20
- :northing => @northing,
21
- :gazeteer_code => @gazeteer_code
16
+ {
17
+ name: @name,
18
+ identifier: @identifier,
19
+ easting: @easting,
20
+ northing: @northing,
21
+ gazeteer_code: @gazeteer_code
22
22
  }.to_json(*a)
23
23
  end
24
-
25
24
  end
26
-
27
- end
25
+ end
data/lib/atco/stop.rb CHANGED
@@ -1,13 +1,22 @@
1
- module Atco
1
+ # frozen_string_literal: true
2
2
 
3
+ module Atco
3
4
  class Stop
5
+ attr_accessor :bay_number, :location, :timing_point_indicator, :fare_stage_indicator, :published_departure_time,
6
+ :record_identity
7
+
8
+ def origin?
9
+ @record_identity == 'QO'
10
+ end
4
11
 
5
- attr_accessor :bay_number, :location, :timing_point_indicator, :fare_stage_indicator, :published_departure_time, :record_identity
12
+ def intermediate?
13
+ @record_identity == 'QI'
14
+ end
15
+
16
+ def destination?
17
+ @record_identity == 'QT'
18
+ end
6
19
 
7
- def origin?; @record_identity == "QO"; end
8
- def intermediate?; @record_identity == "QI"; end
9
- def destination?; @record_identity == "QT"; end
10
-
11
20
  def initialize(data)
12
21
  @bay_number = data[:bay_number]
13
22
  @location = data[:location]
@@ -19,13 +28,13 @@ module Atco
19
28
 
20
29
  def to_json(*args)
21
30
  {
22
- :record_identity => @record_identity,
23
- :location => @location,
24
- :published_departure_time => @published_departure_time,
25
- :timing_point_indicator => @timing_point_indicator,
26
- :fare_stage_indicator => @fare_stage_indicator,
27
- :bay_number => @bay_number
31
+ record_identity: @record_identity,
32
+ location: @location,
33
+ published_departure_time: @published_departure_time,
34
+ timing_point_indicator: @timing_point_indicator,
35
+ fare_stage_indicator: @fare_stage_indicator,
36
+ bay_number: @bay_number
28
37
  }.to_json(*args)
29
38
  end
30
39
  end
31
- end
40
+ end
data/lib/atco.rb CHANGED
@@ -1,183 +1,182 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__)) unless
4
+ $LOAD_PATH.include?(File.dirname(__FILE__)) || $LOAD_PATH.include?(__dir__)
3
5
 
4
6
  require 'open3'
5
- require 'tempfile'
7
+ require 'tempfile'
6
8
  require 'atco/location'
7
9
  require 'atco/journey'
8
10
  require 'atco/stop'
9
11
 
10
-
11
12
  module Atco
12
13
  VERSION = '0.0.1'
13
-
14
+
14
15
  class << self
15
-
16
16
  @path = nil
17
17
  @@methods = {
18
- :bank_holiday => 'QH',
19
- :operator => 'QP',
20
- :additional_location_info => 'QB',
21
- :location => 'QL',
22
- :destination => 'QT',
23
- :intermediate => 'QI',
24
- :origin => 'QO',
25
- :journey_header => 'QS'
18
+ bank_holiday: 'QH',
19
+ operator: 'QP',
20
+ additional_location_info: 'QB',
21
+ location: 'QL',
22
+ destination: 'QT',
23
+ intermediate: 'QI',
24
+ origin: 'QO',
25
+ journey_header: 'QS'
26
26
  }
27
-
27
+
28
28
  def parse(file)
29
29
  @path = File.expand_path(file)
30
30
  data = File.readlines(@path)
31
-
31
+
32
32
  objects = []
33
33
  current_journey = nil
34
34
  current_location = nil
35
35
  locations = []
36
36
  journeys = {}
37
37
  header = nil
38
-
38
+
39
39
  data.each do |line|
40
40
  if line == data.first
41
41
  header = parse_header(line)
42
42
  next
43
43
  end
44
- @@methods.each do |method,identifier|
45
- object = self.send("parse_#{method}", line)
46
- if object[:record_identity] && object[:record_identity] == identifier
47
- current_journey = object if object[:record_identity] && object[:record_identity] == @@methods[:journey_header]
48
- if object[:record_identity] && ( object[:record_identity] == @@methods[:location] || object[:record_identity] == @@methods[:additional_location_info] )
49
- if object[:record_identity] == @@methods[:location]
50
- current_location = object
51
- else
52
- locations << Location.new(current_location, object)
53
- end
44
+ @@methods.each do |method, identifier|
45
+ object = send("parse_#{method}", line)
46
+ next unless object[:record_identity] && object[:record_identity] == identifier
47
+
48
+ current_journey = object if object[:record_identity] && object[:record_identity] == @@methods[:journey_header]
49
+ if object[:record_identity] && (object[:record_identity] == @@methods[:location] || object[:record_identity] == @@methods[:additional_location_info])
50
+ if object[:record_identity] == @@methods[:location]
51
+ current_location = object
52
+ else
53
+ locations << Location.new(current_location, object)
54
54
  end
55
+ end
55
56
 
56
- if current_journey
57
- if journeys[current_journey[:unique_journey_identifier]]
58
- journeys[current_journey[:unique_journey_identifier]].stops << Stop.new(object)
59
- else
60
- journeys[current_journey[:unique_journey_identifier]] = Journey.new(object)
61
- end
57
+ if current_journey
58
+ if journeys[current_journey[:unique_journey_identifier]]
59
+ journeys[current_journey[:unique_journey_identifier]].stops << Stop.new(object)
60
+ else
61
+ journeys[current_journey[:unique_journey_identifier]] = Journey.new(object)
62
62
  end
63
- objects << object
64
63
  end
64
+ objects << object
65
65
  end
66
66
  end
67
- return {:header => header, :locations => locations, :journeys => journeys}
67
+ { header: header, locations: locations, journeys: journeys }
68
68
  end
69
-
69
+
70
70
  def parse_header(string)
71
71
  {
72
- :file_type => string[0,8],
73
- :version => "#{string[8,2].to_i}.#{string[10,2].to_i}",
74
- :file_originator => string[12,32].strip!,
75
- :source_product => string[44,16].strip!,
76
- :production_datetime => string[60,14]
77
- }
72
+ file_type: string[0, 8],
73
+ version: "#{string[8, 2].to_i}.#{string[10, 2].to_i}",
74
+ file_originator: string[12, 32].strip!,
75
+ source_product: string[44, 16].strip!,
76
+ production_datetime: string[60, 14]
77
+ }
78
78
  end
79
-
79
+
80
80
  def parse_bank_holiday(string)
81
81
  {
82
- :record_identity => string[0,2],
83
- :transaction_type => string[2,1],
84
- :date_of_bank_holiday => string[3,8]
82
+ record_identity: string[0, 2],
83
+ transaction_type: string[2, 1],
84
+ date_of_bank_holiday: string[3, 8]
85
85
  }
86
86
  end
87
-
87
+
88
88
  def parse_operator(string)
89
89
  {
90
- :record_identity => string[0,2],
91
- :transaction_type => string[2,1],
92
- :operator => parse_value(string[3,4]),
93
- :operator_short_form => parse_value(string[7,24]),
94
- :operator_legal_name => parse_value(string[31,48])
90
+ record_identity: string[0, 2],
91
+ transaction_type: string[2, 1],
92
+ operator: parse_value(string[3, 4]),
93
+ operator_short_form: parse_value(string[7, 24]),
94
+ operator_legal_name: parse_value(string[31, 48])
95
95
  }
96
96
  end
97
97
 
98
98
  def parse_additional_location_info(string)
99
99
  {
100
- :record_identity => string[0,2],
101
- :transaction_type => string[2,1],
102
- :location => string[3,12].strip,
103
- :grid_reference_easting => parse_value(string[15,8]),
104
- :grid_reference_northing => parse_value(string[23,8])
100
+ record_identity: string[0, 2],
101
+ transaction_type: string[2, 1],
102
+ location: string[3, 12].strip,
103
+ grid_reference_easting: parse_value(string[15, 8]),
104
+ grid_reference_northing: parse_value(string[23, 8])
105
105
  }
106
106
  end
107
107
 
108
108
  def parse_location(string)
109
109
  {
110
- :record_identity => string[0,2],
111
- :transaction_type => string[2,1],
112
- :location => parse_value(string[3,12]),
113
- :full_location => parse_value(string[15,48]),
114
- :gazetteer_code => string[63,1]
110
+ record_identity: string[0, 2],
111
+ transaction_type: string[2, 1],
112
+ location: parse_value(string[3, 12]),
113
+ full_location: parse_value(string[15, 48]),
114
+ gazetteer_code: string[63, 1]
115
115
  }
116
116
  end
117
117
 
118
118
  def parse_destination(string)
119
119
  {
120
- :record_identity => string[0,2],
121
- :location => string[2,12],
122
- :published_arrival_time => string[14,4],
123
- :bay_number => parse_value(string[18,3]),
124
- :timing_point_indicator => string[21,2],
125
- :fare_stage_indicator => string[23,2]
120
+ record_identity: string[0, 2],
121
+ location: string[2, 12],
122
+ published_arrival_time: string[14, 4],
123
+ bay_number: parse_value(string[18, 3]),
124
+ timing_point_indicator: string[21, 2],
125
+ fare_stage_indicator: string[23, 2]
126
126
  }
127
127
  end
128
128
 
129
129
  def parse_intermediate(string)
130
130
  {
131
- :record_identity => string[0,2],
132
- :location => string[2,12],
133
- :published_arrival_time => string[14,4],
134
- :published_departure_time => string[18,4],
135
- :activity_flag => string[22,1],
136
- :bay_number => parse_value(string[23,3]),
137
- :timing_point_indicator => string[26,2],
138
- :fare_stage_indicator => string[28,2]
131
+ record_identity: string[0, 2],
132
+ location: string[2, 12],
133
+ published_arrival_time: string[14, 4],
134
+ published_departure_time: string[18, 4],
135
+ activity_flag: string[22, 1],
136
+ bay_number: parse_value(string[23, 3]),
137
+ timing_point_indicator: string[26, 2],
138
+ fare_stage_indicator: string[28, 2]
139
139
  }
140
140
  end
141
141
 
142
142
  def parse_origin(string)
143
143
  {
144
- :record_identity => string[0,2],
145
- :location => string[2,12],
146
- :published_departure_time => string[14,4],
147
- :bay_number => parse_value(string[18,3]),
148
- :timing_point_indicator => string[21,2],
149
- :fare_stage_indicator => string[23,2]
144
+ record_identity: string[0, 2],
145
+ location: string[2, 12],
146
+ published_departure_time: string[14, 4],
147
+ bay_number: parse_value(string[18, 3]),
148
+ timing_point_indicator: string[21, 2],
149
+ fare_stage_indicator: string[23, 2]
150
150
  }
151
151
  end
152
152
 
153
153
  def parse_journey_header(string)
154
154
  {
155
- :record_identity => string[0,2],
156
- :transaction_type => string[2,1],
157
- :operator => string[3,4].strip,
158
- :unique_journey_identifier => string[7,6],
159
- :first_date_of_operation => parse_value(string[13,8]),
160
- :last_date_of_operation => parse_value(string[21,8]),
161
- :operates_on_mondays => string[29,1],
162
- :operates_on_tuesdays => string[30,1],
163
- :operates_on_wednesdays => string[31,1],
164
- :operates_on_thursdays => string[32,1],
165
- :operates_on_fridays => string[33,1],
166
- :operates_on_saturdays => string[34,1],
167
- :operates_on_sundays => string[35,1],
168
- :school_term_time => parse_value(string[36,1]),
169
- :bank_holidays => parse_value(string[37,1]),
170
- :route_number => parse_value(string[38,4]),
171
- :running_board => parse_value(string[42,6]),
172
- :vehicle_type => parse_value(string[48,8]),
173
- :registration_number => parse_value(string[56,8]),
174
- :route_direction => string[64,1]
155
+ record_identity: string[0, 2],
156
+ transaction_type: string[2, 1],
157
+ operator: string[3, 4].strip,
158
+ unique_journey_identifier: string[7, 6],
159
+ first_date_of_operation: parse_value(string[13, 8]),
160
+ last_date_of_operation: parse_value(string[21, 8]),
161
+ operates_on_mondays: string[29, 1],
162
+ operates_on_tuesdays: string[30, 1],
163
+ operates_on_wednesdays: string[31, 1],
164
+ operates_on_thursdays: string[32, 1],
165
+ operates_on_fridays: string[33, 1],
166
+ operates_on_saturdays: string[34, 1],
167
+ operates_on_sundays: string[35, 1],
168
+ school_term_time: parse_value(string[36, 1]),
169
+ bank_holidays: parse_value(string[37, 1]),
170
+ route_number: parse_value(string[38, 4]),
171
+ running_board: parse_value(string[42, 6]),
172
+ vehicle_type: parse_value(string[48, 8]),
173
+ registration_number: parse_value(string[56, 8]),
174
+ route_direction: string[64, 1]
175
175
  }
176
176
  end
177
-
177
+
178
178
  def parse_value(value)
179
- return value.strip if value
179
+ value&.strip
180
180
  end
181
181
  end
182
-
183
- end
182
+ end
data/spec/atco_spec.rb CHANGED
@@ -1,150 +1,174 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "#{File.dirname(__FILE__)}/spec_helper"
2
4
  require 'json'
3
5
 
4
6
  describe Atco do
5
-
6
7
  before(:all) do
7
-
8
8
  end
9
-
10
- it "should output file for debugging!" do
9
+
10
+ it 'should output file for debugging!' do
11
11
  result = Atco.parse('spec/fixtures/example.cif')
12
12
  File.open('test.output', 'w+') do |f|
13
13
  f.flush
14
14
  f.write(JSON.pretty_generate(result))
15
15
  end
16
- #fixture = JSON.parse(File.read('spec/fixtures/example.json'))
17
16
  end
18
-
19
- it "should parse header from fixture" do
17
+
18
+ it 'should parse header from fixture' do
20
19
  result = Atco.parse('spec/fixtures/example.cif')
21
- result[:header].should == {
22
- :file_type => "ATCO-CIF",
23
- :file_originator => "Electronic Registration",
24
- :source_product => "MIA 4.20.18",
25
- :version => "5.0",
26
- :production_datetime => "20090915113809"
20
+ expect result[:header] == {
21
+ file_type: 'ATCO-CIF',
22
+ file_originator: 'Electronic Registration',
23
+ source_product: 'MIA 4.20.18',
24
+ version: '5.0',
25
+ production_datetime: '20090915113809'
27
26
  }
28
27
  end
29
-
30
- it "should parse locations from fixture" do
28
+
29
+ it 'should parse locations from fixture' do
31
30
  result = Atco.parse('spec/fixtures/example.cif')
32
- result[:header].should == {
33
- :file_type => "ATCO-CIF",
34
- :file_originator => "Electronic Registration",
35
- :source_product => "MIA 4.20.18",
36
- :version => "5.0",
37
- :production_datetime => "20090915113809"
31
+ expect result[:header] == {
32
+ file_type: 'ATCO-CIF',
33
+ file_originator: 'Electronic Registration',
34
+ source_product: 'MIA 4.20.18',
35
+ version: '5.0',
36
+ production_datetime: '20090915113809'
38
37
  }
39
38
  end
40
-
41
- it "should parse header" do
42
- Atco.parse_header("ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n").should == {
43
- :file_type => 'ATCO-CIF',
44
- :version => '5.0',
45
- :file_originator => 'Electronic Registration',
46
- :source_product => 'MIA 4.20.18',
47
- :production_datetime => '20090915113809'
39
+
40
+ it 'should parse header' do
41
+ expect Atco.parse_header("ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n") == {
42
+ file_type: 'ATCO-CIF',
43
+ version: '5.0',
44
+ file_originator: 'Electronic Registration',
45
+ source_product: 'MIA 4.20.18',
46
+ production_datetime: '20090915113809'
48
47
  }
49
48
  end
50
-
51
- it "should parse bank holiday" do
52
- Atco.parse_bank_holiday("QHN20061225").should == {
53
- :record_identity => 'QH',
54
- :transaction_type => 'N',
55
- :date_of_bank_holiday => '20061225'
49
+
50
+ it 'should parse bank holiday' do
51
+ expect Atco.parse_bank_holiday('QHN20061225') == {
52
+ record_identity: 'QH',
53
+ transaction_type: 'N',
54
+ date_of_bank_holiday: '20061225'
56
55
  }
57
56
  end
58
-
59
- it "should parse operator" do
60
- Atco.parse_operator("QPNTM Translink Metro Translink Metro \r\n").should == {
61
- :record_identity => 'QP',
62
- :transaction_type => 'N',
63
- :operator => 'TM',
64
- :operator_short_form => 'Translink Metro',
65
- :operator_legal_name => 'Translink Metro'
57
+
58
+ it 'should parse operator' do
59
+ expect Atco.parse_operator("QPNTM Translink Metro Translink Metro \r\n") == {
60
+ record_identity: 'QP',
61
+ transaction_type: 'N',
62
+ operator: 'TM',
63
+ operator_short_form: 'Translink Metro',
64
+ operator_legal_name: 'Translink Metro'
66
65
  }
67
66
  end
68
-
69
- it "should parse additional location information" do
70
- Atco.parse_additional_location_info("QBN700000001252 328622 367433 \r\n").should == {
71
- :record_identity => 'QB',
72
- :transaction_type => 'N',
73
- :location => '700000001252',
74
- :grid_reference_easting => '328622',
75
- :grid_reference_northing => '367433'
67
+
68
+ it 'should parse additional location information' do
69
+ expect Atco.parse_additional_location_info("QBN700000001252 328622 367433 \r\n") == {
70
+ record_identity: 'QB',
71
+ transaction_type: 'N',
72
+ location: '700000001252',
73
+ grid_reference_easting: '328622',
74
+ grid_reference_northing: '367433'
76
75
  }
77
76
  end
78
-
79
- it "should parse location" do
80
- Atco.parse_location("QLN700000001252Conway (River Rd) 1\r\n").should == {
81
- :record_identity => 'QL',
82
- :transaction_type => 'N',
83
- :location => '700000001252',
84
- :full_location => 'Conway (River Rd)',
85
- :gazetteer_code => '1'
77
+
78
+ it 'should parse location' do
79
+ expect Atco.parse_location("QLN700000001252Conway (River Rd) 1\r\n") == {
80
+ record_identity: 'QL',
81
+ transaction_type: 'N',
82
+ location: '700000001252',
83
+ full_location: 'Conway (River Rd)',
84
+ gazetteer_code: '1'
86
85
  }
87
86
  end
88
87
 
89
88
  # QT7000000012520605 T1F0
90
- it "should parse destination" do
91
- Atco.parse_destination("QT7000000012520605 T1F0\r\n").should == {
92
- :record_identity => 'QT',
93
- :location => '700000001252',
94
- :published_arrival_time => '0605',
95
- :bay_number => "",
96
- :timing_point_indicator => 'T1',
97
- :fare_stage_indicator => 'F0'
89
+ it 'should parse destination' do
90
+ expect Atco.parse_destination("QT7000000012520605 T1F0\r\n") == {
91
+ record_identity: 'QT',
92
+ location: '700000001252',
93
+ published_arrival_time: '0605',
94
+ bay_number: '',
95
+ timing_point_indicator: 'T1',
96
+ fare_stage_indicator: 'F0'
98
97
  }
99
98
  end
100
-
101
- it "should parse intermediate" do
102
- Atco.parse_intermediate("QI70000000125607120712B T1F0\r\n").should == {
103
- :record_identity => 'QI',
104
- :location => '700000001256',
105
- :published_arrival_time => '0712',
106
- :published_departure_time => '0712',
107
- :activity_flag => "B",
108
- :bay_number => "",
109
- :timing_point_indicator => 'T1',
110
- :fare_stage_indicator => 'F0'
99
+
100
+ it 'should parse intermediate' do
101
+ expect Atco.parse_intermediate("QI70000000125607120712B T1F0\r\n") == {
102
+ record_identity: 'QI',
103
+ location: '700000001256',
104
+ published_arrival_time: '0712',
105
+ published_departure_time: '0712',
106
+ activity_flag: 'B',
107
+ bay_number: '',
108
+ timing_point_indicator: 'T1',
109
+ fare_stage_indicator: 'F0'
111
110
  }
112
111
  end
113
-
114
- it "should parse origin" do
115
- Atco.parse_origin("QO7000000012520730 T1F0\r\n").should == {
116
- :record_identity => 'QO',
117
- :location => '700000001252',
118
- :published_departure_time => '0730',
119
- :bay_number => "",
120
- :timing_point_indicator => 'T1',
121
- :fare_stage_indicator => 'F0'
112
+
113
+ it 'should parse origin' do
114
+ expect Atco.parse_origin("QO7000000012520730 T1F0\r\n") == {
115
+ record_identity: 'QO',
116
+ location: '700000001252',
117
+ published_departure_time: '0730',
118
+ bay_number: '',
119
+ timing_point_indicator: 'T1',
120
+ fare_stage_indicator: 'F0'
122
121
  }
123
122
  end
124
123
 
125
- it "should parse journey header" do
126
- Atco.parse_journey_header("QSNTM 13986520091005 1111100 9A 9018 0 I\r\n").should == {
127
- :record_identity => 'QS',
128
- :transaction_type => 'N',
129
- :operator => 'TM',
130
- :unique_journey_identifier => '139865',
131
- :first_date_of_operation => '20091005',
132
- :last_date_of_operation => '',
133
- :operates_on_mondays => '1',
134
- :operates_on_tuesdays => '1',
135
- :operates_on_wednesdays => '1',
136
- :operates_on_thursdays => '1',
137
- :operates_on_fridays => '1',
138
- :operates_on_saturdays => '0',
139
- :operates_on_sundays => '0',
140
- :school_term_time => '',
141
- :bank_holidays => '',
142
- :route_number => '9A',
143
- :running_board => '9018',
144
- :vehicle_type => '0',
145
- :registration_number => '',
146
- :route_direction => 'I'
124
+ it 'should parse journey header' do
125
+ expect Atco.parse_journey_header("QSNTM 13986520091005 1111100 9A 9018 0 I\r\n") == {
126
+ record_identity: 'QS',
127
+ transaction_type: 'N',
128
+ operator: 'TM',
129
+ unique_journey_identifier: '139865',
130
+ first_date_of_operation: '20091005',
131
+ last_date_of_operation: '',
132
+ operates_on_mondays: '1',
133
+ operates_on_tuesdays: '1',
134
+ operates_on_wednesdays: '1',
135
+ operates_on_thursdays: '1',
136
+ operates_on_fridays: '1',
137
+ operates_on_saturdays: '0',
138
+ operates_on_sundays: '0',
139
+ school_term_time: '',
140
+ bank_holidays: '',
141
+ route_number: '9A',
142
+ running_board: '9018',
143
+ vehicle_type: '0',
144
+ registration_number: '',
145
+ route_direction: 'I'
147
146
  }
148
147
  end
149
148
 
150
- end
149
+ describe 'with example.cif' do
150
+ before(:all) do
151
+ @atco = Atco.parse('spec/fixtures/example.cif')
152
+ end
153
+
154
+ it 'should parse 1 journey' do
155
+ expect @atco[:journeys].size == 1
156
+ end
157
+
158
+ it 'should parse journeys into Atco::Joruney objects' do
159
+ expect(@atco[:journeys]['139748']).to be_a_kind_of(Atco::Journey)
160
+ end
161
+
162
+ it 'should parse 6 stops for joureny 139748' do
163
+ expect @atco[:journeys]['139748'].stops.size == 6
164
+ end
165
+
166
+ it 'should parse 6 stops for joureny 139748' do
167
+ expect @atco[:journeys]['139748'].stops.size == 6
168
+ end
169
+
170
+ it 'should parse 2 locations' do
171
+ expect @atco[:locations].size == 2
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,30 @@
1
+ ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809
2
+ QLN700000001433Donegal Square East 1
3
+ QBN700000001433 333935 373979
4
+ GS00001433 N Belfast Metro Ops 7000
5
+ GR00001433Donegall Square East 7000
6
+ QLN700000001627Great Northern Mall 1
7
+ QBN700000001627 333575 373717
8
+ GS00001627 N Belfast Metro Ops 7000
9
+ GR00001627Great Victoria Street 7000 7000
10
+ QPNTM Translink Metro Translink Metro
11
+ QQ
12
+ ZLTMAO009AT05O
13
+ ZD20091005 Monday to Friday FFFFF00
14
+ ZSTMAO009A9A City Centre - Conway
15
+ ZAN700000001433 P1W1T1
16
+ ZAN700000001627 P1W1T1
17
+ QSNTM 13974820091005 1111100 9A 9011 0 O
18
+ ZJTMAO009A004 1 370 000CB 545 2237 C FFFFF00L0
19
+ QO7000000014330545 T1F0
20
+ ZECH0 054500054500P0W0
21
+ QI70000000162705460546B T1F0
22
+ ZECH0 054600054600P0W0
23
+ QI70000000124806020602B T1F0
24
+ ZECH0 060200060200P0W0
25
+ QI70000000125006030603B T0F0
26
+ ZECH0 060348060348P0W0
27
+ QT7000000012520605 T1F0
28
+ ZECH0 060500060500P0W0
29
+ QVN0 Bus
30
+ QHN20071226
@@ -0,0 +1,98 @@
1
+ {
2
+ "header": {
3
+ "file_type": "ATCO-CIF",
4
+ "file_originator": "Electronic Registration",
5
+ "source_product": "MIA 4.20.18",
6
+ "version": "5.0",
7
+ "production_datetime": "20090915113809"
8
+ },
9
+ "locations": [
10
+ [
11
+ {
12
+ "record_identity": "QL",
13
+ "location": "700000001433",
14
+ "transaction_type": "N",
15
+ "full_location": "Donegal Square East",
16
+ "gazetteer_code": "1"
17
+ },
18
+ {
19
+ "record_identity": "QB",
20
+ "location": "700000001433",
21
+ "transaction_type": "N",
22
+ "grid_reference_easting": "333935",
23
+ "grid_reference_northing": "373979"
24
+ }
25
+ ],
26
+ [
27
+ {
28
+ "record_identity": "QL",
29
+ "location": "700000001627",
30
+ "transaction_type": "N",
31
+ "full_location": "Great Northern Mall",
32
+ "gazetteer_code": "1"
33
+ },
34
+ {
35
+ "record_identity": "QB",
36
+ "location": "700000001627",
37
+ "transaction_type": "N",
38
+ "grid_reference_easting": "333575",
39
+ "grid_reference_northing": "373717"
40
+ }
41
+ ]
42
+ ],
43
+ "journeys": {
44
+ "139748": [
45
+ {
46
+ "record_identity": "QO",
47
+ "published_departure_time": "0545",
48
+ "location": "700000001433",
49
+ "bay_number": "",
50
+ "timing_point_indicator": "T1",
51
+ "fare_stage_indicator": "F0"
52
+ },
53
+ {
54
+ "record_identity": "QI",
55
+ "published_departure_time": "0546",
56
+ "location": "700000001627",
57
+ "published_arrival_time": "0546",
58
+ "activity_flag": "B",
59
+ "bay_number": "",
60
+ "timing_point_indicator": "T1",
61
+ "fare_stage_indicator": "F0"
62
+ },
63
+ {
64
+ "record_identity": "QI",
65
+ "published_departure_time": "0602",
66
+ "location": "700000001248",
67
+ "published_arrival_time": "0602",
68
+ "activity_flag": "B",
69
+ "bay_number": "",
70
+ "timing_point_indicator": "T1",
71
+ "fare_stage_indicator": "F0"
72
+ },
73
+ {
74
+ "record_identity": "QI",
75
+ "published_departure_time": "0603",
76
+ "location": "700000001250",
77
+ "published_arrival_time": "0603",
78
+ "activity_flag": "B",
79
+ "bay_number": "",
80
+ "timing_point_indicator": "T0",
81
+ "fare_stage_indicator": "F0"
82
+ },
83
+ {
84
+ "record_identity": "QT",
85
+ "location": "700000001252",
86
+ "published_arrival_time": "0605",
87
+ "bay_number": "",
88
+ "timing_point_indicator": "T1",
89
+ "fare_stage_indicator": "F0"
90
+ },
91
+ {
92
+ "record_identity": "QH",
93
+ "transaction_type": "N",
94
+ "date_of_bank_holiday": "20071226"
95
+ }
96
+ ]
97
+ }
98
+ }
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
- require File.dirname(__FILE__) + '/../lib/atco'
4
+ require 'rspec'
5
+
6
+ require "#{File.dirname(__FILE__)}/../lib/atco"
metadata CHANGED
@@ -1,69 +1,84 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: atco
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 2
9
- version: 0.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
10
5
  platform: ruby
11
- authors:
6
+ authors:
12
7
  - David Rice
13
8
  autorequire:
14
9
  bindir: bin
15
10
  cert_chain: []
16
-
17
- date: 2010-02-22 00:00:00 +00:00
18
- default_executable:
19
- dependencies: []
20
-
21
- description: Simple and opinionated library for parsing ATCO-CIF files with Ruby.
11
+ date: 2024-04-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Simple and opinionated library for parsing ATCO .cif files to JSON with
42
+ Ruby
22
43
  email: me@davidjrice.co.uk
23
44
  executables: []
24
-
25
45
  extensions: []
26
-
27
- extra_rdoc_files:
28
- - README.mdown
29
- files:
30
- - README.mdown
46
+ extra_rdoc_files:
47
+ - README.md
48
+ files:
49
+ - README.md
31
50
  - Rakefile
32
51
  - VERSION
33
52
  - lib/atco.rb
34
53
  - lib/atco/journey.rb
35
54
  - lib/atco/location.rb
36
55
  - lib/atco/stop.rb
37
- has_rdoc: true
56
+ - spec/atco_spec.rb
57
+ - spec/fixtures/example.cif
58
+ - spec/fixtures/example.json
59
+ - spec/spec_helper.rb
38
60
  homepage: http://github.com/davidjrice/atco
39
- licenses: []
40
-
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
41
64
  post_install_message:
42
- rdoc_options:
43
- - --charset=UTF-8
44
- require_paths:
65
+ rdoc_options:
66
+ - "--charset=UTF-8"
67
+ require_paths:
45
68
  - lib
46
- required_ruby_version: !ruby/object:Gem::Requirement
47
- requirements:
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
48
71
  - - ">="
49
- - !ruby/object:Gem::Version
50
- segments:
51
- - 0
52
- version: "0"
53
- required_rubygems_version: !ruby/object:Gem::Requirement
54
- requirements:
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
55
76
  - - ">="
56
- - !ruby/object:Gem::Version
57
- segments:
58
- - 0
59
- version: "0"
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
60
79
  requirements: []
61
-
62
- rubyforge_project:
63
- rubygems_version: 1.3.6
80
+ rubygems_version: 3.5.3
64
81
  signing_key:
65
- specification_version: 3
66
- summary: Simple and opinionated library for parsing ATCO-CIF files with Ruby.
67
- test_files:
68
- - spec/atco_spec.rb
69
- - spec/spec_helper.rb
82
+ specification_version: 4
83
+ summary: Parse ATCO .cif files to JSON with Ruby
84
+ test_files: []