Packages
phoenix_kit
1.7.112
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/system/dependencies.ex
defmodule PhoenixKit.System.Dependencies do
@moduledoc """
System dependency checker for PhoenixKit.
Probes for required system tools like ImageMagick and FFmpeg.
Results are cached to avoid repeated system calls.
"""
require Logger
# Cache TTL for dependency checks (1 hour)
@cache_ttl 3_600_000
@doc """
Check if ImageMagick is installed and available.
Returns:
- `{:ok, version}` - ImageMagick is installed with version string
- `{:error, :not_installed}` - ImageMagick not found
- `{:error, reason}` - Other error occurred
"""
def check_imagemagick do
case check_command("identify", ["--version"]) do
{:ok, output} ->
# Extract version from output (first line is usually the version)
version =
output
|> String.split("\n")
|> List.first("")
|> String.trim()
{:ok, version}
{:error, :enoent} ->
{:error, :not_installed}
error ->
error
end
rescue
_error -> {:error, :not_installed}
end
@doc """
Check if Poppler (pdftoppm/pdfinfo) is installed and available.
Returns:
- `{:ok, version}` - Poppler is installed with version string
- `{:error, :not_installed}` - Poppler not found
- `{:error, reason}` - Other error occurred
"""
def check_poppler do
case System.cmd("pdftoppm", ["-v"], stderr_to_stdout: true) do
{output, _exit_code} ->
version =
output
|> String.split("\n")
|> List.first("")
|> String.trim()
if version != "", do: {:ok, version}, else: {:error, :not_installed}
end
rescue
_error -> {:error, :not_installed}
end
@doc """
Check if FFmpeg is installed and available.
Returns:
- `{:ok, version}` - FFmpeg is installed with version string
- `{:error, :not_installed}` - FFmpeg not found
- `{:error, reason}` - Other error occurred
"""
def check_ffmpeg do
case check_command("ffmpeg", ["-version"]) do
{:ok, output} ->
# Extract version from output (first line is usually the version)
version =
output
|> String.split("\n")
|> List.first("")
|> String.trim()
{:ok, version}
{:error, :enoent} ->
{:error, :not_installed}
error ->
error
end
rescue
_error -> {:error, :not_installed}
end
@doc """
Check if ImageMagick is installed (cached version).
Returns the cached result if available, otherwise probes system.
"""
def check_imagemagick_cached do
case get_cached("imagemagick") do
nil ->
result = check_imagemagick()
cache_result("imagemagick", result)
result
cached_result ->
cached_result
end
end
@doc """
Check if Poppler is installed (cached version).
Returns the cached result if available, otherwise probes system.
"""
def check_poppler_cached do
case get_cached("poppler") do
nil ->
result = check_poppler()
cache_result("poppler", result)
result
cached_result ->
cached_result
end
end
@doc """
Check if FFmpeg is installed (cached version).
Returns the cached result if available, otherwise probes system.
"""
def check_ffmpeg_cached do
case get_cached("ffmpeg") do
nil ->
result = check_ffmpeg()
cache_result("ffmpeg", result)
result
cached_result ->
cached_result
end
end
@doc """
Clear the dependency check cache.
Useful for testing or when you know system dependencies have changed.
"""
def clear_cache do
:persistent_term.erase(:phoenix_kit_deps_imagemagick)
:persistent_term.erase(:phoenix_kit_deps_ffmpeg)
:persistent_term.erase(:phoenix_kit_deps_poppler)
:ok
end
# Private helper to check a system command
defp check_command(command, args) do
case System.cmd(command, args, stderr_to_stdout: true) do
{output, 0} ->
{:ok, output}
{_output, _code} ->
{:error, :command_failed}
end
rescue
e in ErlangError ->
# ErlangError with :enoent means command not found
if e.reason == :enoent do
{:error, :enoent}
else
{:error, "Error checking #{command}: #{inspect(e.reason)}"}
end
error ->
{:error, "Unexpected error: #{inspect(error)}"}
end
# Get cached result with TTL check
defp get_cached(tool) do
cache_key = String.to_atom("phoenix_kit_deps_#{tool}")
case :persistent_term.get(cache_key, nil) do
{timestamp, result} ->
current_time = System.monotonic_time(:millisecond)
if current_time - timestamp < @cache_ttl do
result
else
# Cache expired
:persistent_term.erase(cache_key)
nil
end
_ ->
nil
end
end
# Cache a result with timestamp
defp cache_result(tool, result) do
cache_key = String.to_atom("phoenix_kit_deps_#{tool}")
timestamp = System.monotonic_time(:millisecond)
:persistent_term.put(cache_key, {timestamp, result})
end
end