Listing books
This commit is contained in:
parent
f8f35007bf
commit
46c728c3c8
@ -20,17 +20,20 @@ import View
|
||||
|
||||
import qualified API.Users as Users
|
||||
import qualified API.Channels as Channels
|
||||
import qualified API.Books as Books
|
||||
|
||||
data Index = Index
|
||||
|
||||
type API = Get '[HTML] (AppView Index)
|
||||
:<|> Users.API
|
||||
:<|> Channels.API
|
||||
:<|> Books.API
|
||||
|
||||
handler :: ServerT API AppM
|
||||
handler = indexHandler
|
||||
:<|> Users.handler
|
||||
:<|> Channels.handler
|
||||
:<|> Books.handler
|
||||
|
||||
instance ToHtml Index where
|
||||
toHtml _ = do
|
||||
|
51
src/API/Books.hs
Normal file
51
src/API/Books.hs
Normal file
@ -0,0 +1,51 @@
|
||||
{-# Language DataKinds #-}
|
||||
{-# Language TypeFamilies #-}
|
||||
{-# Language TypeOperators #-}
|
||||
{-# Language NoImplicitPrelude #-}
|
||||
{-# Language MultiParamTypeClasses #-}
|
||||
{-# Language OverloadedStrings #-}
|
||||
{-# Language TemplateHaskell #-}
|
||||
{-# Language QuasiQuotes #-}
|
||||
{-# Language RecordWildCards #-}
|
||||
{-# Language DeriveGeneric #-}
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language TypeApplications #-}
|
||||
{-# Language DataKinds #-}
|
||||
module API.Books where
|
||||
|
||||
import Servant hiding (contentType)
|
||||
import Types
|
||||
import ClassyPrelude
|
||||
import Server.Auth
|
||||
import Servant.Auth as SA
|
||||
import Data.Aeson
|
||||
import API.Channels (JsonChannel(..))
|
||||
import Database.Book
|
||||
import Database.Channel
|
||||
import Database
|
||||
import Control.Lens
|
||||
import Data.Generics.Product
|
||||
|
||||
data JsonBook = JsonBook { contentType :: Text
|
||||
, title :: Maybe Text
|
||||
, description :: Maybe Text
|
||||
, channels :: [JsonChannel] }
|
||||
deriving (Generic, Show)
|
||||
|
||||
instance ToJSON JsonBook
|
||||
instance FromJSON JsonBook
|
||||
|
||||
type API = Auth '[SA.BasicAuth, SA.JWT] SafeUser :> BaseAPI
|
||||
|
||||
type BaseAPI = "books" :> Get '[JSON] [JsonBook]
|
||||
|
||||
handler :: ServerT API AppM
|
||||
handler user = listBooksHandler user
|
||||
|
||||
listBooksHandler :: AuthResult SafeUser -> AppM [JsonBook]
|
||||
listBooksHandler = requireLoggedIn $ \user -> do
|
||||
runDB (usersBooks (view (field @"username") user) >>= mapM augment)
|
||||
where
|
||||
augment Book{..} = do
|
||||
channels <- fmap (\Channel{..} -> JsonChannel{..}) <$> booksChannels contentHash
|
||||
pure JsonBook{..}
|
@ -11,7 +11,7 @@
|
||||
{-# Language FlexibleInstances #-}
|
||||
{-# Language TypeApplications #-}
|
||||
{-# Language DataKinds #-}
|
||||
module API.Channels (API, handler) where
|
||||
module API.Channels (API, handler, JsonChannel(..)) where
|
||||
|
||||
import Servant
|
||||
import Types
|
||||
|
21
src/Database/Book.hs
Normal file
21
src/Database/Book.hs
Normal file
@ -0,0 +1,21 @@
|
||||
{-# Language TypeApplications #-}
|
||||
{-# Language DataKinds #-}
|
||||
module Database.Book (usersBooks, Book(..)) where
|
||||
|
||||
import ClassyPrelude
|
||||
import Database.Schema
|
||||
import Database
|
||||
import Database.Selda
|
||||
|
||||
usersBooks :: (MonadMask m, MonadIO m) => Username -> SeldaT m [Book]
|
||||
usersBooks username = fromRels <$> query q
|
||||
where
|
||||
q = do
|
||||
userId :*: _ :*: username' :*: _ <- select (gen users)
|
||||
userId' :*: bookHash' <- select (gen userBooks)
|
||||
book@(bookHash :*: _) <- select (gen books)
|
||||
restrict (bookHash .== bookHash')
|
||||
restrict (username' .== literal username)
|
||||
restrict (userId .== userId')
|
||||
return book
|
||||
|
@ -3,6 +3,7 @@
|
||||
module Database.Channel
|
||||
( userChannels
|
||||
, insertChannel
|
||||
, booksChannels
|
||||
, Channel(..) )
|
||||
where
|
||||
|
||||
@ -32,3 +33,13 @@ insertChannel username channel = do
|
||||
userId :*: _ :*: user :*: _ <- select (gen users)
|
||||
restrict (user .== literal username)
|
||||
return userId
|
||||
|
||||
booksChannels :: (MonadMask m, MonadIO m) => HashDigest -> SeldaT m [Channel]
|
||||
booksChannels contentHash = fromRels <$> query q
|
||||
where
|
||||
q = do
|
||||
channelId :*: contentHash' <- select (gen bookChannels)
|
||||
ch@(channelId' :*: _) <- select (gen channels)
|
||||
restrict (channelId .== channelId')
|
||||
restrict (contentHash' .== literal contentHash)
|
||||
return ch
|
||||
|
@ -83,15 +83,15 @@ instance SqlType HashDigest where
|
||||
books :: GenTable Book
|
||||
books = genTable "books" [ contentHash :- primaryGen ]
|
||||
|
||||
data UserBook = UserBook { email :: Text
|
||||
data UserBook = UserBook { user :: RowID
|
||||
, book :: HashDigest }
|
||||
deriving (Generic, Show)
|
||||
|
||||
userBooks :: GenTable UserBook
|
||||
userBooks = genTable "user_book" [ (email :: UserBook -> Text) :- fkGen (gen users) userEmail
|
||||
userBooks = genTable "user_book" [ (user :: UserBook -> RowID) :- fkGen (gen users) userId
|
||||
, (book :: UserBook -> HashDigest) :- fkGen (gen books) bookHash ]
|
||||
where
|
||||
_ :*: userEmail :*: _ = selectors (gen users)
|
||||
userId :*: _ = selectors (gen users)
|
||||
bookHash :*: _ = selectors (gen books)
|
||||
|
||||
-- | Categorizing books
|
||||
|
Loading…
Reference in New Issue
Block a user