TzWorld.Downloader (TzWorld v2.5.0)

Copy Markdown View Source

Downloads the time zone boundary data from the timezone-boundary-builder releases on GitHub.

mix tz_world.update is the usual way to install the data, and update_release/1 does the same from code.

Configuration

Downloads are made with :httpc over HTTPS, verifying the server's certificate. They can be configured with:

  • config :tz_world, cacertfile: path to name the certificate trust store. Without it, the store from the castore or certifi package is used if either is installed, and otherwise the first of several well-known system locations that exists.

  • config :tz_world, https_proxy: url, or the HTTPS_PROXY or https_proxy environment variable, to download through a proxy.

  • the TZWORLD_HTTP_TIMEOUT and TZWORLD_HTTP_CONNECTION_TIMEOUT environment variables, in milliseconds, to change the request timeout from 120,000 and the connection timeout from 60,000.

  • the TZWORLD_UNSAFE_HTTPS environment variable, which turns off certificate verification when it is set to anything other than an empty string, false or nil. This is not recommended.

Summary

Functions

Returns the release of the installed time zone boundary data.

Downloads the body of an HTTPS URL.

Downloads the headers and body of an HTTPS URL.

Returns the latest release of the time zone boundary data.

Downloads a URL to a file without holding the response in memory.

Installs the latest time zone boundary data if it is newer than the installed data.

Functions

current_release()

Returns the release of the installed time zone boundary data.

The release is read from the installed data file, so no backend needs to be running.

Returns

  • {:ok, release} where release is the name of the release.

  • {:error, reason} if no data is installed, when reason is :enoent, or the installed file cannot be read.

Examples

iex> TzWorld.Downloader.current_release()
{:ok, "2026d"}

get(url, options \\ [])

@spec get(String.t() | {String.t(), list()}, options :: Keyword.t()) ::
  {:ok, binary()} | {:not_modified, any()} | {:error, any()}

Downloads the body of an HTTPS URL.

The request is made with :httpc, verifying the server's certificate as the EEF security guidelines recommend. The trust store, proxy and timeouts are configured as the module documentation describes.

Arguments

  • url is the URL as a string, or a {url, headers} tuple where headers is a list of {name, value} tuples of charlists.

  • options is a keyword list of options.

Options

  • :verify_peer is a boolean. When false the server's certificate is not verified. The default is true.

  • :timeout is the number of milliseconds the request may take. The default is the value of TZWORLD_HTTP_TIMEOUT, or 120,000.

  • :connection_timeout is the number of milliseconds allowed to connect to the server. The default is the value of TZWORLD_HTTP_CONNECTION_TIMEOUT, or 60,000.

  • :https_proxy is the URL of a proxy to download through. The default is the configured :https_proxy, or the HTTPS_PROXY or https_proxy environment variable.

Returns

  • {:ok, body} if the server responds with status 200.

  • {:not_modified, headers} if the server responds with status 304, which needs a conditional request header such as If-None-Match.

  • {:error, reason} otherwise, where reason is the HTTP status code or the :httpc error. The failure is also logged.

Examples

iex> {:ok, body} = TzWorld.Downloader.get("https://example.com")
iex> String.starts_with?(body, "<!doctype html>")
true

get_with_headers(request, options \\ [])

@spec get_with_headers(String.t() | {String.t(), list()}, options :: Keyword.t()) ::
  {:ok, list(), binary()} | {:not_modified, any()} | {:error, any()}

Downloads the headers and body of an HTTPS URL.

The request is made as get/2 describes.

Arguments

  • url is the URL as a string, or a {url, headers} tuple where headers is a list of {name, value} tuples of charlists.

  • options is a keyword list of options.

Options

  • The options are those of get/2.

Returns

  • {:ok, headers, body} if the server responds with status 200, where headers is a list of {name, value} tuples of charlists.

  • {:not_modified, headers} if the server responds with status 304.

  • {:error, reason} otherwise, where reason is the HTTP status code or the :httpc error. The failure is also logged.

Examples

iex> {:ok, headers, _body} = TzWorld.Downloader.get_with_headers("https://example.com")
iex> List.keymember?(headers, ~c"content-type", 0)
true

latest_release(include_oceans? \\ false, trace? \\ false)

Returns the latest release of the time zone boundary data.

Arguments

  • include_oceans? is a boolean. When true the download URL is for the data that also covers the oceans. The default is false.

  • trace? is a boolean. When true progress is logged at the debug level. The default is false.

Returns

  • {release, url} where release is the name of the release and url is the download URL of its data.

A RuntimeError is raised if the list of releases cannot be fetched.

Examples

iex> TzWorld.Downloader.latest_release()
{"2026d", "https://github.com/evansiroky/timezone-boundary-builder/releases/download/2026d/timezones.geojson.zip"}

stream_get_url(url, path, trace? \\ false)

Downloads a URL to a file without holding the response in memory.

Arguments

  • url is the URL to download.

  • path is the path of the file the response body is written to.

  • trace? is a boolean. When true the download is logged at the debug level. The default is false.

Returns

  • {:ok, path} once the response body has been written to path.

  • {:error, reason} if the download fails, where reason is the HTTP status code or the :httpc error. The failure is also logged.

Examples

iex> path = Path.join(System.tmp_dir!(), "example.html")
iex> {:ok, ^path} = TzWorld.Downloader.stream_get_url("https://example.com", path)
iex> File.exists?(path)
true

update_release(options \\ [])

Installs the latest time zone boundary data if it is newer than the installed data.

The data is downloaded, compressed into the data directory and then loaded into every running backend with TzWorld.reload_timezone_data/0.

Arguments

  • options is a keyword list of options.

Options

  • :include_oceans is a boolean. When true the data that also covers the oceans is installed. The default is false.

  • :force is a boolean. When true the latest data is installed even if it is already installed, which is how to switch between the data with and without the oceans. The default is false.

  • :trace is a boolean. When true progress is logged at the debug level. The default is false.

Returns

  • {:ok, release} if the installed data is already the latest release.

  • The result of TzWorld.reload_timezone_data/0 once the latest data has been installed.

  • {:error, reason} if the download fails.

A RuntimeError is raised if the list of releases cannot be fetched.

Examples

iex> TzWorld.Downloader.update_release()
{:ok, "2026d"}