Current section

4 Versions

Jump to

Compare versions

3 files changed
+53 additions
-33 deletions
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/err931/magika_ex">>}]}.
2 2 {<<"name">>,<<"magika_ex">>}.
3 - {<<"version">>,<<"0.1.0">>}.
3 + {<<"version">>,<<"0.1.1">>}.
4 4 {<<"description">>,<<"Elixir NIF wrapper for google/magika">>}.
5 5 {<<"elixir">>,<<"~> 1.18">>}.
6 6 {<<"app">>,<<"magika_ex">>}.
  @@ -1,44 +1,47 @@
1 1 defmodule MagikaEx do
2 2 @moduledoc """
3 - MagikaEx is an Elixir wrapper for Google's Magika, a deep-learning-based content-type detection tool.
3 + Provides the main interface for using Magika to identify the content type of
4 + files or binary data.
4 5
5 - This module uses a `GenServer` to manage a native Magika session resource, ensuring safe
6 - and efficient access to the underlying Rust-based identification engine.
6 + This module offers functions that wrap the Magika engine and allow you to
7 + classify file contents in an efficient and convenient way.
7 8 """
8 9
9 10 use GenServer
11 +
10 12 alias MagikaEx.Native
11 13
12 - @name __MODULE__
14 + @type option :: GenServer.option()
13 15
14 - @doc """
15 - Starts the `MagikaEx` GenServer.
16 -
17 - This initializes the native Magika session required for content identification.
18 - """
16 + @spec start_link([option()]) :: GenServer.on_start()
19 17 def start_link(opts \\ []) do
20 - opts = Keyword.put_new(opts, :name, @name)
18 + opts = Keyword.put_new(opts, :name, __MODULE__)
21 19 GenServer.start_link(__MODULE__, :ok, opts)
22 20 end
23 21
24 22 @doc """
25 - Identifies the content type of the given binary data.
26 -
27 - Returns a `%MagikaEx.Result{}` struct containing details such as the label, score, and group.
23 + Identify the data type of raw bytes.
28 24 """
25 + @spec identify_bytes(binary()) :: {:ok, MagikaEx.Result.t()} | {:error, term}
29 26 def identify_bytes(data) when is_binary(data) do
30 - resource = GenServer.call(@name, :get_resource)
31 - Native.identify_bytes(resource, data)
27 + resource = GenServer.call(__MODULE__, :get_resource)
28 +
29 + case Native.identify_bytes(resource, data) do
30 + {:error, _} = err -> err
31 + result -> {:ok, result}
32 + end
32 33 end
33 34
34 35 @doc """
35 - Identifies the content type of a file at the specified path.
36 -
37 - Returns `{:ok, %MagikaEx.Result{}}` on success or `{:error, reason}` if the file cannot be read.
36 + Identify the data type of a file given its path.
38 37 """
39 - def identify_path(path) do
40 - with {:ok, binary} <- File.read(path) do
41 - {:ok, identify_bytes(binary)}
38 + @spec identify_path(String.t()) :: {:ok, MagikaEx.Result.t()} | {:error, term}
39 + def identify_path(path) when is_binary(path) do
40 + with {:ok, data} <- File.read(path),
41 + {:ok, result} <- identify_bytes(data) do
42 + {:ok, result}
43 + else
44 + {:error, _} = err -> err
42 45 end
43 46 end
44 47
  @@ -61,15 +64,30 @@ end
61 64
62 65 defmodule MagikaEx.Result do
63 66 @moduledoc """
64 - A struct representing the identification result from Magika.
65 -
66 - Fields:
67 - * `:label` - The detected content type label (e.g., "python").
68 - * `:score` - The confidence score for the prediction.
69 - * `:mime_type` - The associated MIME type (e.g., "text/x-python").
70 - * `:group` - The high-level category of the content (e.g., "code", "image").
71 - * `:description` - A human-readable description of the detected type.
72 - * `:is_text` - Boolean indicating whether the content is text-based.
67 + File type information with inference scoring.
73 68 """
74 - defstruct [:label, :score, :mime_type, :group, :description, :is_text]
69 +
70 + @typedoc "A struct representing the identification result from Magika."
71 + @type t :: %__MODULE__{
72 + label: String.t(),
73 + mime_type: String.t(),
74 + group: String.t(),
75 + description: String.t(),
76 + score: float(),
77 + is_text: boolean()
78 + }
79 +
80 + @doc """
81 + File type information.
82 +
83 + ## Fields
84 + * `:label` - The unique label identifying this file type.
85 + * `:mime_type` - The MIME type of the file type.
86 + * `:group` - The group of the file type.
87 + * `:description` - The description of the file type.
88 + * `:score` - The inference score between 0 and 1.
89 + * `:is_text` - Whether the file type is text.
90 + """
91 + @enforce_keys [:label, :mime_type, :group, :description, :score, :is_text]
92 + defstruct [:label, :mime_type, :group, :description, :score, :is_text]
75 93 end
  @@ -2,7 +2,7 @@ defmodule MagikaEx.MixProject do
2 2 use Mix.Project
3 3
4 4 @source_url "https://github.com/err931/magika_ex"
5 - @version "0.1.0"
5 + @version "0.1.1"
6 6
7 7 def project do
8 8 [
  @@ -35,6 +35,8 @@ defmodule MagikaEx.MixProject do
35 35
36 36 defp deps do
37 37 [
38 + {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
39 + {:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
38 40 {:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
39 41 {:rustler, "~> 0.37.1", runtime: false}
40 42 ]