Class: Ungulate::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/ungulate/job.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeJob

Returns a new instance of Job.



34
35
36
37
# File 'lib/ungulate/job.rb', line 34

def initialize
  @logger = Ungulate::Server.logger
  self.versions = []
end

Instance Attribute Details

#bucketObject

Returns the value of attribute bucket.



11
12
13
# File 'lib/ungulate/job.rb', line 11

def bucket
  @bucket
end

#keyObject

Returns the value of attribute key.



11
12
13
# File 'lib/ungulate/job.rb', line 11

def key
  @key
end

#notification_urlObject

Returns the value of attribute notification_url.



11
12
13
# File 'lib/ungulate/job.rb', line 11

def notification_url
  @notification_url
end

#queueObject

Returns the value of attribute queue.



11
12
13
# File 'lib/ungulate/job.rb', line 11

def queue
  @queue
end

#versionsObject

Returns the value of attribute versions.



11
12
13
# File 'lib/ungulate/job.rb', line 11

def versions
  @versions
end

Class Method Details

.pop(queue_name) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/ungulate/job.rb', line 25

def self.pop(queue_name)
  job = new
  job.queue = sqs.queue queue_name
  message = job.queue.pop
  attributes = YAML.load message.to_s
  job.attributes = attributes if attributes
  job
end

.s3Object



13
14
15
16
17
# File 'lib/ungulate/job.rb', line 13

def self.s3
  @s3 ||=
    RightAws::S3.new(ENV['AMAZON_ACCESS_KEY_ID'],
                     ENV['AMAZON_SECRET_ACCESS_KEY'])
end

.sqsObject



19
20
21
22
23
# File 'lib/ungulate/job.rb', line 19

def self.sqs
  @sqs ||= 
    RightAws::SqsGen2.new(ENV['AMAZON_ACCESS_KEY_ID'],
                          ENV['AMAZON_SECRET_ACCESS_KEY'])
end

Instance Method Details

#attributes=(options) ⇒ Object



39
40
41
42
43
44
# File 'lib/ungulate/job.rb', line 39

def attributes=(options)
  self.bucket = Job.s3.bucket(options[:bucket])
  self.key = options[:key]
  self.notification_url = options[:notification_url]
  self.versions = options[:versions]
end

#image_from_instruction(original, instruction) ⇒ Object



65
66
67
68
69
70
71
72
73
74
# File 'lib/ungulate/job.rb', line 65

def image_from_instruction(original, instruction)
  method, *args = instruction
  send_args = instruction_args(args)

  @logger.info "Performing #{method} with #{args.join(', ')}"
  original.send(method, *send_args).tap do |new_image|
    original.destroy!
    send_args.select {|arg| arg.is_a?(Magick::Image)}.each(&:destroy!)
  end
end

#image_from_instruction_chain(original, chain) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/ungulate/job.rb', line 76

def image_from_instruction_chain(original, chain)
  if chain.one?
    image_from_instruction(original, chain.first)
  else
    image_from_instruction_chain(
      image_from_instruction(original, chain.shift),
      chain
    )
  end
end

#instruction_args(args) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ungulate/job.rb', line 53

def instruction_args(args)
  args.map do |arg|
    if arg.is_a?(Symbol)
      "Magick::#{arg.to_s.classify}".constantize
    elsif arg.respond_to?(:match) && arg.match(/^http/)
      Magick::Image.from_blob(Curl::Easy.http_get(arg).body_str).first
    else
      arg
    end
  end
end

#processObject



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/ungulate/job.rb', line 108

def process
  return false if processed_versions.empty?

  processed_versions.each do |version, image|
    version_key = version_key version
    @logger.info "Storing #{version} @ #{version_key}"
    bucket.put(
      version_key, 
      image.to_blob, 
      {},
      'public-read',
      {
        'Content-Type' => MIME::Types.type_for(image.format).to_s,
        # expire in about one month: refactor to grab from job description
        'Cache-Control' => 'max-age=2629743',
      }
    )
    image.destroy!
  end

  send_notification

  true
end

#processed_image(original, instruction) ⇒ Object



87
88
89
90
91
92
93
# File 'lib/ungulate/job.rb', line 87

def processed_image(original, instruction)
  if instruction.first.respond_to?(:entries)
    image_from_instruction_chain(original, instruction)
  else
    image_from_instruction(original, instruction)
  end
end

#processed_versionsObject



46
47
48
49
50
51
# File 'lib/ungulate/job.rb', line 46

def processed_versions
  @processed_versions ||=
    versions.map do |name, instruction|
      [name, processed_image(source_image, instruction)]
    end
end

#send_notificationObject



133
134
135
136
137
138
# File 'lib/ungulate/job.rb', line 133

def send_notification
  return false if notification_url.blank?

  @logger.info "Sending notification to #{notification_url}"
  Curl::Easy.http_put(notification_url, '')
end

#sourceObject



99
100
101
102
103
104
105
106
# File 'lib/ungulate/job.rb', line 99

def source
  if @source
    @source
  else
    @logger.info "Grabbing source image #{key}"
    @source = bucket.get key
  end
end

#source_imageObject



95
96
97
# File 'lib/ungulate/job.rb', line 95

def source_image
  Magick::Image.from_blob(source).first
end

#version_key(version) ⇒ Object



140
141
142
143
144
145
# File 'lib/ungulate/job.rb', line 140

def version_key(version)
  dirname = File.dirname(key)
  extname = File.extname(key)
  basename = File.basename(key, extname)
  "#{dirname}/#{basename}_#{version}#{extname}".sub(/^\.\//, '')
end