atco 0.0.2 → 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 215cf54f3257e776c20d54d0177731f06cf62eda409e7763457c709757aa1a52
4
+ data.tar.gz: 97ebd8cf82c779b872f23204079a230aae0d9b159bacdf3db5042cada877a197
5
+ SHA512:
6
+ metadata.gz: 69b1de96881df1044138cbebe82ea3e22053c47d36aa38dbb39c1018683675eb44e27619be1d29346d5ef156f924c3ee8e408808aec11b7940ad2ca4877dfc25
7
+ data.tar.gz: d14f0b410610dbaf1d2e4e80ce41703becb6fddc99c06bbe3a88500d65bde6b3b44bdfa7768405682c654abf8cb0ecb5470a7589b7f6b978f0933db2e230736e
@@ -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,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+
1
5
  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
6
+ require "rspec/core/rake_task"
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
+ begin
13
+ require "rubocop/rake_task"
14
+ RuboCop::RakeTask.new
15
+ rescue LoadError
16
+ puts "rubocop, or one of its dependencies, is not available. Install it with: bundle install"
17
+ end
18
+
19
+ task default: %i[spec rubocop]
data/lib/atco/journey.rb CHANGED
@@ -1,13 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Atco
2
-
4
+ # Atco::Journey is a data class to abstract ATCO-CIF Journey records.
3
5
  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
6
+ attr_accessor :vehicle_type, :registration_number, :identifier, :operator, :route_number, :first_date_of_operation,
7
+ :running_board, :last_date_of_operation, :school_term_time, :route_direction, :bank_holidays, :stops
9
8
 
10
- def initialize(data)
9
+ def initialize(data) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
11
10
  @mondays = parse_boolean_int data[:operates_on_mondays]
12
11
  @tuesdays = parse_boolean_int data[:operates_on_tuesdays]
13
12
  @wednesdays = parse_boolean_int data[:operates_on_wednesdays]
@@ -15,7 +14,7 @@ module Atco
15
14
  @fridays = parse_boolean_int data[:operates_on_fridays]
16
15
  @saturdays = parse_boolean_int data[:operates_on_saturdays]
17
16
  @sundays = parse_boolean_int data[:operates_on_sundays]
18
-
17
+
19
18
  @vehicle_type = data[:vehicle_type]
20
19
  @registration_number = data[:registration_number]
21
20
  @identifier = data[:unique_journey_identifier]
@@ -27,40 +26,60 @@ module Atco
27
26
  @running_board = data[:running_board]
28
27
  @school_term_time = data[:school_term_time]
29
28
  @bank_holidays = data[:bank_holidays]
30
-
29
+
31
30
  @stops = []
32
- #stops.each do |s|
33
- # @stops << Stop.new(s)
34
- #end
31
+ # stops.each do |s|
32
+ # @stops << Stop.new(s)
33
+ # end
34
+ end
35
+
36
+ def mondays?
37
+ @mondays
38
+ end
39
+
40
+ def tuesdays?
41
+ @tuesdays
42
+ end
43
+
44
+ def wednesdays?
45
+ @wednesdays
46
+ end
47
+
48
+ def thursdays?
49
+ @thursdays
50
+ end
51
+
52
+ def fridays?
53
+ @fridays
54
+ end
55
+
56
+ def saturdays?
57
+ @saturdays
58
+ end
59
+
60
+ def sundays?
61
+ @sundays
35
62
  end
36
63
 
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
64
  def parse_boolean_int(string)
46
- (string && string == "1") ? true : false
65
+ string && string == "1"
47
66
  end
48
-
49
- def to_json(*args)
67
+
68
+ def to_json(*attrs) # rubocop:disable Metrics/MethodLength
50
69
  {
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
63
- }.to_json(*args)
70
+ vehicle_type: @vehicle_type,
71
+ registration_number: @registration_number,
72
+ identifier: @identifier,
73
+ operator: @operator,
74
+ route_number: @route_number,
75
+ first_date_of_operation: @first_date_of_operation,
76
+ running_board: @running_board,
77
+ last_date_of_operation: @last_date_of_operation,
78
+ school_term_time: @school_term_time,
79
+ route_direction: @route_direction,
80
+ bank_holidays: @bank_holidays,
81
+ stops: @stops
82
+ }.to_json(*attrs)
64
83
  end
65
84
  end
66
- end
85
+ end
data/lib/atco/location.rb CHANGED
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Atco
2
-
4
+ # Atco::Location is a data class to abstract ATCO-CIF Location records.
3
5
  class Location
4
-
5
6
  attr_accessor :name, :identifier, :easting, :northing, :gazeteer_code
6
7
 
7
8
  def initialize(location_header, additional_location_information)
@@ -12,16 +13,14 @@ module Atco
12
13
  @gazeteer_code = location_header[:gazetteer_code]
13
14
  end
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
22
- }.to_json(*a)
16
+ def to_json(*attrs)
17
+ {
18
+ name: @name,
19
+ identifier: @identifier,
20
+ easting: @easting,
21
+ northing: @northing,
22
+ gazeteer_code: @gazeteer_code
23
+ }.to_json(*attrs)
23
24
  end
24
-
25
25
  end
26
-
27
- end
26
+ end
data/lib/atco/stop.rb CHANGED
@@ -1,13 +1,23 @@
1
- module Atco
1
+ # frozen_string_literal: true
2
2
 
3
+ module Atco
4
+ # Atco::Stop is a class to abstract ATCO-CIF Origin, Intermediate and Destination (Stop) records.
3
5
  class Stop
6
+ attr_accessor :bay_number, :location, :timing_point_indicator, :fare_stage_indicator, :published_departure_time,
7
+ :record_identity
8
+
9
+ def origin?
10
+ @record_identity == "QO"
11
+ end
4
12
 
5
- attr_accessor :bay_number, :location, :timing_point_indicator, :fare_stage_indicator, :published_departure_time, :record_identity
13
+ def intermediate?
14
+ @record_identity == "QI"
15
+ end
16
+
17
+ def destination?
18
+ @record_identity == "QT"
19
+ end
6
20
 
7
- def origin?; @record_identity == "QO"; end
8
- def intermediate?; @record_identity == "QI"; end
9
- def destination?; @record_identity == "QT"; end
10
-
11
21
  def initialize(data)
12
22
  @bay_number = data[:bay_number]
13
23
  @location = data[:location]
@@ -17,15 +27,15 @@ module Atco
17
27
  @record_identity = data[:record_identity]
18
28
  end
19
29
 
20
- def to_json(*args)
30
+ def to_json(*attrs)
21
31
  {
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
28
- }.to_json(*args)
32
+ record_identity: @record_identity,
33
+ location: @location,
34
+ published_departure_time: @published_departure_time,
35
+ timing_point_indicator: @timing_point_indicator,
36
+ fare_stage_indicator: @fare_stage_indicator,
37
+ bay_number: @bay_number
38
+ }.to_json(*attrs)
29
39
  end
30
40
  end
31
- end
41
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Atco
4
+ VERSION = "1.0.1"
5
+ end
data/lib/atco.rb CHANGED
@@ -1,183 +1,179 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
1
+ # frozen_string_literal: true
3
2
 
4
- require 'open3'
5
- require 'tempfile'
6
- require 'atco/location'
7
- require 'atco/journey'
8
- require 'atco/stop'
3
+ require "open3"
4
+ require "tempfile"
5
+ require_relative "atco/location"
6
+ require_relative "atco/journey"
7
+ require_relative "atco/stop"
8
+ require_relative "atco/version"
9
9
 
10
-
11
- module Atco
12
- VERSION = '0.0.1'
13
-
14
- class << self
15
-
10
+ # Public: Atco is a module that provides a parser for the ATCO-CIF data format.
11
+ module Atco # rubocop:disable Metrics/ModuleLength
12
+ class << self # rubocop:disable Metrics/ClassLength
16
13
  @path = nil
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'
26
- }
27
-
28
- def parse(file)
14
+ METHODS = {
15
+ bank_holiday: "QH",
16
+ operator: "QP",
17
+ additional_location_info: "QB",
18
+ location: "QL",
19
+ destination: "QT",
20
+ intermediate: "QI",
21
+ origin: "QO",
22
+ journey_header: "QS"
23
+ }.freeze
24
+
25
+ def parse(file) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
29
26
  @path = File.expand_path(file)
30
27
  data = File.readlines(@path)
31
-
28
+
32
29
  objects = []
33
30
  current_journey = nil
34
31
  current_location = nil
35
32
  locations = []
36
33
  journeys = {}
37
34
  header = nil
38
-
35
+
39
36
  data.each do |line|
40
37
  if line == data.first
41
38
  header = parse_header(line)
42
39
  next
43
40
  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
41
+ METHODS.each do |method, identifier|
42
+ object = send("parse_#{method}", line)
43
+ next unless object[:record_identity] && object[:record_identity] == identifier
44
+
45
+ current_journey = object if object[:record_identity] && object[:record_identity] == METHODS[:journey_header]
46
+ if object[:record_identity] && (object[:record_identity] == METHODS[:location] || object[:record_identity] == METHODS[:additional_location_info]) # rubocop:disable Layout/LineLength
47
+ if object[:record_identity] == METHODS[:location]
48
+ current_location = object
49
+ else
50
+ locations << Location.new(current_location, object)
54
51
  end
52
+ end
55
53
 
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
54
+ if current_journey
55
+ if journeys[current_journey[:unique_journey_identifier]]
56
+ journeys[current_journey[:unique_journey_identifier]].stops << Stop.new(object)
57
+ else
58
+ journeys[current_journey[:unique_journey_identifier]] = Journey.new(object)
62
59
  end
63
- objects << object
64
60
  end
61
+ objects << object
65
62
  end
66
63
  end
67
- return {:header => header, :locations => locations, :journeys => journeys}
64
+ { header: header, locations: locations, journeys: journeys }
68
65
  end
69
-
66
+
70
67
  def parse_header(string)
71
68
  {
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
- }
69
+ file_type: string[0, 8],
70
+ version: "#{string[8, 2].to_i}.#{string[10, 2].to_i}",
71
+ file_originator: string[12, 32].strip!,
72
+ source_product: string[44, 16].strip!,
73
+ production_datetime: string[60, 14]
74
+ }
78
75
  end
79
-
76
+
80
77
  def parse_bank_holiday(string)
81
78
  {
82
- :record_identity => string[0,2],
83
- :transaction_type => string[2,1],
84
- :date_of_bank_holiday => string[3,8]
79
+ record_identity: string[0, 2],
80
+ transaction_type: string[2, 1],
81
+ date_of_bank_holiday: string[3, 8]
85
82
  }
86
83
  end
87
-
84
+
88
85
  def parse_operator(string)
89
86
  {
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])
87
+ record_identity: string[0, 2],
88
+ transaction_type: string[2, 1],
89
+ operator: parse_value(string[3, 4]),
90
+ operator_short_form: parse_value(string[7, 24]),
91
+ operator_legal_name: parse_value(string[31, 48])
95
92
  }
96
93
  end
97
94
 
98
95
  def parse_additional_location_info(string)
99
96
  {
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])
97
+ record_identity: string[0, 2],
98
+ transaction_type: string[2, 1],
99
+ location: string[3, 12].strip,
100
+ grid_reference_easting: parse_value(string[15, 8]),
101
+ grid_reference_northing: parse_value(string[23, 8])
105
102
  }
106
103
  end
107
104
 
108
105
  def parse_location(string)
109
106
  {
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]
107
+ record_identity: string[0, 2],
108
+ transaction_type: string[2, 1],
109
+ location: parse_value(string[3, 12]),
110
+ full_location: parse_value(string[15, 48]),
111
+ gazetteer_code: string[63, 1]
115
112
  }
116
113
  end
117
114
 
118
115
  def parse_destination(string)
119
116
  {
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]
117
+ record_identity: string[0, 2],
118
+ location: string[2, 12],
119
+ published_arrival_time: string[14, 4],
120
+ bay_number: parse_value(string[18, 3]),
121
+ timing_point_indicator: string[21, 2],
122
+ fare_stage_indicator: string[23, 2]
126
123
  }
127
124
  end
128
125
 
129
126
  def parse_intermediate(string)
130
127
  {
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]
128
+ record_identity: string[0, 2],
129
+ location: string[2, 12],
130
+ published_arrival_time: string[14, 4],
131
+ published_departure_time: string[18, 4],
132
+ activity_flag: string[22, 1],
133
+ bay_number: parse_value(string[23, 3]),
134
+ timing_point_indicator: string[26, 2],
135
+ fare_stage_indicator: string[28, 2]
139
136
  }
140
137
  end
141
138
 
142
139
  def parse_origin(string)
143
140
  {
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]
141
+ record_identity: string[0, 2],
142
+ location: string[2, 12],
143
+ published_departure_time: string[14, 4],
144
+ bay_number: parse_value(string[18, 3]),
145
+ timing_point_indicator: string[21, 2],
146
+ fare_stage_indicator: string[23, 2]
150
147
  }
151
148
  end
152
149
 
153
- def parse_journey_header(string)
150
+ def parse_journey_header(string) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
154
151
  {
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]
152
+ record_identity: string[0, 2],
153
+ transaction_type: string[2, 1],
154
+ operator: string[3, 4].strip,
155
+ unique_journey_identifier: string[7, 6],
156
+ first_date_of_operation: parse_value(string[13, 8]),
157
+ last_date_of_operation: parse_value(string[21, 8]),
158
+ operates_on_mondays: string[29, 1],
159
+ operates_on_tuesdays: string[30, 1],
160
+ operates_on_wednesdays: string[31, 1],
161
+ operates_on_thursdays: string[32, 1],
162
+ operates_on_fridays: string[33, 1],
163
+ operates_on_saturdays: string[34, 1],
164
+ operates_on_sundays: string[35, 1],
165
+ school_term_time: parse_value(string[36, 1]),
166
+ bank_holidays: parse_value(string[37, 1]),
167
+ route_number: parse_value(string[38, 4]),
168
+ running_board: parse_value(string[42, 6]),
169
+ vehicle_type: parse_value(string[48, 8]),
170
+ registration_number: parse_value(string[56, 8]),
171
+ route_direction: string[64, 1]
175
172
  }
176
173
  end
177
-
174
+
178
175
  def parse_value(value)
179
- return value.strip if value
176
+ value&.strip
180
177
  end
181
178
  end
182
-
183
- end
179
+ end
data/spec/atco_spec.rb CHANGED
@@ -1,150 +1,175 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
- require 'json'
1
+ # frozen_string_literal: true
3
2
 
4
- describe Atco do
5
-
6
- before(:all) do
7
-
3
+ require "#{File.dirname(__FILE__)}/spec_helper"
4
+ require "json"
5
+
6
+ describe Atco do # rubocop:disable Metrics/BlockLength
7
+ it "has a version number" do
8
+ expect(Atco::VERSION).not_to be nil
8
9
  end
9
-
10
+
10
11
  it "should output file for debugging!" do
11
- result = Atco.parse('spec/fixtures/example.cif')
12
- File.open('test.output', 'w+') do |f|
12
+ result = Atco.parse("spec/fixtures/example.cif")
13
+ File.open("test.output", "w+") do |f|
13
14
  f.flush
14
15
  f.write(JSON.pretty_generate(result))
15
16
  end
16
- #fixture = JSON.parse(File.read('spec/fixtures/example.json'))
17
17
  end
18
-
18
+
19
19
  it "should parse header from fixture" do
20
- 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
+ result = Atco.parse("spec/fixtures/example.cif")
21
+ expect result[:header] == {
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"
27
27
  }
28
28
  end
29
-
29
+
30
30
  it "should parse locations from fixture" do
31
- 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
+ result = Atco.parse("spec/fixtures/example.cif")
32
+ expect result[:header] == {
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"
38
38
  }
39
39
  end
40
-
40
+
41
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'
42
+ expect Atco.parse_header("ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n") == {
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"
48
48
  }
49
49
  end
50
-
50
+
51
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'
52
+ expect Atco.parse_bank_holiday("QHN20061225") == {
53
+ record_identity: "QH",
54
+ transaction_type: "N",
55
+ date_of_bank_holiday: "20061225"
56
56
  }
57
57
  end
58
-
58
+
59
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'
60
+ expect Atco.parse_operator("QPNTM Translink Metro Translink Metro \r\n") == {
61
+ record_identity: "QP",
62
+ transaction_type: "N",
63
+ operator: "TM",
64
+ operator_short_form: "Translink Metro",
65
+ operator_legal_name: "Translink Metro"
66
66
  }
67
67
  end
68
-
68
+
69
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'
70
+ expect Atco.parse_additional_location_info("QBN700000001252 328622 367433 \r\n") == {
71
+ record_identity: "QB",
72
+ transaction_type: "N",
73
+ location: "700000001252",
74
+ grid_reference_easting: "328622",
75
+ grid_reference_northing: "367433"
76
76
  }
77
77
  end
78
-
78
+
79
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'
80
+ expect Atco.parse_location("QLN700000001252Conway (River Rd) 1\r\n") == {
81
+ record_identity: "QL",
82
+ transaction_type: "N",
83
+ location: "700000001252",
84
+ full_location: "Conway (River Rd)",
85
+ gazetteer_code: "1"
86
86
  }
87
87
  end
88
88
 
89
89
  # QT7000000012520605 T1F0
90
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'
91
+ expect Atco.parse_destination("QT7000000012520605 T1F0\r\n") == {
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"
98
98
  }
99
99
  end
100
-
100
+
101
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'
102
+ expect Atco.parse_intermediate("QI70000000125607120712B T1F0\r\n") == {
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"
111
111
  }
112
112
  end
113
-
113
+
114
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'
115
+ expect Atco.parse_origin("QO7000000012520730 T1F0\r\n") == {
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"
122
122
  }
123
123
  end
124
124
 
125
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'
126
+ expect Atco.parse_journey_header("QSNTM 13986520091005 1111100 9A 9018 0 I\r\n") == {
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"
147
147
  }
148
148
  end
149
149
 
150
- end
150
+ describe "with example.cif" do
151
+ before(:all) do
152
+ @atco = Atco.parse("spec/fixtures/example.cif")
153
+ end
154
+
155
+ it "should parse 1 journey" do
156
+ expect @atco[:journeys].size == 1
157
+ end
158
+
159
+ it "should parse journeys into Atco::Joruney objects" do
160
+ expect(@atco[:journeys]["139748"]).to be_a_kind_of(Atco::Journey)
161
+ end
162
+
163
+ it "should parse 6 stops for joureny 139748" do
164
+ expect @atco[:journeys]["139748"].stops.size == 6
165
+ end
166
+
167
+ it "should parse 6 stops for joureny 139748" do
168
+ expect @atco[:journeys]["139748"].stops.size == 6
169
+ end
170
+
171
+ it "should parse 2 locations" do
172
+ expect @atco[:locations].size == 2
173
+ end
174
+ end
175
+ 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
- require 'rubygems'
2
- require File.dirname(__FILE__) + '/../lib/atco'
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems"
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.1
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-11 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: '13.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '13.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: '3.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.9'
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
- - VERSION
33
51
  - lib/atco.rb
34
52
  - lib/atco/journey.rb
35
53
  - lib/atco/location.rb
36
54
  - lib/atco/stop.rb
37
- has_rdoc: true
55
+ - lib/atco/version.rb
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: 2.7.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: []
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.0.2