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.
- checksums.yaml +7 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +35 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1139 -0
- data/Rakefile +43 -0
- data/VERSION +1 -0
- data/lib/capistrano/sitemap_generator.rb +1 -0
- data/lib/capistrano/tasks/sitemap_generator.cap +36 -0
- data/lib/sitemap_generator.rb +85 -0
- data/lib/sitemap_generator/adapters.rb +0 -0
- data/lib/sitemap_generator/adapters/file_adapter.rb +43 -0
- data/lib/sitemap_generator/adapters/fog_adapter.rb +28 -0
- data/lib/sitemap_generator/adapters/s3_adapter.rb +41 -0
- data/lib/sitemap_generator/adapters/wave_adapter.rb +21 -0
- data/lib/sitemap_generator/application.rb +49 -0
- data/lib/sitemap_generator/builder.rb +8 -0
- data/lib/sitemap_generator/builder/sitemap_file.rb +172 -0
- data/lib/sitemap_generator/builder/sitemap_index_file.rb +149 -0
- data/lib/sitemap_generator/builder/sitemap_index_url.rb +28 -0
- data/lib/sitemap_generator/builder/sitemap_url.rb +250 -0
- data/lib/sitemap_generator/core_ext.rb +3 -0
- data/lib/sitemap_generator/core_ext/big_decimal.rb +45 -0
- data/lib/sitemap_generator/core_ext/numeric.rb +48 -0
- data/lib/sitemap_generator/helpers/number_helper.rb +237 -0
- data/lib/sitemap_generator/interpreter.rb +80 -0
- data/lib/sitemap_generator/link_set.rb +677 -0
- data/lib/sitemap_generator/railtie.rb +7 -0
- data/lib/sitemap_generator/sitemap_location.rb +192 -0
- data/lib/sitemap_generator/sitemap_namer.rb +75 -0
- data/lib/sitemap_generator/tasks.rb +53 -0
- data/lib/sitemap_generator/templates.rb +41 -0
- data/lib/sitemap_generator/utilities.rb +181 -0
- data/lib/tasks/sitemap_generator_tasks.rake +1 -0
- data/rails/install.rb +2 -0
- data/rails/uninstall.rb +2 -0
- data/spec/blueprint.rb +15 -0
- data/spec/files/sitemap.create.rb +12 -0
- data/spec/files/sitemap.groups.rb +49 -0
- data/spec/sitemap_generator/adapters/s3_adapter_spec.rb +23 -0
- data/spec/sitemap_generator/alternate_sitemap_spec.rb +79 -0
- data/spec/sitemap_generator/application_spec.rb +69 -0
- data/spec/sitemap_generator/builder/sitemap_file_spec.rb +110 -0
- data/spec/sitemap_generator/builder/sitemap_index_file_spec.rb +124 -0
- data/spec/sitemap_generator/builder/sitemap_index_url_spec.rb +28 -0
- data/spec/sitemap_generator/builder/sitemap_url_spec.rb +186 -0
- data/spec/sitemap_generator/core_ext/bigdecimal_spec.rb +20 -0
- data/spec/sitemap_generator/core_ext/numeric_spec.rb +43 -0
- data/spec/sitemap_generator/file_adaptor_spec.rb +20 -0
- data/spec/sitemap_generator/geo_sitemap_spec.rb +30 -0
- data/spec/sitemap_generator/helpers/number_helper_spec.rb +196 -0
- data/spec/sitemap_generator/interpreter_spec.rb +90 -0
- data/spec/sitemap_generator/link_set_spec.rb +864 -0
- data/spec/sitemap_generator/mobile_sitemap_spec.rb +27 -0
- data/spec/sitemap_generator/news_sitemap_spec.rb +42 -0
- data/spec/sitemap_generator/pagemap_sitemap_spec.rb +57 -0
- data/spec/sitemap_generator/sitemap_generator_spec.rb +582 -0
- data/spec/sitemap_generator/sitemap_groups_spec.rb +144 -0
- data/spec/sitemap_generator/sitemap_location_spec.rb +210 -0
- data/spec/sitemap_generator/sitemap_namer_spec.rb +96 -0
- data/spec/sitemap_generator/templates_spec.rb +24 -0
- data/spec/sitemap_generator/utilities/existence_spec.rb +26 -0
- data/spec/sitemap_generator/utilities/hash_spec.rb +57 -0
- data/spec/sitemap_generator/utilities/rounding_spec.rb +31 -0
- data/spec/sitemap_generator/utilities_spec.rb +101 -0
- data/spec/sitemap_generator/video_sitemap_spec.rb +117 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/file_macros.rb +39 -0
- data/spec/support/schemas/siteindex.xsd +73 -0
- data/spec/support/schemas/sitemap-geo.xsd +41 -0
- data/spec/support/schemas/sitemap-mobile.xsd +32 -0
- data/spec/support/schemas/sitemap-news.xsd +159 -0
- data/spec/support/schemas/sitemap-pagemap.xsd +97 -0
- data/spec/support/schemas/sitemap-video.xsd +643 -0
- data/spec/support/schemas/sitemap.xsd +115 -0
- data/spec/support/xml_macros.rb +67 -0
- data/templates/sitemap.rb +27 -0
- 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
|
+
|