Class: SitemapGenerator::Builder::SitemapFile

Inherits:
Object
  • Object
show all
Includes:
Helpers::NumberHelper
Defined in:
lib/sitemap_generator/builder/sitemap_file.rb

Overview

General Usage:

sitemap = SitemapFile.new(:location => SitemapLocation.new(...))
sitemap.add('/', { ... })    <- add a link to the sitemap
sitemap.finalize!            <- write the sitemap file and freeze the object
                               to protect it from further modification

Direct Known Subclasses

SitemapIndexFile

Constant Summary

Constants included from Helpers::NumberHelper

Helpers::NumberHelper::DECIMAL_UNITS, Helpers::NumberHelper::STORAGE_UNITS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helpers::NumberHelper

#number_to_human_size, #number_with_delimiter, #number_with_precision

Constructor Details

#initialize(opts = {}) ⇒ SitemapFile

Options

  • location - a SitemapGenerator::SitemapLocation instance or a Hash of options from which a SitemapLocation will be created for you. See SitemapGenerator::SitemapLocation for the supported list of options.


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 27

def initialize(opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
  @location = opts.is_a?(Hash) ? SitemapGenerator::SitemapLocation.new(opts) : opts
  @link_count = 0
  @news_count = 0
  # The + prefix makes this string explicitly mutable. Ruby 2.x with
  # --enable=frozen-string-literal freezes interpolated heredocs, and
  # gsub! below requires a mutable string.
  @xml_wrapper_start = +<<-HTML
    <?xml version="1.0" encoding="UTF-8"?>
      <urlset
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
          http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="#{SitemapGenerator::SCHEMAS['image']}"
        xmlns:video="#{SitemapGenerator::SCHEMAS['video']}"
        xmlns:news="#{SitemapGenerator::SCHEMAS['news']}"
        xmlns:mobile="#{SitemapGenerator::SCHEMAS['mobile']}"
        xmlns:pagemap="#{SitemapGenerator::SCHEMAS['pagemap']}"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
      >
  HTML
  @xml_wrapper_start.gsub!(/\s+/, ' ').gsub!(/ *> */, '>').strip!
  @xml_wrapper_end = '</urlset>'
  @filesize = SitemapGenerator::Utilities.bytesize(@xml_wrapper_start) +
              SitemapGenerator::Utilities.bytesize(@xml_wrapper_end)
  @xml_content = @xml_wrapper_start
  @written = false
  @reserved_name = nil # holds the name reserved from the namer
  @frozen = false      # rather than actually freeze, use this boolean
end

Instance Attribute Details

#filesizeObject (readonly)

Returns the value of attribute filesize.



20
21
22
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 20

def filesize
  @filesize
end

Returns the value of attribute link_count.



20
21
22
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 20

def link_count
  @link_count
end

#locationObject (readonly)

Returns the value of attribute location.



20
21
22
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 20

def location
  @location
end

#news_countObject (readonly)

Returns the value of attribute news_count.



20
21
22
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 20

def news_count
  @news_count
end

Instance Method Details

#add(link, options = {}) ⇒ Object

Add a link to the sitemap file.

If a link cannot be added, for example if the file is too large or the link limit has been reached, a SitemapGenerator::SitemapFullError exception is raised and the sitemap is finalized.

If the Sitemap has already been finalized a SitemapGenerator::SitemapFinalizedError exception is raised.

Return the new link count.

Call with:

sitemap_url - a SitemapUrl instance
sitemap, options - a Sitemap instance and options hash
path, options - a path for the URL and options hash.  For supported options
              see the SitemapGenerator::Builder::SitemapUrl class.

The link added to the sitemap will use the host from its location object if no host has been specified.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 102

def add(link, options = {}) # rubocop:disable Metrics/MethodLength
  raise SitemapGenerator::SitemapFinalizedError if finalized?

  sitemap_url =
    if link.is_a?(SitemapUrl)
      link
    else
      options[:host] ||= @location.host
      SitemapUrl.new(link, options)
    end

  xml = sitemap_url.to_xml
  raise SitemapGenerator::SitemapFullError unless file_can_fit?(xml)

  @news_count += 1 if sitemap_url.news?

  # Add the XML to the sitemap
  @xml_content << xml
  @filesize += SitemapGenerator::Utilities.bytesize(xml)
  @link_count += 1
end

#empty?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 69

def empty?
  @link_count.zero?
end

#file_can_fit?(bytes) ⇒ Boolean

Return a boolean indicating whether the sitemap file can fit another link of bytes bytes in size. You can also pass a string and the bytesize will be calculated for you.

Returns:

  • (Boolean)


76
77
78
79
80
81
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 76

def file_can_fit?(bytes)
  bytes = SitemapGenerator::Utilities.bytesize(bytes) if bytes.is_a?(String)
  (@filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE &&
    @link_count < max_sitemap_links &&
    @news_count < SitemapGenerator::MAX_SITEMAP_NEWS
end

#finalize!Object

"Freeze" this object. Actually just flags it as frozen.

A SitemapGenerator::SitemapFinalizedError exception is raised if the Sitemap has already been finalized.



128
129
130
131
132
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 128

def finalize!
  raise SitemapGenerator::SitemapFinalizedError if finalized?

  @frozen = true
end

#finalized?Boolean

Returns:

  • (Boolean)


134
135
136
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 134

def finalized?
  @frozen
end

#lastmodObject

If a name has been reserved, use the last modified time from the file. Otherwise return nil. We don't want to prematurely assign a name for this sitemap if one has not yet been reserved, because we may mess up the name-assignment sequence.



63
64
65
66
67
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 63

def lastmod
  File.mtime(location.path) if location.reserved_name?
rescue StandardError
  nil
end


180
181
182
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 180

def max_sitemap_links
  @location[:max_sitemap_links] || SitemapGenerator::MAX_SITEMAP_LINKS
end

#newObject

Return a new instance of the sitemap file with the same options, and the next name in the sequence.



174
175
176
177
178
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 174

def new
  location = @location.dup
  location.delete(:filename) if location.namer
  self.class.new(location)
end

#reserve_nameObject

Reserve a name from the namer unless one has already been reserved. Safe to call more than once.



163
164
165
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 163

def reserve_name
  @reserved_name ||= @location.reserve_name # rubocop:disable Naming/MemoizedInstanceVariableName
end

#reserved_name?Boolean

Return a boolean indicating whether a name has been reserved

Returns:

  • (Boolean)


168
169
170
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 168

def reserved_name?
  !!@reserved_name
end

#writeObject

Write out the sitemap and free up memory.

All the xml content in the instance is cleared, but attributes like filesize are still available.

A SitemapGenerator::SitemapError exception is raised if the file has already been written.



145
146
147
148
149
150
151
152
153
154
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 145

def write
  raise SitemapGenerator::SitemapError, 'Sitemap already written!' if written?

  finalize! unless finalized?
  reserve_name
  @xml_content << @xml_wrapper_end
  @location.write(@xml_content, link_count)
  @xml_content = @xml_wrapper_end = ''
  @written = true
end

#written?Boolean

Return true if this file has been written out to disk

Returns:

  • (Boolean)


157
158
159
# File 'lib/sitemap_generator/builder/sitemap_file.rb', line 157

def written?
  @written
end