dynamic_sitemaps 1.0.8 → 2.0.0.beta

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 (72) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/Gemfile +17 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +106 -0
  6. data/Rakefile +10 -0
  7. data/dynamic_sitemaps.gemspec +22 -0
  8. data/lib/dynamic_sitemaps.rb +89 -4
  9. data/lib/dynamic_sitemaps/generator.rb +59 -0
  10. data/lib/dynamic_sitemaps/index_generator.rb +47 -0
  11. data/lib/dynamic_sitemaps/pinger.rb +35 -0
  12. data/lib/dynamic_sitemaps/rails/engine.rb +9 -0
  13. data/lib/dynamic_sitemaps/sitemap.rb +40 -5
  14. data/lib/dynamic_sitemaps/sitemap_generator.rb +153 -0
  15. data/lib/dynamic_sitemaps/sitemap_result.rb +24 -0
  16. data/lib/dynamic_sitemaps/tasks/sitemap.rake +12 -0
  17. data/lib/dynamic_sitemaps/version.rb +3 -0
  18. data/lib/generators/dynamic_sitemaps/USAGE +8 -0
  19. data/lib/generators/dynamic_sitemaps/install_generator.rb +9 -0
  20. data/lib/generators/dynamic_sitemaps/templates/config.rb +7 -0
  21. data/test/dummy/README.rdoc +261 -0
  22. data/test/dummy/Rakefile +7 -0
  23. data/test/dummy/app/assets/javascripts/application.js +15 -0
  24. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/test/dummy/app/controllers/application_controller.rb +3 -0
  26. data/test/dummy/app/helpers/application_helper.rb +2 -0
  27. data/test/dummy/app/mailers/.gitkeep +0 -0
  28. data/test/dummy/app/models/.gitkeep +0 -0
  29. data/test/dummy/app/models/product.rb +3 -0
  30. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/test/dummy/config.ru +4 -0
  32. data/test/dummy/config/application.rb +59 -0
  33. data/test/dummy/config/boot.rb +10 -0
  34. data/test/dummy/config/database.yml +25 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +37 -0
  37. data/test/dummy/config/environments/production.rb +67 -0
  38. data/test/dummy/config/environments/test.rb +37 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/inflections.rb +15 -0
  41. data/test/dummy/config/initializers/mime_types.rb +5 -0
  42. data/test/dummy/config/initializers/secret_token.rb +7 -0
  43. data/test/dummy/config/initializers/session_store.rb +8 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +5 -0
  46. data/test/dummy/config/routes.rb +58 -0
  47. data/test/dummy/db/development.sqlite3 +0 -0
  48. data/test/dummy/db/migrate/20130211190343_create_products.rb +12 -0
  49. data/test/dummy/db/schema.rb +25 -0
  50. data/test/dummy/db/test.sqlite3 +0 -0
  51. data/test/dummy/lib/assets/.gitkeep +0 -0
  52. data/test/dummy/log/.gitkeep +0 -0
  53. data/test/dummy/log/development.log +902 -0
  54. data/test/dummy/log/test.log +10 -0
  55. data/test/dummy/public/404.html +26 -0
  56. data/test/dummy/public/422.html +26 -0
  57. data/test/dummy/public/500.html +25 -0
  58. data/test/dummy/public/favicon.ico +0 -0
  59. data/test/dummy/script/rails +6 -0
  60. data/test/dummy/test/fixtures/products.yml +9 -0
  61. data/test/dummy/test/unit/product_test.rb +7 -0
  62. data/test/dynamic_sitemaps_test.rb +7 -0
  63. data/test/test_helper.rb +15 -0
  64. metadata +160 -56
  65. data/app/controllers/sitemaps_controller.rb +0 -92
  66. data/app/views/sitemaps/index.builder +0 -11
  67. data/app/views/sitemaps/sitemap.builder +0 -20
  68. data/lib/dynamic_sitemaps/engine.rb +0 -4
  69. data/lib/dynamic_sitemaps/page.rb +0 -21
  70. data/lib/dynamic_sitemaps/url.rb +0 -9
  71. data/lib/generators/dynamic_sitemaps/dynamic_sitemaps_generator.rb +0 -11
  72. data/lib/generators/dynamic_sitemaps/templates/initializer.rb +0 -28
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5df17dde12a20c3a3cca9273c46aa26834d93c47
4
+ data.tar.gz: e026ef0473a20a0e0bafe8551d846983a23c2f49
5
+ SHA512:
6
+ metadata.gz: 12da553942f24fdcbefe729b747e32389d2eeed1f14b9bb3363fbbf0ac58c0a502e9630d949bbd85e8db74bac2e837cd156ce9b2aa9cfb3df0135fe656d41be0
7
+ data.tar.gz: b52815f7ae238b587867cf3a288f2ea44df35bfe98d38c2f4759fc4f61fb0305a85b6c2cd4c387d7d752ed4a16920b9c3d98e42b29b45c8eaac8a354f11a5af0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Declare your gem's dependencies in dynamic_sitemaps.gemspec.
4
+ # Bundler will treat runtime dependencies like base dependencies, and
5
+ # development dependencies will be added by default to the :development group.
6
+ gemspec
7
+
8
+ # jquery-rails is used by the dummy application
9
+ gem "jquery-rails"
10
+
11
+ # Declare any dependencies that are still in development here instead of in
12
+ # your gemspec. These might include edge Rails or gems from your path or
13
+ # Git. Remember to move these dependencies to your gemspec before releasing
14
+ # your gem to rubygems.org.
15
+
16
+ # To use debugger
17
+ # gem 'debugger'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010-2013 Lasse Bunk
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # DynamicSitemaps
2
+
3
+ Dynamic Sitemaps is a plugin for Ruby on Rails that enables you to easily create flexible, dynamic sitemaps. It creates sitemaps in the [sitemaps.org](http://sitemaps.org) standard which is supported by several crawlers including Google, Bing, and Yahoo.
4
+
5
+ Dynamic Sitemaps is designed to be very (very) simple so there's a lot you cannot do, but possibly don't need (I didn't). If you need an advanced sitemap generator, please see Karl Varga's [SitemapGenerator](https://github.com/kjvarga/sitemap_generator).
6
+
7
+ ## Planned for version 2.0 (this branch)
8
+
9
+ Version 2.0 will make it possible to make very large sitemaps (up to 2.5 billion URLs) in a fast and memory efficient way; it will be built for large amounts of data, i.e. millions of URLs without pushing your server to the limit, memory and CPU wise.
10
+
11
+ Version 2.0 will not be compatible with version 1.0 as version 2.0 will generate static sitemap XML files whereas 1.0 generates them dynamically on each request.
12
+
13
+ Idea for the version 2.0 DSL, in ```config/sitemap.rb```:
14
+
15
+ ```ruby
16
+ host "www.mysite.com"
17
+
18
+ sitemap :site do
19
+ url root_url, last_mod: Time.now, change_freq: "daily", priority: 1.0
20
+ url contact_url
21
+ Page.all.each do |page|
22
+ url page, last_mod: page.updated_at
23
+ end
24
+ end
25
+
26
+ # All products and editions URLs
27
+ sitemap :products, Product do |product|
28
+ url product, last_mod: product.updated_at
29
+ url product_editions_url(product)
30
+ end
31
+
32
+ # Autogenerate a tags sitemap with URLs for all tags containing products.
33
+ # Automatically sets last_mod to tag.updated_at.
34
+ sitemap Tag.where("products_count > 0")
35
+ ```
36
+
37
+ You then run:
38
+
39
+ ```bash
40
+ $ rake sitemap:generate
41
+ ```
42
+
43
+ This will generate the sitemaps, remove all files from ```public/sitemaps``` replacing them with:
44
+
45
+ ```bash
46
+ - public/sitemaps/index.xml
47
+ - public/sitemaps/site.xml
48
+ - public/sitemaps/products.xml
49
+ - public/sitemaps/products2.xml
50
+ - public/sitemaps/products3.xml # etc.
51
+ - public/sitemaps/tags.xml
52
+ - public/sitemaps/tags2.xml # etc.
53
+ ```
54
+
55
+ And symlink ```/sitemap.xml``` to ```/sitemaps/sitemap.xml``` because the sitemaps.org spec only allows URLs in a sitemap to be *below* the ```sitemap.xml``` index file:
56
+
57
+ ```bash
58
+ $ ln -s /var/www/mysite/public/sitemaps/index.xml /var/www/mysite/public/sitemap.xml
59
+ ```
60
+
61
+ If you use Capistrano and have a ```shared``` folder:
62
+
63
+ ```bash
64
+ $ mkdir -p /var/www/mysite/shared/sitemaps
65
+ $ rm -r /var/www/mysite/current/public/sitemaps # if uploaded accidentally
66
+ $ ln -s /var/www/mysite/shared/sitemaps /var/www/mysite/current/public/sitemaps
67
+ ```
68
+
69
+ If for example you have multiple subdomains, then in ```config/sitemap.rb```:
70
+
71
+ ```ruby
72
+ Site.all.each do |site|
73
+ host "#{site.subdomain}.mysite.com"
74
+ path Rails.root.join("public", "sitemaps", site.subdomain)
75
+
76
+ url root_url
77
+ sitemap site.products
78
+ # etc.
79
+ end
80
+ ```
81
+
82
+ ## Installation
83
+
84
+ Add this line to your application's Gemfile:
85
+
86
+ gem "dynamic_sitemaps", git: "git://github.com/lassebunk/dynamic_sitemaps.git", branch: "2.0"
87
+
88
+ And then execute:
89
+
90
+ $ bundle
91
+
92
+ Or install it yourself as:
93
+
94
+ $ gem install dynamic_sitemaps
95
+
96
+ ## Usage
97
+
98
+ TODO: Write usage instructions here
99
+
100
+ ## Contributing
101
+
102
+ 1. Fork it
103
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
104
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
105
+ 4. Push to the branch (`git push origin my-new-feature`)
106
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake/testtask'
2
+ require 'bundler/gem_tasks'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dynamic_sitemaps/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "dynamic_sitemaps"
8
+ gem.version = DynamicSitemaps::VERSION
9
+ gem.authors = ["Lasse Bunk"]
10
+ gem.email = ["lassebunk@gmail.com"]
11
+ gem.description = %q{Dynamic Sitemaps is a plugin for Ruby on Rails that enables you to easily create flexible, dynamic sitemaps for Google, Bing, and Yahoo.}
12
+ gem.summary = %q{Dynamic sitemap generation plugin for Ruby on Rails.}
13
+ gem.homepage = "http://github.com/lassebunk/dynamic_sitemaps"
14
+ gem.license = "MIT"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.test_files = gem.files.grep(%r{^test/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "rails", "~> 3.2.13"
21
+ gem.add_development_dependency "sqlite3"
22
+ end
@@ -1,4 +1,89 @@
1
- require 'dynamic_sitemaps/page'
2
- require 'dynamic_sitemaps/sitemap'
3
- require 'dynamic_sitemaps/url'
4
- require 'dynamic_sitemaps/engine'
1
+ require "dynamic_sitemaps/rails/engine"
2
+ require "dynamic_sitemaps/sitemap"
3
+ require "dynamic_sitemaps/generator"
4
+ require "dynamic_sitemaps/sitemap_generator"
5
+ require "dynamic_sitemaps/index_generator"
6
+ require "dynamic_sitemaps/sitemap_result"
7
+ require "dynamic_sitemaps/pinger"
8
+
9
+ module DynamicSitemaps
10
+ DEFAULT_PER_PAGE = 50000
11
+ DEFAULT_FOLDER = "sitemaps"
12
+ DEFAULT_INDEX_FILE_NAME = "sitemap.xml"
13
+ DEFAULT_ALWAYS_GENERATE_INDEX = false
14
+ SEARCH_ENGINE_PING_URLS = [
15
+ "http://www.google.com/webmasters/sitemaps/ping?sitemap=%s",
16
+ "http://www.bing.com/webmaster/ping.aspx?siteMap=%s"
17
+ ]
18
+
19
+ class << self
20
+ attr_writer :path, :folder, :index_file_name, :always_generate_index, :config_path, :search_engine_ping_urls
21
+
22
+ def generate_sitemap
23
+ DynamicSitemaps::Generator.generate
24
+ end
25
+
26
+ # Configure DynamicSitemaps.
27
+ # Defaults:
28
+ #
29
+ # DynamicSitemaps.configure do |config|
30
+ # config.path = Rails.root.join("public")
31
+ # config.folder = "sitemaps"
32
+ # config.index_file_name = "sitemap.xml"
33
+ # config.always_generate_index = false
34
+ # config.config_path = Rails.root.join("config", "sitemap.rb")
35
+ # end
36
+ #
37
+ # To ping search engines after generating the sitemap:
38
+ #
39
+ # DynamicSitemaps.configure do |config|
40
+ # config.search_engine_ping_urls << "http://customsearchengine.com/ping?url=%s" # Default is Google and Bing
41
+ # config.sitemap_ping_urls = ["http://www.domain.com/sitemap.xml"]
42
+ # # or dynamically:
43
+ # config.sitemap_ping_urls = -> { Site.all.map { |site| "http://#{site.domain}/sitemap.xml" } }
44
+ # end
45
+ def configure
46
+ yield self
47
+ end
48
+
49
+ def folder
50
+ @folder ||= DEFAULT_FOLDER
51
+ end
52
+
53
+ def path
54
+ @path ||= Rails.root.join("public")
55
+ end
56
+
57
+ def index_file_name
58
+ @index_file_name ||= DEFAULT_INDEX_FILE_NAME
59
+ end
60
+
61
+ def always_generate_index
62
+ return @always_generate_index if instance_variable_defined?(:@always_generate_index)
63
+ @always_generate_index = DEFAULT_ALWAYS_GENERATE_INDEX
64
+ end
65
+
66
+ def config_path
67
+ @config_path ||= Rails.root.join("config", "sitemap.rb")
68
+ end
69
+
70
+ def search_engine_ping_urls
71
+ @search_engine_ping_urls ||= SEARCH_ENGINE_PING_URLS
72
+ end
73
+
74
+ def sitemap_ping_urls
75
+ case @sitemap_ping_urls
76
+ when Array then @sitemap_ping_urls
77
+ when Proc then @sitemap_ping_urls.call
78
+ else []
79
+ end
80
+ end
81
+
82
+ def sitemap_ping_urls=(array_or_proc)
83
+ unless array_or_proc.is_a?(Array) || array_or_proc.is_a?(Proc)
84
+ raise "Unknown type #{array_or_proc.class.name} for sitemap_ping_urls."
85
+ end
86
+ @sitemap_ping_urls = array_or_proc
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,59 @@
1
+ module DynamicSitemaps
2
+ class Generator
3
+ class << self
4
+ def generate
5
+ instance_eval open(DynamicSitemaps.config_path).read
6
+ generate_index
7
+ end
8
+
9
+ def generate_index
10
+ IndexGenerator.new(sitemaps).generate
11
+ end
12
+
13
+ def sitemap(*args, &block)
14
+ args << {} unless args.last.is_a?(Hash)
15
+ args.last[:host] ||= host
16
+ args.last[:folder] ||= folder
17
+ sitemap = Sitemap.new(*args, &block)
18
+ sitemaps << SitemapGenerator.new(sitemap).generate
19
+ end
20
+
21
+ def sitemap_for(collection, options = {}, &block)
22
+ raise "The collection given to `sitemap_for` must respond to #find_each. This is for performance. Use `Model.scoped` to get an ActiveRecord relation that responds to #find_each." unless collection.respond_to?(:find_each)
23
+
24
+ name = options.delete(:name) || collection.model_name.underscore.pluralize.to_sym
25
+ options[:collection] = collection
26
+
27
+ sitemap(name, options, &block)
28
+ end
29
+
30
+ # Array of SitemapResult
31
+ def sitemaps
32
+ @sitemaps ||= []
33
+ end
34
+
35
+ def host(*args)
36
+ if args.any?
37
+ @host = args.first
38
+ Rails.application.routes.default_url_options[:host] = @host
39
+ else
40
+ @host
41
+ end
42
+ end
43
+
44
+ def folder(*args)
45
+ if args.any?
46
+ @folder = args.first
47
+ raise ArgumentError, "Folder can't be blank." if @folder.blank?
48
+
49
+ FileUtils.rm_rf Dir.glob("#{DynamicSitemaps.path}/#{folder}/*")
50
+ else
51
+ # Ensure that the default folder is set and cleaned.
52
+ folder DynamicSitemaps.folder if @folder.blank?
53
+
54
+ @folder
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,47 @@
1
+ module DynamicSitemaps
2
+ class IndexGenerator
3
+ attr_reader :sitemaps # Array of sitemap results
4
+
5
+ # Initialize the class with an array of SitemapResult
6
+ def initialize(sitemaps)
7
+ @sitemaps = sitemaps
8
+ end
9
+
10
+ def generate
11
+ sitemaps.group_by(&:folder).each do |folder, sitemaps|
12
+ index_path = "#{DynamicSitemaps.path}/#{folder}/#{DynamicSitemaps.index_file_name}"
13
+
14
+ if !DynamicSitemaps.always_generate_index && sitemaps.count == 1 && sitemaps.first.files.count == 1
15
+ file_path = "#{DynamicSitemaps.path}/#{folder}/#{sitemaps.first.files.first}"
16
+ FileUtils.copy file_path, index_path
17
+ File.delete file_path
18
+ else
19
+ File.open(index_path, "w") do |file|
20
+ write_beginning(file)
21
+ write_sitemaps(file, sitemaps)
22
+ write_end(file)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def write_beginning(file)
29
+ file.puts '<?xml version="1.0" encoding="UTF-8"?>',
30
+ '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
31
+ end
32
+
33
+ def write_sitemaps(file, sitemaps)
34
+ sitemaps.each do |sitemap|
35
+ sitemap.files.each do |file_name|
36
+ file.puts '<sitemap>',
37
+ "<loc>http://#{sitemap.host}/#{sitemap.folder}/#{file_name}</loc>",
38
+ '</sitemap>'
39
+ end
40
+ end
41
+ end
42
+
43
+ def write_end(file)
44
+ file.puts '</sitemapindex>'
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,35 @@
1
+ module DynamicSitemaps
2
+ class Pinger
3
+ class << self
4
+ def ping_search_engines
5
+ sitemap_urls = DynamicSitemaps.sitemap_ping_urls
6
+ if sitemap_urls.any?
7
+ puts "Pinging search engines..."
8
+
9
+ sitemap_urls.each do |url|
10
+ ping_search_engines_with_sitemap_url url
11
+ end
12
+
13
+ puts "Done pinging search engines."
14
+ end
15
+ end
16
+
17
+ def ping_search_engines_with_sitemap_url(sitemap_url)
18
+ sitemap_url = CGI::escape(sitemap_url)
19
+ DynamicSitemaps.search_engine_ping_urls.each do |ping_url|
20
+ url = ping_url % sitemap_url
21
+ ping url
22
+ end
23
+ end
24
+
25
+ def ping(url)
26
+ puts "Pinging #{url} ..."
27
+ begin
28
+ Net::HTTP.get(URI.parse(url))
29
+ rescue Exception => e
30
+ puts "Failed to ping #{url} : #{e}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end