<commit_before>
{-# LANGUAGE OverloadedStrings #-}

module RestApi (
    apiApp
    ) where

import           Control.Applicative ( Applicative )
import           Control.Monad.Catch ( MonadCatch, MonadMask, MonadThrow, bracket )
import           Control.Monad.IO.Class ( MonadIO, liftIO )
import           Control.Monad.Reader ( ReaderT, ask )
import           Control.Monad.Trans.Class ( lift )
import           Data.Aeson ( ToJSON(..), (.=) )
import qualified Data.Aeson as JSON
import           Network.HTTP.Types ( status200 )
import qualified Network.Wai as WAI
import           Network.Wai.Middleware.AddHeaders ( addHeaders )
import           Rest.Driver.Wai ( apiToApplication )
import           Rest
import           Rest.Api ( Api, Router, Some1(..), route, root, mkVersion, (-/) )
import qualified Rest.Resource as R

import           Database
import           Mdb.Database.Album ( AlbumId )
import           Mdb.Database.File ( FileId )
import           Mdb.Database.Person ( PersonId )

apiApp :: MediaDb -> WAI.Application
apiApp mdb = addHeaders [ ("Access-Control-Allow-Origin", "*") ] $
    apiToApplication (runMDB' mdb) api

api :: (Applicative m, MonadIO m) => Api (MDB m)
api = [(mkVersion 0 1 0, Some1 api010)]

api010 :: (Applicative m, MonadIO m) => Router (MDB m) (MDB m)
api010 = root
            -/ albums
            -/ files
            -/ persons
    where
        albums  = route albumResource
        files   = route fileResource
        persons = route personResource

-------------------------------------------------------------------------------
-- Files
-------------------------------------------------------------------------------

data FileListSelector
    = AllFiles
    | FilesInAlbum AlbumId

type WithFile m = ReaderT FileId m

fileResource :: (Applicative m, MonadIO m) => Resource (MDB m) (WithFile m) FileId FileListSelector Void
fileResource = R.Resource
    { R.name        = "file"
    , R.description = "Access file info"
    , R.schema      = withListing AllFiles $ named [("inAlbum", listingBy (FilesInAlbum . read))]
    , R.list        = fileListHandler
    }

fileListHandler :: MonadIO m => FileListSelector -> ListHandler (MDB m)
fileListHandler AllFiles = mkListing xmlJsonO handler where
    handler r = lift $ listFiles (offset r) (count r)
fileListHandler (FilesInAlbum aid) = mkListing xmlJsonO handler where
    handler _ = lift $ albumFiles aid

-------------------------------------------------------------------------------
-- Persons
-------------------------------------------------------------------------------

data PersonSelector
    = AllPersons
    | InAlbum AlbumId

type WithPerson m = ReaderT PersonId m

personResource :: (Applicative m, MonadIO m) => Resource (MDB m) (WithPerson m) PersonId PersonSelector Void
personResource = R.Resource
    { R.name        = "person"
    , R.description = "Access persons"
    , R.schema      = withListing AllPersons schemas
    , R.list        = personListHandler
    , R.get         = Nothing
    } where
        schemas = named
            [ ( "inAlbum"   , listingBy (InAlbum . read) )
            ]

personListHandler :: MonadIO m => PersonSelector -> ListHandler (MDB m)<commit_msg>rest: Can fetch person files without album<commit_after>
{-# LANGUAGE OverloadedStrings #-}

module RestApi (
    apiApp
    ) where

import           Control.Applicative ( Applicative )
import           Control.Monad.Catch ( MonadCatch, MonadMask, MonadThrow, bracket )
import           Control.Monad.IO.Class ( MonadIO, liftIO )
import           Control.Monad.Reader ( ReaderT, ask )
import           Control.Monad.Trans.Class ( lift )
import           Data.Aeson ( ToJSON(..), (.=) )
import qualified Data.Aeson as JSON
import           Network.HTTP.Types ( status200 )
import qualified Network.Wai as WAI
import           Network.Wai.Middleware.AddHeaders ( addHeaders )
import           Rest.Driver.Wai ( apiToApplication )
import           Rest
import           Rest.Api ( Api, Router, Some1(..), route, root, mkVersion, (-/) )
import qualified Rest.Resource as R

import           Database
import           Mdb.Database.Album ( AlbumId )
import           Mdb.Database.File ( FileId )
import           Mdb.Database.Person ( PersonId )

apiApp :: MediaDb -> WAI.Application
apiApp mdb = addHeaders [ ("Access-Control-Allow-Origin", "*") ] $
    apiToApplication (runMDB' mdb) api

api :: (Applicative m, MonadIO m) => Api (MDB m)
api = [(mkVersion 0 1 0, Some1 api010)]

api010 :: (Applicative m, MonadIO m) => Router (MDB m) (MDB m)
api010 = root
            -/ albums
            -/ files
            -/ persons
    where
        albums  = route albumResource
        files   = route fileResource
        persons = route personResource

-------------------------------------------------------------------------------
-- Files
-------------------------------------------------------------------------------

data FileListSelector
    = AllFiles
    | FilesInAlbum AlbumId
    | PersonNoAlbum PersonId

type WithFile m = ReaderT FileId m

fileResource :: (Applicative m, MonadIO m) => Resource (MDB m) (WithFile m) FileId FileListSelector Void
fileResource = R.Resource
    { R.name        = "file"
    , R.description = "Access file info"
    , R.schema      = withListing AllFiles schemas
    , R.list        = fileListHandler
    } where
        schemas = named
            [ ( "inAlbum"       , listingBy (FilesInAlbum . read) )
            , ( "personNoAlbum" , listingBy (PersonNoAlbum . read) )
            ]

fileListHandler :: MonadIO m => FileListSelector -> ListHandler (MDB m)
fileListHandler AllFiles = mkListing xmlJsonO handler where
    handler r = lift $ listFiles (offset r) (count r)
fileListHandler (FilesInAlbum aid) = mkListing xmlJsonO handler where
    handler _ = lift $ albumFiles aid
fileListHandler (PersonNoAlbum pid) = mkListing xmlJsonO handler where
    handler _ = lift $ getRandomPersonFiles pid

-------------------------------------------------------------------------------
-- Persons
-------------------------------------------------------------------------------

data PersonSelector
    = AllPersons
    | InAlbum AlbumId

type WithPerson m = ReaderT PersonId m

personResource :: (Applicative m, MonadIO m) => Resource (MDB m) (WithPerson m) PersonId PersonSelector Void
personResource = R.Resource
    { R.name        = "person"
    , R.description = "Access persons"
    , R.schema      = withListing AllPersons schemas
    , R.list        = personListHandler
    , R.get         = Nothing
    } where
        schemas = named
            [ ( "inAlbum"   , listingBy (InAlbum . read) )
            ]

personListHandler :: MonadIO m => PersonSelector -> ListHandler (MDB m)
{'fraction_non_alphanumeric': 0.17838561022744165, 'fraction_numerical': 0.00505425895644418, 'mean_word_length': 1.820964360587002, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 5}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '602226', 'n_tokens_mistral': 1872, 'n_tokens_neox': 1813, 'n_words': 535}