class Statixite::CloudSync
Public Class Methods
new(site, container_name)
click to toggle source
# File lib/statixite/cloud_sync.rb, line 4 def initialize(site, container_name) @fog_client = Fog::Storage.new(Statixite.config.fog_credentials) @site = site @site_directory = @site.site_build_path @container_name = container_name @cloud_directory = @fog_client.directories.find{|d| d.key == @container_name} if @cloud_directory.nil? @cloud_directory = @fog_client.directories.create :key => @container_name, :public => true case Statixite.config.fog_credentials[:provider] when 'AWS' @fog_client.put_bucket_website(@container_name, IndexDocument: "index.html", ErrorDocument: "404.html") @fog_client.put_bucket_policy(@container_name, { "Statement" => [ { "Sid" => "PublicReadGetObject", "Effect" => "Allow", "Principal" => "*", "Action" => "s3:GetObject", "Resource" => "arn:aws:s3:::#{@container_name}/*" } ] } ) when 'Rackspace' @cloud_directory.metadata[:web_index] = "index.html" @cloud_directory.metadata[:web_error] = "error.html" end end if @site.hostname.nil? && @cloud_directory.public_url.present? case Statixite.config.fog_credentials[:provider] when 'AWS' @site.hostname = "#{@container_name}.s3-website-#{@fog_client.region}.amazonaws.com" when 'Rackspace' @site.hostname = URI(@cloud_directory.public_url).host end @site.save end end
Public Instance Methods
sync()
click to toggle source
# File lib/statixite/cloud_sync.rb, line 43 def sync g = Git.open(@site.site_build_path, :log => Rails.logger) g.checkout('statixite_build') site_files = Dir.glob(File.join(@site_directory, "**/*")).reject{|f| File.directory?(f) || f.match(File.join(@site_directory, ".git")) } site_files_set = Set.new(site_files.collect{|f| f.gsub(/^#{@site_directory}\//,"")}) site_files_hash = site_files_set.to_a.collect{|f| [f, Digest::MD5.hexdigest(File.read(File.join(@site_directory, f)))]}.inject({}) { |r, s| r.merge!({s[0] => s[1]}) } cloud_files = Statixite.config.fog_credentials[:provider] == 'Rackspace' ? @cloud_directory.files.reject{|f| f.content_type.include?("/directory")} : @cloud_directory.files cloud_files_hash = cloud_files.collect{|f| [f.key, f]}.inject({}) { |r, s| r.merge!({s[0] => s[1]}) } cloud_files_set = Set.new(cloud_files_hash.keys) to_delete_set = cloud_files_set - site_files_set to_delete = cloud_files_hash.select { |key,_| to_delete_set.include? key } # threaded_run(to_delete, 'destroy') to_delete.each do |name, file| file.destroy end to_create = site_files_hash.select { |name, _| !cloud_files_set.include?(name) } # threaded_run(to_create, 'create') to_create.each do |name, hash| @cloud_directory.files.create :key => name, :body => File.open(File.join(@site_directory, name)), :public => true end to_update = site_files_hash.select do |name, md5| cloud_files_set.include?(name) && cloud_files_hash[name].etag != md5 end # threaded_run!(to_update, 'update') to_update.each do |name, hash| @cloud_directory.files.create :key => name, :body => File.open(File.join(@site_directory, name)), :public => true end if(to_delete.size + to_create.size + to_update.size > 0) Rails.logger.info "------------" Rails.logger.info "Changes: " Rails.logger.info to_delete_set.to_a.collect{|f| " D #{f}"}.join("\n") if to_delete.size > 0 Rails.logger.info to_create.collect{|f, _| " A #{f}"}.join("\n") if to_create.size > 0 Rails.logger.info to_update.collect{|f, _| " M #{f}"}.join("\n") if to_update.size > 0 end end
Private Instance Methods
threaded_run!(files, change)
click to toggle source
todo improve speed
# File lib/statixite/cloud_sync.rb, line 93 def threaded_run!(files, change) return if files.empty? file_number = 0 total_files = files.length mutex = Mutex.new threads = [] 5.times do |i| threads[i] = Thread.new { until files.empty? mutex.synchronize do file_number += 1 Thread.current["file_number"] = file_number end file = files.pop rescue nil next unless file Rails.logger.info "[#{Thread.current["file_number"]}/#{total_files}] to #{change}..." case change when 'destroy' when 'create' when 'update' end end } end threads.each { |t| t.join } end