sitemap_generator 6.3.0 → 7.1.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +107 -61
  3. data/README.md +176 -171
  4. data/VERSION +1 -1
  5. data/lib/capistrano/sitemap_generator.rb +2 -0
  6. data/lib/sitemap_generator/adapters/active_storage_adapter.rb +31 -0
  7. data/lib/sitemap_generator/adapters/aws_sdk_adapter.rb +29 -13
  8. data/lib/sitemap_generator/adapters/file_adapter.rb +12 -13
  9. data/lib/sitemap_generator/adapters/fog_adapter.rb +9 -7
  10. data/lib/sitemap_generator/adapters/google_storage_adapter.rb +8 -5
  11. data/lib/sitemap_generator/adapters/s3_adapter.rb +23 -18
  12. data/lib/sitemap_generator/adapters/wave_adapter.rb +8 -6
  13. data/lib/sitemap_generator/application.rb +9 -3
  14. data/lib/sitemap_generator/builder/sitemap_file.rb +41 -31
  15. data/lib/sitemap_generator/builder/sitemap_index_file.rb +31 -23
  16. data/lib/sitemap_generator/builder/sitemap_index_url.rb +10 -9
  17. data/lib/sitemap_generator/builder/sitemap_url.rb +130 -80
  18. data/lib/sitemap_generator/builder.rb +7 -3
  19. data/lib/sitemap_generator/core_ext/big_decimal.rb +40 -33
  20. data/lib/sitemap_generator/core_ext/numeric.rb +52 -46
  21. data/lib/sitemap_generator/core_ext.rb +2 -0
  22. data/lib/sitemap_generator/helpers/number_helper.rb +84 -76
  23. data/lib/sitemap_generator/interpreter.rb +22 -18
  24. data/lib/sitemap_generator/link_set.rb +114 -113
  25. data/lib/sitemap_generator/railtie.rb +4 -1
  26. data/lib/sitemap_generator/simple_namer.rb +8 -6
  27. data/lib/sitemap_generator/sitemap_location.rb +52 -40
  28. data/lib/sitemap_generator/tasks.rb +16 -26
  29. data/lib/sitemap_generator/templates.rb +11 -9
  30. data/lib/sitemap_generator/utilities.rb +46 -24
  31. data/lib/sitemap_generator.rb +42 -27
  32. data/lib/tasks/sitemap_generator_tasks.rake +2 -0
  33. data/rails/install.rb +2 -0
  34. data/rails/uninstall.rb +2 -0
  35. data/templates/sitemap.rb +3 -1
  36. metadata +7 -131
@@ -1,25 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'builder'
2
4
 
3
5
  module SitemapGenerator
4
6
  module Builder
7
+ # Wraps a sitemap file reference as a +<sitemap>+ XML entry for use in a sitemap index.
5
8
  class SitemapIndexUrl < SitemapUrl
6
-
7
- def initialize(path, options={})
8
- if index = path.is_a?(SitemapGenerator::Builder::SitemapIndexFile) && path
9
- options = SitemapGenerator::Utilities.reverse_merge(options, :host => index.location.host, :lastmod => Time.now, :priority => 1.0)
9
+ def initialize(path, options = {})
10
+ if (index = path.is_a?(SitemapGenerator::Builder::SitemapIndexFile) && path)
11
+ options = SitemapGenerator::Utilities.reverse_merge(options, host: index.location.host, lastmod: SitemapGenerator::Utilities.current_time,
12
+ priority: 1.0)
10
13
  path = index.location.path_in_public
11
- super(path, options)
12
- else
13
- super
14
14
  end
15
+ super
15
16
  end
16
17
 
17
18
  # Return the URL as XML
18
- def to_xml(builder=nil)
19
+ def to_xml(builder = nil)
19
20
  builder = ::Builder::XmlMarkup.new if builder.nil?
20
21
  builder.sitemap do
21
22
  builder.loc self[:loc]
22
- builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
23
+ builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
23
24
  end
24
25
  builder << '' # force to string
25
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'builder'
2
4
  require 'uri'
3
5
  require 'time'
@@ -7,8 +9,7 @@ module SitemapGenerator
7
9
  module Builder
8
10
  # A Hash-like class for holding information about a sitemap URL and
9
11
  # generating an XML <url> element suitable for sitemaps.
10
- class SitemapUrl < Hash
11
-
12
+ class SitemapUrl < Hash # rubocop:disable Metrics/ClassLength
12
13
  # Return a new instance with options configured on it.
13
14
  #
14
15
  # == Arguments
@@ -29,63 +30,67 @@ module SitemapGenerator
29
30
  # * +mobile+
30
31
  # * +alternate+/+alternates+
31
32
  # * +pagemap+
32
- def initialize(path, options={})
33
+ def initialize(path, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
34
+ super()
33
35
  options = SitemapGenerator::Utilities.symbolize_keys(options)
34
- if sitemap = path.is_a?(SitemapGenerator::Builder::SitemapFile) && path
36
+ if (sitemap = path.is_a?(SitemapGenerator::Builder::SitemapFile) && path)
35
37
  SitemapGenerator::Utilities.reverse_merge!(
36
38
  options,
37
- :host => sitemap.location.host,
38
- :lastmod => sitemap.lastmod
39
+ host: sitemap.location.host,
40
+ lastmod: sitemap.lastmod
39
41
  )
40
42
  path = sitemap.location.path_in_public
41
43
  end
42
44
 
43
45
  SitemapGenerator::Utilities.assert_valid_keys(
44
46
  options,
45
- :priority, :changefreq, :lastmod, :expires, :host, :images, :video, :news, :videos, :mobile, :alternate, :alternates, :pagemap
47
+ :priority, :changefreq, :lastmod, :expires, :host,
48
+ :images, :video, :news, :videos, :mobile,
49
+ :alternate, :alternates, :pagemap
46
50
  )
47
51
  SitemapGenerator::Utilities.reverse_merge!(
48
52
  options,
49
- :priority => 0.5,
50
- :changefreq => 'weekly',
51
- :lastmod => Time.now,
52
- :images => [],
53
- :news => {},
54
- :videos => [],
55
- :mobile => false,
56
- :alternates => []
53
+ priority: 0.5,
54
+ changefreq: 'weekly',
55
+ lastmod: SitemapGenerator::Utilities.current_time,
56
+ images: [],
57
+ news: {},
58
+ videos: [],
59
+ mobile: false,
60
+ alternates: []
57
61
  )
58
- raise "Cannot generate a url without a host" unless SitemapGenerator::Utilities.present?(options[:host])
62
+ raise 'Cannot generate a url without a host' unless SitemapGenerator::Utilities.present?(options[:host])
59
63
 
60
- if video = options.delete(:video)
64
+ if (video = options.delete(:video))
61
65
  options[:videos] = video.is_a?(Array) ? options[:videos].concat(video) : options[:videos] << video
62
66
  end
63
- if alternate = options.delete(:alternate)
64
- options[:alternates] = alternate.is_a?(Array) ? options[:alternates].concat(alternate) : options[:alternates] << alternate
67
+ if (alternate = options.delete(:alternate))
68
+ options[:alternates] =
69
+ alternate.is_a?(Array) ? options[:alternates].concat(alternate) : options[:alternates] << alternate
65
70
  end
66
71
 
67
- path = path.to_s.sub(/^\//, '')
68
- loc = path.empty? ? options[:host] : (options[:host].to_s.sub(/\/$/, '') + '/' + path)
69
- self.merge!(
70
- :priority => options[:priority],
71
- :changefreq => options[:changefreq],
72
- :lastmod => options[:lastmod],
73
- :expires => options[:expires],
74
- :host => options[:host],
75
- :loc => loc,
76
- :images => prepare_images(options[:images], options[:host]),
77
- :news => prepare_news(options[:news]),
78
- :videos => options[:videos],
79
- :mobile => options[:mobile],
80
- :alternates => options[:alternates],
81
- :pagemap => options[:pagemap]
72
+ path = encode_non_ascii(path.to_s.sub(%r{^/}, ''))
73
+ loc = path.empty? ? options[:host] : "#{options[:host].to_s.sub(%r{/$}, '')}/#{path}"
74
+ merge!(
75
+ priority: options[:priority],
76
+ changefreq: options[:changefreq],
77
+ lastmod: options[:lastmod],
78
+ expires: options[:expires],
79
+ host: options[:host],
80
+ loc: loc,
81
+ images: prepare_images(options[:images], options[:host]),
82
+ news: prepare_news(options[:news]),
83
+ videos: options[:videos],
84
+ mobile: options[:mobile],
85
+ alternates: prepare_alternates(options[:alternates], options[:host]),
86
+ pagemap: options[:pagemap]
82
87
  )
83
88
  end
84
89
 
85
90
  # Return the URL as XML
86
- def to_xml(builder=nil)
91
+ def to_xml(builder = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
87
92
  builder = ::Builder::XmlMarkup.new if builder.nil?
88
- builder.url do
93
+ builder.url do # rubocop:disable Metrics/BlockLength
89
94
  builder.loc self[:loc]
90
95
  builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
91
96
  builder.expires w3c_date(self[:expires]) if self[:expires]
@@ -94,8 +99,8 @@ module SitemapGenerator
94
99
 
95
100
  unless SitemapGenerator::Utilities.blank?(self[:news])
96
101
  news_data = self[:news]
97
- builder.news:news do
98
- builder.news:publication do
102
+ builder.news :news do
103
+ builder.news :publication do
99
104
  builder.news :name, news_data[:publication_name].to_s if news_data[:publication_name]
100
105
  builder.news :language, news_data[:publication_language].to_s if news_data[:publication_language]
101
106
  end
@@ -110,7 +115,7 @@ module SitemapGenerator
110
115
  end
111
116
 
112
117
  self[:images].each do |image|
113
- builder.image:image do
118
+ builder.image :image do
114
119
  builder.image :loc, image[:loc]
115
120
  builder.image :caption, image[:caption].to_s if image[:caption]
116
121
  builder.image :geo_location, image[:geo_location].to_s if image[:geo_location]
@@ -119,54 +124,67 @@ module SitemapGenerator
119
124
  end
120
125
  end
121
126
 
122
- self[:videos].each do |video|
123
- builder.video :video do
127
+ self[:videos].each do |video| # rubocop:disable Metrics/BlockLength
128
+ builder.video :video do # rubocop:disable Metrics/BlockLength
124
129
  builder.video :thumbnail_loc, video[:thumbnail_loc].to_s
125
130
  builder.video :title, video[:title].to_s
126
131
  builder.video :description, video[:description].to_s
127
- builder.video :content_loc, video[:content_loc].to_s if video[:content_loc]
132
+ builder.video :content_loc, video[:content_loc].to_s if video[:content_loc]
128
133
  if video[:player_loc]
129
- loc_attributes = { :allow_embed => yes_or_no_with_default(video[:allow_embed], true) }
130
- loc_attributes[:autoplay] = video[:autoplay].to_s if SitemapGenerator::Utilities.present?(video[:autoplay])
134
+ loc_attributes = { allow_embed: yes_or_no_with_default(video[:allow_embed], true) }
135
+ if SitemapGenerator::Utilities.present?(video[:autoplay])
136
+ loc_attributes[:autoplay] = video[:autoplay].to_s
137
+ end
131
138
  builder.video :player_loc, video[:player_loc].to_s, loc_attributes
132
139
  end
133
- builder.video :duration, video[:duration].to_s if video[:duration]
134
- builder.video :expiration_date, w3c_date(video[:expiration_date]) if video[:expiration_date]
135
- builder.video :rating, format_float(video[:rating]) if video[:rating]
136
- builder.video :view_count, video[:view_count].to_s if video[:view_count]
140
+ builder.video :duration, video[:duration].to_s if video[:duration]
141
+ builder.video :expiration_date, w3c_date(video[:expiration_date]) if video[:expiration_date]
142
+ builder.video :rating, format_float(video[:rating]) if video[:rating]
143
+ builder.video :view_count, video[:view_count].to_s if video[:view_count]
137
144
  builder.video :publication_date, w3c_date(video[:publication_date]) if video[:publication_date]
138
- video[:tags].each {|tag| builder.video :tag, tag.to_s } if video[:tags]
145
+ video[:tags]&.each { |tag| builder.video :tag, tag.to_s }
139
146
  builder.video :tag, video[:tag].to_s if video[:tag]
140
147
  builder.video :category, video[:category].to_s if video[:category]
141
- builder.video :family_friendly, yes_or_no_with_default(video[:family_friendly], true) if video.has_key?(:family_friendly)
142
- builder.video :gallery_loc, video[:gallery_loc].to_s, :title => video[:gallery_title].to_s if video[:gallery_loc]
143
- builder.video :price, video[:price].to_s, prepare_video_price_attribs(video) if SitemapGenerator::Utilities.present?(video[:price])
148
+ if video.key?(:family_friendly)
149
+ builder.video :family_friendly,
150
+ yes_or_no_with_default(video[:family_friendly], true)
151
+ end
152
+ if video[:gallery_loc]
153
+ builder.video :gallery_loc, video[:gallery_loc].to_s,
154
+ title: video[:gallery_title].to_s
155
+ end
156
+ if SitemapGenerator::Utilities.present?(video[:price])
157
+ builder.video :price, video[:price].to_s, prepare_video_price_attribs(video)
158
+ end
144
159
  if video[:uploader]
145
- builder.video :uploader, video[:uploader].to_s, video[:uploader_info] ? { :info => video[:uploader_info].to_s } : {}
160
+ builder.video :uploader, video[:uploader].to_s,
161
+ video[:uploader_info] ? { info: video[:uploader_info].to_s } : {}
162
+ end
163
+ builder.video :live, yes_or_no_with_default(video[:live], true) if video.key?(:live)
164
+ if video.key?(:requires_subscription)
165
+ builder.video :requires_subscription,
166
+ yes_or_no_with_default(video[:requires_subscription],
167
+ true)
146
168
  end
147
- builder.video :live, yes_or_no_with_default(video[:live], true) if video.has_key?(:live)
148
- builder.video :requires_subscription, yes_or_no_with_default(video[:requires_subscription], true) if video.has_key?(:requires_subscription)
149
169
  end
150
170
  end
151
171
 
152
172
  self[:alternates].each do |alternate|
153
173
  rel = alternate[:nofollow] ? 'alternate nofollow' : 'alternate'
154
- attributes = { :rel => rel, :href => alternate[:href].to_s }
174
+ attributes = { rel: rel, href: alternate[:href].to_s }
155
175
  attributes[:hreflang] = alternate[:lang].to_s if SitemapGenerator::Utilities.present?(alternate[:lang])
156
176
  attributes[:media] = alternate[:media].to_s if SitemapGenerator::Utilities.present?(alternate[:media])
157
177
  builder.xhtml :link, attributes
158
178
  end
159
179
 
160
- unless SitemapGenerator::Utilities.blank?(self[:mobile])
161
- builder.mobile :mobile
162
- end
180
+ builder.mobile :mobile unless SitemapGenerator::Utilities.blank?(self[:mobile])
163
181
 
164
182
  unless SitemapGenerator::Utilities.blank?(self[:pagemap])
165
183
  builder.pagemap :PageMap do
166
184
  SitemapGenerator::Utilities.as_array(self[:pagemap][:dataobjects]).each do |dataobject|
167
- builder.pagemap :DataObject, :type => dataobject[:type].to_s, :id => dataobject[:id].to_s do
185
+ builder.pagemap :DataObject, type: dataobject[:type].to_s, id: dataobject[:id].to_s do
168
186
  SitemapGenerator::Utilities.as_array(dataobject[:attributes]).each do |attribute|
169
- builder.pagemap :Attribute, attribute[:value].to_s, :name => attribute[:name].to_s
187
+ builder.pagemap :Attribute, attribute[:value].to_s, name: attribute[:name].to_s
170
188
  end
171
189
  end
172
190
  end
@@ -186,48 +204,69 @@ module SitemapGenerator
186
204
  attribs = {}
187
205
  attribs[:currency] = video[:price_currency].to_s # required
188
206
  attribs[:type] = video[:price_type] if SitemapGenerator::Utilities.present?(video[:price_type])
189
- attribs[:resolution] = video[:price_resolution] if SitemapGenerator::Utilities.present?(video[:price_resolution])
207
+ if SitemapGenerator::Utilities.present?(video[:price_resolution])
208
+ attribs[:resolution] = video[:price_resolution]
209
+ end
190
210
  attribs
191
211
  end
192
212
 
193
213
  def prepare_news(news)
194
- SitemapGenerator::Utilities.assert_valid_keys(news, :publication_name, :publication_language, :publication_date, :genres, :access, :title, :keywords, :stock_tickers) unless news.empty?
214
+ unless news.empty?
215
+ SitemapGenerator::Utilities.assert_valid_keys(
216
+ news,
217
+ :publication_name, :publication_language, :publication_date,
218
+ :genres, :access, :title, :keywords, :stock_tickers
219
+ )
220
+ end
195
221
  news
196
222
  end
197
223
 
224
+ # Return an Array of alternate option Hashes with relative hrefs expanded to absolute URLs.
225
+ def prepare_alternates(alternates, host)
226
+ alternates.map do |alt|
227
+ next alt unless alt.is_a?(Hash)
228
+
229
+ href = alt[:href].to_s
230
+ if href.start_with?('/')
231
+ alt.merge(href: URI.join(host, href).to_s)
232
+ else
233
+ alt
234
+ end
235
+ end
236
+ end
237
+
198
238
  # Return an Array of image option Hashes suitable to be parsed by SitemapGenerator::Builder::SitemapFile
199
239
  def prepare_images(images, host)
200
- images.delete_if { |key,value| key[:loc] == nil }
240
+ images.delete_if { |key, _value| key[:loc].nil? }
201
241
  images.each do |r|
202
242
  SitemapGenerator::Utilities.assert_valid_keys(r, :loc, :caption, :geo_location, :title, :license)
203
243
  r[:loc] = URI.join(host, r[:loc]).to_s
204
244
  end
205
- images[0..(SitemapGenerator::MAX_SITEMAP_IMAGES-1)]
245
+ images[0..(SitemapGenerator::MAX_SITEMAP_IMAGES - 1)]
206
246
  end
207
247
 
208
- def w3c_date(date)
248
+ def w3c_date(date) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
209
249
  if date.is_a?(String)
210
250
  date
211
251
  elsif date.respond_to?(:iso8601)
212
252
  date.iso8601.sub(/Z$/i, '+00:00')
213
253
  elsif date.is_a?(Date) && !date.is_a?(DateTime)
214
- date.strftime("%Y-%m-%d")
254
+ date.strftime('%Y-%m-%d')
215
255
  else
216
- zulutime = if date.is_a?(DateTime)
217
- date.new_offset(0)
218
- elsif date.respond_to?(:utc)
219
- date.utc
220
- elsif date.is_a?(Integer)
221
- Time.at(date).utc
222
- else
223
- nil
224
- end
256
+ zulutime =
257
+ if date.is_a?(DateTime)
258
+ date.new_offset(0)
259
+ elsif date.respond_to?(:utc)
260
+ date.utc
261
+ elsif date.is_a?(Integer)
262
+ Time.at(date).utc
263
+ end
225
264
 
226
265
  if zulutime
227
- zulutime.strftime("%Y-%m-%dT%H:%M:%S+00:00")
266
+ zulutime.strftime('%Y-%m-%dT%H:%M:%S+00:00')
228
267
  else
229
268
  zone = date.strftime('%z').insert(-3, ':')
230
- date.strftime("%Y-%m-%dT%H:%M:%S") + zone
269
+ date.strftime('%Y-%m-%dT%H:%M:%S') + zone
231
270
  end
232
271
  end
233
272
  end
@@ -236,7 +275,10 @@ module SitemapGenerator
236
275
  # value must be 'yes' or 'no'. Pass the default value as a boolean using `default`.
237
276
  def yes_or_no(value)
238
277
  if value.is_a?(String)
239
- raise ArgumentError.new("Unrecognized value for yes/no field: #{value.inspect}") unless value =~ /^(yes|no)$/i
278
+ unless /^(yes|no)$/i.match?(value)
279
+ raise ArgumentError, "Unrecognized value for yes/no field: #{value.inspect}"
280
+ end
281
+
240
282
  value.downcase
241
283
  else
242
284
  value ? 'yes' : 'no'
@@ -252,7 +294,15 @@ module SitemapGenerator
252
294
  # Format a float to to one decimal precision.
253
295
  # TODO: Use rounding with precision once merged with framework_agnostic.
254
296
  def format_float(value)
255
- value.is_a?(String) ? value : ('%0.1f' % value)
297
+ value.is_a?(String) ? value : format('%0.1f', value)
298
+ end
299
+
300
+ private
301
+
302
+ # Percent-encode non-ASCII bytes in a path segment, leaving already-encoded %XX sequences untouched.
303
+ # Applied to paths only — not the host — IDN hostnames require punycode, not percent-encoding.
304
+ def encode_non_ascii(str)
305
+ str.gsub(/[^\x00-\x7F]/) { |c| c.bytes.map { |b| format('%%%02X', b) }.join }
256
306
  end
257
307
  end
258
308
  end
@@ -1,8 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sitemap_generator/builder/sitemap_file'
2
4
  require 'sitemap_generator/builder/sitemap_index_file'
3
5
  require 'sitemap_generator/builder/sitemap_url'
4
6
  require 'sitemap_generator/builder/sitemap_index_url'
5
7
 
6
- module SitemapGenerator::Builder
7
- LinkHolder = Struct.new(:link, :options)
8
- end
8
+ module SitemapGenerator
9
+ module Builder
10
+ LinkHolder = Struct.new(:link, :options)
11
+ end
12
+ end
@@ -1,55 +1,62 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bigdecimal'
2
4
 
3
5
  begin
4
6
  require 'psych'
5
7
  rescue LoadError
8
+ # psych is optional; fall back gracefully if unavailable
6
9
  end
7
10
 
8
11
  require 'yaml'
9
12
 
10
13
  # Define our own class rather than modify the global class
11
- class SitemapGenerator::BigDecimal
12
- YAML_TAG = 'tag:yaml.org,2002:float'
13
- YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
14
+ module SitemapGenerator
15
+ # Scoped BigDecimal wrapper that serializes to YAML without scientific notation.
16
+ # Defined here rather than reopening the global BigDecimal class.
17
+ class BigDecimal
18
+ YAML_TAG = 'tag:yaml.org,2002:float'
19
+ YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }.freeze
14
20
 
15
- yaml_tag YAML_TAG
21
+ yaml_tag YAML_TAG
16
22
 
17
- def initialize(num)
18
- @value = BigDecimal(num)
19
- end
23
+ def initialize(num)
24
+ @value = BigDecimal(num)
25
+ end
20
26
 
21
- def *(other)
22
- other * @value
23
- end
27
+ def *(other)
28
+ other * @value
29
+ end
24
30
 
25
- def /(other)
26
- SitemapGenerator::BigDecimal === other ? @value / other.instance_variable_get(:@value) : @value / other
27
- end
31
+ def /(other)
32
+ other.is_a?(SitemapGenerator::BigDecimal) ? @value / other.instance_variable_get(:@value) : @value / other
33
+ end
28
34
 
29
- # This emits the number without any scientific notation.
30
- # This is better than self.to_f.to_s since it doesn't lose precision.
31
- #
32
- # Note that reconstituting YAML floats to native floats may lose precision.
33
- def to_yaml(opts = {})
34
- return super unless defined?(YAML::ENGINE) && YAML::ENGINE.syck?
35
+ # This emits the number without any scientific notation.
36
+ # This is better than self.to_f.to_s since it doesn't lose precision.
37
+ #
38
+ # Note that reconstituting YAML floats to native floats may lose precision.
39
+ def to_yaml(opts = {})
40
+ return super unless defined?(YAML::ENGINE) && YAML::ENGINE.syck?
41
+
42
+ YAML.quick_emit(nil, opts) do |out|
43
+ string = to_s
44
+ out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
45
+ end
46
+ end
35
47
 
36
- YAML.quick_emit(nil, opts) do |out|
48
+ def encode_with(coder)
37
49
  string = to_s
38
- out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
50
+ coder.represent_scalar(nil, YAML_MAPPING[string] || string)
39
51
  end
40
- end
41
-
42
- def encode_with(coder)
43
- string = to_s
44
- coder.represent_scalar(nil, YAML_MAPPING[string] || string)
45
- end
46
52
 
47
- def to_d
48
- self
49
- end
53
+ def to_d
54
+ self
55
+ end
50
56
 
51
- DEFAULT_STRING_FORMAT = 'F'
52
- def to_s(format = DEFAULT_STRING_FORMAT)
53
- @value.to_s(format)
57
+ DEFAULT_STRING_FORMAT = 'F'
58
+ def to_s(format = DEFAULT_STRING_FORMAT)
59
+ @value.to_s(format)
60
+ end
54
61
  end
55
62
  end
@@ -1,48 +1,54 @@
1
- class SitemapGenerator::Numeric
2
- KILOBYTE = 1024
3
- MEGABYTE = KILOBYTE * 1024
4
- GIGABYTE = MEGABYTE * 1024
5
- TERABYTE = GIGABYTE * 1024
6
- PETABYTE = TERABYTE * 1024
7
- EXABYTE = PETABYTE * 1024
8
-
9
- def initialize(number)
10
- @number = number
1
+ # frozen_string_literal: true
2
+
3
+ module SitemapGenerator
4
+ # Scoped Numeric wrapper providing byte-unit helpers (+kilobytes+, +megabytes+, etc.).
5
+ # Defined here rather than reopening the global Numeric class.
6
+ class Numeric
7
+ KILOBYTE = 1024
8
+ MEGABYTE = KILOBYTE * 1024
9
+ GIGABYTE = MEGABYTE * 1024
10
+ TERABYTE = GIGABYTE * 1024
11
+ PETABYTE = TERABYTE * 1024
12
+ EXABYTE = PETABYTE * 1024
13
+
14
+ def initialize(number)
15
+ @number = number
16
+ end
17
+
18
+ # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
19
+ def bytes
20
+ @number
21
+ end
22
+ alias byte bytes
23
+
24
+ def kilobytes
25
+ @number * KILOBYTE
26
+ end
27
+ alias kilobyte kilobytes
28
+
29
+ def megabytes
30
+ @number * MEGABYTE
31
+ end
32
+ alias megabyte megabytes
33
+
34
+ def gigabytes
35
+ @number * GIGABYTE
36
+ end
37
+ alias gigabyte gigabytes
38
+
39
+ def terabytes
40
+ @number * TERABYTE
41
+ end
42
+ alias terabyte terabytes
43
+
44
+ def petabytes
45
+ @number * PETABYTE
46
+ end
47
+ alias petabyte petabytes
48
+
49
+ def exabytes
50
+ @number * EXABYTE
51
+ end
52
+ alias exabyte exabytes
11
53
  end
12
-
13
- # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
14
- def bytes
15
- @number
16
- end
17
- alias :byte :bytes
18
-
19
- def kilobytes
20
- @number * KILOBYTE
21
- end
22
- alias :kilobyte :kilobytes
23
-
24
- def megabytes
25
- @number * MEGABYTE
26
- end
27
- alias :megabyte :megabytes
28
-
29
- def gigabytes
30
- @number * GIGABYTE
31
- end
32
- alias :gigabyte :gigabytes
33
-
34
- def terabytes
35
- @number * TERABYTE
36
- end
37
- alias :terabyte :terabytes
38
-
39
- def petabytes
40
- @number * PETABYTE
41
- end
42
- alias :petabyte :petabytes
43
-
44
- def exabytes
45
- @number * EXABYTE
46
- end
47
- alias :exabyte :exabytes
48
54
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Dir["#{File.dirname(__FILE__)}/core_ext/**/*.rb"].sort.each do |path|
2
4
  require path
3
5
  end