This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
README Asoiaf.Models

Asoiaf.Api

Characters

getCharacters : Pagination -> Http.Request (List Models.Character)

Get a list of characters

getCharacter : Models.Id -> Http.Request Models.Character

Get a character by id

queryCharacters : Pagination -> CharacterQuery -> Http.Request (List Models.Character)

Query characters

pagination =
  { page = 1
  , pageSize = 25
  }
query =
  { defaultCharacterQuery
  | name = Just "Jon Snow"
  }
queryCharacters pagination query == [ { name = "Jon Snow", ... } ]

Houses

getHouses : Pagination -> Http.Request (List Models.House)

Get a list of houses

getHouse : Models.Id -> Http.Request Models.House

Get a house by id

queryHouses : Pagination -> HouseQuery -> Http.Request (List Models.House)

Query houses

pagination =
  { page = 1
  , pageSize = 25
  }
query =
  { defaultBookQuery
  | words = Just "Winter is Coming"
  }
queryHouses pagination query == [ { name = "House Stark of Winterfell", ... } ]

Books

getBooks : Pagination -> Http.Request (List Models.Book)

Get a list of books

getBook : Models.Id -> Http.Request Models.Book

Get a book by id

queryBooks : Pagination -> BookQuery -> Http.Request (List Models.Book)

Query books

pagination =
  { page = 1
  , pageSize = 25
  }
query =
  { defaultBookQuery
  | name = Just "A Game of Thrones"
  }
queryBooks pagination query == [ { name = "A Game of Thrones", ... } ]

Pagination

type alias Pagination = { page : Int , pageSize : Int }

All requests are paginated. Use this to specify which page to request and what page size to use.

defaultPagination : Pagination

Default pagination.

{ page = 1
, pageSize = 10
}

Queries

type alias CharacterQuery = { name : Maybe String , gender : Maybe String , culture : Maybe String , born : Maybe Int , died : Maybe Int , isAlive : Maybe Bool }

Represents the fields we can query characters by

type alias HouseQuery = { name : Maybe String , region : Maybe String , words : Maybe String , hasWords : Maybe Bool , hasTitles : Maybe Bool , hasSeats : Maybe Bool , hasDiedOut : Maybe Bool , hasAncestralWeapons : Maybe Bool }

Represents the fields we can query houses by

type alias BookQuery = { name : Maybe String , fromReleaseDate : Maybe Date , toReleaseDate : Maybe Date }

Represents the fields we can query books by

defaultCharacterQuery : CharacterQuery

Default character query. No fields specified.

defaultHouseQuery : HouseQuery

Default house query. No fields specified.

defaultBookQuery : BookQuery

Default book query. No fields specified.

module Asoiaf.Api
    exposing
        ( getCharacters
        , getCharacter
        , queryCharacters
        , getHouses
        , getHouse
        , queryHouses
        , getBooks
        , getBook
        , queryBooks
        , CharacterQuery
        , defaultCharacterQuery
        , HouseQuery
        , defaultHouseQuery
        , BookQuery
        , defaultBookQuery
        , Pagination
        , defaultPagination
        )

{-|

# Characters
@docs getCharacters, getCharacter, queryCharacters

# Houses
@docs getHouses, getHouse, queryHouses

# Books
@docs getBooks, getBook, queryBooks

# Pagination
@docs Pagination, defaultPagination

# Queries
@docs CharacterQuery, HouseQuery, BookQuery, defaultCharacterQuery, defaultHouseQuery, defaultBookQuery

-}

import Http
import HttpBuilder
import Date exposing (Date)
import Json.Decode
import Asoiaf.Models as Models


-- TYPES


type Query
    = Character CharacterQuery
    | House HouseQuery
    | Book BookQuery


{-| All requests are paginated. Use this to specify which page to request and
what page size to use.
-}
type alias Pagination =
    { page : Int
    , pageSize : Int
    }


{-| Represents the fields we can query characters by
-}
type alias CharacterQuery =
    { name : Maybe String
    , gender : Maybe String
    , culture : Maybe String
    , born : Maybe Int
    , died : Maybe Int
    , isAlive : Maybe Bool
    }


{-| Represents the fields we can query houses by
-}
type alias HouseQuery =
    { name : Maybe String
    , region : Maybe String
    , words : Maybe String
    , hasWords : Maybe Bool
    , hasTitles : Maybe Bool
    , hasSeats : Maybe Bool
    , hasDiedOut : Maybe Bool
    , hasAncestralWeapons : Maybe Bool
    }


{-| Represents the fields we can query books by
-}
type alias BookQuery =
    { name : Maybe String
    , fromReleaseDate : Maybe Date
    , toReleaseDate : Maybe Date
    }


{-| Default pagination.

    { page = 1
    , pageSize = 10
    }
-}
defaultPagination : Pagination
defaultPagination =
    { page = 1
    , pageSize = 10
    }


{-| Default character query. No fields specified.
-}
defaultCharacterQuery : CharacterQuery
defaultCharacterQuery =
    CharacterQuery Nothing
        Nothing
        Nothing
        Nothing
        Nothing
        Nothing


{-| Default house query. No fields specified.
-}
defaultHouseQuery : HouseQuery
defaultHouseQuery =
    HouseQuery Nothing
        Nothing
        Nothing
        Nothing
        Nothing
        Nothing
        Nothing
        Nothing


{-| Default book query. No fields specified.
-}
defaultBookQuery : BookQuery
defaultBookQuery =
    BookQuery Nothing
        Nothing
        Nothing



-- URLS


baseUrl : Models.Url
baseUrl =
    "https://www.anapioficeandfire.com/api"


charactersUrl : Models.Url
charactersUrl =
    baseUrl ++ "/characters/"


booksUrl : Models.Url
booksUrl =
    baseUrl ++ "/books/"


housesUrl : Models.Url
housesUrl =
    baseUrl ++ "/houses/"



-- QUERIES


{-| Query characters

    pagination =
      { page = 1
      , pageSize = 25
      }
    query =
      { defaultCharacterQuery
      | name = Just "Jon Snow"
      }
    queryCharacters pagination query == [ { name = "Jon Snow", ... } ]
-}
queryCharacters : Pagination -> CharacterQuery -> Http.Request (List Models.Character)
queryCharacters pagination query =
    getMultiple Models.decodeCharacter charactersUrl pagination (Character query)


{-| Query books

    pagination =
      { page = 1
      , pageSize = 25
      }
    query =
      { defaultBookQuery
      | name = Just "A Game of Thrones"
      }
    queryBooks pagination query == [ { name = "A Game of Thrones", ... } ]
-}
queryBooks : Pagination -> BookQuery -> Http.Request (List Models.Book)
queryBooks pagination query =
    getMultiple Models.decodeBook booksUrl pagination (Book query)


{-| Query houses

    pagination =
      { page = 1
      , pageSize = 25
      }
    query =
      { defaultBookQuery
      | words = Just "Winter is Coming"
      }
    queryHouses pagination query == [ { name = "House Stark of Winterfell", ... } ]
-}
queryHouses : Pagination -> HouseQuery -> Http.Request (List Models.House)
queryHouses pagination query =
    getMultiple Models.decodeHouse housesUrl pagination (House query)



-- GETTERS


{-| Get a list of characters
-}
getCharacters : Pagination -> Http.Request (List Models.Character)
getCharacters pagination =
    queryCharacters pagination defaultCharacterQuery


{-| Get a character by id
-}
getCharacter : Models.Id -> Http.Request Models.Character
getCharacter id =
    getSingle Models.decodeCharacter charactersUrl id


{-| Get a list of books
-}
getBooks : Pagination -> Http.Request (List Models.Book)
getBooks pagination =
    queryBooks pagination defaultBookQuery


{-| Get a book by id
-}
getBook : Models.Id -> Http.Request Models.Book
getBook id =
    getSingle Models.decodeBook booksUrl id


{-| Get a list of houses
-}
getHouses : Pagination -> Http.Request (List Models.House)
getHouses pagination =
    queryHouses pagination defaultHouseQuery


{-| Get a house by id
-}
getHouse : Models.Id -> Http.Request Models.House
getHouse id =
    getSingle Models.decodeHouse housesUrl id



-- HELPERS


isJust : Maybe a -> Bool
isJust mb =
    case mb of
        Just _ ->
            True

        Nothing ->
            False


queryToList : Query -> List ( String, String )
queryToList query =
    let
        queryList : List ( String, Maybe String )
        queryList =
            case query of
                Book q ->
                    [ ( "name", q.name )
                    , ( "fromReleaseDate", q.fromReleaseDate |> Maybe.map toString )
                    , ( "toReleaseTade", q.toReleaseDate |> Maybe.map toString )
                    ]

                Character q ->
                    [ ( "name", q.name )
                    , ( "gender", q.gender )
                    , ( "culture", q.culture )
                    , ( "born", q.born |> Maybe.map toString )
                    , ( "died", q.died |> Maybe.map toString )
                    , ( "isAlive", q.isAlive |> Maybe.map toString )
                    ]

                House q ->
                    [ ( "name", q.name )
                    , ( "region", q.region )
                    , ( "words", q.words )
                    , ( "hasWords", q.hasWords |> Maybe.map toString )
                    , ( "hasTitles", q.hasTitles |> Maybe.map toString )
                    , ( "hasSeats", q.hasSeats |> Maybe.map toString )
                    , ( "hasDiedOut", q.hasDiedOut |> Maybe.map toString )
                    , ( "hasAncestralWeapons", q.hasAncestralWeapons |> Maybe.map toString )
                    ]

        sndWithDefault ( a, b ) =
            ( a, b |> Maybe.withDefault "" )
    in
        queryList
            |> List.filter (Tuple.second >> isJust)
            |> List.map sndWithDefault


paginationToList : Pagination -> List ( String, String )
paginationToList pagination =
    [ ( "page", pagination.page |> toString )
    , ( "pageSize", pagination.pageSize |> toString )
    ]


getSingle : Json.Decode.Decoder a -> Models.Url -> Models.Id -> Http.Request a
getSingle decoder url id =
    Http.get (url ++ toString id) decoder


getMultiple : Json.Decode.Decoder a -> Models.Url -> Pagination -> Query -> Http.Request (List a)
getMultiple decoder url pagination query =
    let
        queryParams =
            queryToList query ++ paginationToList pagination
    in
        Http.get (HttpBuilder.url url queryParams) (Json.Decode.list decoder)