Class: Riffer::Messages::FilePart

Inherits:
Object
  • Object
show all
Defined in:
lib/riffer/messages/file_part.rb

Overview

Represents a file attachment (image or document) — from a URL (from_url) or raw base64 data (new).

Constant Summary collapse

MEDIA_TYPES =
{
  ".jpg" => "image/jpeg",
  ".jpeg" => "image/jpeg",
  ".png" => "image/png",
  ".gif" => "image/gif",
  ".webp" => "image/webp",
  ".pdf" => "application/pdf",
  ".txt" => "text/plain",
  ".md" => "text/plain",
  ".csv" => "text/csv",
  ".html" => "text/html"
}.freeze
SUPPORTED_MEDIA_TYPES =

: Hash[String, String]

MEDIA_TYPES.values.uniq.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(media_type:, data: nil, filename: nil, url: nil) ⇒ FilePart

Raises Riffer::ArgumentError unless data or url is given and media_type is supported. – : (media_type: String, ?data: String?, ?filename: String?, ?url: String?) -> void



37
38
39
40
41
42
43
44
45
# File 'lib/riffer/messages/file_part.rb', line 37

def initialize(media_type:, data: nil, filename: nil, url: nil)
  raise Riffer::ArgumentError, "Either data or url must be provided" if data.nil? && url.nil?
  raise Riffer::ArgumentError, "Unsupported media type: #{media_type}" unless SUPPORTED_MEDIA_TYPES.include?(media_type)

  @data = data
  @media_type = media_type
  @filename = filename
  @url_string = url
end

Instance Attribute Details

#dataObject (readonly)

Returns the base64-encoded data, or nil for URL-only sources.



88
89
90
# File 'lib/riffer/messages/file_part.rb', line 88

def data
  @data
end

#filenameObject (readonly)

The filename, if available.



31
32
33
# File 'lib/riffer/messages/file_part.rb', line 31

def filename
  @filename
end

#media_typeObject (readonly)

The MIME type of the file.



28
29
30
# File 'lib/riffer/messages/file_part.rb', line 28

def media_type
  @media_type
end

Class Method Details

.from_hash(file) ⇒ Object

Builds a FilePart from a {url:, media_type:} or {data:, media_type:} hash, or returns file unchanged when it is already a FilePart. Raises Riffer::ArgumentError on an invalid hash. – : ((Hash[Symbol, untyped] | Riffer::Messages::FilePart)) -> Riffer::Messages::FilePart



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/riffer/messages/file_part.rb', line 66

def self.from_hash(file)
  return file if file.is_a?(Riffer::Messages::FilePart)

  unless file.is_a?(Hash)
    raise Riffer::ArgumentError, "File must be a Hash or FilePart object, got #{file.class}"
  end

  url = file[:url]
  data = file[:data]
  media_type = file[:media_type]
  filename = file[:filename]

  if url
    from_url(url, media_type: media_type)
  elsif data && media_type
    new(data: data, media_type: media_type, filename: filename)
  else
    raise Riffer::ArgumentError, "File hash must include :url or :data with :media_type"
  end
end

.from_url(url, media_type: nil) ⇒ Object

Creates a FilePart from a URL, detecting media_type from the path extension when omitted. Raises Riffer::ArgumentError if it can’t be detected. – : (String, ?media_type: String?) -> Riffer::Messages::FilePart



51
52
53
54
55
56
57
58
59
# File 'lib/riffer/messages/file_part.rb', line 51

def self.from_url(url, media_type: nil)
  unless media_type
    ext = ::File.extname(URI.parse(url).path.to_s).downcase
    media_type = MEDIA_TYPES[ext]
    raise Riffer::ArgumentError, "Cannot detect media type from URL; provide media_type explicitly" unless media_type
  end

  new(url: url, media_type: media_type)
end

Instance Method Details

#document?Boolean

Returns true if the file is a document (not an image).

– : () -> bool

Returns:

  • (Boolean)


118
119
120
# File 'lib/riffer/messages/file_part.rb', line 118

def document?
  !image?
end

#image?Boolean

Returns true if the file is an image.

– : () -> bool

Returns:

  • (Boolean)


110
111
112
# File 'lib/riffer/messages/file_part.rb', line 110

def image?
  media_type.start_with?("image/")
end

#to_hObject

Serializes the FilePart to a hash.

– : () -> Hash[Symbol, untyped]



126
127
128
129
130
131
132
# File 'lib/riffer/messages/file_part.rb', line 126

def to_h
  hash = {media_type: media_type} #: Hash[Symbol, untyped]
  hash[:data] = @data if @data
  hash[:url] = @url_string if @url_string
  hash[:filename] = filename if filename
  hash
end

#urlObject

Returns the URL if the source was a URL, nil otherwise.

– : () -> String?



94
95
96
# File 'lib/riffer/messages/file_part.rb', line 94

def url
  @url_string
end

#url?Boolean

Returns true if the source was a URL.

– : () -> bool

Returns:

  • (Boolean)


102
103
104
# File 'lib/riffer/messages/file_part.rb', line 102

def url?
  !@url_string.nil?
end