Current section

Files

Jump to
thetvdb lib user.ex
Raw

lib/user.ex

defmodule TheTVDB.User do
use TheTVDB.Model
@moduledoc """
This module contains access to all user-scoped endpoints.
All functions allow the user to specify an optional username. If no
username is specified, the last authenticated user will be used. See
`TheTVDB` for more information.
"""
import TheTVDB.API.Utils, only: [unwrap_or_raise: 1]
@rating_types [:series, :episode, :image]
@type username :: String.t | nil
@type rating_type :: :series | :episode | :image
model do
field "favoritesDisplaymode"
field "language"
field "userName"
end
defmodule Rating do
use TheTVDB.Model
model do
field "rating"
field "ratingItemId"
field "ratingType"
end
end
@doc """
Get info about a user.
"""
@spec info(username) :: {:ok, t} | {:error, term}
def info(username \\ nil) do
case TheTVDB.API.get("/user", scope: scope(username)) do
{:ok, %{"data" => data}} ->
{:ok, from_json(data)}
{:error, reason} ->
{:error, reason}
end
end
@doc """
See `info/1`.
"""
@spec info!(username) :: t
def info!(username \\ nil), do: info(username) |> unwrap_or_raise
@doc """
Get a list of all favorited series for a given user.
"""
@spec favorites(username) :: {:ok, [binary]} | {:error, term}
def favorites(username \\ nil) do
case TheTVDB.API.get("/user/favorites", scope: scope(username)) do
{:ok, %{"data" => data}} ->
{:ok, data["favorites"]}
{:error, reason} ->
{:error, reason}
end
end
@doc """
See `favorites/1`.
"""
@spec favorites!(username) :: [binary]
def favorites!(username \\ nil), do: favorites(username) |> unwrap_or_raise
@doc """
Add a favorite series for a given user.
"""
@spec add_favorite(username, integer) :: :ok | {:error, term}
def add_favorite(username \\ nil, series_id) do
endpoint = "/user/favorites/#{series_id}"
case TheTVDB.API.put(endpoint, "", scope: scope(username)) do
{:ok, _} ->
:ok
{:error, reason} ->
{:error, reason}
end
end
@doc """
See `add_favorite/2`.
"""
@spec add_favorite!(username, integer) :: :ok
def add_favorite!(username \\ nil, series_id) do
add_favorite(username, series_id) |> unwrap_or_raise
end
@doc """
Remove a favorite series for a given user.
"""
@spec remove_favorite(username, integer) :: :ok | {:error, term}
def remove_favorite(username \\ nil, series_id) do
endpoint = "/user/favorites/#{series_id}"
TheTVDB.API.delete(endpoint, scope: scope(username))
end
@doc """
See `remove_favorite/2`.
"""
@spec remove_favorite!(username, integer) :: :ok
def remove_favorite!(username \\ nil, series_id) do
remove_favorite(username, series_id) |> unwrap_or_raise
end
@doc """
Get a list of all ratings for a given user.
"""
@spec ratings(username) :: {:ok, [Rating.t]}
def ratings(username \\ nil) do
case TheTVDB.API.get_iter("/user/ratings", scope: scope(username)) do
{:ok, data} ->
{:ok, Enum.map(data, &Rating.from_json/1)}
{:error, reason} ->
{:error, reason}
end
end
@doc """
See `ratings/1`.
"""
@spec ratings!(username) :: [Rating.t]
def ratings!(username \\ nil), do: ratings(username) |> unwrap_or_raise
@doc """
Add a rating for a given user.
# Rate a series
TheTVDB.User.add_rating(:series, series_id, 10.0)
# => :ok
# Rate an episode
TheTVDB.User.add_rating(:episode, episode_id, 10.0)
# => :ok
# Rate an image
TheTVDB.User.add_rating(:image, image_id, 10.0)
# => :ok
"""
@spec add_rating(username, rating_type, integer, integer) :: :ok | {:error, term}
def add_rating(username \\ nil, type, item, rating)
when type in @rating_types and is_integer(rating) do
type = Atom.to_string(type)
endpoint = "/user/ratings/#{type}/#{item}/#{rating}"
case TheTVDB.API.put(endpoint, "", scope: scope(username)) do
{:ok, _} ->
:ok
{:error, reason} ->
{:error, reason}
end
end
@doc """
See `add_rating/4`.
"""
@spec add_rating!(username, rating_type, integer, integer) :: :ok
def add_rating!(username \\ nil, type, item, rating) do
add_rating(username, type, item, rating) |> unwrap_or_raise
end
@doc """
Remove a rating for a given user.
"""
@spec remove_rating(username, rating_type, integer) :: :ok | {:error, term}
def remove_rating(username \\ nil, type, item) when type in @rating_types do
type = Atom.to_string(type)
endpoint = "/user/ratings/#{type}/#{item}"
TheTVDB.API.delete(endpoint, scope: scope(username))
end
@doc """
See `remove_rating/3`.
"""
@spec remove_rating!(username, rating_type, integer) :: :ok
def remove_rating!(username, type, item) do
remove_rating(username, type, item) |> unwrap_or_raise
end
defp scope(username) when is_nil(username), do: :user
defp scope(username), do: {:user, username}
end