Class: Ragdoll::ImageContent

Inherits:
Content
  • Object
show all
Defined in:
app/models/ragdoll/image_content.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Content

#character_count, search_content, #word_count

Class Method Details

.statsObject



153
154
155
156
157
158
159
160
161
162
# File 'app/models/ragdoll/image_content.rb', line 153

def self.stats
  {
    total_image_contents: count,
    by_model: group(:embedding_model).count,
    total_embeddings: joins(:embeddings).count,
    with_images: with_images.count,
    with_descriptions: with_descriptions.count,
    average_image_size: joins(:image_attachment).average("active_storage_blobs.byte_size")
  }
end

Instance Method Details

#alt_textObject

Image-specific technical metadata (raw file properties) This metadata is about the actual image file data, not AI-generated insights



34
35
36
# File 'app/models/ragdoll/image_content.rb', line 34

def alt_text
  .dig("alt_text")
end

#alt_text=(value) ⇒ Object



38
39
40
# File 'app/models/ragdoll/image_content.rb', line 38

def alt_text=(value)
  self. = .merge("alt_text" => value)
end

#bit_depthObject



96
97
98
# File 'app/models/ragdoll/image_content.rb', line 96

def bit_depth
  .dig("bit_depth")
end

#bit_depth=(value) ⇒ Object



100
101
102
# File 'app/models/ragdoll/image_content.rb', line 100

def bit_depth=(value)
  self. = .merge("bit_depth" => value)
end

#color_spaceObject

Image format and technical details



88
89
90
# File 'app/models/ragdoll/image_content.rb', line 88

def color_space
  .dig("color_space")
end

#color_space=(value) ⇒ Object



92
93
94
# File 'app/models/ragdoll/image_content.rb', line 92

def color_space=(value)
  self. = .merge("color_space" => value)
end

#content_for_embeddingObject

Override content for embedding to combine description and alt_text



131
132
133
134
135
136
# File 'app/models/ragdoll/image_content.rb', line 131

def content_for_embedding
  content_parts = []
  content_parts << alt_text if alt_text.present?
  content_parts << description if description.present?
  content_parts.join(" ")
end

#descriptionObject

Image content accessors - content field stores description for embedding



15
16
17
# File 'app/models/ragdoll/image_content.rb', line 15

def description
  content
end

#description=(value) ⇒ Object



19
20
21
# File 'app/models/ragdoll/image_content.rb', line 19

def description=(value)
  self.content = value
end

#embedding_countObject



42
43
44
# File 'app/models/ragdoll/image_content.rb', line 42

def embedding_count
  embeddings.count
end

#generate_description_from_image!(options = {}) ⇒ Object

Generate description from image file using LLM vision capabilities



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'app/models/ragdoll/image_content.rb', line 105

def generate_description_from_image!(options = {})
  return false unless image_attached? || file_path_available?

  begin
    image_path = get_image_path
    return false unless image_path

    # Use the image description service
    description_service = Ragdoll::ImageDescriptionService.new

    generated_description = description_service.generate_description(image_path, options)

    if generated_description.present?
      self.description = generated_description
      save!
      return true
    end

    false
  rescue StandardError => e
    puts "Failed to generate image description: #{e.message}"
    false
  end
end

#generate_embeddings!Object



138
139
140
141
142
143
144
145
146
# File 'app/models/ragdoll/image_content.rb', line 138

def generate_embeddings!
  return unless should_generate_embeddings?

  embedding_content = content_for_embedding
  return if embedding_content.blank?

  # Generate embeddings using the base class method
  super
end

#image_attached?Boolean

Image file technical properties (stored in content metadata - raw file data)

Returns:

  • (Boolean)


47
48
49
# File 'app/models/ragdoll/image_content.rb', line 47

def image_attached?
  data.present?
end

#image_content_typeObject



59
60
61
# File 'app/models/ragdoll/image_content.rb', line 59

def image_content_type
  .dig("content_type")
end

#image_content_type=(value) ⇒ Object



63
64
65
# File 'app/models/ragdoll/image_content.rb', line 63

def image_content_type=(value)
  self. = .merge("content_type" => value)
end

#image_dataObject

Image file data accessor



24
25
26
# File 'app/models/ragdoll/image_content.rb', line 24

def image_data
  data
end

#image_data=(value) ⇒ Object



28
29
30
# File 'app/models/ragdoll/image_content.rb', line 28

def image_data=(value)
  self.data = value
end

#image_dimensionsObject



75
76
77
78
79
80
81
# File 'app/models/ragdoll/image_content.rb', line 75

def image_dimensions
  width = .dig("width")
  height = .dig("height")
  return nil unless width && height

  { width: width, height: height }
end

#image_filenameObject



67
68
69
# File 'app/models/ragdoll/image_content.rb', line 67

def image_filename
  .dig("filename")
end

#image_filename=(value) ⇒ Object



71
72
73
# File 'app/models/ragdoll/image_content.rb', line 71

def image_filename=(value)
  self. = .merge("filename" => value)
end

#image_sizeObject



51
52
53
# File 'app/models/ragdoll/image_content.rb', line 51

def image_size
  .dig("file_size") || 0
end

#image_size=(value) ⇒ Object



55
56
57
# File 'app/models/ragdoll/image_content.rb', line 55

def image_size=(value)
  self. = .merge("file_size" => value)
end

#set_image_dimensions(width, height) ⇒ Object



83
84
85
# File 'app/models/ragdoll/image_content.rb', line 83

def set_image_dimensions(width, height)
  self. = .merge("width" => width, "height" => height)
end

#should_generate_embeddings?Boolean

Override should_generate_embeddings to check for content

Returns:

  • (Boolean)


149
150
151
# File 'app/models/ragdoll/image_content.rb', line 149

def should_generate_embeddings?
  content_for_embedding.present? && embeddings.empty?
end