Class: Keinaufwand::Sync::Asset

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/keinaufwand/sync_core/asset.rb

Constant Summary collapse

ASSET_URL_PATTERN =
%r{\Ahttps?://.+/shrine/(?:production|development)/(?:store|cache)/}.freeze
URL_PATTERN =
%r{https?://[^"'<>\s\\]+}.freeze

Class Method Summary collapse

Class Method Details

.asset_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/keinaufwand/sync_core/asset.rb', line 35

def self.asset_url?(url)
  url.to_s.match?(ASSET_URL_PATTERN)
end

.fetch(url, limit = 3) ⇒ Object

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/keinaufwand/sync_core/asset.rb', line 54

def self.fetch(url, limit = 3)
  raise ArgumentError, "too many redirects for #{url}" if limit < 0

  uri = URI(url)
  response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
    http.get(uri.request_uri)
  end

  return fetch(response["location"], limit - 1) if response.is_a?(Net::HTTPRedirection)
  raise "Could not fetch #{url}: #{response.code}" unless response.is_a?(Net::HTTPSuccess)

  response
end

.key_for(source_url) ⇒ Object



31
32
33
# File 'lib/keinaufwand/sync_core/asset.rb', line 31

def self.key_for(source_url)
  Digest::SHA256.hexdigest(source_url.to_s)
end

.sync_url(source_url) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/keinaufwand/sync_core/asset.rb', line 11

def self.sync_url(source_url)
  return unless asset_url?(source_url)

  key = key_for(source_url)
  return find_by(key:) if exists?(key:)

  response = fetch(source_url)
  body = response.body.to_s.b
  content_type = response["content-type"].to_s.split(";").first
  create!(
    key: key,
    source_url: source_url,
    content_type: content_type.empty? ? "application/octet-stream" : content_type,
    byte_size: body.bytesize,
    checksum: Digest::SHA256.hexdigest(body),
    data: body,
    synced_at: Time.current
  )
end

.urls_from(value, urls = []) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/keinaufwand/sync_core/asset.rb', line 39

def self.urls_from(value, urls = [])
  case value
  when Hash
    value.each_value { |child| urls_from(child, urls) }
  when Array
    value.each { |child| urls_from(child, urls) }
  when String
    CGI.unescapeHTML(value).scan(URL_PATTERN).each do |url|
      urls << url if asset_url?(url)
    end
  end

  urls
end