rightmove_blm 0.1.6 → 0.2.0

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: d86b0d52da5fad3fdac5c44ad7cc0ee515b67b6f4bdb7b2abd25ae92cd65aad3
4
- data.tar.gz: 84d91eda581f2a813bd5da72db9f2a9384262505913074077ba78fe104169bd8
3
+ metadata.gz: a4ec5f3eee9950c331f0a1dd23129b47d6917c332fae762df37346f67c3ae15b
4
+ data.tar.gz: e803eb23307b33115103e2cd99c94398d272576db5206670eff24c64f13f72af
5
5
  SHA512:
6
- metadata.gz: 653deacb786ab85ba54a77318e62f36fc570c2da370163b475191003190db55d7d77e4019924e2643c56ad00b2a04060ae142fc57eb65f5997f0aa41ee53e9dc
7
- data.tar.gz: e16d71c8a41018d8d4adbeedf69059e5b111a3dbb22a23f818ab36c7d6545529eed67d1f6cbba0d900811bf0abda5ebab79792f55852aecdce449021bc1e41d0
6
+ metadata.gz: 784c8aad75336281c6e7bc59a0a16866929f62268542d0ebf93c5bccb5a21b1e651a91b1edeca885d571ab18bdd35289afd27937316ff8a5c473d44ad612c760
7
+ data.tar.gz: 9f8dc40c0e294360d4ca3b7b713da7922b4c9a90795517f98fcd71d13b9ba22e21435aa5f984618d3d30aabb91a6ffa0fad7640d248339a2b59c1c20453e4f96
data/.rubocop.yml CHANGED
@@ -1,6 +1,9 @@
1
+ require:
2
+ - rubocop-rspec
3
+
1
4
  AllCops:
2
5
  NewCops: enable
3
6
 
4
7
  Metrics/BlockLength:
5
8
  Exclude:
6
- - 'spec/blm_spec.rb'
9
+ - 'spec/**/*_spec.rb'
data/README.md CHANGED
@@ -10,6 +10,8 @@ This library is not affiliated with or endorsed by _Rightmove Plc_ in any way.
10
10
 
11
11
  ### Loading a BLM file
12
12
 
13
+ #### RightmoveBLM::Document
14
+
13
15
  Load a BLM file by passing the `source` parameter to `RightmoveBLM::Document.new`:
14
16
 
15
17
  ```ruby
@@ -20,17 +22,32 @@ The returned `RightmoveBLM::Document` instance implements:
20
22
 
21
23
  * `#header` - the header containing information about the document's structure.
22
24
  * `#definition` - the field list contained in the document.
23
- * `#data` - an array of `RightmoveBLM::Row` objects (use dot notation to access fields, e.g. `row.foo` to access the "foo" field).
25
+ * `#rows` - an array of `RightmoveBLM::Row` objects.
26
+ * `#valid?` - `true` if no rows have errors, `false` if any rows have errors.
27
+ * `#errors` - all error messages for all invalid rows.
28
+ * `#version` - the version of the document format as a string (e.g. `'3'`).
29
+ * `#international?` - `true` if document meets the [Rightmove International](https://www.rightmove.co.uk/ps/pdf/guides/RightmoveDatafeedFormatV3iOVS_1.6.pdf) specification, `false` otherwise.
30
+
31
+ #### RightmoveBLM::Row
32
+
33
+ `RightmoveBLM::Row` implements:
24
34
 
25
- `RightmoveBLM::Row` also implements `#to_h` which provides a _Hash_ of the row data.
35
+ * `#valid?` - `true` if no errors were encountered, false otherwise.
36
+ * `#errors` - an array of error strings (empty if no errors present).
37
+ * `#to_h` (or `#attributes`) - a hash of row attributes (`nil` if errors encountered).
38
+ * `#method_missing` - allows accessing row attributes by dot notation (e.g. `row.address_1`).
26
39
 
27
40
  #### Example
28
41
 
29
42
  ```ruby
30
- blm.data.each do |row|
43
+ blm.data.select(&:valid?).each do |row|
31
44
  puts row.address_1
32
45
  puts row.to_h
33
46
  end
47
+
48
+ blm.data.reject(&:valid?).each do |row|
49
+ puts "Errors: #{row.errors.join(', ')}"
50
+ end
34
51
  ```
35
52
 
36
53
  ### Writing BLM data
@@ -13,7 +13,15 @@ module RightmoveBLM
13
13
  @source = source
14
14
  @header = header
15
15
  @definition = definition
16
- @data = data&.map { |row| Row.new(row) }
16
+ initialize_with_data(data) unless data.nil?
17
+ end
18
+
19
+ def inspect
20
+ %(<##{self.class.name} version=#{version} rows=#{rows.size} valid=#{valid?} errors=#{errors.size}>)
21
+ end
22
+
23
+ def to_s
24
+ inspect
17
25
  end
18
26
 
19
27
  def to_blm
@@ -43,27 +51,49 @@ module RightmoveBLM
43
51
  end.compact
44
52
  end
45
53
 
46
- def data
47
- @data ||= contents.split(header[:eor]).map do |line|
48
- row(line)
49
- end
54
+ def rows
55
+ data
56
+ end
57
+
58
+ def errors
59
+ @errors ||= data.reject(&:valid?).flat_map(&:errors)
60
+ end
61
+
62
+ def valid?
63
+ errors.empty?
64
+ end
65
+
66
+ def version
67
+ header[:version]
68
+ end
69
+
70
+ def international?
71
+ %w[H1 3I].include?(version)
50
72
  end
51
73
 
52
74
  private
53
75
 
76
+ def initialize_with_data(data)
77
+ @data = data.each_with_index.map { |hash, index| Row.from_attributes(hash, index: index) }
78
+ end
79
+
80
+ def data
81
+ @data ||= contents.split(header[:eor]).each_with_index.map do |line, index|
82
+ Row.new(index: index, data: line, separator: header[:eof], definition: definition)
83
+ end
84
+ end
85
+
54
86
  def contents(section = :data)
55
87
  marker = "##{section.to_s.upcase}#"
56
- start = @source.index(marker) + marker.size
57
- finish = @source.index('#', start) - 1
88
+ start = verify(:start, @source.index(marker)) + marker.size
89
+ finish = verify(:end, @source.index('#', start)) - 1
58
90
  @source[start..finish].strip
59
91
  end
60
92
 
61
- def row(line)
62
- entry = {}
63
- line.split(header[:eof]).each_with_index do |field, index|
64
- entry[definition[index].to_sym] = field.strip
65
- end
66
- Row.new(entry)
93
+ def verify(type, val)
94
+ return val unless val.nil?
95
+
96
+ raise ParserError, "Unable to parse document: could not detect #{type} marker."
67
97
  end
68
98
 
69
99
  def generated_date
@@ -3,22 +3,72 @@
3
3
  module RightmoveBLM
4
4
  # A row in a BLM document.
5
5
  class Row
6
- attr_accessor :attributes
6
+ attr_reader :index
7
7
 
8
- def initialize(hash)
9
- @attributes = hash
8
+ def self.from_attributes(attributes, index:)
9
+ new(index: index, data: nil, separator: nil, definition: attributes.keys, attributes: attributes)
10
+ end
11
+
12
+ def initialize(index:, data:, separator:, definition:, attributes: nil)
13
+ @index = index
14
+ @data = data
15
+ @separator = separator
16
+ @definition = definition
17
+ @attributes = attributes
18
+ @fields = attributes.keys unless attributes.nil?
10
19
  end
11
20
 
12
21
  def to_h
13
- @attributes
22
+ attributes
23
+ end
24
+
25
+ def valid?
26
+ return false unless field_size_valid?
27
+
28
+ true
29
+ end
30
+
31
+ def errors
32
+ return [] if valid?
33
+
34
+ errors = []
35
+ errors << field_size_mismatch_message unless field_size_valid?
36
+ errors
37
+ end
38
+
39
+ def attributes
40
+ return nil unless valid?
41
+
42
+ @attributes ||= fields.each_with_index.to_h do |field, field_index|
43
+ [definition[field_index].to_sym, field.strip]
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ attr_reader :data, :separator, :definition
50
+
51
+ def field_size_mismatch_message
52
+ "Field size mismatch in row #{index}. Expected: #{definition.size} fields, found: #{fields.size}"
53
+ end
54
+
55
+ def fields
56
+ @fields ||= data.split(separator)
57
+ end
58
+
59
+ def field_size_valid?
60
+ definition.size >= fields.size
14
61
  end
15
62
 
16
63
  def method_missing(method, *_arguments)
17
- return @attributes[method] unless @attributes[method].nil?
64
+ return super if attributes.nil?
65
+ return attributes[method] unless attributes[method].nil?
66
+
67
+ super
18
68
  end
19
69
 
20
70
  def respond_to_missing?(method, _ = false)
21
- !@attributes[method].nil?
71
+ !attributes[method].nil?
22
72
  end
23
73
  end
24
74
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RightmoveBLM
4
- VERSION = '0.1.6'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/rightmove_blm.rb CHANGED
@@ -8,4 +8,6 @@ require 'time'
8
8
  # Rightmove BLM (Bulk Load Mass) data format parsing tools.
9
9
  # https://www.rightmove.co.uk/ps/pdf/guides/RightmoveDatafeedFormatV3iOVS_1.6.pdf
10
10
  module RightmoveBLM
11
+ class Error < StandardError; end
12
+ class ParserError < Error; end
11
13
  end
@@ -5,7 +5,7 @@ require_relative 'lib/rightmove_blm/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'rightmove_blm'
7
7
  spec.version = RightmoveBLM::VERSION
8
- spec.authors = ['Robert Farrell']
8
+ spec.authors = ['Bob Farrell']
9
9
  spec.email = 'git@bob.frl'
10
10
 
11
11
  spec.summary
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rightmove_blm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Robert Farrell
7
+ - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-29 00:00:00.000000000 Z
11
+ date: 2023-05-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Parse and generate Rightmove BLM files
14
14
  email: git@bob.frl
@@ -27,7 +27,6 @@ files:
27
27
  - Makefile
28
28
  - README.md
29
29
  - Rakefile
30
- - VERSION
31
30
  - lib/rightmove_blm.rb
32
31
  - lib/rightmove_blm/document.rb
33
32
  - lib/rightmove_blm/row.rb
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.1.6