cartocss_helper 1.2.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,12 @@
1
1
  module CartoCSSHelper
2
2
  class StyleSpecificData
3
- attr_reader :min_z, :max_z, :list_of_documented_tags, :list_of_documented_compositions
4
- def initialize(min_z, max_z, list_of_documented_tags, list_of_documented_compositions)
3
+ attr_reader :min_z, :max_z, :list_of_documented_tags, :list_of_documented_compositions, :name_label_is_not_required
4
+ def initialize(min_z, max_z, list_of_documented_tags, list_of_documented_compositions, name_label_is_not_required)
5
5
  @min_z = min_z
6
6
  @max_z = max_z
7
7
  @list_of_documented_tags = list_of_documented_tags
8
8
  @list_of_documented_compositions = list_of_documented_compositions
9
+ @name_label_is_not_required = name_label_is_not_required
9
10
  end
10
11
  end
11
- end
12
+ end
@@ -6,12 +6,13 @@ include CartoCSSHelper::Heuristic
6
6
  module CartoCSSHelper
7
7
  class TagRenderingStatus
8
8
  attr_accessor :key, :value, :state, :composite
9
- def initialize(key, value, state, composite=nil)
9
+ def initialize(key, value, state, composite = nil)
10
10
  @key = key
11
11
  @value = value
12
12
  @state = state
13
13
  @composite = composite
14
14
  end
15
+
15
16
  def print
16
17
  composite_string = ''
17
18
  if composite
@@ -19,60 +20,103 @@ module CartoCSSHelper
19
20
  end
20
21
  puts "#{@key}=#{@value} #{@state} #{composite_string}"
21
22
  end
23
+
22
24
  def code_print
23
25
  string = "Status.new('#{@key}', '#{@value}', :#{@state}"
24
- if @composite != nil
25
- string << ", #{@composite.to_s}"
26
- end
26
+ string << ", #{@composite}" if @composite != nil
27
27
  string << '),'
28
28
  puts string
29
29
  end
30
30
  end
31
31
 
32
32
  class Info
33
- def get_expected_composite(key, value)
34
- CartoCSSHelper::Configuration.get_style_specific_data.list_of_documented_tags.each { |documented|
35
- if documented.key == key
36
- if documented.value == value
37
- return documented.composite
38
- end
39
- end
40
- }
33
+ def self.get_expected_state(key, value)
34
+ CartoCSSHelper::Configuration.get_style_specific_data.list_of_documented_tags.each do |documented|
35
+ next unless documented.key == key
36
+ return documented.state if documented.value == value
37
+ end
38
+ return nil
39
+ end
40
+
41
+ def self.get_expected_composite(key, value)
42
+ CartoCSSHelper::Configuration.get_style_specific_data.list_of_documented_tags.each do |documented|
43
+ next unless documented.key == key
44
+ return documented.composite if documented.value == value
45
+ end
41
46
  return nil
42
47
  end
43
48
 
44
49
  def print_render_state_of_tags(git_branch)
45
50
  Git.checkout git_branch
46
- get_render_state_of_tags.each { |state|
51
+ get_render_state_of_tags.each do |state|
47
52
  state.code_print
48
- }
53
+ end
49
54
  end
50
55
 
51
- def get_render_state_of_tags
56
+ def get_render_state_of_tags(quick_and_more_prone_to_errors)
52
57
  states = []
53
58
  @last_composite = nil
54
- Heuristic.get_tags.each { |tag|
59
+ Heuristic.get_tags.each do |tag|
55
60
  key = tag[0]
56
61
  value = tag[1]
57
- #print_render_state_of_tag key, value
58
- state = get_render_state_of_tag(key, value)
62
+ # print_render_state_of_tag key, value
63
+ state = get_render_state_of_tag(key, value, quick_and_more_prone_to_errors)
59
64
  states.push(TagRenderingStatus.new(key, value, state, @last_composite))
60
- }
65
+ end
61
66
  return states
62
67
  end
63
68
 
64
- def get_render_state_of_tag(key, value)
65
- if is_rendered key, value
69
+ def get_render_state_of_tag(key, value, quick_and_more_prone_to_errors)
70
+ if Info.get_expected_state(key, value) == :ignored
66
71
  @last_composite = nil
72
+ return :ignored
73
+ end
74
+ zlevels = [22, 13] # TODO: - this is specially tuned for Default
75
+ expected_composite = Info.get_expected_composite(key, value)
76
+ if quick_and_more_prone_to_errors
77
+ return get_render_state_of_tag_quick_heurestic(key, value, expected_composite, zlevels)
78
+ end
79
+ return get_render_state_of_tag_thorough(key, value, expected_composite, zlevels)
80
+ end
81
+
82
+ def get_render_state_of_tag_quick_heurestic
83
+ if expected_composite != nil
84
+ return assume_that_only_this_composite_can_match(key, value, zlevels, expected_composite)
85
+ else
86
+ return asssume_that_no_composite_will_match(key, value, zlevels)
87
+ end
88
+ end
89
+
90
+ def assume_that_only_this_composite_can_match(key, value, zlevels, expected_composite)
91
+ if is_rendered_as_composite key, value, expected_composite, zlevels
92
+ @last_composite = how_rendered_as_composite key, value, expected_composite, zlevels
93
+ return :composite
94
+ else
95
+ @last_composite = nil
96
+ return :ignored
97
+ end
98
+ end
99
+
100
+ def asssume_that_no_composite_will_match(key, value, zlevels)
101
+ @last_composite = nil
102
+ if is_rendered key, value, zlevels
67
103
  return :primary
68
104
  else
69
- if is_rendered_as_composite key, value, get_expected_composite(key, value)
70
- @last_composite = how_rendered_as_composite key, value, get_expected_composite(key, value)
71
- return :composite
72
- else
73
- @last_composite = nil
74
- return :ignored
75
- end
105
+ return :ignored
106
+ end
107
+ end
108
+
109
+ def get_render_state_of_tag_thorough(key, value, expected_composite, zlevels)
110
+ if is_rendered key, value, zlevels
111
+ @last_composite = nil
112
+ return :primary
113
+ end
114
+ if is_rendered_as_composite key, value, expected_composite
115
+ @last_composite = how_rendered_as_composite key, value, expected_composite
116
+ return :composite
117
+ else
118
+ @last_composite = nil
119
+ return :ignored
76
120
  end
77
121
  end
78
122
 
@@ -83,82 +127,69 @@ module CartoCSSHelper
83
127
  puts "#{key}=#{value} - primary generic tag value"
84
128
  elsif is_key_rendered_and_value_ignored(key, value)
85
129
  puts "#{key}=#{value} - primary, but rendering the same as generic value"
86
- elsif
87
- puts "#{key}=#{value} - primary"
88
- end
89
- else
90
- if is_rendered_as_composite key, value, @last_composite
91
- @last_composite = how_rendered_as_composite key, value, @last_composite
92
- puts "#{key}=#{value} - composite with #{@last_composite} - and maybe other tags"
93
130
  else
94
- @last_composite = nil
95
- puts "#{key}=#{value} - not displayed"
131
+ puts "#{key}=#{value} - primary"
96
132
  end
133
+ elsif is_rendered_as_composite key, value, @last_composite
134
+ @last_composite = how_rendered_as_composite key, value, @last_composite
135
+ puts "#{key}=#{value} - composite with #{@last_composite} - and maybe other tags"
136
+ else
137
+ @last_composite = nil
138
+ puts "#{key}=#{value} - not displayed"
97
139
  end
98
140
  end
99
141
 
100
142
  def is_key_rendered_and_value_ignored(key, value)
101
- if not is_rendered key,get_generic_tag_value
102
- return false
103
- end
104
- [false, true].each { |on_water|
105
- [Configuration.get_max_z].each { |zlevel|
106
- ['area', 'closed_way', 'way', 'node'].each{ |type|
107
- if CartoCSSHelper::Info.rendered_on_zlevel({key => value}, type, zlevel, on_water)
108
- if !is_key_rendered_and_value_ignored_set(key, value, type, zlevel, on_water)
109
- return false
110
- end
143
+ return false if notis_rendered key, get_generic_tag_value
144
+ [false, true].each do |on_water|
145
+ [Configuration.get_max_z].each do |zlevel|
146
+ ['area', 'closed_way', 'way', 'node'].each do |type|
147
+ next unless CartoCSSHelper::Info.rendered_on_zlevel({ key => value }, type, zlevel, on_water)
148
+ unless is_key_rendered_and_value_ignored_set(key, value, type, zlevel, on_water)
149
+ return false
111
150
  end
112
- }
113
- }
114
- }
151
+ end
152
+ end
153
+ end
115
154
  return true
116
155
  end
117
156
 
118
157
  def is_key_rendered_and_value_ignored_set(key, value, type, zlevel, on_water)
119
- with_tested_value = Scene.new({key => value}, zlevel, on_water, type)
120
- with_generic_value = Scene.new({key => get_generic_tag_value}, zlevel, on_water, type)
158
+ with_tested_value = Scene.new({ key => value }, zlevel, on_water, type, true)
159
+ with_generic_value = Scene.new({ key => get_generic_tag_value }, zlevel, on_water, type, true)
121
160
  return !with_tested_value.is_output_different(with_generic_value)
122
161
  end
123
162
 
124
- def is_rendered(key, value)
125
- [false, true].each { |on_water|
126
- [Configuration.get_max_z].each { |zlevel| #TODO - note that some tags may be rendered up to X zoom level, but checking all zlevels would take too much time
127
- ['area', 'closed_way', 'way', 'node'].each{ |type|
128
- if CartoCSSHelper::Info.rendered_on_zlevel({key => value}, type, zlevel, on_water)
163
+ def is_rendered(key, value, zlevels = [Configuration.get_max_z]) # TODO: - note that some tags may be rendered up to X zoom level, but checking all zlevels would take too much time
164
+ [false, true].each do |on_water|
165
+ zlevels.each do |zlevel| #
166
+ ['area', 'closed_way', 'way', 'node'].each do |type|
167
+ if CartoCSSHelper::Info.rendered_on_zlevel({ key => value }, type, zlevel, on_water)
129
168
  return true
130
169
  end
131
- }
132
- }
133
- }
170
+ end
171
+ end
172
+ end
134
173
  return false
135
174
  end
136
175
 
137
- def is_rendered_as_composite(key, value, suggested_composite=nil)
138
- reason = how_rendered_as_composite key, value, suggested_composite
139
- if reason == nil
140
- return false
141
- end
176
+ def is_rendered_as_composite(key, value, suggested_composite = nil, zlevels = [Configuration.get_max_z]) # TODO: - note that some tags may be rendered up to X zoom level, but checking all zlevels would take too much time
177
+ reason = how_rendered_as_composite key, value, suggested_composite, zlevels
178
+ return false if reason == nil
142
179
  return true
143
180
  end
144
181
 
145
- def how_rendered_as_composite(key, value, suggested_composite)
146
- [false, true].each { |on_water|
147
- [Configuration.get_max_z].each { |zlevel|
148
- result = how_rendered_on_zlevel_as_composite({key => value}, 'closed_way', zlevel, on_water, suggested_composite)
149
- if result != nil
150
- return result
151
- end
152
- result = how_rendered_on_zlevel_as_composite({key => value}, 'way', zlevel, on_water, suggested_composite)
153
- if result != nil
154
- return result
155
- end
156
- result = how_rendered_on_zlevel_as_composite({key => value}, 'node', zlevel, on_water, suggested_composite)
157
- if result != nil
158
- return result
159
- end
160
- }
161
- }
182
+ def how_rendered_as_composite(key, value, suggested_composite, zlevels = [Configuration.get_max_z]) # TODO: - note that some tags may be rendered up to X zoom level, but checking all zlevels would take too much time
183
+ [false, true].each do |on_water|
184
+ zlevels.each do |zlevel|
185
+ result = how_rendered_on_zlevel_as_composite({ key => value }, 'closed_way', zlevel, on_water, suggested_composite)
186
+ return result if result != nil
187
+ result = how_rendered_on_zlevel_as_composite({ key => value }, 'way', zlevel, on_water, suggested_composite)
188
+ return result if result != nil
189
+ result = how_rendered_on_zlevel_as_composite({ key => value }, 'node', zlevel, on_water, suggested_composite)
190
+ return result if result != nil
191
+ end
192
+ end
162
193
  if suggested_composite != nil
163
194
  return how_rendered_as_composite key, value, nil
164
195
  end
@@ -166,8 +197,8 @@ module CartoCSSHelper
166
197
  end
167
198
 
168
199
  def self.rendered_on_zlevel(tags, type, zlevel, on_water)
169
- empty = Scene.new({}, zlevel, on_water, type)
170
- tested = Scene.new(tags, zlevel, on_water, type)
200
+ empty = Scene.new({}, zlevel, on_water, type, true)
201
+ tested = Scene.new(tags, zlevel, on_water, type, true)
171
202
  return tested.is_output_different(empty)
172
203
  end
173
204
 
@@ -180,44 +211,37 @@ module CartoCSSHelper
180
211
  end
181
212
  return nil
182
213
  end
183
- CartoCSSHelper::Configuration.get_style_specific_data.list_of_documented_compositions.each { |composite|
214
+ CartoCSSHelper::Configuration.get_style_specific_data.list_of_documented_compositions.each do |composite|
184
215
  if is_rendered_with_this_composite tags, type, composite, zlevel, on_water
185
216
  return composite
186
217
  end
187
- }
218
+ end
188
219
  return nil
189
220
  end
190
221
 
222
+ def deep_clone(input)
223
+ return Marshal.load(Marshal.dump(input))
224
+ end
225
+
191
226
  def is_rendered_with_this_composite(tags, type, provided_composite, zlevel, on_water)
192
- #puts "<<<\n#{tags}\n#{composite}<<<\n\n"
193
- # noinspection RubyResolve
194
- # see https://youtrack.jetbrains.com/issue/RUBY-16061
195
- tags_with_composite = Marshal.load(Marshal.dump(tags))
196
- # noinspection RubyResolve
197
- # see https://youtrack.jetbrains.com/issue/RUBY-16061
198
- composite = Marshal.load(Marshal.dump(provided_composite))
199
- composite.each { |key, value|
227
+ tags_with_composite = deep_clone(tags)
228
+ composite = deep_clone(provided_composite)
229
+ composite.each do |key, value|
200
230
  if tags_with_composite[key] != nil
201
- return false #shadowing
231
+ return false # shadowing
202
232
  end
203
233
  tags_with_composite[key] = value
204
- }
205
- with_composite = Scene.new(tags_with_composite, zlevel, on_water, type)
206
- only_composite = Scene.new(composite, zlevel, on_water, type)
207
- empty = Scene.new({}, zlevel, on_water, type)
208
- if with_composite.is_output_different(empty)
209
- if with_composite.is_output_different(only_composite)
210
- if composite['area'] != nil
211
- return true
212
- end
213
- composite['area'] = 'yes'
214
- composite_interpreted_as_area = Scene.new(composite, zlevel, on_water, type)
215
- if with_composite.is_output_different(composite_interpreted_as_area)
216
- return true
217
- end
218
- end
219
234
  end
220
- return false
235
+ with_composite = Scene.new(tags_with_composite, zlevel, on_water, type, true)
236
+ only_composite = Scene.new(composite, zlevel, on_water, type, true)
237
+ empty = Scene.new({}, zlevel, on_water, type, true)
238
+ return false if with_composite.is_output_identical(empty)
239
+ return false if with_composite.is_output_identical(only_composite)
240
+ return true if composite['area'] != nil
241
+ composite['area'] = 'yes'
242
+ composite_interpreted_as_area = Scene.new(composite, zlevel, on_water, type, true)
243
+ return false if with_composite.is_output_identical(composite_interpreted_as_area)
244
+ return true
221
245
  end
222
246
  end
223
- end
247
+ end
@@ -3,4 +3,4 @@ module FileHelper
3
3
  def self.make_string_usable_as_filename(string)
4
4
  return string.gsub(/[\x00\/\\:\*\?\"<>\|]/, '_')
5
5
  end
6
- end
6
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'generic_downloader.rb'
2
+
3
+ class GenericCachedDownloader
4
+ def initialize(timeout: 20, error_message: nil, stop_on_timeout: true, wrapper: RestClientWrapper.new)
5
+ @request_timeout = timeout
6
+ @error_message = error_message
7
+ @stop_on_timeout = stop_on_timeout
8
+ @wrapper = wrapper
9
+ end
10
+
11
+ def get_specified_resource(url, cache_filename, description: nil, invalidate_cache: false)
12
+ cache = read_from_cache(cache_filename)
13
+ cache = nil if invalidate_cache
14
+ return cache if cache != nil
15
+ response = download(url, description)
16
+ write_cache(response, cache_filename)
17
+
18
+ return response
19
+ end
20
+
21
+ def read_from_cache(cache_filename)
22
+ if File.exist?(cache_filename)
23
+ file = File.new(cache_filename)
24
+ cached = file.read
25
+ file.close
26
+ return cached
27
+ end
28
+ return nil
29
+ end
30
+
31
+ def get_cache_timestamp(cache_filename)
32
+ return nil unless File.exist?(cache_filename)
33
+ f = File.new(cache_filename)
34
+ timestamp = f.mtime.to_i
35
+ f.close
36
+ return timestamp
37
+ end
38
+
39
+ def download(url, description)
40
+ downloader = GenericDownloader.new(timeout: @request_timeout, error_message: @error_message, stop_on_timeout: @stop_on_timeout, wrapper: @wrapper)
41
+ return downloader.get_specified_resource(url, description: description)
42
+ end
43
+
44
+ def write_cache(response, cache_filename)
45
+ file = File.new(cache_filename, 'w')
46
+ file.write response
47
+ file.close
48
+ end
49
+ end
@@ -0,0 +1,65 @@
1
+ require 'ruby-progressbar'
2
+ require_relative 'rest-client_wrapper.rb'
3
+ require_relative 'logger.rb'
4
+
5
+ class BuggyRestClient < StandardError
6
+ end
7
+
8
+ class ExceptionWithResponse < StandardError
9
+ attr_accessor :http_code, :response
10
+ end
11
+
12
+ class ExceptionWithoutResponse < StandardError
13
+ attr_accessor :http_code, :response
14
+ end
15
+
16
+ class RequestTimeout < StandardError
17
+ end
18
+
19
+ class GenericDownloader
20
+ def initialize(timeout: 20, error_message: nil, stop_on_timeout: true, wrapper: RestClientWrapper.new)
21
+ @request_timeout = timeout
22
+ @retry_count = 0
23
+ @error_message = error_message
24
+ @stop_on_timeout = stop_on_timeout
25
+ @wrapper = wrapper
26
+ end
27
+
28
+ def max_retry_count
29
+ 5
30
+ end
31
+
32
+ def output_shared_error_part(url, e)
33
+ Log.warn @error_message unless @error_message.nil?
34
+ Log.warn
35
+ Log.warn url
36
+ Log.warn
37
+ Log.warn e.class
38
+ Log.warn e
39
+ end
40
+
41
+ def retry_allowed(exception_with_response)
42
+ raise exception_with_response if @retry_count > max_retry_count
43
+ if @stop_on_timeout
44
+ raise exception_with_response if exception_with_response.is_a?(RequestTimeout)
45
+ end
46
+ if [429, 503, 504].include?(exception_with_response.http_code)
47
+ @retry_count += 1
48
+ return true
49
+ end
50
+ raise exception_with_response
51
+ end
52
+
53
+ def get_specified_resource(url, description: nil)
54
+ Log.info description if description
55
+ return @wrapper.fetch_data_from_url(url, @request_timeout)
56
+ rescue ExceptionWithResponse => e
57
+ output_shared_error_part(url, e)
58
+ Log.warn e.response
59
+ Log.warn e.http_code
60
+ get_specified_resource(url) if retry_allowed(e)
61
+ rescue ExceptionWithoutResponse => e
62
+ output_shared_error_part(url, e)
63
+ raise e
64
+ end
65
+ end