module Network.Google.Drive.Search
( listFiles
, listVisibleContents
, Query
, Field(..)
, QueryValue(..)
, (?=)
, (?!=)
, (?<)
, (?<=)
, (?>)
, (?>=)
, (?&&)
, (?||)
, qIn
, qHas
, qContains
, qAnd
, qOr
, qNot
) where
import Network.Google.Api
import Network.Google.Drive.DateTime
import Network.Google.Drive.File
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>), (<$>))
#endif
import Control.Monad (mzero)
import Data.Aeson
import Data.Char (toLower)
import Data.Monoid ((<>))
import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8)
import Data.Time (UTCTime)
import qualified Data.Text as T
type Query = Text
data Field
= Title
| FullText
| MimeType
| ModifiedDate
| LastViewedByMeDate
| Trashed
| Starred
| Parents
| Owners
| Writers
| Readers
| SharedWithMe
| Properties
deriving Show
class QueryValue a where
escapeValue :: a -> Text
instance QueryValue Text where
escapeValue t = "'" <> t <> "'"
instance QueryValue Bool where
escapeValue True = "true"
escapeValue False = "false"
instance QueryValue UTCTime where
escapeValue = formatDateTime
newtype Items = Items [File]
instance FromJSON Items where
parseJSON (Object o) = Items <$> (mapM parseJSON =<< o .: "items")
parseJSON _ = mzero
listFiles :: Query -> Api [File]
listFiles query = do
Items items <- getJSON (baseUrl <> "/files")
[ ("q", Just $ encodeUtf8 query)
, ("maxResults", Just "1000")
]
return items
listVisibleContents :: File -> Api [File]
listVisibleContents folder =
listFiles $ (fileId folder) `qIn` Parents `qAnd` Trashed ?= False
(?=) :: QueryValue a => Field -> a -> Query
(?=) = qOp "="
(?!=) :: QueryValue a => Field -> a -> Query
(?!=) = qOp "!="
(?<) :: QueryValue a => Field -> a -> Query
(?<) = qOp "<"
(?<=) :: QueryValue a => Field -> a -> Query
(?<=) = qOp "<="
(?>) :: QueryValue a => Field -> a -> Query
(?>) = qOp ">"
(?>=) :: QueryValue a => Field -> a -> Query
(?>=) = qOp ">="
qIn :: QueryValue a => a -> Field -> Query
qIn v f = T.intercalate " " [escapeValue v, "in", escapeField f]
qHas :: QueryValue a => Field -> a -> Query
qHas = qOp "has"
qContains :: QueryValue a => Field -> a -> Query
qContains = qOp "contains"
infixr 3 ?&&
(?&&) :: Query -> Query -> Query
q ?&& p = "(" <> p <> ") and (" <> q <> ")"
infixr 3 `qAnd`
qAnd :: Query -> Query -> Query
qAnd = (?&&)
infixr 2 ?||
(?||) :: Query -> Query -> Query
q ?|| p = "(" <> p <> ") or (" <> q <> ")"
infixr 2 `qOr`
qOr :: Query -> Query -> Query
qOr = (?||)
qNot :: Query -> Query
qNot q = "not " <> "(" <> q <> ")"
qOp :: QueryValue a => Text -> Field -> a -> Query
qOp x f v = T.intercalate " " [escapeField f, x, escapeValue v]
escapeField :: Field -> Text
escapeField = T.pack . lowerCase . show
where
lowerCase [] = []
lowerCase (x:xs) = toLower x : xs
baseUrl :: URL
baseUrl = "https://www.googleapis.com/drive/v2"