Current section

Files

Jump to
extika lib extika.ex
Raw

lib/extika.ex

defmodule ExTika do
@moduledoc """
Wrapper for Apache Tika, a toolkit that detects and extracts metadata and
text from over a thousand different file types.
"""
@priv_dir Path.join(Path.expand("../", __DIR__), "priv")
@doc ~S"""
Extracts the text from the given file.
## Examples
iex> ExTika.get_text("test/test-files/test.doc")
{:ok, "This is a DOC file.\n\n"}
iex> ExTika.get_text("test/test-files/test-password.pdf", password: "password")
{:ok, "\nThis is a password-protected PDF file.\n\n\n"}
"""
@spec get_text(String.t) :: {:ok, String.t} | {:error, String.t}
@spec get_text(String.t, Keyword.t) :: {:ok, String.t} | {:error, String.t}
def get_text(file, opts \\ []) do
call_tika(file, ["--text"], opts)
end
@doc ~S"""
Extracts the text from the given file. Fails on error.
## Examples
iex> ExTika.get_text!("test/test-files/test.doc")
"This is a DOC file.\n\n"
"""
@spec get_text!(String.t) :: String.t
@spec get_text!(String.t, Keyword.t) :: String.t
def get_text!(file, opts \\ []) do
{:ok, text} = get_text(file, opts)
text
end
@doc ~S"""
Returns the language of the document.
## Examples
iex> ExTika.get_language("test/test-files/test.doc")
{:ok, "en"}
"""
@spec get_language(String.t) :: {:ok, String.t} | {:error, String.t}
@spec get_language(String.t, Keyword.t) :: {:ok, String.t} | {:error, String.t}
def get_language(file, opts \\ []) do
case call_tika(file, ["--language"], opts) do
{:ok, lang} ->
{:ok, ExTika.Utils.trim(lang)}
{:error, msg} ->
{:ok, msg}
end
end
@doc ~S"""
Returns the language of the document. Fails on error.
## Examples
iex> ExTika.get_language!("test/test-files/test.doc")
"en"
"""
@spec get_language!(String.t) :: String.t
@spec get_language!(String.t, Keyword.t) :: String.t
def get_language!(file, opts \\ []) do
{:ok, lang} = get_language(file, opts)
lang
end
@doc ~S"""
Returns the content type of the document.
## Examples
iex> ExTika.get_content_type("test/test-files/test.doc")
{:ok, "application/msword"}
"""
@spec get_content_type(String.t) :: {:ok, String.t} | {:error, String.t}
@spec get_content_type(String.t, Keyword.t) :: {:ok, String.t} | {:error, String.t}
def get_content_type(file, opts \\ []) do
case call_tika(file, ["--detect"], opts) do
{:ok, ct} ->
{:ok, ExTika.Utils.trim(ct)}
{:error, msg} ->
{:error, msg}
end
end
@doc ~S"""
Returns the content type of the document. Fails on error.
## Examples
iex> ExTika.get_content_type!("test/test-files/test.doc")
"application/msword"
"""
@spec get_content_type!(String.t) :: String.t
@spec get_content_type!(String.t, Keyword.t) :: String.t
def get_content_type!(file, opts \\ []) do
{:ok, ct} = get_content_type(file, opts)
ct
end
@doc ~S"""
Fetches metadata about the document.
## Examples
iex> {:ok, meta} = ExTika.get_metadata("test/test-files/test.docx")
iex> meta["meta:creation-date"]
"2016-08-14T14:51:38Z"
"""
@spec get_metadata(String.t) :: {:ok, map} | {:error, String.t}
@spec get_metadata(String.t, Keyword.t) :: {:ok, map} | {:error, String.t}
def get_metadata(file, opts \\ []) do
case call_tika(file, ["--json"], opts) do
{:ok, json} ->
Poison.Parser.parse(json)
{:error, msg} ->
{:error, msg}
end
end
@doc ~S"""
Fetches metadata about the document. Fails on error.
## Examples
iex> meta = ExTika.get_metadata!("test/test-files/test.docx")
iex> meta["meta:creation-date"]
"2016-08-14T14:51:38Z"
"""
@spec get_metadata!(String.t) :: map
@spec get_metadata!(String.t, Keyword.t) :: map
def get_metadata!(file, opts \\ []) do
{:ok, meta} = get_metadata(file, opts)
meta
end
##################################################
## HELPER FUNCTIONS
defp call_tika(file, flags, opts) do
version = File.read!(Path.join([
__DIR__,
"..",
".tika-version",
])) |> ExTika.Utils.trim
args = ["-jar", Path.join(@priv_dir, "tika-#{version}.jar")]
args = args ++ flags
args = if Keyword.get(opts, :pretty, false) do
args ++ ["--pretty-print"]
else
args
end
args = case Keyword.get(opts, :password) do
nil -> args
val -> args ++ ["--password=#{val}"]
end
args = case Keyword.get(opts, :encoding) do
nil -> args
val -> args ++ ["--encoding=#{val}"]
end
args = args ++ [file]
case System.cmd("java", args) do
{out, 0} ->
{:ok, out}
{out, code} ->
{:error, "tika returned code #{code}: #{out}"}
end
end
end