Class: JekyllImgFlow::Providers::BaseProvider

Inherits:
Object
  • Object
show all
Defined in:
lib/jekyll-imgflow/providers/base_provider.rb

Overview

Base provider class - all providers must inherit from this

Direct Known Subclasses

Flyimg, Imagemagick, Imgproxy, Libvips, Sharp, Weserv

Constant Summary collapse

SMARTCROP_POSITIONS =

Valid smartcrop position values

%w[attention entropy center centre].freeze
KNOWN_OPERATIONS =

Provider capability methods

%i[crop format opacity optimize quality resize
watermark alpha_opacity].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ BaseProvider

Returns a new instance of BaseProvider.



15
16
17
18
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 15

def initialize(config = {})
  @config = config
  @operations = []
end

Instance Attribute Details

#configObject

Returns the value of attribute config.



13
14
15
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 13

def config
  @config
end

Class Method Details

.provider_nameObject

Provider name for identification (override in subclasses)



190
191
192
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 190

def provider_name
  name.split("::").last.downcase
end

.supports_operation?(operation) ⇒ Boolean

Returns:

  • (Boolean)


202
203
204
205
206
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 202

def supports_operation?(operation)
  return false unless KNOWN_OPERATIONS.include?(operation)

  !unsupported_operations.include?(operation)
end

.unsupported_operationsObject



198
199
200
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 198

def unsupported_operations
  [] # Default: no unsupported operations
end

Instance Method Details

#add_watermark(watermark_path, options = {}) ⇒ Object



125
126
127
128
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 125

def add_watermark(watermark_path, options = {})
  @operations << { type: :watermark, watermark_path: watermark_path,
                   options: options }
end

#alpha_opacity=(opacity) ⇒ Object



130
131
132
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 130

def alpha_opacity=(opacity)
  @operations << { type: :alpha_opacity, opacity: opacity }
end

#available?Boolean

Check if this provider is available (must be implemented by subclasses)

Returns:

  • (Boolean)


21
22
23
24
25
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 21

def available?
  # Default: not available unless subclass implements actual check
  # This ensures providers explicitly check their availability
  false
end

#check_http_service(url) ⇒ Object

Helper method for HTTP providers to check service availability



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 28

def check_http_service(url)
  return false unless url

  begin
    require "net/http"
    require "uri"

    uri = URI(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = uri.scheme == "https"
    http.read_timeout = 2
    http.open_timeout = 2

    request = Net::HTTP::Get.new(uri)
    http.request(request)

    # Consider available if we get any response (even 404 means service is running)
    true
  rescue StandardError
    false
  end
end

#convert_format(format) ⇒ Object



105
106
107
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 105

def convert_format(format)
  @operations << { type: :format, format: format }
end

#crop(ratio_or_width, height_val = nil, x_val = nil, y_val = nil) ⇒ Object



90
91
92
93
94
95
96
97
98
99
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 90

def crop(ratio_or_width, height_val = nil, x_val = nil, y_val = nil)
  if height_val.is_a?(Hash)
    @operations << { type: :crop, ratio: ratio_or_width, options: height_val }
  elsif height_val
    options = { width: ratio_or_width, height: height_val, x: x_val, y: y_val }
    @operations << options.merge(type: :crop, ratio: nil, options: options)
  else
    @operations << { type: :crop, ratio: ratio_or_width, options: {} }
  end
end

#encode_file_url(file_path) ⇒ Object

Helper method for HTTP providers to construct HTTP URLs from file paths



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 52

def encode_file_url(file_path)
  # If already a URL, return as-is
  return file_path if file_path.start_with?("http://", "https://")

  # For HTTP providers, construct proper HTTP URL
  site = @config.site

  # Get the relative path from site source using Pathname
  source_path = Pathname.new(site.source)
  file_pathname = Pathname.new(file_path)
  relative_path = if file_pathname.absolute? && file_path.to_s.start_with?(site.source)
                    file_pathname.relative_path_from(source_path).to_s
                  elsif file_path.start_with?("/")
                    file_path[1..]
                  else
                    file_path
                  end

  # URL-encode each path segment to handle spaces and special characters
  encoded_path = relative_path.split("/").map do |segment|
    URI.encode_www_form_component(segment)
  end.join("/")

  # Construct HTTP URL for the file
  # Use Jekyll server URL (localhost:4000 by default for development)
  # In production, this would be the actual site URL from config
  base_url = site.config["url"] || "http://localhost:4000"
  baseurl = site.config["baseurl"] || ""

  "#{base_url}#{baseurl}/#{encoded_path}"
end

#execute(input_path, output_path) ⇒ Object

Final execution method - providers must implement this

Raises:

  • (NotImplementedError)


143
144
145
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 143

def execute(input_path, output_path)
  raise NotImplementedError, "Provider must implement execute method"
end

#format(value) ⇒ Object



113
114
115
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 113

def format(value)
  convert_format(value)
end

#opacity(value) ⇒ Object



121
122
123
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 121

def opacity(value)
  self.alpha_opacity = value
end

#operationsObject

Get current operations (for testing/debugging)



153
154
155
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 153

def operations
  @operations.dup
end

#optimize(level = :medium) ⇒ Object



117
118
119
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 117

def optimize(level = :medium)
  @operations << { type: :optimize, level: level }
end

#quality(value) ⇒ Object



109
110
111
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 109

def quality(value)
  self.quality = value
end

#quality=(quality) ⇒ Object



101
102
103
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 101

def quality=(quality)
  @operations << { type: :quality, quality: quality }
end

#reset_operationsObject

Reset operations for next processing



148
149
150
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 148

def reset_operations
  @operations = []
end

#resize(width, height, options = {}) ⇒ Object

Operation collection methods - these should NOT execute immediately



85
86
87
88
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 85

def resize(width, height, options = {})
  @operations << { type: :resize, width: width, height: height,
                   options: options }
end

#supports_operation?(operation) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 138

def supports_operation?(operation)
  self.class.supports_operation?(operation)
end

#watermark(watermark_path, options = {}) ⇒ Object



134
135
136
# File 'lib/jekyll-imgflow/providers/base_provider.rb', line 134

def watermark(watermark_path, options = {})
  add_watermark(watermark_path, options)
end