mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-12-05 00:57:59 +01:00
68 lines
1.8 KiB
Elixir
68 lines
1.8 KiB
Elixir
|
defmodule PhilomenaMedia.Mime do
|
||
|
@moduledoc """
|
||
|
Utilities for determining the MIME type of a file via parsing.
|
||
|
|
||
|
Many MIME type libraries assume the MIME type of the file by reading file extensions.
|
||
|
This is inherently unreliable, as many websites disguise the content types of files with
|
||
|
specific names for cost or bandwidth saving reasons. As processing depends on correctly
|
||
|
identifying the type of a file, parsing the file contents is necessary.
|
||
|
"""
|
||
|
|
||
|
@type t :: String.t()
|
||
|
|
||
|
@doc """
|
||
|
Gets the MIME type of the given pathname.
|
||
|
|
||
|
## Examples
|
||
|
|
||
|
iex> PhilomenaMedia.Mime.file("image.png")
|
||
|
{:ok, "image/png"}
|
||
|
|
||
|
iex> PhilomenaMedia.Mime.file("file.txt")
|
||
|
{:unsupported_mime, "text/plain"}
|
||
|
|
||
|
iex> PhilomenaMedia.Mime.file("nonexistent.file")
|
||
|
:error
|
||
|
|
||
|
"""
|
||
|
@spec file(Path.t()) :: {:ok, t()} | {:unsupported_mime, t()} | :error
|
||
|
def file(path) do
|
||
|
System.cmd("file", ["-b", "--mime-type", path])
|
||
|
|> case do
|
||
|
{output, 0} ->
|
||
|
true_mime(String.trim(output))
|
||
|
|
||
|
_error ->
|
||
|
:error
|
||
|
end
|
||
|
end
|
||
|
|
||
|
@doc """
|
||
|
Provides the "true" MIME type of this file.
|
||
|
|
||
|
Some files are identified as a type they should not be based on how they are used by
|
||
|
this library. These MIME types (and their "corrected") versions are:
|
||
|
|
||
|
- `image/svg` -> `image/svg+xml`
|
||
|
- `audio/webm` -> `video/webm`
|
||
|
|
||
|
## Examples
|
||
|
|
||
|
iex> PhilomenaMedia.Mime.file("image.svg")
|
||
|
"image/svg+xml"
|
||
|
|
||
|
iex> PhilomenaMedia.Mime.file("audio.webm")
|
||
|
"video/webm"
|
||
|
|
||
|
"""
|
||
|
@spec true_mime(String.t()) :: {:ok, t()} | {:unsupported_mime, t()}
|
||
|
def true_mime("image/svg"), do: {:ok, "image/svg+xml"}
|
||
|
def true_mime("audio/webm"), do: {:ok, "video/webm"}
|
||
|
|
||
|
def true_mime(mime)
|
||
|
when mime in ~W(image/gif image/jpeg image/png image/svg+xml video/webm),
|
||
|
do: {:ok, mime}
|
||
|
|
||
|
def true_mime(mime), do: {:unsupported_mime, mime}
|
||
|
end
|