dynamic_sitemaps 1.0.8 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
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