Module: Omnizip::FileType

Defined in:
lib/omnizip/file_type.rb,
lib/omnizip/file_type/mime_classifier.rb

Overview

File type detection module using Marcel for MIME type detection

Provides MIME type detection using the Marcel library:

  • Path-based detection (examines file extension and content)
  • Data-based detection (analyzes binary data)
  • Stream-based detection (reads from IO streams)

Examples:

Detect file type from path

mime_type = Omnizip::FileType.detect('app.exe')
# => 'application/x-executable'

Detect from binary data

mime_type = Omnizip::FileType.detect_data(File.binread('image.png'))
# => 'image/png'

Detect from IO stream with filename hint

File.open('document.pdf', 'rb') do |file|
  mime_type = Omnizip::FileType.detect_stream(file, filename: 'document.pdf')
  # => 'application/pdf'
end

Defined Under Namespace

Classes: MimeClassifier

Class Method Summary collapse

Class Method Details

.detect(path) ⇒ String?

Detect MIME type from file path

Uses Marcel to detect the MIME type by examining both the file extension and file content. This is the most accurate detection method when you have a file path.

Examples:

FileType.detect('document.pdf')
# => 'application/pdf'

Parameters:

  • path (String, Pathname)

    File path

Returns:

  • (String, nil)

    MIME type string or nil if detection fails



41
42
43
44
45
46
47
48
# File 'lib/omnizip/file_type.rb', line 41

def detect(path)
  return nil unless path
  return nil unless File.exist?(path)

  Marcel::MimeType.for(Pathname.new(path))
rescue StandardError
  nil
end

.detect_data(data, filename: nil) ⇒ String?

Detect MIME type from binary data

Uses Marcel to analyze binary data for MIME type detection. Optionally accepts a filename hint for better accuracy.

Examples:

Without filename hint

data = File.binread('image.png')
FileType.detect_data(data)
# => 'image/png'

With filename hint

FileType.detect_data(data, filename: 'image.png')
# => 'image/png'

Parameters:

  • data (String)

    Binary data

  • filename (String, nil) (defaults to: nil)

    Optional filename hint

Returns:

  • (String, nil)

    MIME type string or nil if detection fails



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/omnizip/file_type.rb', line 67

def detect_data(data, filename: nil)
  return nil unless data
  return nil if data.empty?

  io = StringIO.new(data)
  io.set_encoding(Encoding::BINARY)

  Marcel::MimeType.for(io, name: filename)
rescue StandardError
  nil
end

.detect_stream(io, filename: nil) ⇒ String?

Detect MIME type from IO stream

Uses Marcel to analyze an IO stream for MIME type detection. Optionally accepts a filename hint for better accuracy. The stream position is preserved.

Examples:

File.open('document.pdf', 'rb') do |file|
  FileType.detect_stream(file, filename: 'document.pdf')
  # => 'application/pdf'
end

Parameters:

  • io (IO)

    IO stream

  • filename (String, nil) (defaults to: nil)

    Optional filename hint

Returns:

  • (String, nil)

    MIME type string or nil if detection fails



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/omnizip/file_type.rb', line 94

def detect_stream(io, filename: nil)
  return nil unless io

  # Save current position
  original_pos = io.pos if io.respond_to?(:pos)

  mime_type = Marcel::MimeType.for(io, name: filename)

  # Restore position
  io.seek(original_pos) if original_pos && io.respond_to?(:seek)

  mime_type
rescue StandardError
  # Attempt to restore position even on error
  io.seek(original_pos) if original_pos && io.respond_to?(:seek)
  nil
end