sitemap_generator 7.0.3 → 7.1.0

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +73 -64
  3. data/README.md +142 -143
  4. data/VERSION +1 -1
  5. data/lib/capistrano/sitemap_generator.rb +2 -0
  6. data/lib/sitemap_generator/adapters/active_storage_adapter.rb +15 -10
  7. data/lib/sitemap_generator/adapters/aws_sdk_adapter.rb +13 -12
  8. data/lib/sitemap_generator/adapters/file_adapter.rb +10 -13
  9. data/lib/sitemap_generator/adapters/fog_adapter.rb +2 -2
  10. data/lib/sitemap_generator/adapters/google_storage_adapter.rb +5 -4
  11. data/lib/sitemap_generator/adapters/s3_adapter.rb +15 -14
  12. data/lib/sitemap_generator/adapters/wave_adapter.rb +5 -5
  13. data/lib/sitemap_generator/application.rb +5 -3
  14. data/lib/sitemap_generator/builder/sitemap_file.rb +17 -14
  15. data/lib/sitemap_generator/builder/sitemap_index_file.rb +20 -18
  16. data/lib/sitemap_generator/builder/sitemap_index_url.rb +5 -6
  17. data/lib/sitemap_generator/builder/sitemap_url.rb +58 -34
  18. data/lib/sitemap_generator/builder.rb +4 -2
  19. data/lib/sitemap_generator/core_ext/big_decimal.rb +38 -33
  20. data/lib/sitemap_generator/core_ext/numeric.rb +50 -46
  21. data/lib/sitemap_generator/helpers/number_helper.rb +52 -46
  22. data/lib/sitemap_generator/interpreter.rb +11 -15
  23. data/lib/sitemap_generator/link_set.rb +63 -65
  24. data/lib/sitemap_generator/railtie.rb +1 -0
  25. data/lib/sitemap_generator/simple_namer.rb +3 -4
  26. data/lib/sitemap_generator/sitemap_location.rb +44 -36
  27. data/lib/sitemap_generator/tasks.rb +1 -1
  28. data/lib/sitemap_generator/templates.rb +6 -7
  29. data/lib/sitemap_generator/utilities.rb +25 -17
  30. data/lib/sitemap_generator.rb +22 -14
  31. data/lib/tasks/sitemap_generator_tasks.rake +2 -0
  32. data/rails/install.rb +2 -0
  33. data/rails/uninstall.rb +2 -0
  34. data/templates/sitemap.rb +2 -0
  35. metadata +2 -2
@@ -10,23 +10,26 @@ module SitemapGenerator
10
10
  # compressed prior to being written out. Otherwise the data will be written out
11
11
  # unchanged.
12
12
  # @param raw_data - data to write to the file.
13
- def write(location, raw_data)
13
+ def write(location, raw_data) # rubocop:disable Metrics/MethodLength
14
14
  # Ensure that the directory exists
15
15
  dir = location.directory
16
16
  if !File.exist?(dir)
17
17
  FileUtils.mkdir_p(dir)
18
18
  elsif !File.directory?(dir)
19
- raise SitemapError.new("#{dir} should be a directory!")
19
+ raise SitemapError, "#{dir} should be a directory!"
20
20
  end
21
21
 
22
- stream = open(location.path, 'wb')
23
- if location.path.to_s =~ /.gz$/
24
- gzip(stream, raw_data)
25
- else
26
- plain(stream, raw_data)
22
+ File.open(location.path, 'wb') do |stream|
23
+ if location.gzip?
24
+ gzip(stream, raw_data)
25
+ else
26
+ stream.write raw_data
27
+ end
27
28
  end
28
29
  end
29
30
 
31
+ private
32
+
30
33
  # Write `data` to a stream, passing the data through a GzipWriter
31
34
  # to compress it.
32
35
  def gzip(stream, data)
@@ -34,11 +37,5 @@ module SitemapGenerator
34
37
  gz.write data
35
38
  gz.close
36
39
  end
37
-
38
- # Write `data` to a stream as is.
39
- def plain(stream, data)
40
- stream.write data
41
- stream.close
42
- end
43
40
  end
44
41
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if !defined?(Fog::Storage)
3
+ unless defined?(Fog::Storage)
4
4
  raise LoadError, "Error: `Fog::Storage` is not defined.\n\n" \
5
- "Please `require 'fog'` - or another library that defines this class."
5
+ "Please `require 'fog'` - or another library that defines this class."
6
6
  end
7
7
 
8
8
  module SitemapGenerator
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if !defined?(Google::Cloud::Storage)
3
+ unless defined?(Google::Cloud::Storage)
4
4
  raise LoadError, "Error: `Google::Cloud::Storage` is not defined.\n\n" \
5
- "Please `require 'google/cloud/storage'` - or another library that defines this class."
5
+ "Please `require 'google/cloud/storage'` - or another library that defines this class."
6
6
  end
7
7
 
8
8
  module SitemapGenerator
@@ -12,7 +12,8 @@ module SitemapGenerator
12
12
  #
13
13
  # @param [Hash] opts Google::Cloud::Storage configuration options.
14
14
  # @option :bucket [String] Required. Name of Google Storage Bucket where the file is to be uploaded.
15
- # @option :acl [String] Optional. Access control which is applied to the uploaded file(s). Default value is 'public'.
15
+ # @option :acl [String] Optional. Access control which is applied to the uploaded file(s).
16
+ # Default value is 'public'.
16
17
  #
17
18
  # All options other than the `:bucket` and `:acl` options are passed to the `Google::Cloud::Storage.new`
18
19
  # initializer. See https://googleapis.dev/ruby/google-cloud-storage/latest/file.AUTHENTICATION.html
@@ -25,7 +26,7 @@ module SitemapGenerator
25
26
  def initialize(opts = {})
26
27
  opts = opts.clone
27
28
  @bucket = opts.delete(:bucket)
28
- @acl = opts.has_key?(:acl) ? opts.delete(:acl) : 'public'
29
+ @acl = opts.key?(:acl) ? opts.delete(:acl) : 'public'
29
30
  @storage_options = opts
30
31
  end
31
32
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if !defined?(Fog::Storage)
3
+ unless defined?(Fog::Storage)
4
4
  raise LoadError, "Error: `Fog::Storage` is not defined.\n\n" \
5
- "Please `require 'fog-aws'` - or another library that defines this class."
5
+ "Please `require 'fog-aws'` - or another library that defines this class."
6
6
  end
7
7
 
8
8
  module SitemapGenerator
@@ -22,21 +22,21 @@ module SitemapGenerator
22
22
  #
23
23
  # Alternatively you can use an environment variable to configure each option (except `fog_storage_options`).
24
24
  # The environment variables have the same name but capitalized, e.g. `FOG_PATH_STYLE`.
25
- def initialize(opts = {})
26
- @aws_access_key_id = opts[:aws_access_key_id] || ENV['AWS_ACCESS_KEY_ID']
27
- @aws_secret_access_key = opts[:aws_secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY']
28
- @aws_session_token = opts[:aws_session_token] || ENV['AWS_SESSION_TOKEN']
29
- @fog_provider = opts[:fog_provider] || ENV['FOG_PROVIDER']
30
- @fog_directory = opts[:fog_directory] || ENV['FOG_DIRECTORY']
31
- @fog_region = opts[:fog_region] || ENV['FOG_REGION']
32
- @fog_path_style = opts[:fog_path_style] || ENV['FOG_PATH_STYLE']
25
+ def initialize(opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
26
+ @aws_access_key_id = opts[:aws_access_key_id] || ENV.fetch('AWS_ACCESS_KEY_ID', nil)
27
+ @aws_secret_access_key = opts[:aws_secret_access_key] || ENV.fetch('AWS_SECRET_ACCESS_KEY', nil)
28
+ @aws_session_token = opts[:aws_session_token] || ENV.fetch('AWS_SESSION_TOKEN', nil)
29
+ @fog_provider = opts[:fog_provider] || ENV.fetch('FOG_PROVIDER', nil)
30
+ @fog_directory = opts[:fog_directory] || ENV.fetch('FOG_DIRECTORY', nil)
31
+ @fog_region = opts[:fog_region] || ENV.fetch('FOG_REGION', nil)
32
+ @fog_path_style = opts[:fog_path_style] || ENV.fetch('FOG_PATH_STYLE', nil)
33
33
  @fog_storage_options = opts[:fog_storage_options] || {}
34
- fog_public = opts[:fog_public].nil? ? ENV['FOG_PUBLIC'] : opts[:fog_public]
35
- @fog_public = SitemapGenerator::Utilities.falsy?(fog_public) ? false : true
34
+ fog_public = opts[:fog_public].nil? ? ENV.fetch('FOG_PUBLIC', nil) : opts[:fog_public]
35
+ @fog_public = !SitemapGenerator::Utilities.falsy?(fog_public)
36
36
  end
37
37
 
38
38
  # Call with a SitemapLocation and string data
39
- def write(location, raw_data)
39
+ def write(location, raw_data) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
40
40
  SitemapGenerator::FileAdapter.new.write(location, raw_data)
41
41
 
42
42
  credentials = { provider: @fog_provider }
@@ -57,7 +57,8 @@ module SitemapGenerator
57
57
  directory.files.create(
58
58
  key: location.path_in_public,
59
59
  body: File.open(location.path),
60
- public: @fog_public
60
+ public: @fog_public,
61
+ content_type: location.content_type
61
62
  )
62
63
  end
63
64
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if !defined?(::CarrierWave::Uploader::Base)
3
+ unless defined?(CarrierWave::Uploader::Base)
4
4
  raise LoadError, "Error: `CarrierWave::Uploader::Base` is not defined.\n\n" \
5
- "Please `require 'carrierwave'` - or another library that defines this class."
5
+ "Please `require 'carrierwave'` - or another library that defines this class."
6
6
  end
7
7
 
8
8
  module SitemapGenerator
@@ -14,10 +14,10 @@ module SitemapGenerator
14
14
  def write(location, raw_data)
15
15
  SitemapGenerator::FileAdapter.new.write(location, raw_data)
16
16
  directory = File.dirname(location.path_in_public)
17
- if directory != '.'
18
- self.store_dir = directory
17
+ self.store_dir = directory if directory != '.'
18
+ File.open(location.path, 'rb') do |io|
19
+ store!(io)
19
20
  end
20
- store!(open(location.path, 'rb'))
21
21
  end
22
22
  end
23
23
  end
@@ -3,17 +3,19 @@
3
3
  require 'pathname'
4
4
 
5
5
  module SitemapGenerator
6
+ # Thin abstraction over the host application environment.
7
+ # Provides the app +root+ path and Rails version detection.
6
8
  class Application
7
- def is_rails?
9
+ def is_rails? # rubocop:disable Naming/PredicatePrefix
8
10
  !!defined?(Rails::VERSION)
9
11
  end
10
12
 
11
13
  # Returns a boolean indicating whether this environment is Rails 3
12
14
  #
13
15
  # @return [Boolean]
14
- def is_at_least_rails3?
16
+ def is_at_least_rails3? # rubocop:disable Naming/PredicatePrefix
15
17
  is_rails? && Rails.version.to_f >= 3
16
- rescue
18
+ rescue StandardError
17
19
  false # Rails.version defined in 2.1.0
18
20
  end
19
21
 
@@ -11,10 +11,12 @@ module SitemapGenerator
11
11
  #
12
12
  # sitemap = SitemapFile.new(:location => SitemapLocation.new(...))
13
13
  # sitemap.add('/', { ... }) <- add a link to the sitemap
14
- # sitemap.finalize! <- write the sitemap file and freeze the object to protect it from further modification
14
+ # sitemap.finalize! <- write the sitemap file and freeze the object
15
+ # to protect it from further modification
15
16
  #
16
17
  class SitemapFile
17
18
  include SitemapGenerator::Helpers::NumberHelper
19
+
18
20
  attr_reader :link_count, :filesize, :location, :news_count
19
21
 
20
22
  # === Options
@@ -22,7 +24,7 @@ module SitemapGenerator
22
24
  # * <tt>location</tt> - a SitemapGenerator::SitemapLocation instance or a Hash of options
23
25
  # from which a SitemapLocation will be created for you. See `SitemapGenerator::SitemapLocation` for
24
26
  # the supported list of options.
25
- def initialize(opts = {})
27
+ def initialize(opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
26
28
  @location = opts.is_a?(Hash) ? SitemapGenerator::SitemapLocation.new(opts) : opts
27
29
  @link_count = 0
28
30
  @news_count = 0
@@ -46,7 +48,8 @@ module SitemapGenerator
46
48
  HTML
47
49
  @xml_wrapper_start.gsub!(/\s+/, ' ').gsub!(/ *> */, '>').strip!
48
50
  @xml_wrapper_end = '</urlset>'
49
- @filesize = SitemapGenerator::Utilities.bytesize(@xml_wrapper_start) + SitemapGenerator::Utilities.bytesize(@xml_wrapper_end)
51
+ @filesize = SitemapGenerator::Utilities.bytesize(@xml_wrapper_start) +
52
+ SitemapGenerator::Utilities.bytesize(@xml_wrapper_end)
50
53
  @xml_content = @xml_wrapper_start
51
54
  @written = false
52
55
  @reserved_name = nil # holds the name reserved from the namer
@@ -59,20 +62,22 @@ module SitemapGenerator
59
62
  # mess up the name-assignment sequence.
60
63
  def lastmod
61
64
  File.mtime(location.path) if location.reserved_name?
62
- rescue
65
+ rescue StandardError
63
66
  nil
64
67
  end
65
68
 
66
69
  def empty?
67
- @link_count == 0
70
+ @link_count.zero?
68
71
  end
69
72
 
70
73
  # Return a boolean indicating whether the sitemap file can fit another link
71
74
  # of <tt>bytes</tt> bytes in size. You can also pass a string and the
72
75
  # bytesize will be calculated for you.
73
76
  def file_can_fit?(bytes)
74
- bytes = bytes.is_a?(String) ? SitemapGenerator::Utilities.bytesize(bytes) : bytes
75
- (@filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE && @link_count < max_sitemap_links && @news_count < SitemapGenerator::MAX_SITEMAP_NEWS
77
+ bytes = SitemapGenerator::Utilities.bytesize(bytes) if bytes.is_a?(String)
78
+ (@filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE &&
79
+ @link_count < max_sitemap_links &&
80
+ @news_count < SitemapGenerator::MAX_SITEMAP_NEWS
76
81
  end
77
82
 
78
83
  # Add a link to the sitemap file.
@@ -94,7 +99,7 @@ module SitemapGenerator
94
99
  #
95
100
  # The link added to the sitemap will use the host from its location object
96
101
  # if no host has been specified.
97
- def add(link, options = {})
102
+ def add(link, options = {}) # rubocop:disable Metrics/MethodLength
98
103
  raise SitemapGenerator::SitemapFinalizedError if finalized?
99
104
 
100
105
  sitemap_url =
@@ -106,11 +111,9 @@ module SitemapGenerator
106
111
  end
107
112
 
108
113
  xml = sitemap_url.to_xml
109
- raise SitemapGenerator::SitemapFullError if !file_can_fit?(xml)
114
+ raise SitemapGenerator::SitemapFullError unless file_can_fit?(xml)
110
115
 
111
- if sitemap_url.news?
112
- @news_count += 1
113
- end
116
+ @news_count += 1 if sitemap_url.news?
114
117
 
115
118
  # Add the XML to the sitemap
116
119
  @xml_content << xml
@@ -140,7 +143,7 @@ module SitemapGenerator
140
143
  # A SitemapGenerator::SitemapError exception is raised if the file has
141
144
  # already been written.
142
145
  def write
143
- raise SitemapGenerator::SitemapError.new('Sitemap already written!') if written?
146
+ raise SitemapGenerator::SitemapError, 'Sitemap already written!' if written?
144
147
 
145
148
  finalize! unless finalized?
146
149
  reserve_name
@@ -158,7 +161,7 @@ module SitemapGenerator
158
161
  # Reserve a name from the namer unless one has already been reserved.
159
162
  # Safe to call more than once.
160
163
  def reserve_name
161
- @reserved_name ||= @location.reserve_name
164
+ @reserved_name ||= @location.reserve_name # rubocop:disable Naming/MemoizedInstanceVariableName
162
165
  end
163
166
 
164
167
  # Return a boolean indicating whether a name has been reserved
@@ -2,13 +2,15 @@
2
2
 
3
3
  module SitemapGenerator
4
4
  module Builder
5
+ # Builds the sitemap index XML file, listing all sitemap files.
6
+ # Manages deferred naming (waits for a second sitemap before reserving the index name)
7
+ # and controls whether an index is written at all via +create_index+.
5
8
  class SitemapIndexFile < SitemapFile
6
-
7
9
  # === Options
8
10
  #
9
11
  # * <tt>location</tt> - a SitemapGenerator::SitemapIndexLocation instance or a Hash of options
10
12
  # from which a SitemapLocation will be created for you.
11
- def initialize(opts = {})
13
+ def initialize(opts = {}) # rubocop:disable Lint/MissingSuper, Metrics/MethodLength
12
14
  @location = opts.is_a?(Hash) ? SitemapGenerator::SitemapIndexLocation.new(opts) : opts
13
15
  @link_count = 0
14
16
  @sitemaps_link_count = 0
@@ -49,9 +51,9 @@ module SitemapGenerator
49
51
  # If a link is being added to the index manually as a string, then we
50
52
  # can assume that the index is required (unless create_index is false of course).
51
53
  # This seems like the logical thing to do.
52
- alias_method :super_add, :add
53
- def add(link, options = {})
54
- if file = link.is_a?(SitemapFile) && link
54
+ alias super_add add
55
+ def add(link, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
56
+ if (file = link.is_a?(SitemapFile) && link)
55
57
  @sitemaps_link_count += file.link_count
56
58
  file.finalize! unless file.finalized?
57
59
 
@@ -62,7 +64,7 @@ module SitemapGenerator
62
64
  # first name (the index, or the sitemap). If the item is not a SitemapFile,
63
65
  # then it has been manually added and we can be sure that the user intends
64
66
  # for there to be an index.
65
- if @link_count == 0
67
+ if @link_count.zero?
66
68
  @first_sitemap = SitemapGenerator::Builder::LinkHolder.new(file, options)
67
69
  @link_count += 1 # pretend it's added, but don't add it yet
68
70
  else
@@ -90,7 +92,7 @@ module SitemapGenerator
90
92
  # of <tt>bytes</tt> bytes in size. You can also pass a string and the
91
93
  # bytesize will be calculated for you.
92
94
  def file_can_fit?(bytes)
93
- bytes = bytes.is_a?(String) ? SitemapGenerator::Utilities.bytesize(bytes) : bytes
95
+ bytes = SitemapGenerator::Utilities.bytesize(bytes) if bytes.is_a?(String)
94
96
  (@filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE && @link_count < SitemapGenerator::MAX_SITEMAP_FILES
95
97
  end
96
98
 
@@ -101,7 +103,7 @@ module SitemapGenerator
101
103
 
102
104
  def stats_summary(opts = {})
103
105
  str = "Sitemap stats: #{number_with_delimiter(@sitemaps_link_count)} links / #{@link_count} sitemaps"
104
- str += ' / %dm%02ds' % opts[:time_taken].divmod(60) if opts[:time_taken]
106
+ str + format(' / %dm%02ds', *opts[:time_taken].divmod(60)) if opts[:time_taken] # rubocop:disable Style/FormatStringToken
105
107
  end
106
108
 
107
109
  def finalize!
@@ -122,7 +124,7 @@ module SitemapGenerator
122
124
  # If a link is added manually and create_index is not false, we force index
123
125
  # creation because they obviously intend for there to be an index. False otherwise.
124
126
  def create_index?
125
- @create_index || @location.create_index == true || @location.create_index == :auto && @link_count > 1
127
+ @create_index || @location.create_index == true || (@location.create_index == :auto && @link_count > 1)
126
128
  end
127
129
 
128
130
  # Return the index file URL. If create_index is true, this is the URL
@@ -141,15 +143,15 @@ module SitemapGenerator
141
143
 
142
144
  # Make sure the first sitemap has been written out and added to the index
143
145
  def write_first_sitemap
144
- if @first_sitemap
145
- @first_sitemap.link.write unless @first_sitemap.link.written?
146
- super_add(SitemapGenerator::Builder::SitemapIndexUrl.new(@first_sitemap.link, @first_sitemap.options))
147
- @link_count -= 1 # we already counted it, don't count it twice
148
- # Store the URL because if create_index is false, this is the
149
- # "index" URL
150
- @first_sitemap_url = @first_sitemap.link.location.url
151
- @first_sitemap = nil
152
- end
146
+ return unless @first_sitemap
147
+
148
+ @first_sitemap.link.write unless @first_sitemap.link.written?
149
+ super_add(SitemapGenerator::Builder::SitemapIndexUrl.new(@first_sitemap.link, @first_sitemap.options))
150
+ @link_count -= 1 # we already counted it, don't count it twice
151
+ # Store the URL because if create_index is false, this is the
152
+ # "index" URL
153
+ @first_sitemap_url = @first_sitemap.link.location.url
154
+ @first_sitemap = nil
153
155
  end
154
156
  end
155
157
  end
@@ -4,16 +4,15 @@ require 'builder'
4
4
 
5
5
  module SitemapGenerator
6
6
  module Builder
7
+ # Wraps a sitemap file reference as a +<sitemap>+ XML entry for use in a sitemap index.
7
8
  class SitemapIndexUrl < SitemapUrl
8
-
9
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: Time.now, priority: 1.0)
10
+ if (index = path.is_a?(SitemapGenerator::Builder::SitemapIndexFile) && path)
11
+ options = SitemapGenerator::Utilities.reverse_merge(options, host: index.location.host, lastmod: Time.now,
12
+ priority: 1.0)
12
13
  path = index.location.path_in_public
13
- super(path, options)
14
- else
15
- super
16
14
  end
15
+ super
17
16
  end
18
17
 
19
18
  # Return the URL as XML
@@ -9,8 +9,7 @@ module SitemapGenerator
9
9
  module Builder
10
10
  # A Hash-like class for holding information about a sitemap URL and
11
11
  # generating an XML <url> element suitable for sitemaps.
12
- class SitemapUrl < Hash
13
-
12
+ class SitemapUrl < Hash # rubocop:disable Metrics/ClassLength
14
13
  # Return a new instance with options configured on it.
15
14
  #
16
15
  # == Arguments
@@ -31,9 +30,10 @@ module SitemapGenerator
31
30
  # * +mobile+
32
31
  # * +alternate+/+alternates+
33
32
  # * +pagemap+
34
- def initialize(path, options = {})
33
+ def initialize(path, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
34
+ super()
35
35
  options = SitemapGenerator::Utilities.symbolize_keys(options)
36
- if sitemap = path.is_a?(SitemapGenerator::Builder::SitemapFile) && path
36
+ if (sitemap = path.is_a?(SitemapGenerator::Builder::SitemapFile) && path)
37
37
  SitemapGenerator::Utilities.reverse_merge!(
38
38
  options,
39
39
  host: sitemap.location.host,
@@ -44,7 +44,9 @@ module SitemapGenerator
44
44
 
45
45
  SitemapGenerator::Utilities.assert_valid_keys(
46
46
  options,
47
- :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
48
50
  )
49
51
  SitemapGenerator::Utilities.reverse_merge!(
50
52
  options,
@@ -59,16 +61,17 @@ module SitemapGenerator
59
61
  )
60
62
  raise 'Cannot generate a url without a host' unless SitemapGenerator::Utilities.present?(options[:host])
61
63
 
62
- if video = options.delete(:video)
64
+ if (video = options.delete(:video))
63
65
  options[:videos] = video.is_a?(Array) ? options[:videos].concat(video) : options[:videos] << video
64
66
  end
65
- if alternate = options.delete(:alternate)
66
- 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
67
70
  end
68
71
 
69
- path = path.to_s.sub(/^\//, '')
70
- loc = path.empty? ? options[:host] : (options[:host].to_s.sub(/\/$/, '') + '/' + path)
71
- self.merge!(
72
+ path = path.to_s.sub(%r{^/}, '')
73
+ loc = path.empty? ? options[:host] : "#{options[:host].to_s.sub(%r{/$}, '')}/#{path}"
74
+ merge!(
72
75
  priority: options[:priority],
73
76
  changefreq: options[:changefreq],
74
77
  lastmod: options[:lastmod],
@@ -85,9 +88,9 @@ module SitemapGenerator
85
88
  end
86
89
 
87
90
  # Return the URL as XML
88
- def to_xml(builder = nil)
91
+ def to_xml(builder = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
89
92
  builder = ::Builder::XmlMarkup.new if builder.nil?
90
- builder.url do
93
+ builder.url do # rubocop:disable Metrics/BlockLength
91
94
  builder.loc self[:loc]
92
95
  builder.lastmod w3c_date(self[:lastmod]) if self[:lastmod]
93
96
  builder.expires w3c_date(self[:expires]) if self[:expires]
@@ -121,15 +124,17 @@ module SitemapGenerator
121
124
  end
122
125
  end
123
126
 
124
- self[:videos].each do |video|
125
- builder.video :video do
127
+ self[:videos].each do |video| # rubocop:disable Metrics/BlockLength
128
+ builder.video :video do # rubocop:disable Metrics/BlockLength
126
129
  builder.video :thumbnail_loc, video[:thumbnail_loc].to_s
127
130
  builder.video :title, video[:title].to_s
128
131
  builder.video :description, video[:description].to_s
129
132
  builder.video :content_loc, video[:content_loc].to_s if video[:content_loc]
130
133
  if video[:player_loc]
131
134
  loc_attributes = { allow_embed: yes_or_no_with_default(video[:allow_embed], true) }
132
- loc_attributes[:autoplay] = video[:autoplay].to_s if SitemapGenerator::Utilities.present?(video[:autoplay])
135
+ if SitemapGenerator::Utilities.present?(video[:autoplay])
136
+ loc_attributes[:autoplay] = video[:autoplay].to_s
137
+ end
133
138
  builder.video :player_loc, video[:player_loc].to_s, loc_attributes
134
139
  end
135
140
  builder.video :duration, video[:duration].to_s if video[:duration]
@@ -137,17 +142,30 @@ module SitemapGenerator
137
142
  builder.video :rating, format_float(video[:rating]) if video[:rating]
138
143
  builder.video :view_count, video[:view_count].to_s if video[:view_count]
139
144
  builder.video :publication_date, w3c_date(video[:publication_date]) if video[:publication_date]
140
- video[:tags].each { |tag| builder.video :tag, tag.to_s } if video[:tags]
145
+ video[:tags]&.each { |tag| builder.video :tag, tag.to_s }
141
146
  builder.video :tag, video[:tag].to_s if video[:tag]
142
147
  builder.video :category, video[:category].to_s if video[:category]
143
- builder.video :family_friendly, yes_or_no_with_default(video[:family_friendly], true) if video.has_key?(:family_friendly)
144
- builder.video :gallery_loc, video[:gallery_loc].to_s, title: video[:gallery_title].to_s if video[:gallery_loc]
145
- 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
146
159
  if video[:uploader]
147
- 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)
148
168
  end
149
- builder.video :live, yes_or_no_with_default(video[:live], true) if video.has_key?(:live)
150
- builder.video :requires_subscription, yes_or_no_with_default(video[:requires_subscription], true) if video.has_key?(:requires_subscription)
151
169
  end
152
170
  end
153
171
 
@@ -159,9 +177,7 @@ module SitemapGenerator
159
177
  builder.xhtml :link, attributes
160
178
  end
161
179
 
162
- unless SitemapGenerator::Utilities.blank?(self[:mobile])
163
- builder.mobile :mobile
164
- end
180
+ builder.mobile :mobile unless SitemapGenerator::Utilities.blank?(self[:mobile])
165
181
 
166
182
  unless SitemapGenerator::Utilities.blank?(self[:pagemap])
167
183
  builder.pagemap :PageMap do
@@ -188,18 +204,26 @@ module SitemapGenerator
188
204
  attribs = {}
189
205
  attribs[:currency] = video[:price_currency].to_s # required
190
206
  attribs[:type] = video[:price_type] if SitemapGenerator::Utilities.present?(video[:price_type])
191
- 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
192
210
  attribs
193
211
  end
194
212
 
195
213
  def prepare_news(news)
196
- 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
197
221
  news
198
222
  end
199
223
 
200
224
  # Return an Array of image option Hashes suitable to be parsed by SitemapGenerator::Builder::SitemapFile
201
225
  def prepare_images(images, host)
202
- images.delete_if { |key, value| key[:loc] == nil }
226
+ images.delete_if { |key, _value| key[:loc].nil? }
203
227
  images.each do |r|
204
228
  SitemapGenerator::Utilities.assert_valid_keys(r, :loc, :caption, :geo_location, :title, :license)
205
229
  r[:loc] = URI.join(host, r[:loc]).to_s
@@ -207,7 +231,7 @@ module SitemapGenerator
207
231
  images[0..(SitemapGenerator::MAX_SITEMAP_IMAGES - 1)]
208
232
  end
209
233
 
210
- def w3c_date(date)
234
+ def w3c_date(date) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
211
235
  if date.is_a?(String)
212
236
  date
213
237
  elsif date.respond_to?(:iso8601)
@@ -222,8 +246,6 @@ module SitemapGenerator
222
246
  date.utc
223
247
  elsif date.is_a?(Integer)
224
248
  Time.at(date).utc
225
- else
226
- nil
227
249
  end
228
250
 
229
251
  if zulutime
@@ -239,7 +261,9 @@ module SitemapGenerator
239
261
  # value must be 'yes' or 'no'. Pass the default value as a boolean using `default`.
240
262
  def yes_or_no(value)
241
263
  if value.is_a?(String)
242
- raise ArgumentError.new("Unrecognized value for yes/no field: #{value.inspect}") unless value =~ /^(yes|no)$/i
264
+ unless /^(yes|no)$/i.match?(value)
265
+ raise ArgumentError, "Unrecognized value for yes/no field: #{value.inspect}"
266
+ end
243
267
 
244
268
  value.downcase
245
269
  else
@@ -256,7 +280,7 @@ module SitemapGenerator
256
280
  # Format a float to to one decimal precision.
257
281
  # TODO: Use rounding with precision once merged with framework_agnostic.
258
282
  def format_float(value)
259
- value.is_a?(String) ? value : ('%0.1f' % value)
283
+ value.is_a?(String) ? value : format('%0.1f', value)
260
284
  end
261
285
  end
262
286
  end
@@ -5,6 +5,8 @@ require 'sitemap_generator/builder/sitemap_index_file'
5
5
  require 'sitemap_generator/builder/sitemap_url'
6
6
  require 'sitemap_generator/builder/sitemap_index_url'
7
7
 
8
- module SitemapGenerator::Builder
9
- LinkHolder = Struct.new(:link, :options)
8
+ module SitemapGenerator
9
+ module Builder
10
+ LinkHolder = Struct.new(:link, :options)
11
+ end
10
12
  end