2017-01-11 08:27:06 -07:00
|
|
|
require "open-uri"
|
2018-05-04 10:36:43 -06:00
|
|
|
# A set of image URLs (thumbs) + Associated meta data.
|
2017-01-10 21:31:05 -07:00
|
|
|
class Image < ApplicationRecord
|
2017-01-11 08:27:06 -07:00
|
|
|
belongs_to :device
|
2019-07-20 15:33:05 -06:00
|
|
|
validates :device, presence: true
|
|
|
|
serialize :meta
|
2018-03-18 09:23:00 -06:00
|
|
|
|
2017-01-11 13:22:12 -07:00
|
|
|
# http://stackoverflow.com/a/5127684/1064917
|
|
|
|
after_initialize :set_defaults
|
|
|
|
|
|
|
|
def set_defaults
|
|
|
|
self.meta ||= {}
|
|
|
|
end
|
2017-01-11 08:27:06 -07:00
|
|
|
|
2018-12-30 11:04:24 -07:00
|
|
|
PLACEHOLDER = "/placeholder_farmbot.jpg\?text=Processing..."
|
2019-07-20 15:33:05 -06:00
|
|
|
PROTO = ENV["FORCE_SSL"] ? "https:" : "http:"
|
|
|
|
DEFAULT_URL = "#{PROTO}#{$API_URL}#{PLACEHOLDER}"
|
|
|
|
RMAGICK_STYLES = {
|
|
|
|
x1280: "1280x1280>",
|
|
|
|
x640: "640x640>",
|
|
|
|
x320: "320x320>",
|
|
|
|
x160: "160x160>",
|
|
|
|
x80: "80x80>",
|
2017-04-14 07:30:24 -06:00
|
|
|
}
|
2019-07-20 15:33:05 -06:00
|
|
|
MAX_IMAGE_SIZE = 7.megabytes
|
|
|
|
CONFIG = { default_url: DEFAULT_URL,
|
|
|
|
styles: RMAGICK_STYLES,
|
|
|
|
size: { in: 0..MAX_IMAGE_SIZE } }
|
|
|
|
BUCKET = ENV["GCS_BUCKET"]
|
2019-07-22 16:24:40 -06:00
|
|
|
|
|
|
|
ROOT_PATH = BUCKET ?
|
|
|
|
"https://#{BUCKET}.storage.googleapis.com" : "/system"
|
|
|
|
IMAGE_URL_TPL =
|
|
|
|
ROOT_PATH + "/images/attachments/%{chunks}/%{size}/%{filename}?%{timestamp}"
|
|
|
|
|
2019-07-20 15:33:05 -06:00
|
|
|
CONTENT_TYPES = ["image/jpg", "image/jpeg", "image/png", "image/gif"]
|
|
|
|
GCS_ACCESS_KEY_ID = ENV.fetch("GCS_KEY") { puts "Not using Google Cloud" }
|
|
|
|
GCS_HOST = "http://#{BUCKET}.storage.googleapis.com"
|
|
|
|
GCS_SECRET_ACCESS_KEY = ENV.fetch("GCS_ID") { puts "Not using Google Cloud" }
|
|
|
|
# Worst case scenario for 1280x1280 BMP.
|
|
|
|
GCS_BUCKET_NAME = ENV["GCS_BUCKET"]
|
2017-04-14 07:30:24 -06:00
|
|
|
|
2019-07-22 13:09:40 -06:00
|
|
|
has_one_attached :attachment
|
2017-01-11 09:07:34 -07:00
|
|
|
|
2017-01-11 08:27:06 -07:00
|
|
|
def set_attachment_by_url(url)
|
2020-01-03 08:31:48 -07:00
|
|
|
attachment.attach(io: URI.open(url), filename: "image_#{self.id}")
|
2017-01-11 09:07:34 -07:00
|
|
|
self.attachment_processed_at = Time.now
|
2017-01-11 08:27:06 -07:00
|
|
|
self
|
|
|
|
end
|
2018-06-13 07:36:46 -06:00
|
|
|
|
|
|
|
# Scenario:
|
|
|
|
# User clicks "take photo" and "delete" on Image#123 very quickly.
|
|
|
|
# Problem:
|
|
|
|
# Now there's a Delayed::Job pointing to (nonexistent) Image#123,
|
2019-02-19 19:10:08 -07:00
|
|
|
# causing runtime errors in the work queue.
|
2018-06-13 07:36:46 -06:00
|
|
|
# Solution:
|
|
|
|
# Don't retry failed deletions. Users can always click the "delete"
|
|
|
|
# button again if need be.
|
|
|
|
def self.maybe_destroy(id)
|
|
|
|
image = find_by(id: id)
|
|
|
|
image.destroy! if image
|
|
|
|
end
|
2019-07-20 15:33:05 -06:00
|
|
|
|
2019-07-25 12:10:06 -06:00
|
|
|
def legacy_image?
|
|
|
|
!!self.attachment_file_size # This is a now-unused legacy field.
|
|
|
|
end
|
|
|
|
|
|
|
|
def regular_image?
|
2019-10-28 08:23:12 -06:00
|
|
|
attachment && attachment.attached?
|
2019-07-25 12:10:06 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def regular_url
|
2019-07-25 16:58:05 -06:00
|
|
|
if BUCKET
|
|
|
|
# Not sure why. TODO: Investigate why Rails URL helpers don't work here.
|
2019-07-26 13:34:29 -06:00
|
|
|
"https://storage.googleapis.com/#{BUCKET}/#{attachment.key}"
|
2019-07-25 16:58:05 -06:00
|
|
|
else
|
|
|
|
Rails
|
|
|
|
.application
|
|
|
|
.routes
|
|
|
|
.url_helpers
|
2019-07-26 07:29:28 -06:00
|
|
|
.rails_blob_url(attachment)
|
2019-07-25 16:58:05 -06:00
|
|
|
end
|
2019-07-25 12:10:06 -06:00
|
|
|
end
|
|
|
|
|
|
|
|
def legacy_url(size)
|
|
|
|
url = IMAGE_URL_TPL % {
|
|
|
|
chunks: id.to_s.rjust(9, "0").scan(/.{3}/).join("/"),
|
|
|
|
filename: attachment_file_name,
|
|
|
|
size: size,
|
|
|
|
timestamp: attachment_updated_at.to_i,
|
|
|
|
}
|
|
|
|
return ENV["GCS_KEY"].present? ? url.gsub("http://", "https://") : url
|
|
|
|
end
|
|
|
|
|
2019-07-20 15:33:05 -06:00
|
|
|
def attachment_url(size = "x640")
|
2019-07-22 13:09:40 -06:00
|
|
|
# Detect legacy attachments by way of
|
|
|
|
# superceded PaperClip-related field.
|
|
|
|
# If it has an `attachment_file_size`,
|
|
|
|
# it was made with paperclip.
|
2019-07-25 12:10:06 -06:00
|
|
|
return regular_url if regular_image?
|
2019-07-22 13:09:40 -06:00
|
|
|
|
2019-07-25 12:10:06 -06:00
|
|
|
return legacy_url(size) if legacy_image?
|
2019-07-22 13:11:31 -06:00
|
|
|
|
|
|
|
return DEFAULT_URL
|
2019-07-20 15:33:05 -06:00
|
|
|
end
|
2017-01-10 21:31:05 -07:00
|
|
|
end
|