# `TuningFork.Sample.Fetch`
[🔗](https://github.com/jaman/tuning_fork/blob/v0.1.11/tuning_fork/lib/tuning_fork/sample/fetch.ex#L1)

Downloads a file once into the cache directory and gives its local path.

    {:ok, path} = TuningFork.Sample.Fetch.fetch("https://example.org/kick.wav")
    :ok = TuningFork.Sample.Fetch.prefetch(urls)

# `background`

```elixir
@spec background(term(), (-&gt; term())) :: :ok
```

Start `fun` under `key` in the background unless one is already running; return at once.

# `cached?`

```elixir
@spec cached?(String.t()) :: boolean()
```

Whether `url` is already in the cache.

# `dir`

```elixir
@spec dir() :: Path.t()
```

Where fetched files are kept.

# `fetch`

```elixir
@spec fetch(String.t()) :: {:ok, Path.t()} | {:error, term()}
```

The local path of `url`, fetched if it is not in the cache yet. A fetch of the same URL
already under way is waited for rather than repeated.

The cache is `$XDG_CACHE_HOME/tuning_fork/samples`, or `~/.cache/tuning_fork/samples`.
`{:error, reason}` when the fetch fails or the cache cannot be written.

# `get`

```elixir
@spec get(String.t()) :: {:ok, binary()} | {:error, term()}
```

Fetch the body of `url`. Spaces and other characters a URL cannot carry are percent-encoded; what is already percent-encoded is left as it is.

# `once`

```elixir
@spec once(term(), (-&gt; term())) :: :done
```

Run `fun` in a task registered under `key`, or wait for the one already running under
that key, and return when it is done.

# `prefetch`

```elixir
@spec prefetch([String.t()]) :: :ok
```

Start fetching every URL not yet in the cache, one after another in the background, and
return at once. A list already being walked is not walked again.

# `settle`

```elixir
@spec settle() :: :ok
```

Wait until every fetch and background task under way has finished.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
