Class: Middleman::S3Sync::Resource

Inherits:
Object
  • Object
show all
Includes:
Status
Defined in:
lib/middleman/s3_sync/resource.rb

Constant Summary collapse

CONTENT_MD5_KEY =
'x-amz-meta-content-md5'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Status

#say_status

Constructor Details

#initialize(resource, partial_s3_resource) ⇒ Resource

Returns a new instance of Resource.



10
11
12
13
14
# File 'lib/middleman/s3_sync/resource.rb', line 10

def initialize(resource, partial_s3_resource)
  @resource = resource
  @path = resource ? resource.destination_path : partial_s3_resource.key
  @partial_s3_resource = partial_s3_resource
end

Instance Attribute Details

#content_typeObject

Returns the value of attribute content_type.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def content_type
  @content_type
end

#full_s3_resourceObject

S3 resource as returned by a HEAD request



21
22
23
# File 'lib/middleman/s3_sync/resource.rb', line 21

def full_s3_resource
  @full_s3_resource
end

#gzippedObject

Returns the value of attribute gzipped.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def gzipped
  @gzipped
end

#options=(value) ⇒ Object

Sets the attribute options

Parameters:

  • value

    the value to set the attribute options to.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def options=(value)
  @options = value
end

#partial_s3_resourceObject

Returns the value of attribute partial_s3_resource.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def partial_s3_resource
  @partial_s3_resource
end

#pathObject

Returns the value of attribute path.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def path
  @path
end

#resourceObject

Returns the value of attribute resource.



4
5
6
# File 'lib/middleman/s3_sync/resource.rb', line 4

def resource
  @resource
end

Instance Method Details

#alternate_encoding?Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/middleman/s3_sync/resource.rb', line 109

def alternate_encoding?
  status == :alternate_encoding
end

#caching_policyObject



217
218
219
# File 'lib/middleman/s3_sync/resource.rb', line 217

def caching_policy
  @caching_policy ||= Middleman::S3Sync.caching_policy_for(content_type)
end

#caching_policy_match?Boolean

Returns:

  • (Boolean)


221
222
223
224
225
226
227
# File 'lib/middleman/s3_sync/resource.rb', line 221

def caching_policy_match?
  if (caching_policy)
    caching_policy.cache_control == full_s3_resource.cache_control
  else
    true
  end
end

#create!Object



83
84
85
86
87
88
# File 'lib/middleman/s3_sync/resource.rb', line 83

def create!
  say_status "#{ANSI.green{"Creating"}} #{remote_path}#{ gzipped ? ANSI.white {' (gzipped)'} : ''}"
  local_content { |body|
    bucket.files.create(to_h.merge(body: body)) unless options.dry_run
  }
end

#destroy!Object



78
79
80
81
# File 'lib/middleman/s3_sync/resource.rb', line 78

def destroy!
  say_status "#{ANSI.red{"Deleting"}} #{remote_path}"
  bucket.files.destroy remote_path unless options.dry_run
end

#directory?Boolean

Returns:

  • (Boolean)


180
181
182
# File 'lib/middleman/s3_sync/resource.rb', line 180

def directory?
  File.directory?(local_path)
end

#encoding_match?Boolean

Returns:

  • (Boolean)


192
193
194
# File 'lib/middleman/s3_sync/resource.rb', line 192

def encoding_match?
  (options.prefer_gzip && gzipped && full_s3_resource.content_encoding == 'gzip') || (!options.prefer_gzip && !gzipped && !full_s3_resource.content_encoding )
end

#identical?Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/middleman/s3_sync/resource.rb', line 113

def identical?
  status == :identical
end

#ignore!Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/middleman/s3_sync/resource.rb', line 90

def ignore!
  if options.verbose
    reason = if redirect?
               :redirect
             elsif directory?
               :directory
             end
    say_status "#{ANSI.yellow{"Ignoring"}} #{remote_path} #{ reason ? ANSI.white {"(#{reason})" } : "" }"
  end
end

#local?Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/middleman/s3_sync/resource.rb', line 168

def local?
  File.exist?(local_path) && resource
end

#local_content(&block) ⇒ Object



125
126
127
# File 'lib/middleman/s3_sync/resource.rb', line 125

def local_content(&block)
  File.open(local_path, &block)
end

#local_content_md5Object



204
205
206
# File 'lib/middleman/s3_sync/resource.rb', line 204

def local_content_md5
  @local_content_md5 ||= Digest::MD5.hexdigest(File.read(original_path))
end

#local_object_md5Object



200
201
202
# File 'lib/middleman/s3_sync/resource.rb', line 200

def local_object_md5
  @local_object_md5 ||= Digest::MD5.hexdigest(File.read(local_path))
end

#local_pathObject



69
70
71
72
73
74
75
76
# File 'lib/middleman/s3_sync/resource.rb', line 69

def local_path
  local_path = build_dir + '/' + path.gsub(/^#{options.prefix}/, '')
  if options.prefer_gzip && File.exist?(local_path + ".gz")
    @gzipped = true
    local_path += ".gz"
  end
  local_path
end

#original_pathObject



208
209
210
# File 'lib/middleman/s3_sync/resource.rb', line 208

def original_path
  gzipped ? local_path.gsub(/\.gz$/, '') : local_path
end

#redirect?Boolean

Returns:

  • (Boolean)


176
177
178
# File 'lib/middleman/s3_sync/resource.rb', line 176

def redirect?
  full_s3_resource && full_s3_resource..has_key?('x-amz-website-redirect-location')
end

#relative_pathObject



184
185
186
# File 'lib/middleman/s3_sync/resource.rb', line 184

def relative_path
  @relative_path ||= local_path.gsub(/#{build_dir}/, '')
end

#remote?Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/middleman/s3_sync/resource.rb', line 172

def remote?
  !!s3_resource
end

#remote_content_md5Object



196
197
198
# File 'lib/middleman/s3_sync/resource.rb', line 196

def remote_content_md5
  full_s3_resource.[CONTENT_MD5_KEY]
end

#remote_object_md5Object



188
189
190
# File 'lib/middleman/s3_sync/resource.rb', line 188

def remote_object_md5
  s3_resource.etag
end

#remote_pathObject Also known as: key



25
26
27
# File 'lib/middleman/s3_sync/resource.rb', line 25

def remote_path
  s3_resource ? s3_resource.key : "#{options.prefix}#{path}"
end

#s3_resourceObject



16
17
18
# File 'lib/middleman/s3_sync/resource.rb', line 16

def s3_resource
  @full_s3_resource || @partial_s3_resource
end

#statusObject



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/middleman/s3_sync/resource.rb', line 129

def status
  @status ||= if directory?
                if remote?
                  :deleted
                else
                  :ignored
                end
              elsif local? && remote?
                if options.force
                  :updated
                elsif not caching_policy_match?
                  :updated
                elsif local_object_md5 == remote_object_md5
                  :identical
                else
                  if !gzipped
                    # we're not gzipped, object hashes being different indicates updated content
                    :updated
                  elsif !encoding_match? || local_content_md5 != remote_content_md5
                    # we're gzipped, so we checked the content MD5, and it also changed
                    :updated
                  else
                    # we're gzipped, the object hashes differ, but the content hashes are equal
                    # this means the gzipped bits changed while the original bits did not
                    # what's more, we spent a HEAD request to find out
                    :alternate_encoding
                  end
                end
              elsif local?
                :new
              elsif remote? && redirect?
                :ignored
              elsif remote?
                :deleted
              else
                :ignored
              end
end

#to_create?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/middleman/s3_sync/resource.rb', line 105

def to_create?
  status == :new
end

#to_delete?Boolean

Returns:

  • (Boolean)


101
102
103
# File 'lib/middleman/s3_sync/resource.rb', line 101

def to_delete?
  status == :deleted
end

#to_hObject Also known as: attributes



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/middleman/s3_sync/resource.rb', line 30

def to_h
  attributes = {
    :key => key,
    :acl => options.acl,
    :content_type => content_type,
    CONTENT_MD5_KEY => local_content_md5
  }

  if caching_policy
    attributes[:cache_control] = caching_policy.cache_control
    attributes[:expires] = caching_policy.expires
  end

  if options.prefer_gzip && gzipped
    attributes[:content_encoding] = "gzip"
  end

  if options.reduced_redundancy_storage
    attributes[:storage_class] = 'REDUCED_REDUNDANCY'
  end

  if options.encryption
    attributes[:encryption] = 'AES256'
  end

  attributes
end

#to_ignore?Boolean

Returns:

  • (Boolean)


121
122
123
# File 'lib/middleman/s3_sync/resource.rb', line 121

def to_ignore?
  status == :ignored || status == :alternate_encoding
end

#to_update?Boolean

Returns:

  • (Boolean)


117
118
119
# File 'lib/middleman/s3_sync/resource.rb', line 117

def to_update?
  status == :updated
end

#update!Object



59
60
61
62
63
64
65
66
67
# File 'lib/middleman/s3_sync/resource.rb', line 59

def update!
  local_content { |body|
    say_status "#{ANSI.blue{"Updating"}} #{remote_path}#{ gzipped ? ANSI.white {' (gzipped)'} : ''}"
    s3_resource.merge_attributes(to_h)
    s3_resource.body = body

    s3_resource.save unless options.dry_run
  }
end