Packages
tz
0.9.0
0.28.2
0.28.1
0.28.0
0.27.3
0.27.2
0.27.1
0.27.0
0.26.6
0.26.5
0.26.4
0.26.3
0.26.2
0.26.1
0.26.0
0.25.1
0.25.0
0.24.0
0.23.0
0.22.0
0.21.1
0.21.0
0.20.1
0.20.0
0.19.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Time zone support for Elixir
Current section
Files
Jump to
Current section
Files
lib/updater.ex
if Code.ensure_loaded?(Mint.HTTP) do
defmodule Tz.Updater do
@moduledoc false
require Logger
alias Tz.Compiler
alias Tz.PeriodsProvider
alias Tz.HTTP.HTTPClient
alias Tz.HTTP.HTTPResponse
def maybe_recompile() do
if maybe_update_tz_database() == :updated do
Logger.info("Tz is recompiling time zone periods...")
Code.compiler_options(ignore_module_conflict: true)
Compiler.compile()
Code.compiler_options(ignore_module_conflict: false)
Logger.info("Tz compilation done")
end
end
def fetch_iana_tz_version() do
case HTTPClient.request("GET", "/time-zones/tzdb/version", hostname: "data.iana.org") do
%HTTPResponse{body: body, status_code: 200} ->
{:ok, body |> List.first() |> String.trim()}
_ ->
:error
end
end
defp maybe_update_tz_database() do
case fetch_iana_tz_version() do
{:ok, latest_version} ->
if latest_version != PeriodsProvider.version() do
case update_tz_database(latest_version) do
:ok ->
delete_tz_database(PeriodsProvider.version())
:updated
_ -> :error
end
end
:error ->
Logger.error("Tz failed to read the latest version of the IANA time zone database")
:no_update
end
end
defp update_tz_database(version) do
case download_tz_database(version) do
{:ok, content} ->
extract_tz_database(version, content)
:ok
:error ->
Logger.error("Tz failed to download the latest archived IANA time zone database (version #{version})")
:error
end
end
defp download_tz_database(version) do
Logger.info("Tz is downloading the latest IANA time zone database (version #{version})...")
case HTTPClient.request("GET", "/time-zones/releases/tzdata#{version}.tar.gz", hostname: "data.iana.org") do
%HTTPResponse{body: body, status_code: 200} ->
Logger.info("Tz download done")
{:ok, body}
_ ->
:error
end
end
defp extract_tz_database(version, content) do
tmp_archive_path = Path.join(:code.priv_dir(:tz), "tzdata#{version}.tar.gz")
tz_data_dir = "tzdata#{version}"
:ok = File.write!(tmp_archive_path, content)
:ok = :erl_tar.extract(tmp_archive_path, [:compressed, {:cwd, Path.join(:code.priv_dir(:tz), tz_data_dir)}])
:ok = File.rm!(tmp_archive_path)
end
defp delete_tz_database(version) do
Path.join(:code.priv_dir(:tz), "tzdata#{version}")
|> File.rm_rf!()
end
end
end