ftbpro_sitemap_generator 5.0.8

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 (78) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +13 -0
  3. data/Gemfile.lock +35 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +1139 -0
  6. data/Rakefile +43 -0
  7. data/VERSION +1 -0
  8. data/lib/capistrano/sitemap_generator.rb +1 -0
  9. data/lib/capistrano/tasks/sitemap_generator.cap +36 -0
  10. data/lib/sitemap_generator.rb +85 -0
  11. data/lib/sitemap_generator/adapters.rb +0 -0
  12. data/lib/sitemap_generator/adapters/file_adapter.rb +43 -0
  13. data/lib/sitemap_generator/adapters/fog_adapter.rb +28 -0
  14. data/lib/sitemap_generator/adapters/s3_adapter.rb +41 -0
  15. data/lib/sitemap_generator/adapters/wave_adapter.rb +21 -0
  16. data/lib/sitemap_generator/application.rb +49 -0
  17. data/lib/sitemap_generator/builder.rb +8 -0
  18. data/lib/sitemap_generator/builder/sitemap_file.rb +172 -0
  19. data/lib/sitemap_generator/builder/sitemap_index_file.rb +149 -0
  20. data/lib/sitemap_generator/builder/sitemap_index_url.rb +28 -0
  21. data/lib/sitemap_generator/builder/sitemap_url.rb +250 -0
  22. data/lib/sitemap_generator/core_ext.rb +3 -0
  23. data/lib/sitemap_generator/core_ext/big_decimal.rb +45 -0
  24. data/lib/sitemap_generator/core_ext/numeric.rb +48 -0
  25. data/lib/sitemap_generator/helpers/number_helper.rb +237 -0
  26. data/lib/sitemap_generator/interpreter.rb +80 -0
  27. data/lib/sitemap_generator/link_set.rb +677 -0
  28. data/lib/sitemap_generator/railtie.rb +7 -0
  29. data/lib/sitemap_generator/sitemap_location.rb +192 -0
  30. data/lib/sitemap_generator/sitemap_namer.rb +75 -0
  31. data/lib/sitemap_generator/tasks.rb +53 -0
  32. data/lib/sitemap_generator/templates.rb +41 -0
  33. data/lib/sitemap_generator/utilities.rb +181 -0
  34. data/lib/tasks/sitemap_generator_tasks.rake +1 -0
  35. data/rails/install.rb +2 -0
  36. data/rails/uninstall.rb +2 -0
  37. data/spec/blueprint.rb +15 -0
  38. data/spec/files/sitemap.create.rb +12 -0
  39. data/spec/files/sitemap.groups.rb +49 -0
  40. data/spec/sitemap_generator/adapters/s3_adapter_spec.rb +23 -0
  41. data/spec/sitemap_generator/alternate_sitemap_spec.rb +79 -0
  42. data/spec/sitemap_generator/application_spec.rb +69 -0
  43. data/spec/sitemap_generator/builder/sitemap_file_spec.rb +110 -0
  44. data/spec/sitemap_generator/builder/sitemap_index_file_spec.rb +124 -0
  45. data/spec/sitemap_generator/builder/sitemap_index_url_spec.rb +28 -0
  46. data/spec/sitemap_generator/builder/sitemap_url_spec.rb +186 -0
  47. data/spec/sitemap_generator/core_ext/bigdecimal_spec.rb +20 -0
  48. data/spec/sitemap_generator/core_ext/numeric_spec.rb +43 -0
  49. data/spec/sitemap_generator/file_adaptor_spec.rb +20 -0
  50. data/spec/sitemap_generator/geo_sitemap_spec.rb +30 -0
  51. data/spec/sitemap_generator/helpers/number_helper_spec.rb +196 -0
  52. data/spec/sitemap_generator/interpreter_spec.rb +90 -0
  53. data/spec/sitemap_generator/link_set_spec.rb +864 -0
  54. data/spec/sitemap_generator/mobile_sitemap_spec.rb +27 -0
  55. data/spec/sitemap_generator/news_sitemap_spec.rb +42 -0
  56. data/spec/sitemap_generator/pagemap_sitemap_spec.rb +57 -0
  57. data/spec/sitemap_generator/sitemap_generator_spec.rb +582 -0
  58. data/spec/sitemap_generator/sitemap_groups_spec.rb +144 -0
  59. data/spec/sitemap_generator/sitemap_location_spec.rb +210 -0
  60. data/spec/sitemap_generator/sitemap_namer_spec.rb +96 -0
  61. data/spec/sitemap_generator/templates_spec.rb +24 -0
  62. data/spec/sitemap_generator/utilities/existence_spec.rb +26 -0
  63. data/spec/sitemap_generator/utilities/hash_spec.rb +57 -0
  64. data/spec/sitemap_generator/utilities/rounding_spec.rb +31 -0
  65. data/spec/sitemap_generator/utilities_spec.rb +101 -0
  66. data/spec/sitemap_generator/video_sitemap_spec.rb +117 -0
  67. data/spec/spec_helper.rb +24 -0
  68. data/spec/support/file_macros.rb +39 -0
  69. data/spec/support/schemas/siteindex.xsd +73 -0
  70. data/spec/support/schemas/sitemap-geo.xsd +41 -0
  71. data/spec/support/schemas/sitemap-mobile.xsd +32 -0
  72. data/spec/support/schemas/sitemap-news.xsd +159 -0
  73. data/spec/support/schemas/sitemap-pagemap.xsd +97 -0
  74. data/spec/support/schemas/sitemap-video.xsd +643 -0
  75. data/spec/support/schemas/sitemap.xsd +115 -0
  76. data/spec/support/xml_macros.rb +67 -0
  77. data/templates/sitemap.rb +27 -0
  78. metadata +226 -0
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'bundler/setup'
2
+ Bundler.require
3
+
4
+ desc 'Default: run spec tests.'
5
+ task :default => :spec
6
+
7
+ require "rspec/core/rake_task"
8
+ RSpec::Core::RakeTask.new(:spec) do |spec|
9
+ spec.pattern = Dir.glob(['spec/sitemap_generator/**/*'])
10
+ spec.rspec_opts = ['--backtrace']
11
+ end
12
+
13
+ #
14
+ # Helpers
15
+ #
16
+
17
+ def name; @name ||= Dir['*.gemspec'].first.split('.').first end
18
+ def version; File.read('VERSION').chomp end
19
+ def gemspec_file; "#{name}.gemspec" end
20
+ def gem_file; "#{name}-#{version}.gem" end
21
+
22
+ #
23
+ # Release Tasks
24
+ # @see https://github.com/mojombo/rakegem
25
+ #
26
+
27
+ desc "Create tag v#{version}, build the gem and push to Git"
28
+ task :release => :build do
29
+ unless `git branch` =~ /^\* master$/
30
+ puts "You must be on the master branch to release!"
31
+ exit!
32
+ end
33
+ sh "git tag v#{version}"
34
+ sh "git push origin master --tags"
35
+ end
36
+
37
+ desc "Build #{gem_file} into the pkg/ directory"
38
+ task :build do
39
+ sh "mkdir -p pkg"
40
+ sh "gem build #{gemspec_file}"
41
+ sh "mv #{gem_file} pkg"
42
+ sh "bundle --local"
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 5.0.8
@@ -0,0 +1 @@
1
+ load File.expand_path(File.join('..', 'tasks', 'sitemap_generator.cap'), __FILE__)
@@ -0,0 +1,36 @@
1
+ namespace :deploy do
2
+ namespace :sitemap do
3
+ desc 'Create sitemap and ping search engines'
4
+ task :refresh do
5
+ on roles :web do
6
+ within release_path do
7
+ with rails_env: fetch(:rails_env) do
8
+ execute :rake, "sitemap:refresh"
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ desc 'Create sitemap without pinging search engines'
15
+ task :create do
16
+ on roles :web do
17
+ within release_path do
18
+ with rails_env: fetch(:rails_env) do
19
+ execute :rake, "sitemap:create"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ desc 'Clean up sitemaps in sitemap_generator path'
26
+ task :clean do
27
+ on roles :web do
28
+ within release_path do
29
+ with rails_env: fetch(:rails_env) do
30
+ execute :rake, "sitemap:clean"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,85 @@
1
+ require 'sitemap_generator/sitemap_namer'
2
+ require 'sitemap_generator/builder'
3
+ require 'sitemap_generator/link_set'
4
+ require 'sitemap_generator/templates'
5
+ require 'sitemap_generator/utilities'
6
+ require 'sitemap_generator/application'
7
+ require 'sitemap_generator/adapters'
8
+ require 'sitemap_generator/sitemap_location'
9
+
10
+ module SitemapGenerator
11
+ autoload(:Interpreter, 'sitemap_generator/interpreter')
12
+ autoload(:FileAdapter, 'sitemap_generator/adapters/file_adapter')
13
+ autoload(:S3Adapter, 'sitemap_generator/adapters/s3_adapter')
14
+ autoload(:WaveAdapter, 'sitemap_generator/adapters/wave_adapter')
15
+ autoload(:FogAdapter, 'sitemap_generator/adapters/fog_adapter')
16
+ autoload(:BigDecimal, 'sitemap_generator/core_ext/big_decimal')
17
+ autoload(:Numeric, 'sitemap_generator/core_ext/numeric')
18
+
19
+ SitemapError = Class.new(StandardError)
20
+ SitemapFullError = Class.new(SitemapError)
21
+ SitemapFinalizedError = Class.new(SitemapError)
22
+
23
+ Utilities.with_warnings(nil) do
24
+ VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").strip
25
+ MAX_SITEMAP_FILES = 50_000 # max sitemap links per index file
26
+ MAX_SITEMAP_LINKS = 50_000 # max links per sitemap
27
+ MAX_SITEMAP_IMAGES = 1_000 # max images per url
28
+ MAX_SITEMAP_NEWS = 1_000 # max news sitemap per index_file
29
+ MAX_SITEMAP_FILESIZE = 10_000_000 # bytes
30
+ SCHEMAS = {
31
+ 'geo' => 'http://www.google.com/geo/schemas/sitemap/1.0',
32
+ 'image' => 'http://www.google.com/schemas/sitemap-image/1.1',
33
+ 'mobile' => 'http://www.google.com/schemas/sitemap-mobile/1.0',
34
+ 'news' => 'http://www.google.com/schemas/sitemap-news/0.9',
35
+ 'pagemap' => 'http://www.google.com/schemas/sitemap-pagemap/1.0',
36
+ 'video' => 'http://www.google.com/schemas/sitemap-video/1.1'
37
+ }
38
+ SCHEMA_LOCATION = "http://www.sitemaps.org/schemas/sitemap/0.9
39
+ http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
40
+
41
+ # Lazy-initialize the LinkSet instance
42
+ Sitemap = (Class.new do
43
+ def method_missing(*args, &block)
44
+ (@link_set ||= reset!).send(*args, &block)
45
+ end
46
+
47
+ # Use a new LinkSet instance
48
+ def reset!
49
+ @link_set = LinkSet.new
50
+ end
51
+ end).new
52
+ end
53
+
54
+ class << self
55
+ attr_accessor :root, :app, :templates
56
+ attr_writer :yield_sitemap, :verbose
57
+ end
58
+
59
+ # Global default for the verbose setting.
60
+ def self.verbose
61
+ if @verbose.nil?
62
+ @verbose = if SitemapGenerator::Utilities.truthy?(ENV['VERBOSE'])
63
+ true
64
+ elsif SitemapGenerator::Utilities.falsy?(ENV['VERBOSE'])
65
+ false
66
+ else
67
+ nil
68
+ end
69
+ else
70
+ @verbose
71
+ end
72
+ end
73
+
74
+ # Returns true if we should yield the sitemap instance to the block, false otherwise.
75
+ def self.yield_sitemap?
76
+ !!@yield_sitemap
77
+ end
78
+
79
+ self.root = File.expand_path(File.join(File.dirname(__FILE__), '../')) # Root of the install dir, not the Rails app
80
+ self.templates = SitemapGenerator::Templates.new(self.root)
81
+ self.app = SitemapGenerator::Application.new
82
+ end
83
+
84
+ require 'sitemap_generator/railtie' if SitemapGenerator.app.rails3?
85
+
File without changes
@@ -0,0 +1,43 @@
1
+ module SitemapGenerator
2
+ # Class for writing out data to a file.
3
+ class FileAdapter
4
+
5
+ # Write data to a file.
6
+ # @param location - File object giving the full path and file name of the file.
7
+ # If the location specifies a directory(ies) which does not exist, the directory(ies)
8
+ # will be created for you. If the location path ends with `.gz` the data will be
9
+ # compressed prior to being written out. Otherwise the data will be written out
10
+ # unchanged.
11
+ # @param raw_data - data to write to the file.
12
+ def write(location, raw_data)
13
+ # Ensure that the directory exists
14
+ dir = location.directory
15
+ if !File.exists?(dir)
16
+ FileUtils.mkdir_p(dir)
17
+ elsif !File.directory?(dir)
18
+ raise SitemapError.new("#{dir} should be a directory!")
19
+ end
20
+
21
+ stream = open(location.path, 'wb')
22
+ if location.path.to_s =~ /.gz$/
23
+ gzip(stream, raw_data)
24
+ else
25
+ plain(stream, raw_data)
26
+ end
27
+ end
28
+
29
+ # Write `data` to a stream, passing the data through a GzipWriter
30
+ # to compress it.
31
+ def gzip(stream, data)
32
+ gz = Zlib::GzipWriter.new(stream)
33
+ gz.write data
34
+ gz.close
35
+ end
36
+
37
+ # Write `data` to a stream as is.
38
+ def plain(stream, data)
39
+ stream.write data
40
+ stream.close
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ begin
2
+ require 'fog'
3
+ rescue LoadError
4
+ raise LoadError.new("Missing required 'fog'. Please 'gem install fog' and require it in your application.")
5
+ end
6
+
7
+ module SitemapGenerator
8
+ class FogAdapter
9
+
10
+ def initialize(opts = {})
11
+ @fog_credentials = opts[:fog_credentials]
12
+ @fog_directory = opts[:fog_directory]
13
+ end
14
+
15
+ # Call with a SitemapLocation and string data
16
+ def write(location, raw_data)
17
+ SitemapGenerator::FileAdapter.new.write(location, raw_data)
18
+
19
+ storage = Fog::Storage.new(@fog_credentials)
20
+ directory = storage.directories.new(:key => @fog_directory)
21
+ directory.files.create(
22
+ :key => location.path_in_public,
23
+ :body => File.open(location.path),
24
+ :public => true
25
+ )
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,41 @@
1
+ begin
2
+ require 'fog'
3
+ rescue LoadError
4
+ raise LoadError.new("Missing required 'fog'. Please 'gem install fog' and require it in your application.")
5
+ end
6
+
7
+ module SitemapGenerator
8
+ class S3Adapter
9
+
10
+ def initialize(opts = {})
11
+ @aws_access_key_id = opts[:aws_access_key_id] || ENV['AWS_ACCESS_KEY_ID']
12
+ @aws_secret_access_key = opts[:aws_secret_access_key] || ENV['AWS_SECRET_ACCESS_KEY']
13
+ @fog_provider = opts[:fog_provider] || ENV['FOG_PROVIDER']
14
+ @fog_directory = opts[:fog_directory] || ENV['FOG_DIRECTORY']
15
+ @fog_region = opts[:fog_region] || ENV['FOG_REGION']
16
+ @fog_path_style = opts[:fog_path_style] || ENV['FOG_PATH_STYLE']
17
+ end
18
+
19
+ # Call with a SitemapLocation and string data
20
+ def write(location, raw_data)
21
+ SitemapGenerator::FileAdapter.new.write(location, raw_data)
22
+
23
+ credentials = {
24
+ :aws_access_key_id => @aws_access_key_id,
25
+ :aws_secret_access_key => @aws_secret_access_key,
26
+ :provider => @fog_provider,
27
+ }
28
+ credentials[:region] = @fog_region if @fog_region
29
+ credentials[:path_style] = @fog_path_style if @fog_path_style
30
+
31
+ storage = Fog::Storage.new(credentials)
32
+ directory = storage.directories.new(:key => @fog_directory)
33
+ directory.files.create(
34
+ :key => location.path_in_public,
35
+ :body => File.open(location.path),
36
+ :public => true
37
+ )
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'carrierwave'
3
+ rescue LoadError
4
+ raise LoadError.new("Missing required 'carrierwave'. Please 'gem install carrierwave' and require it in your application.")
5
+ end
6
+
7
+ module SitemapGenerator
8
+ class WaveAdapter < ::CarrierWave::Uploader::Base
9
+ attr_accessor :store_dir
10
+
11
+ # Call with a SitemapLocation and string data
12
+ def write(location, raw_data)
13
+ SitemapGenerator::FileAdapter.new.write(location, raw_data)
14
+ directory = File.dirname(location.path_in_public)
15
+ if directory != '.'
16
+ self.store_dir = directory
17
+ end
18
+ store!(open(location.path, 'rb'))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,49 @@
1
+ require 'pathname'
2
+
3
+ module SitemapGenerator
4
+ class Application
5
+ def rails?
6
+ defined?(Rails)
7
+ end
8
+
9
+ # Returns a boolean indicating whether this environment is Rails 3
10
+ #
11
+ # @return [Boolean]
12
+ def rails3?
13
+ rails? && Rails.version.to_f >= 3
14
+ rescue
15
+ false # Rails.version defined in 2.1.0
16
+ end
17
+
18
+ def root
19
+ Pathname.new(rails_root || Dir.getwd)
20
+ end
21
+
22
+ protected
23
+
24
+ # Returns the root of the Rails application,
25
+ # if this is running in a Rails context.
26
+ # Returns `nil` if no such root is defined.
27
+ #
28
+ # @return [String, nil]
29
+ def rails_root
30
+ if defined?(::Rails.root)
31
+ return ::Rails.root.to_s if ::Rails.root
32
+ raise "ERROR: Rails.root is nil!"
33
+ end
34
+ return RAILS_ROOT.to_s if defined?(RAILS_ROOT)
35
+ return nil
36
+ end
37
+
38
+ # Returns the environment of the Rails application,
39
+ # if this is running in a Rails context.
40
+ # Returns `nil` if no such environment is defined.
41
+ #
42
+ # @return [String, nil]
43
+ def rails_env
44
+ return ::Rails.env.to_s if defined?(::Rails.env)
45
+ return RAILS_ENV.to_s if defined?(RAILS_ENV)
46
+ return nil
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,8 @@
1
+ require 'sitemap_generator/builder/sitemap_file'
2
+ require 'sitemap_generator/builder/sitemap_index_file'
3
+ require 'sitemap_generator/builder/sitemap_url'
4
+ require 'sitemap_generator/builder/sitemap_index_url'
5
+
6
+ module SitemapGenerator::Builder
7
+ LinkHolder = Struct.new(:link, :options)
8
+ end
@@ -0,0 +1,172 @@
1
+ require 'zlib'
2
+ require 'fileutils'
3
+ require 'sitemap_generator/helpers/number_helper'
4
+
5
+ module SitemapGenerator
6
+ module Builder
7
+ #
8
+ # General Usage:
9
+ #
10
+ # sitemap = SitemapFile.new(:location => SitemapLocation.new(...))
11
+ # sitemap.add('/', { ... }) <- add a link to the sitemap
12
+ # sitemap.finalize! <- write the sitemap file and freeze the object to protect it from further modification
13
+ #
14
+ class SitemapFile
15
+ include SitemapGenerator::Helpers::NumberHelper
16
+ attr_reader :link_count, :filesize, :location, :news_count
17
+
18
+ # === Options
19
+ #
20
+ # * <tt>location</tt> - a SitemapGenerator::SitemapLocation instance or a Hash of options
21
+ # from which a SitemapLocation will be created for you.
22
+ def initialize(opts={}, schemas, schema_location)
23
+ @location = opts.is_a?(Hash) ? SitemapGenerator::SitemapLocation.new(opts) : opts
24
+ @link_count = 0
25
+ @news_count = 0
26
+ @xml_content = '' # XML urlset content
27
+ @schemas = schemas
28
+ @schema_location = schema_location
29
+ @xml_wrapper_start = xml_wrapper_start.gsub(/\s+/, ' ').gsub(/ *> */, '>').strip.slice(1..-2)
30
+ @xml_wrapper_end = %q[</urlset>]
31
+ @filesize = SitemapGenerator::Utilities.bytesize(@xml_wrapper_start) + SitemapGenerator::Utilities.bytesize(@xml_wrapper_end)
32
+ @written = false
33
+ @reserved_name = nil # holds the name reserved from the namer
34
+ @frozen = false # rather than actually freeze, use this boolean
35
+ end
36
+
37
+ def xml_wrapper_start
38
+ wrapper_start = '<?xml version="1.0" encoding="UTF-8"?>
39
+ <urlset
40
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
41
+ schema_location = "xsi:schemaLocation=\"#{@schema_location}\""
42
+ general_schema = 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"'
43
+ customized_schemas = @schemas.collect do |schema, content|
44
+ "xmlns:#{schema}=\"#{content}\""
45
+ end
46
+ wrapper_end = 'xmlns:xhtml="http://www.w3.org/1999/xhtml">'
47
+ xml_start = [wrapper_start, schema_location, general_schema, customized_schemas, wrapper_end].join(" ")
48
+ return <<-HTML
49
+ "#{xml_start}"
50
+ HTML
51
+ end
52
+
53
+ # If a name has been reserved, use the last modified time from the file.
54
+ # Otherwise return nil. We don't want to prematurely assign a name
55
+ # for this sitemap if one has not yet been reserved, because we may
56
+ # mess up the name-assignment sequence.
57
+ def lastmod
58
+ File.mtime(location.path) if location.reserved_name?
59
+ rescue
60
+ nil
61
+ end
62
+
63
+ def empty?
64
+ @link_count == 0
65
+ end
66
+
67
+ # Return a boolean indicating whether the sitemap file can fit another link
68
+ # of <tt>bytes</tt> bytes in size. You can also pass a string and the
69
+ # bytesize will be calculated for you.
70
+ def file_can_fit?(bytes)
71
+ bytes = bytes.is_a?(String) ? SitemapGenerator::Utilities.bytesize(bytes) : bytes
72
+ (@filesize + bytes) < SitemapGenerator::MAX_SITEMAP_FILESIZE && @link_count < SitemapGenerator::MAX_SITEMAP_LINKS && @news_count < SitemapGenerator::MAX_SITEMAP_NEWS
73
+ end
74
+
75
+ # Add a link to the sitemap file.
76
+ #
77
+ # If a link cannot be added, for example if the file is too large or the link
78
+ # limit has been reached, a SitemapGenerator::SitemapFullError exception is raised
79
+ # and the sitemap is finalized.
80
+ #
81
+ # If the Sitemap has already been finalized a SitemapGenerator::SitemapFinalizedError
82
+ # exception is raised.
83
+ #
84
+ # Return the new link count.
85
+ #
86
+ # Call with:
87
+ # sitemap_url - a SitemapUrl instance
88
+ # sitemap, options - a Sitemap instance and options hash
89
+ # path, options - a path for the URL and options hash. For supported options
90
+ # see the SitemapGenerator::Builder::SitemapUrl class.
91
+ #
92
+ # The link added to the sitemap will use the host from its location object
93
+ # if no host has been specified.
94
+ def add(link, options={})
95
+ raise SitemapGenerator::SitemapFinalizedError if finalized?
96
+
97
+ sitemap_url = if link.is_a?(SitemapUrl)
98
+ link
99
+ else
100
+ options[:host] ||= @location.host
101
+ SitemapUrl.new(link, options)
102
+ end
103
+
104
+ xml = sitemap_url.to_xml
105
+ raise SitemapGenerator::SitemapFullError if !file_can_fit?(xml)
106
+
107
+ if sitemap_url.news?
108
+ @news_count += 1
109
+ end
110
+
111
+ # Add the XML to the sitemap
112
+ @xml_content << xml
113
+ @filesize += SitemapGenerator::Utilities.bytesize(xml)
114
+ @link_count += 1
115
+ end
116
+
117
+ # "Freeze" this object. Actually just flags it as frozen.
118
+ #
119
+ # A SitemapGenerator::SitemapFinalizedError exception is raised if the Sitemap
120
+ # has already been finalized.
121
+ def finalize!
122
+ raise SitemapGenerator::SitemapFinalizedError if finalized?
123
+ @frozen = true
124
+ end
125
+
126
+ def finalized?
127
+ @frozen
128
+ end
129
+
130
+ # Write out the sitemap and free up memory.
131
+ #
132
+ # All the xml content in the instance is cleared, but attributes like
133
+ # <tt>filesize</tt> are still available.
134
+ #
135
+ # A SitemapGenerator::SitemapError exception is raised if the file has
136
+ # already been written.
137
+ def write
138
+ raise SitemapGenerator::SitemapError.new("Sitemap already written!") if written?
139
+ finalize! unless finalized?
140
+ reserve_name
141
+ @location.write(@xml_wrapper_start + @xml_content + @xml_wrapper_end, link_count)
142
+ @xml_content = @xml_wrapper_start = @xml_wrapper_end = ''
143
+ @written = true
144
+ end
145
+
146
+ # Return true if this file has been written out to disk
147
+ def written?
148
+ @written
149
+ end
150
+
151
+ # Reserve a name from the namer unless one has already been reserved.
152
+ # Safe to call more than once.
153
+ def reserve_name
154
+ @reserved_name ||= @location.reserve_name
155
+ end
156
+
157
+ # Return a boolean indicating whether a name has been reserved
158
+ def reserved_name?
159
+ !!@reserved_name
160
+ end
161
+
162
+ # Return a new instance of the sitemap file with the same options,
163
+ # and the next name in the sequence.
164
+ def new
165
+ location = @location.dup
166
+ location.delete(:filename) if location.namer
167
+ self.class.new(location, @schemas, @schema_location)
168
+ end
169
+ end
170
+ end
171
+ end
172
+