Rorra's blog Senior Developer

January 30, 2012

Updating sitemap_generator to upload your files to s3 with aws-s3 and aws-sdk

Filed under: Ruby — admin @ 4:35 AM

Recently I had to do a job where I was suppose to either find a gem that was able to generate sitemaps in rails 3 and upload it to S3, or update the current behavior of the gem sitemap_generator (which is a great gem), so I ended updated the behavior of the gem.

The gem already supports uploads to S3, but the problem is that it ask you to install carrierwave, and if you are already using paperclip, aws-s3 and aws-sdk, that’s not the best way to go, so what I did was to enhance the rake tasks of the gem in order to add behavior for the S3 upload and notification to the different search engines as well.

You can check my code in this here: https://gist.github.com/1693860

Something important is to add this line of code to your file config/sitemap.rb

SitemapGenerator::Sitemap.public_path = File.join(Rails.root, "public", "system", "sitemaps").to_s

And here’s the code

require 'aws'

class Rake::Task
  def replace &block
    @actions.clear
    prerequisites.clear
    enhance &block
  end
end

namespace 'sitemap' do
  desc 'Upload the sitemap files to S3 (using your configuration in config/s3.yml)'
  task :upload_to_s3 => :environment do
    if File.exist?(File.join(Rails.root, "config", "s3.yml"))

      # Load credentials
      s3_options = YAML.load_file(File.join(Rails.root, "config", "s3.yml"))[Rails.env].symbolize_keys
      bucket_name = s3_options[:bucket]
      s3_options.delete(:bucket)

      # Establish S3 connection
      AWS.config(s3_options)

      Dir.entries(File.join(Rails.root, "public", "system", "sitemaps")).each do |file_name|
        next if ['.', '..'].include? file_name
        path = "sitemaps/#{file_name}"
        file = File.join(Rails.root, "public", "system", "sitemaps", file_name)

        begin
          s3 = AWS::S3.new
          bucket = s3.buckets.create(bucket_name)


          object = bucket.objects[path]
          object.write(:file => file)
        rescue Exception => e
          raise
        end
        puts "Saved #{file_name} to S3"
      end
    end
  end
end

Rake::Task["sitemap:create"].enhance do
  Rake::Task["sitemap:upload_to_s3"].invoke
end

Rake::Task[:'sitemap:refresh'].replace do
  if File.exist?(File.join(Rails.root, "config", "s3.yml"))
    s3_options = YAML.load_file(File.join(Rails.root, "config", "s3.yml"))[Rails.env].symbolize_keys
    bucket_name = s3_options[:bucket]
    SitemapGenerator::Sitemap.ping_search_engines(:sitemap_index_url => "https://#{bucket_name}.s3.amazonaws.com/sitemaps/sitemap_index.xml.gz")
  else
    SitemapGenerator::Sitemap.ping_search_engines
  end
end

Powered by WordPress