freesound-0.2.0: src/Sound/Freesound/Search/Filter.hs
{-# LANGUAGE CPP, OverloadedStrings #-}
module Sound.Freesound.Search.Filter (
Filters
, id
, username
, created
, originalFilename
, description
, tag
, license
, isRemix
, wasRemixed
, pack
, isGeotagged
, fileType
, duration
, bitdepth
, bitrate
, samplerate
, filesize
, channels
, md5
, numDownloads
, avgRating
, numRatings
, comment
, comments
) where
import Data.Default (Default(..))
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import Network.HTTP.Types.QueryLike (QueryValueLike(..))
import Prelude hiding (id)
import Sound.Freesound.Search.Numerical (Numerical)
import Sound.Freesound.Sound.Type (FileType, SoundId)
#if __GLASGOW_HASKELL__ < 710
import Data.Monoid (Monoid(..))
#endif
data License = Attribution | AttributionNoncommercial | CreativeCommons0 deriving (Eq, Show)
instance QueryValueLike License where
toQueryValue Attribution = toQueryValue $ BS.pack "Attribution"
toQueryValue AttributionNoncommercial = toQueryValue $ BS.pack "Attribution Noncommercial"
toQueryValue CreativeCommons0 = toQueryValue $ BS.pack "Creative Commons 0"
-- | Newtype wrapper for avoiding orphan instance.
newtype F_Bool = F_Bool Bool deriving (Eq, Show)
instance QueryValueLike F_Bool where
toQueryValue (F_Bool True) = toQueryValue $ BS.pack "true"
toQueryValue (F_Bool False) = toQueryValue $ BS.pack "false"
data Filter =
F_id (Numerical SoundId) -- integer, sound id on freesound
| F_username Text -- string, not tokenized
| F_created Text -- date
| F_original_filename Text -- string, tokenized
| F_description Text -- string, tokenized
| F_tag Text
| F_license License
| F_is_remix F_Bool
| F_was_remixed F_Bool
| F_pack Text
--pack_tokenized: string, tokenized
| F_is_geotagged F_Bool
| F_type FileType
| F_duration (Numerical Double) -- duration of sound in seconds
| F_bitdepth (Numerical Integer) -- WARNING is not to be trusted right now
| F_bitrate (Numerical Integer) -- WARNING is not to be trusted right now
| F_samplerate (Numerical Integer)
| F_filesize (Numerical Integer) -- file size in bytes
| F_channels (Numerical Integer) -- number of channels in sound, mostly 1 or 2, sometimes more
| F_md5 Text -- 32-byte md5 hash of file
| F_num_downloads (Numerical Integer) -- all zero right now (not imported data)
| F_avg_rating (Numerical Double) -- average rating, from 0 to 5
| F_num_ratings (Numerical Integer) -- number of ratings
| F_comment Text -- tokenized
| F_comments (Numerical Integer) -- number of comments
deriving (Eq, Show)
mkF :: QueryValueLike a => ByteString -> a -> Maybe ByteString
mkF t = fmap (BS.append (BS.append t ":")) . toQueryValue
instance QueryValueLike Filter where
toQueryValue filterSpec =
case filterSpec of
F_id x -> mkF "id" x
F_username x -> mkF "username" x
F_created x -> mkF "created" x
F_original_filename x -> mkF "original_filename" x
F_description x -> mkF "description" x
F_tag x -> mkF "tag" x
F_license x -> mkF "license" x
F_is_remix x -> mkF "is_remix" x
F_was_remixed x -> mkF "was_remixed" x
F_pack x -> mkF "pack" x
--F_pack_tokenized: string, tokenized
F_is_geotagged x -> mkF "is_geotagged" x
F_type x -> mkF "type" x
F_duration x -> mkF "duration" x
F_bitdepth x -> mkF "bitdepth" x
F_bitrate x -> mkF "bitrate" x
F_samplerate x -> mkF "samplerate" x
F_filesize x -> mkF "filesize" x
F_channels x -> mkF "channels" x
F_md5 x -> mkF "md5" x
F_num_downloads x -> mkF "num_downloads" x
F_avg_rating x -> mkF "avg_rating" x
F_num_ratings x -> mkF "num_ratings" x
F_comment x -> mkF "comment" x
F_comments x -> mkF "comments" x
newtype Filters = Filters [Filter] deriving (Show)
instance Monoid Filters where
mempty = Filters []
mappend (Filters a) (Filters b) = Filters (a++b)
instance Default Filters where
def = mempty
instance QueryValueLike Filters where
toQueryValue (Filters []) = Nothing
toQueryValue (Filters fs) = Just $ BS.unwords $ mapMaybe toQueryValue fs
fromFilter :: Filter -> Filters
fromFilter = Filters . (:[])
-- | Sound id on Freesound.
id :: Numerical SoundId -> Filters
id = fromFilter . F_id
username :: Text -> Filters
username = fromFilter . F_username
created :: Text -> Filters
created = fromFilter . F_created
originalFilename :: Text -> Filters
originalFilename = fromFilter . F_original_filename
description :: Text -> Filters
description = fromFilter . F_description
tag :: Text -> Filters
tag = fromFilter . F_tag
license :: License -> Filters
license = fromFilter . F_license
isRemix :: Bool -> Filters
isRemix = fromFilter . F_is_remix . F_Bool
wasRemixed :: Bool -> Filters
wasRemixed = fromFilter . F_was_remixed . F_Bool
pack :: Text -> Filters
pack = fromFilter . F_pack
isGeotagged :: Bool -> Filters
isGeotagged = fromFilter . F_is_geotagged . F_Bool
fileType :: FileType -> Filters
fileType = fromFilter . F_type
-- | Duration of sound in seconds.
duration :: Numerical Double -> Filters
duration = fromFilter . F_duration
-- | WARNING is not to be trusted right now.
bitdepth :: Numerical Integer -> Filters
bitdepth = fromFilter . F_bitdepth
-- | WARNING is not to be trusted right now.
bitrate :: Numerical Integer -> Filters
bitrate = fromFilter . F_bitrate
samplerate :: Numerical Integer -> Filters
samplerate = fromFilter . F_samplerate
-- | File size in bytes.
filesize :: Numerical Integer -> Filters
filesize = fromFilter . F_filesize
-- | Number of channels in sound, mostly 1 or 2, sometimes more.
channels :: Numerical Integer -> Filters
channels = fromFilter . F_channels
-- | 32-byte md5 hash of file.
md5 :: Text -> Filters
md5 = fromFilter . F_md5
-- | All zero right now (not imported data).
numDownloads :: Numerical Integer -> Filters
numDownloads = fromFilter . F_num_downloads
-- | Average rating, from 0 to 5.
avgRating :: Numerical Double -> Filters
avgRating = fromFilter . F_avg_rating
-- | Number of ratings.
numRatings :: Numerical Integer -> Filters
numRatings = fromFilter . F_num_ratings
comment :: Text -> Filters
comment = fromFilter . F_comment
-- | Number of comments.
comments :: Numerical Integer -> Filters
comments = fromFilter . F_comments