sitemap_generator 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/README.md +4 -9
  2. data/Rakefile +68 -17
  3. data/VERSION +1 -1
  4. data/lib/sitemap_generator.rb +10 -6
  5. data/lib/sitemap_generator/link_set.rb +167 -14
  6. data/rails/install.rb +1 -11
  7. data/rails/uninstall.rb +1 -3
  8. data/tasks/sitemap_generator_tasks.rake +9 -79
  9. metadata +17 -43
  10. data/test/mock_app/app/controllers/application_controller.rb +0 -10
  11. data/test/mock_app/app/controllers/contents_controller.rb +0 -85
  12. data/test/mock_app/app/models/content.rb +0 -2
  13. data/test/mock_app/config/boot.rb +0 -110
  14. data/test/mock_app/config/environment.rb +0 -41
  15. data/test/mock_app/config/environments/development.rb +0 -17
  16. data/test/mock_app/config/environments/production.rb +0 -28
  17. data/test/mock_app/config/environments/test.rb +0 -28
  18. data/test/mock_app/config/initializers/backtrace_silencers.rb +0 -7
  19. data/test/mock_app/config/initializers/inflections.rb +0 -10
  20. data/test/mock_app/config/initializers/mime_types.rb +0 -5
  21. data/test/mock_app/config/initializers/new_rails_defaults.rb +0 -19
  22. data/test/mock_app/config/initializers/session_store.rb +0 -15
  23. data/test/mock_app/config/routes.rb +0 -45
  24. data/test/mock_app/config/sitemap.rb +0 -13
  25. data/test/mock_app/db/migrate/20090826121911_create_contents.rb +0 -12
  26. data/test/mock_app/db/schema.rb +0 -20
  27. data/test/mock_app_gem/app/controllers/application_controller.rb +0 -10
  28. data/test/mock_app_gem/app/controllers/contents_controller.rb +0 -85
  29. data/test/mock_app_gem/app/models/content.rb +0 -2
  30. data/test/mock_app_gem/config/boot.rb +0 -110
  31. data/test/mock_app_gem/config/environment.rb +0 -42
  32. data/test/mock_app_gem/config/environments/development.rb +0 -17
  33. data/test/mock_app_gem/config/environments/production.rb +0 -28
  34. data/test/mock_app_gem/config/environments/test.rb +0 -28
  35. data/test/mock_app_gem/config/initializers/backtrace_silencers.rb +0 -7
  36. data/test/mock_app_gem/config/initializers/inflections.rb +0 -10
  37. data/test/mock_app_gem/config/initializers/mime_types.rb +0 -5
  38. data/test/mock_app_gem/config/initializers/new_rails_defaults.rb +0 -19
  39. data/test/mock_app_gem/config/initializers/session_store.rb +0 -15
  40. data/test/mock_app_gem/config/routes.rb +0 -45
  41. data/test/mock_app_gem/config/sitemap.rb +0 -13
  42. data/test/mock_app_gem/db/migrate/20090826121911_create_contents.rb +0 -12
  43. data/test/mock_app_gem/db/schema.rb +0 -20
  44. data/test/sitemap_generator_test.rb +0 -83
  45. data/test/test_helper.rb +0 -12
data/README.md CHANGED
@@ -6,9 +6,9 @@ This plugin enables ['enterprise-class'][enterprise_class] Google Sitemaps to be
6
6
  Foreword
7
7
  -------
8
8
 
9
- Unfortunately, Adam Salter passed away recently. Those who knew him know what an amazing guy he was, and what an excellent Rails programmer he was. His passing is a great loss to the Rails community.
9
+ Unfortunately, Adam Salter passed away in 2009. Those who knew him know what an amazing guy he was, and what an excellent Rails programmer he was. His passing is a great loss to the Rails community.
10
10
 
11
- I will be taking over maintaining this gem from him. -- Karl
11
+ [Karl Varga](http://github.com/kjvarga) has taken over development of SitemapGenerator. The canonical repository is [http://github.com/kjvarga/sitemap_generator][canonical_repo]
12
12
 
13
13
  Raison d'être
14
14
  -------
@@ -171,20 +171,15 @@ Wishlist
171
171
  Thanks (in no particular order)
172
172
  ========
173
173
 
174
- - [Karl Varga (aka Bear Grylls)](http://github.com/kjvarga)
175
174
  - [Dan Pickett](http://github.com/dpickett)
176
175
  - [Rob Biedenharn](http://github.com/rab)
177
176
  - [Richie Vos](http://github.com/jerryvos)
177
+ - [Adrian Mugnolo](http://github.com/xymbol)
178
178
 
179
179
 
180
- Follow me on:
181
- ---------
182
-
183
- > Twitter: [twitter.com/adamsalter](http://twitter.com/adamsalter)
184
- > Github: [github.com/adamsalter](http://github.com/adamsalter)
185
-
186
180
  Copyright (c) 2009 Adam @ [Codebright.net][cb], released under the MIT license
187
181
 
182
+ [canonical_repo]:http://github.com/kjvarga/sitemap_generator
188
183
  [enterprise_class]:https://twitter.com/dhh/status/1631034662 "I use enterprise in the same sense the Phusion guys do - i.e. Enterprise Ruby. Please don't look down on my use of the word 'enterprise' to represent being a cut above. It doesn't mean you ever have to work for a company the size of IBM. Or constantly fight inertia, writing crappy software, adhering to change management practices and spending hours in meetings... Not that there's anything wrong with that - Wait, what?"
189
184
  [sitemap_engines]:http://en.wikipedia.org/wiki/Sitemap_index "http://en.wikipedia.org/wiki/Sitemap_index"
190
185
  [sitemaps_org]:http://www.sitemaps.org/protocol.php "http://www.sitemaps.org/protocol.php"
data/Rakefile CHANGED
@@ -1,30 +1,81 @@
1
- require 'rake/testtask'
2
- require 'find'
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require 'spec/rake/spectask'
3
4
 
4
5
  begin
5
6
  require 'jeweler'
6
- Jeweler::Tasks.new do |s|
7
- s.name = "sitemap_generator"
8
- s.summary = %Q{Generate 'enterprise-class' Sitemaps for your Rails site using a simple 'Rails Routes'-like DSL and a single Rake task}
9
- s.description = %Q{Install as a plugin or Gem to easily generate ['enterprise-class'][enterprise_class] Google Sitemaps for your Rails site, using a simple 'Rails Routes'-like DSL and a single rake task.}
10
- s.email = "kjvarga@gmail.com"
11
- s.homepage = "http://github.com/kjvarga/sitemap_generator"
12
- s.authors = ["Adam Salter", "Karl Varga"]
13
- s.files = FileList["[A-Z]*", "{bin,lib,rails,templates,tasks}/**/*"]
14
- # s is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "sitemap_generator"
9
+ gem.summary = %Q{Easily generate enterprise class Sitemaps for your Rails site using a simple 'Rails Routes'-like DSL and a single Rake task}
10
+ gem.description = %Q{Installs as a plugin or Gem to easily generate enterprise class Sitemaps readable by all search engines. Automatically ping search engines to notify them of new sitemaps, including Google, Yahoo and Bing. Provides rake tasks to easily manage your sitemaps. Won't clobber your old sitemaps if the new one fails to generate. Setup a cron schedule and never worry about your sitemaps again.}
11
+ gem.email = "kjvarga@gmail.com"
12
+ gem.homepage = "http://github.com/kjvarga/sitemap_generator"
13
+ gem.authors = ["Adam Salter", "Karl Varga"]
14
+ gem.files = FileList["[A-Z]*", "{bin,lib,rails,templates,tasks}/**/*"]
15
+ gem.test_files = []
16
+ gem.add_development_dependency "rspec"
15
17
  end
16
18
  Jeweler::GemcutterTasks.new
17
19
  rescue LoadError
18
20
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
21
  end
20
22
 
21
- desc 'Default: run unit tests.'
22
23
  task :default => :test
23
24
 
24
- desc 'Test.'
25
- Rake::TestTask.new(:test) do |t|
26
- t.libs << 'lib'
27
- t.pattern = 'test/**/*_test.rb'
28
- t.verbose = true
25
+ namespace :test do
26
+ task :gem => ['test:prepare:gem', 'multi_spec']
27
+ task :plugin => ['test:prepare:plugin', 'multi_spec']
28
+
29
+ task :multi_spec do
30
+ Rake::Task['spec'].invoke
31
+ Rake::Task['spec'].reenable
32
+ end
33
+
34
+ namespace :prepare do
35
+ task :gem do
36
+ ENV["SITEMAP_RAILS"] = 'gem'
37
+ prepare_path(local_path('spec/mock_app_gem/vendor/gems/sitemap_generator-1.2.3'))
38
+ rm_rf(local_path('spec/mock_app_gem/public/sitemap*'))
39
+ end
40
+
41
+ task :plugin do
42
+ ENV["SITEMAP_RAILS"] = 'plugin'
43
+ prepare_path(local_path('spec/mock_app_plugin/vendor/plugins/sitemap_generator-1.2.3'))
44
+ rm_rf(local_path('spec/mock_app_plugin/public/sitemap*'))
45
+ end
46
+
47
+ def local_path(path)
48
+ File.join(File.dirname(__FILE__), path)
49
+ end
50
+
51
+ def prepare_path(path)
52
+ rm_rf path
53
+ mkdir_p path
54
+ cp_r(FileList["[A-Z]*", "{bin,lib,rails,templates,tasks}"], path)
55
+ end
56
+ end
29
57
  end
30
58
 
59
+ desc "Run all tests both as a plugin and gem"
60
+ task :test => ['test:plugin', 'test:gem']
61
+
62
+ Spec::Rake::SpecTask.new(:spec) do |spec|
63
+ spec.libs << 'lib' << 'spec'
64
+ spec.spec_files = FileList['spec/**/*_spec.rb']
65
+ end
66
+ task :spec => :check_dependencies
67
+
68
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
69
+ spec.libs << 'lib' << 'spec'
70
+ spec.pattern = 'spec/**/*_spec.rb'
71
+ spec.rcov = true
72
+ end
73
+
74
+ desc 'Generate documentation'
75
+ Rake::RDocTask.new(:rdoc) do |rdoc|
76
+ rdoc.rdoc_dir = 'rdoc'
77
+ rdoc.title = 'SitemapGenerator'
78
+ rdoc.options << '--line-numbers' << '--inline-source'
79
+ rdoc.rdoc_files.include('README.md')
80
+ rdoc.rdoc_files.include('lib/**/*.rb')
81
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.3
1
+ 0.2.4
@@ -4,16 +4,20 @@ require 'sitemap_generator/link_set'
4
4
  require 'sitemap_generator/helper'
5
5
 
6
6
  module SitemapGenerator
7
- class <<self
7
+ silence_warnings do
8
+ VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").strip
9
+ MAX_ENTRIES = 50_000
10
+ Sitemap = LinkSet.new
11
+ end
12
+
13
+ class << self
8
14
  attr_accessor :root, :templates
9
15
  end
16
+
10
17
  self.root = File.expand_path(File.join(File.dirname(__FILE__), '../'))
11
18
  self.templates = {
12
- :sitemap_index => File.join(self.root, 'templates/sitemap_index.builder'),
13
- :sitemap_xml => File.join(self.root, 'templates/xml_sitemap.builder'),
19
+ :sitemap_index => File.join(self.root, 'templates/sitemap_index.builder'),
20
+ :sitemap_xml => File.join(self.root, 'templates/xml_sitemap.builder'),
14
21
  :sitemap_sample => File.join(self.root, 'templates/sitemap.rb'),
15
22
  }
16
-
17
- Sitemap = LinkSet.new
18
23
  end
19
-
@@ -1,28 +1,181 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
1
3
  module SitemapGenerator
2
4
  class LinkSet
5
+ include SitemapGenerator::Helper
6
+ include ActionView::Helpers::NumberHelper
7
+
3
8
  attr_accessor :default_host, :yahoo_app_id, :links
4
-
5
- def initialize
6
- @links = []
7
- end
9
+ attr_accessor :sitemaps
10
+ attr_accessor :max_entries
11
+ attr_accessor :link_count
8
12
 
9
- def default_host=(host)
10
- @default_host = host
11
- add_default_links
13
+ alias :sitemap_files :sitemaps
14
+
15
+ # Create new link set instance.
16
+ def initialize
17
+ self.links = []
18
+ self.sitemaps = []
19
+ self.max_entries = SitemapGenerator::MAX_ENTRIES
20
+ self.link_count = 0
12
21
  end
13
22
 
23
+ # Add default links to sitemap files.
14
24
  def add_default_links
15
- # Add default links
16
- @links << Link.generate('/', :lastmod => Time.now, :changefreq => 'always', :priority => 1.0)
17
- @links << Link.generate('/sitemap_index.xml.gz', :lastmod => Time.now, :changefreq => 'always', :priority => 1.0)
25
+ links.push Link.generate('/', :lastmod => Time.now, :changefreq => 'always', :priority => 1.0)
26
+ links.push Link.generate("/#{index_file}", :lastmod => Time.now, :changefreq => 'always', :priority => 1.0)
27
+ self.link_count += 2
18
28
  end
19
-
29
+
30
+ # Add links to sitemap files passing a block.
20
31
  def add_links
32
+ raise ArgumentError, "Default hostname not set" if default_host.blank?
33
+ add_default_links if first_link?
21
34
  yield Mapper.new(self)
22
35
  end
23
-
36
+
37
+ # Add links from mapper to sitemap files.
24
38
  def add_link(link)
25
- @links << link
39
+ write_upcoming if enough_links?
40
+ links.push link
41
+ self.link_count += 1
42
+ end
43
+
44
+ # Write links to sitemap file.
45
+ def write
46
+ write_pending
47
+ end
48
+
49
+ # Write links to upcoming sitemap file.
50
+ def write_upcoming
51
+ write_sitemap(upcoming_file)
52
+ end
53
+
54
+ # Write pending links to sitemap, write index file if needed.
55
+ def write_pending
56
+ write_upcoming
57
+ write_index
58
+ end
59
+
60
+ # Write links to sitemap file.
61
+ def write_sitemap(file = upcoming_file)
62
+ buffer = ""
63
+ xml = Builder::XmlMarkup.new(:target => buffer)
64
+ eval(File.read(SitemapGenerator.templates[:sitemap_xml]), binding)
65
+ filename = File.join(RAILS_ROOT, "public", file)
66
+ write_file(filename, buffer)
67
+ show_progress("Sitemap", filename, buffer) if verbose
68
+ links.clear
69
+ sitemaps.push filename
70
+ end
71
+
72
+ # Write sitemap links to sitemap index file.
73
+ def write_index
74
+ buffer = ""
75
+ xml = Builder::XmlMarkup.new(:target => buffer)
76
+ eval(File.read(SitemapGenerator.templates[:sitemap_index]), binding)
77
+ filename = File.join(RAILS_ROOT, "public", index_file)
78
+ write_file(filename, buffer)
79
+ show_progress("Sitemap Index", filename, buffer) if verbose
80
+ links.clear
81
+ sitemaps.clear
82
+ end
83
+
84
+ # Return sitemap or sitemap index main name.
85
+ def index_file
86
+ "sitemap_index.xml.gz"
87
+ end
88
+
89
+ # Return upcoming sitemap name with index.
90
+ def upcoming_file
91
+ "sitemap#{upcoming_index}.xml.gz" unless enough_sitemaps?
92
+ end
93
+
94
+ # Return upcoming sitemap index, first is 1.
95
+ def upcoming_index
96
+ sitemaps.length + 1 unless enough_sitemaps?
97
+ end
98
+
99
+ # Return true if upcoming is first sitemap.
100
+ def first_sitemap?
101
+ sitemaps.empty?
102
+ end
103
+
104
+ # Return true if sitemap index needed.
105
+ def multiple_sitemaps?
106
+ !first_sitemap?
107
+ end
108
+
109
+ # Return true if more sitemaps can be added.
110
+ def more_sitemaps?
111
+ sitemaps.length < max_entries
112
+ end
113
+
114
+ # Return true if no sitemaps can be added.
115
+ def enough_sitemaps?
116
+ !more_sitemaps?
117
+ end
118
+
119
+ # Return true if this is the first link added.
120
+ def first_link?
121
+ links.empty? && first_sitemap?
122
+ end
123
+
124
+ # Return true if more links can be added.
125
+ def more_links?
126
+ links.length < max_entries
127
+ end
128
+
129
+ # Return true if no further links can be added.
130
+ def enough_links?
131
+ !more_links?
132
+ end
133
+
134
+ # Commit buffer to gzipped file.
135
+ def write_file(name, buffer)
136
+ Zlib::GzipWriter.open(name) { |gz| gz.write buffer }
137
+ end
138
+
139
+ # Report progress line.
140
+ def show_progress(title, filename, buffer)
141
+ puts "+ #{filename}"
142
+ puts "** #{title} too big! The uncompressed size exceeds 10Mb" if buffer.size > 10.megabytes
143
+ end
144
+
145
+ # Copy templates/sitemap.rb to config if not there yet.
146
+ def install_sitemap_rb
147
+ if File.exist?(File.join(RAILS_ROOT, 'config/sitemap.rb'))
148
+ puts "already exists: config/sitemap.rb, file not copied"
149
+ else
150
+ FileUtils.cp(SitemapGenerator.templates[:sitemap_sample], File.join(RAILS_ROOT, 'config/sitemap.rb'))
151
+ puts "created: config/sitemap.rb"
152
+ end
153
+ end
154
+
155
+ # Remove config/sitemap.rb if exists.
156
+ def uninstall_sitemap_rb
157
+ if File.exist?(File.join(RAILS_ROOT, 'config/sitemap.rb'))
158
+ File.rm(File.join(RAILS_ROOT, 'config/sitemap.rb'))
159
+ end
160
+ end
161
+
162
+ # Clean sitemap files in output directory.
163
+ def clean_files
164
+ FileUtils.rm(Dir[File.join(RAILS_ROOT, 'public/sitemap*.xml.gz')])
165
+ end
166
+
167
+ # Ping search engines passing sitemap location.
168
+ def ping_search_engines
169
+ super index_file
170
+ end
171
+
172
+ # Create sitemap files in output directory.
173
+ def create_files(verbose = true)
174
+ start_time = Time.now
175
+ load_sitemap_rb
176
+ write
177
+ stop_time = Time.now
178
+ puts "Sitemap stats: #{number_with_delimiter(SitemapGenerator::Sitemap.link_count)} links, " + ("%dm%02ds" % (stop_time - start_time).divmod(60)) if verbose
26
179
  end
27
180
  end
28
- end
181
+ end
@@ -1,12 +1,2 @@
1
1
  # Install hook code here
2
-
3
- # Copy sitemap_template.rb to config/sitemap.rb
4
- require 'fileutils'
5
- sitemap_template = File.join(File.dirname(__FILE__), '../templates/sitemap.rb')
6
- new_sitemap = File.join(RAILS_ROOT, 'config/sitemap.rb')
7
- if File.exist?(new_sitemap)
8
- puts "already exists: config/sitemap.rb, file not copied"
9
- else
10
- puts "created: config/sitemap.rb"
11
- FileUtils.cp(sitemap_template, new_sitemap)
12
- end
2
+ SitemapGenerator::Sitemap.install_sitemap_rb
@@ -1,4 +1,2 @@
1
1
  # Uninstall hook code here
2
-
3
- new_sitemap = File.join(RAILS_ROOT, 'config/sitemap.rb')
4
- File.rm(new_sitemap) if File.exist?(new_sitemap)
2
+ SitemapGenerator::Sitemap.uninstall_sitemap_rb
@@ -1,96 +1,26 @@
1
1
  require 'zlib'
2
- require 'sitemap_generator/helper'
3
-
4
- class SiteMapRefreshTask < Rake::Task
5
- include SitemapGenerator::Helper
6
-
7
- def execute(*)
8
- super
9
- ping_search_engines("sitemap_index.xml.gz")
10
- end
11
- end
12
-
13
- class SiteMapCreateTask < Rake::Task
14
- include SitemapGenerator::Helper
15
- include ActionView::Helpers::NumberHelper
16
-
17
- def execute(*)
18
- super
19
- build_files
20
- end
21
-
22
- private
23
- def build_files
24
- start_time = Time.now
25
-
26
- # update links from config/sitemap.rb
27
- load_sitemap_rb
28
-
29
- raise(ArgumentError, "Default hostname not defined") if SitemapGenerator::Sitemap.default_host.blank?
30
-
31
- links_grps = SitemapGenerator::Sitemap.links.in_groups_of(50_000, false)
32
- raise(ArgumentError, "TOO MANY LINKS!! I really thought 2,500,000,000 links would be enough for anybody!") if links_grps.length > 50000
33
-
34
- Rake::Task['sitemap:clean'].invoke
35
-
36
- # render individual sitemaps
37
- sitemap_files = render_sitemap(links_grps)
38
-
39
- # render index
40
- render_index(sitemap_files)
41
-
42
- stop_time = Time.now
43
- puts "Sitemap stats: #{number_with_delimiter(SitemapGenerator::Sitemap.links.length)} links, " + ("%dm%02ds" % (stop_time - start_time).divmod(60)) if verbose
44
- end
45
-
46
- def render_sitemap(links_grps)
47
- sitemap_files = []
48
- links_grps.each_with_index do |links, index|
49
- buffer = ''
50
- xml = Builder::XmlMarkup.new(:target=>buffer)
51
- eval(open(SitemapGenerator.templates[:sitemap_xml]).read, binding)
52
- filename = File.join(RAILS_ROOT, "public/sitemap#{index+1}.xml.gz")
53
- Zlib::GzipWriter.open(filename) do |gz|
54
- gz.write buffer
55
- end
56
- sitemap_files << filename
57
- puts "+ #{filename}" if verbose
58
- puts "** Sitemap too big! The uncompressed size exceeds 10Mb" if (buffer.size > 10 * 1024 * 1024) && verbose
59
- end
60
- sitemap_files
61
- end
62
-
63
- def render_index(sitemap_files)
64
- buffer = ''
65
- xml = Builder::XmlMarkup.new(:target=>buffer)
66
- eval(open(SitemapGenerator.templates[:sitemap_index]).read, binding)
67
- filename = File.join(RAILS_ROOT, "public/sitemap_index.xml.gz")
68
- Zlib::GzipWriter.open(filename) do |gz|
69
- gz.write buffer
70
- end
71
-
72
- puts "+ #{filename}" if verbose
73
- puts "** Sitemap Index too big! The uncompressed size exceeds 10Mb" if (buffer.size > 10 * 1024 * 1024) && verbose
74
- end
75
- end
2
+ require 'sitemap_generator'
76
3
 
77
4
  namespace :sitemap do
78
5
  desc "Install a default config/sitemap.rb file"
79
6
  task :install do
80
- load File.expand_path(File.join(File.dirname(__FILE__), "../rails/install.rb"))
7
+ SitemapGenerator::Sitemap.install_sitemap_rb
81
8
  end
82
9
 
83
10
  desc "Delete all Sitemap files in public/ directory"
84
11
  task :clean do
85
- sitemap_files = Dir[File.join(RAILS_ROOT, 'public/sitemap*.xml.gz')]
86
- FileUtils.rm sitemap_files
12
+ SitemapGenerator::Sitemap.clean_files
87
13
  end
88
14
 
89
15
  desc "Create Sitemap XML files in public/ directory (rake -s for no output)"
90
- SiteMapRefreshTask.define_task :refresh => ['sitemap:create']
16
+ task :refresh => ['sitemap:create'] do
17
+ SitemapGenerator::Sitemap.ping_search_engines
18
+ end
91
19
 
92
20
  desc "Create Sitemap XML files (don't ping search engines)"
93
21
  task 'refresh:no_ping' => ['sitemap:create']
94
22
 
95
- SiteMapCreateTask.define_task :create => [:environment]
23
+ task :create => [:environment] do
24
+ SitemapGenerator::Sitemap.create_files
25
+ end
96
26
  end