Current section
Files
Jump to
Current section
Files
lib/thetvdb.ex
defmodule TheTVDB do
use Application
@moduledoc """
This module provides access to TheTVDB API.
## Authentication
This module supports multiple ways to authenticate with TheTVDB API.
If only interested in globally-scoped endpoints (such as fetching
series/episode information), Authenticating via `TheTVDB.authenticate/1`
is all that's required.
Token refreshes are handled automatically by the library.
### User Authentication
This module supports multi-user authentication. All functions in `TheTVDB.User`
support an optional username. If the username is omitted, the last
authenticated user will be used.
It is recommended that if multiple users have been authenticated, the
username should be specified.
TheTVDB.authenticate(api_key, "johnDoe", acct_id)
# => :ok
# Fetch user authentication for johnDoe
TheTVDB.User.info()
# => {:ok, %TheTVDB.User{user_name: "johnDoe", ...}}
TheTVDB.authenticate(api_key, "jamesDean", acct_id)
# => :ok
# Fetch user authentication for jamesDean
TheTVDB.User.info("jamesDean")
# => {:ok, %TheTVDB.User{user_name: "jamesDean", ...}}
## Automatic retries
In the event of a service outage, requests will be retried using an
exponential backoff strategy. The formula for the delay (in milliseconds)
between requests is as follows:
(2 ** num_attempts) * backoff_multiplier
## Configuration
The parameters below are able to be configured by the user:
- max_attempts - The maximum number of attempts for a single request (default: 5)
- backoff_multiplier - See "Automatic retries" section above (default: 300)
To modify the default configuration, add the following to your config:
config :thetvdb,
max_attempts: 10,
backoff_multiplier: 500
"""
import TheTVDB.API.Utils, only: [unwrap_or_raise: 1]
@doc false
def start(_, _) do
import Supervisor.Spec, warn: false
children = [
registry(:unique, TheTVDB.Auth.Registry),
supervisor(TheTVDB.Auth.Supervisor, [])
]
Supervisor.start_link(children, strategy: :one_for_one)
end
defp registry(type, name) do
import Supervisor.Spec, warn: false
supervisor(Registry, [type, name], name: name)
end
@doc """
Authenticate with TheTVDB API. This will provide access to globally
scoped endpoints.
"""
@spec authenticate(binary) :: :ok | {:error, TheTVDB.NotAuthenticatedError.t}
def authenticate(api_key) do
TheTVDB.Auth.Supervisor.start_child(api_key)
|> handle_sup_response
end
@doc """
See `authenticate/1`.
"""
@spec authenticate!(binary) :: :ok
def authenticate!(api_key), do: authenticate(api_key) |> unwrap_or_raise
@doc """
Authenticate with TheTVDB API. This will provide access to both globally
and user scoped endpoints.
Note: `user_key` corresponds to the "Account Identifier" under the
user account page.
"""
@spec authenticate(binary, String.t, binary) :: :ok | {:error, TheTVDB.NotAuthenticatedError.t}
def authenticate(api_key, username, user_key) when byte_size(username) == 0 do
{:error, %TheTVDB.NotAuthenticatedError{message: "No user specified"}}
end
def authenticate(api_key, username, user_key) do
TheTVDB.Auth.Supervisor.start_child(api_key, username, user_key)
|> handle_sup_response
end
@doc """
See `authenticate/3`.
"""
@spec authenticate!(binary, String.t, binary) :: :ok
def authenticate!(api_key, username, user_key) do
authenticate(api_key, username, user_key) |> unwrap_or_raise
end
defp handle_sup_response(resp) do
case resp do
{:ok, _} -> :ok
{:error, {:already_started, _}} -> :ok
{:error, {reason, _}} -> {:error, reason}
end
end
end