{-# LANGUAGE CPP, OverloadedStrings #-} module Sound.Freesound.Search ( SortMethod(..) , SortDirection(..) , Sorting , unsorted , sortedBy , Pagination(..) , module Sound.Freesound.Search.Filter , module Sound.Freesound.Search.Numerical , module Sound.Freesound.Search.Query , search , search_ ) where import qualified Data.ByteString.Char8 as BS import Data.Default (Default) import Sound.Freesound.Search.Filter import Sound.Freesound.Search.Numerical import Sound.Freesound.Search.Query import qualified Data.ByteString as B import Data.Default (def) import qualified Data.Text as T import Network.HTTP.Types.QueryLike (QueryLike(..), QueryValueLike(..)) import Sound.Freesound.List (List) import Sound.Freesound.Sound.Type import Sound.Freesound.API (Freesound, get, resourceURI) #if __GLASGOW_HASKELL__ < 710 import Control.Applicative #endif data SortMethod = Duration | Created | Downloads | Rating deriving (Eq, Show) data SortDirection = Ascending | Descending deriving (Eq, Show) data Sorting = Unsorted | SortedBy SortMethod SortDirection deriving (Eq, Show) unsorted :: Sorting unsorted = Unsorted sortedBy :: SortMethod -> SortDirection -> Sorting sortedBy = SortedBy instance Default Sorting where def = unsorted instance QueryValueLike Sorting where toQueryValue Unsorted = Nothing toQueryValue (SortedBy Duration Ascending) = Just $ BS.pack "duration_asc" toQueryValue (SortedBy Duration Descending) = Just $ BS.pack "duration_desc" toQueryValue (SortedBy Created Ascending) = Just $ BS.pack "created_asc" toQueryValue (SortedBy Created Descending) = Just $ BS.pack "created_desc" toQueryValue (SortedBy Downloads Ascending) = Just $ BS.pack "downloads_asc" toQueryValue (SortedBy Downloads Descending) = Just $ BS.pack "downloads_desc" toQueryValue (SortedBy Rating Ascending) = Just $ BS.pack "rating_asc" toQueryValue (SortedBy Rating Descending) = Just $ BS.pack "rating_desc" data Pagination = Pagination { page :: Int , pageSize :: Int } deriving (Eq, Show) instance Default Pagination where def = Pagination 0 15 instance QueryLike Pagination where toQuery a = toQuery [ if page def == page a then Nothing else Just (BS.pack "page", show (page a + 1)) , if pageSize def == pageSize a then Nothing else Just (BS.pack "page_size", show (pageSize a)) ] search :: Pagination -> Sorting -> Filters -> Query -> Freesound (List Summary) search p s fs q = get $ resourceURI [ "search", "text" ] (toQuery p ++ toQuery [ pair "query" q , pair "filter" fs , pair "sort" s ]) -- TODO: group_by_pack (changes response type) where pair :: QueryValueLike a => T.Text -> a -> Maybe (T.Text, B.ByteString) pair k a = (,) <$> pure k <*> toQueryValue a search_ :: Query -> Freesound (List Summary) search_ = search def def def