module Alfred.Query (jsonQuery,escapeString,escapeText) where import Network.HTTP import Network.URI hiding (escapeString) import Data.Aeson import Data.ByteString (ByteString) import Data.Char import qualified Data.Text as T import Data.Text (Text) -- | This function performs a query by performing an HTTP GET request -- at the url obtained by concatenating the first argument with the -- second one (after escaping it). The first argument is intended to -- be the base url and the second one the query string. The result is -- then parsed as a JSON object. For example, -- for a Google search: -- -- @ -- runQuery :: String -> IO (Text,[Text]) -- runQuery query = jsonQuery suggestURL query -- -- suggestURL = "http://suggestqueries.google.com/complete/search?output=toolbar&client=firefox&hl=en&q=" -- @ -- jsonQuery :: FromJSON a => String -> String -> IO a jsonQuery base query = case (parseURI $ base ++ escapeString query) of Nothing -> error "illformed url" Just url -> do res <- simpleHTTP (mkJSONRequest url) case res of Left err -> error (show err) Right res -> case eitherDecodeStrict (rspBody res) of Left msg -> error ("JSON decoding error: " ++ msg ++ "\n" ++ show (rspBody res)) Right res -> return res mkJSONRequest :: URI -> Request ByteString mkJSONRequest url = setHeaders (mkRequest GET url) jsonHeaders jsonHeaders :: [Header] jsonHeaders = [mkHeader HdrContentType "application/json"] -- | Escapes the string for use in a URL. escapeString :: String -> String escapeString = escapeURIString isAlphaNum -- | Escapes the text for use in a URL. escapeText :: Text -> Text escapeText = T.pack . escapeString . T.unpack