atco 1.0.7 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4ddb4c619b9d60d92fa99bc37e0df7f1181e5f42d6e001757284077eadbc597b
4
- data.tar.gz: d5c8ebaa0bcec7f07a447a78e20d77727926de121616b700103fb06719cd2c1f
3
+ metadata.gz: 15e9812933c6ca6dcc275bd1f262a30c4b916a12feedf824ce9c4f55f7d24825
4
+ data.tar.gz: 36e55b87cdaa72cdd1601f87ab10e9937f7ba4d6ea8fdcf174bb5f20603978c2
5
5
  SHA512:
6
- metadata.gz: bae3d2d4b0ace8e394497fba4457f76135940198b10fa05a630ff789efaec217d85cc87406dfca5e338c9aa1e16ee2dd4f62fd039c39066c9235c8b888e9368c
7
- data.tar.gz: 44e57ff1c7f56a5b0e1930f2a1fbbd6ec22490fd25608d713f760194520639e509015d38d900587021854d8fbc9160233dbf852d0d1bb2df2d684b3915e18114
6
+ metadata.gz: 72580053068ad316cf22e9d262dbc8d0013a80aa5cde5de3160270fc9727850332df69ef94503f04a913e5f704f381558e361ddb5db857f0e9ae2d373a3fdbe5
7
+ data.tar.gz: e8450ac692fc998e2a1a735f243666abf7a82701a667b6569c307fc13869b30fabfa7ade64988feed77f30381f52d8972534436fcedeb987f1357c1decb71b44
data/README.md CHANGED
@@ -5,34 +5,37 @@ ATCO-CIF is the format of choice for UK public transport authorities. This is a
5
5
  * ATCO (Association of Transport Coordinating Officers)
6
6
  * CIF (Common Interface File)
7
7
 
8
- * **Official spec:** [http://www.pti.org.uk/CIF/atco-cif-spec.pdf](http://www.pti.org.uk/CIF/atco-cif-spec.pdf)
8
+ * **Official spec:** ~~[http://www.pti.org.uk/CIF/atco-cif-spec.pdf](http://www.pti.org.uk/CIF/atco-cif-spec.pdf)~~
9
+ * **NOTE**: official spec is no-longer available from the above URL but can be found on archive.org
10
+ * A copy of the [atco-cif-spec.pdf](http://github.com/davidjrice/atco/blob/master/docs/atco-cif-spec.pdf) is included in the `docs` folder in this repo
9
11
 
10
12
  ### USAGE
11
13
 
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 ).
14
+ 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 ).
13
15
 
14
- * clone this library
15
- * start an irb session
16
- * put the cif file in ./data (needs to change from being hardcoded)
16
+ * clone this library `git clone git@github.com:davidjrice/atco.git`
17
+ * or install the gem `gem install atco`
18
+ * start an irb session (with the helper console command) `bin/console`
17
19
 
18
20
  Code example, for more detailed internal api usage see the spec files.
19
21
 
20
22
 
21
23
  ```ruby
22
- gem install atco
23
- irb
24
+ require "rubygems"
25
+ require "atco"
24
26
 
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
27
+ result = Atco.parse("filename.cif")
28
+ result = Atco.parse("data/SVRTMAO009A-20091005.cif")
31
29
 
32
30
  => {
33
- header: {…},
34
- locations: […],
35
- journies: {…}
31
+ header: {…}, # Atco::Header
32
+ locations: […], # Atco::Location
33
+ journeys: {
34
+ "journey_identifier": {…} # Atco::Journey
35
+ },
36
+ unparsed: [
37
+ {line: "unparsed line", line_number:1234}
38
+ ]
36
39
  }
37
40
  ```
38
41
 
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Atco
4
+ # Atco::Header is a class to abstract ATCO-CIF Header data.
5
+ class Header
6
+ attr_accessor :file_type,
7
+ :version,
8
+ :file_originator,
9
+ :source_product,
10
+ :production_datetime
11
+
12
+ # Public: Parse a header line from an ATCO-CIF file.
13
+ # EXAMPLE:
14
+ # "ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n"
15
+ def self.parse(line)
16
+ data = {
17
+ file_type: line[0, 8],
18
+ version: "#{line[8, 2].to_i}.#{line[10, 2].to_i}",
19
+ file_originator: line[12, 32].strip!,
20
+ source_product: line[44, 16].strip!,
21
+ production_datetime: line[60, 14]
22
+ }
23
+ new(data)
24
+ end
25
+
26
+ def initialize(data)
27
+ @file_type = data[:file_type]
28
+ @version = data[:version]
29
+ @file_originator = data[:file_originator]
30
+ @source_product = data[:source_product]
31
+ @production_datetime = data[:production_datetime]
32
+ end
33
+
34
+ def attributes
35
+ {
36
+ file_type: @file_type,
37
+ version: @version,
38
+ file_originator: @file_originator,
39
+ source_product: @source_product,
40
+ production_datetime: @production_datetime
41
+ }
42
+ end
43
+
44
+ def to_json(*attrs)
45
+ attributes.to_json(*attrs)
46
+ end
47
+ end
48
+ end
data/lib/atco/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Atco
4
- VERSION = "1.0.7"
4
+ VERSION = "1.0.9"
5
5
  end
data/lib/atco.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "open3"
4
4
  require "tempfile"
5
+ require_relative "atco/header"
5
6
  require_relative "atco/location"
6
7
  require_relative "atco/journey"
7
8
  require_relative "atco/stop"
@@ -29,7 +30,6 @@ module Atco # rubocop:disable Metrics/ModuleLength
29
30
  @path = File.expand_path(file)
30
31
  data = File.readlines(@path)
31
32
 
32
- objects = []
33
33
  current_journey = nil
34
34
  current_location = nil
35
35
  locations = []
@@ -39,7 +39,7 @@ module Atco # rubocop:disable Metrics/ModuleLength
39
39
 
40
40
  data.each_with_index do |line, line_number| # rubocop:disable Metrics/BlockLength
41
41
  if line_number.zero?
42
- header = parse_header(line)
42
+ header = Header.parse(line)
43
43
  next
44
44
  end
45
45
 
@@ -68,26 +68,14 @@ module Atco # rubocop:disable Metrics/ModuleLength
68
68
  journeys[current_journey[:unique_journey_identifier]] = Journey.new(object)
69
69
  end
70
70
  end
71
- objects << object
72
71
  rescue UnidentifiedRecordError
73
72
  unparsed << { line: line, line_number: line_number }
74
73
  next
75
74
  end
76
- objects << object
77
75
  end
78
76
  { header: header, locations: locations, journeys: journeys, unparsed: unparsed }
79
77
  end
80
78
 
81
- def parse_header(string)
82
- {
83
- file_type: string[0, 8],
84
- version: "#{string[8, 2].to_i}.#{string[10, 2].to_i}",
85
- file_originator: string[12, 32].strip!,
86
- source_product: string[44, 16].strip!,
87
- production_datetime: string[60, 14]
88
- }
89
- end
90
-
91
79
  def parse_bank_holiday(string)
92
80
  {
93
81
  record_identity: string[0, 2],
data/spec/atco_spec.rb CHANGED
@@ -1,50 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "json"
4
-
5
3
  RSpec.describe Atco do # rubocop:disable Metrics/BlockLength
6
4
  it "has a version number" do
7
5
  expect(Atco::VERSION).not_to be nil
8
6
  end
9
7
 
10
- it "should parse header from fixture" do
11
- result = Atco.parse("spec/fixtures/example.cif")
12
- expect(result[:header]).to eq(
13
- {
14
- file_type: "ATCO-CIF",
15
- file_originator: "Electronic Registration",
16
- source_product: "MIA 4.20.18",
17
- version: "5.0",
18
- production_datetime: "20090915113809"
19
- }
20
- )
21
- end
22
-
23
- it "should parse locations from fixture" do
24
- result = Atco.parse("spec/fixtures/example.cif")
25
- expect(result[:header]).to eq(
26
- {
27
- file_type: "ATCO-CIF",
28
- file_originator: "Electronic Registration",
29
- source_product: "MIA 4.20.18",
30
- version: "5.0",
31
- production_datetime: "20090915113809"
32
- }
33
- )
34
- end
35
-
36
- it "should parse header" do
37
- expect(Atco.parse_header("ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n")).to eq(
38
- {
39
- file_type: "ATCO-CIF",
40
- version: "5.0",
41
- file_originator: "Electronic Registration",
42
- source_product: "MIA 4.20.18",
43
- production_datetime: "20090915113809"
44
- }
45
- )
46
- end
47
-
48
8
  it "should parse bank holiday" do
49
9
  expect(Atco.parse_bank_holiday("QHN20061225")).to eq(
50
10
  {
@@ -159,62 +119,4 @@ RSpec.describe Atco do # rubocop:disable Metrics/BlockLength
159
119
  }
160
120
  )
161
121
  end
162
-
163
- describe "with example.cif" do # rubocop:disable Metrics/BlockLength
164
- before(:all) do
165
- @atco = Atco.parse("spec/fixtures/example.cif")
166
- end
167
-
168
- it "should parse 1 journey" do
169
- expect(@atco[:journeys].size).to eq(1)
170
- end
171
-
172
- it "should parse journeys into Atco::Joruney objects" do
173
- expect(@atco[:journeys]["139748"]).to be_a_kind_of(Atco::Journey)
174
- end
175
-
176
- it "should parse 6 stops for journey 139748" do
177
- expect(@atco[:journeys]["139748"].stops.size).to eq(6)
178
- end
179
-
180
- it "should parse 2 locations" do
181
- expect(@atco[:locations].size).to eq(2)
182
- end
183
-
184
- it "should output file as JSON" do
185
- output = File.join(File.dirname(__FILE__), "artefacts", "test.json")
186
- File.open(output, "w+") do |f|
187
- f.flush
188
- f.write(JSON.pretty_generate(@atco))
189
- end
190
-
191
- expect(File.exist?(output)).to be true
192
-
193
- data = File.read(output)
194
- json = JSON.parse(data)
195
- expect(json).to be_a(Hash)
196
- end
197
-
198
- it "should return 17 unparsed lines" do
199
- expect(@atco[:unparsed].size).to eq(17)
200
- end
201
-
202
- it "should not parse GS records" do
203
- expect(@atco[:unparsed][0]).to eq(
204
- {
205
- line: "GS00001433 N Belfast Metro Ops 7000\n",
206
- line_number: 3
207
- }
208
- )
209
- end
210
-
211
- it "should not parse GR records" do
212
- expect(@atco[:unparsed][1]).to eq(
213
- {
214
- line: "GR00001433Donegall Square East 7000\n", # rubocop:disable Layout/LineLength
215
- line_number: 4
216
- }
217
- )
218
- end
219
- end
220
122
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe "with example.cif" do # rubocop:disable Metrics/BlockLength
4
+ before(:all) do
5
+ @atco = Atco.parse("spec/fixtures/translink-example.cif")
6
+ end
7
+
8
+ it "should parse header from fixture" do
9
+ expect(@atco[:header].attributes).to eq(
10
+ {
11
+ file_type: "ATCO-CIF",
12
+ file_originator: "Electronic Registration",
13
+ source_product: "MIA 4.20.18",
14
+ version: "5.0",
15
+ production_datetime: "20090915113809"
16
+ }
17
+ )
18
+ end
19
+
20
+ it "should parse 1 journey" do
21
+ expect(@atco[:journeys].size).to eq(1)
22
+ end
23
+
24
+ it "should parse journeys into Atco::Joruney objects" do
25
+ expect(@atco[:journeys]["139748"]).to be_a_kind_of(Atco::Journey)
26
+ end
27
+
28
+ it "should parse 6 stops for journey 139748" do
29
+ expect(@atco[:journeys]["139748"].stops.size).to eq(6)
30
+ end
31
+
32
+ it "should parse 2 locations" do
33
+ expect(@atco[:locations].size).to eq(2)
34
+ end
35
+
36
+ it "should output file as JSON" do
37
+ output = File.join(File.dirname(__FILE__), "..", "artefacts", "test.json")
38
+ File.open(output, "w+") do |f|
39
+ f.flush
40
+ f.write(JSON.pretty_generate(@atco))
41
+ end
42
+
43
+ expect(File.exist?(output)).to be true
44
+
45
+ data = File.read(output)
46
+ json = JSON.parse(data)
47
+ expect(json).to be_a(Hash)
48
+ end
49
+
50
+ it "should return 17 unparsed lines" do
51
+ expect(@atco[:unparsed].size).to eq(17)
52
+ end
53
+
54
+ it "should not parse GS records" do
55
+ expect(@atco[:unparsed][0]).to eq(
56
+ {
57
+ line: "GS00001433 N Belfast Metro Ops 7000\n",
58
+ line_number: 3
59
+ }
60
+ )
61
+ end
62
+
63
+ it "should not parse GR records" do
64
+ expect(@atco[:unparsed][1]).to eq(
65
+ {
66
+ line: "GR00001433Donegall Square East 7000\n", # rubocop:disable Layout/LineLength
67
+ line_number: 4
68
+ }
69
+ )
70
+ end
71
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "atco"
4
+ require "json"
4
5
 
5
6
  RSpec.configure do |config|
6
7
  # Enable flags like --only-failures and --next-failure
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe Atco::Header do
4
+ before(:all) do
5
+ line = "ATCO-CIF0500Electronic Registration MIA 4.20.18 20090915113809\r\n"
6
+ @header = Atco::Header.parse(line)
7
+ end
8
+
9
+ it "should be a Header object" do
10
+ expect(@header).to be_a_kind_of(Atco::Header)
11
+ end
12
+
13
+ it "should parse header to attributes" do
14
+ expect(@header.attributes).to eq(
15
+ {
16
+ file_type: "ATCO-CIF",
17
+ version: "5.0",
18
+ file_originator: "Electronic Registration",
19
+ source_product: "MIA 4.20.18",
20
+ production_datetime: "20090915113809"
21
+ }
22
+ )
23
+ end
24
+
25
+ it "should parse header to json" do
26
+ expect(@header.to_json).to eq(
27
+ "{\"file_type\":\"ATCO-CIF\",\"version\":\"5.0\",\"file_originator\":\"Electronic Registration\",\"source_product\":\"MIA 4.20.18\",\"production_datetime\":\"20090915113809\"}" # rubocop:disable Metrics/LineLength
28
+ )
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atco
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.7
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Rice
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-12 00:00:00.000000000 Z
11
+ date: 2024-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -49,14 +49,17 @@ files:
49
49
  - README.md
50
50
  - Rakefile
51
51
  - lib/atco.rb
52
+ - lib/atco/header.rb
52
53
  - lib/atco/journey.rb
53
54
  - lib/atco/location.rb
54
55
  - lib/atco/stop.rb
55
56
  - lib/atco/version.rb
56
57
  - spec/atco_spec.rb
57
- - spec/fixtures/example.cif
58
58
  - spec/fixtures/example.json
59
+ - spec/fixtures/translink-example.cif
60
+ - spec/integration/translink_spec.rb
59
61
  - spec/spec_helper.rb
62
+ - spec/unit/header_spec.rb
60
63
  homepage: http://github.com/davidjrice/atco
61
64
  licenses:
62
65
  - MIT