Farmbot-Web-App/app/models/image.rb

107 lines
3.0 KiB
Ruby

require "open-uri"
# A set of image URLs (thumbs) + Associated meta data.
class Image < ApplicationRecord
belongs_to :device
validates :device, presence: true
serialize :meta
# http://stackoverflow.com/a/5127684/1064917
after_initialize :set_defaults
def set_defaults
self.meta ||= {}
end
PLACEHOLDER = "/placeholder_farmbot.jpg\?text=Processing..."
PROTO = ENV["FORCE_SSL"] ? "https:" : "http:"
DEFAULT_URL = "#{PROTO}#{$API_URL}#{PLACEHOLDER}"
RMAGICK_STYLES = {
x1280: "1280x1280>",
x640: "640x640>",
x320: "320x320>",
x160: "160x160>",
x80: "80x80>",
}
MAX_IMAGE_SIZE = 7.megabytes
CONFIG = { default_url: DEFAULT_URL,
styles: RMAGICK_STYLES,
size: { in: 0..MAX_IMAGE_SIZE } }
BUCKET = ENV["GCS_BUCKET"]
ROOT_PATH = BUCKET ?
"https://#{BUCKET}.storage.googleapis.com" : "/system"
IMAGE_URL_TPL =
ROOT_PATH + "/images/attachments/%{chunks}/%{size}/%{filename}?%{timestamp}"
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"]
has_one_attached :attachment
def set_attachment_by_url(url)
attachment.attach(io: URI.open(url), filename: "image_#{self.id}")
self.attachment_processed_at = Time.now
self
end
# Scenario:
# User clicks "take photo" and "delete" on Image#123 very quickly.
# Problem:
# Now there's a Delayed::Job pointing to (nonexistent) Image#123,
# causing runtime errors in the work queue.
# 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
def legacy_image?
!!self.attachment_file_size # This is a now-unused legacy field.
end
def regular_image?
attachment && attachment.attached?
end
def regular_url
if BUCKET
# Not sure why. TODO: Investigate why Rails URL helpers don't work here.
"https://storage.googleapis.com/#{BUCKET}/#{attachment.key}"
else
Rails
.application
.routes
.url_helpers
.rails_blob_url(attachment)
end
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
def attachment_url(size = "x640")
# Detect legacy attachments by way of
# superceded PaperClip-related field.
# If it has an `attachment_file_size`,
# it was made with paperclip.
return regular_url if regular_image?
return legacy_url(size) if legacy_image?
return DEFAULT_URL
end
end