/src/LambdaLauncher/Plugins/Duckduckgo.hs

https://github.com/balsoft/lambda-launcher · Haskell · 56 lines · 43 code · 12 blank · 1 comment · 1 complexity · cdd8b942878726a099961d38bf3153fc MD5 · raw file

  1. {-# LANGUAGE OverloadedStrings #-}
  2. module LambdaLauncher.Plugins.Duckduckgo where
  3. import LambdaLauncher.Plugins.Support
  4. import LambdaLauncher.Types
  5. import Control.Monad.IO.Class (liftIO)
  6. import Data.Aeson
  7. import Data.Default.Class
  8. import Data.Maybe (catMaybes)
  9. import Data.Monoid ((<>))
  10. import Data.Text (Text)
  11. import Network.HTTP.Req
  12. data RelatedTopic = RelatedTopic
  13. { text :: Maybe Text
  14. , firstURL :: Maybe Text
  15. } deriving (Eq, Show)
  16. newtype DDGResponse = DDGResponse
  17. { relatedTopics :: [RelatedTopic]
  18. } deriving (Eq, Show)
  19. instance FromJSON RelatedTopic where
  20. parseJSON (Object o) = RelatedTopic <$> (o .:? "Text") <*> (o .:? "FirstURL")
  21. parseJSON _ = mempty
  22. instance FromJSON DDGResponse where
  23. parseJSON (Object o) = DDGResponse <$> o .: "RelatedTopics"
  24. parseJSON _ = mempty
  25. fetchDDGAPI s =
  26. runReq defaultHttpConfig $ do
  27. bs <-
  28. req GET (https "api.duckduckgo.com") NoReqBody bsResponse $
  29. ("q" =: s) <>
  30. ("format" =: ("json" :: String))
  31. liftIO $ return $ responseBody bs
  32. getDDGInstantResponse :: Text -> IO DDGResponse
  33. getDDGInstantResponse s = do
  34. Right b <- eitherDecodeStrict <$> fetchDDGAPI s
  35. return b
  36. topicToResult :: RelatedTopic -> Maybe LambdaLauncher.Types.Result
  37. topicToResult (RelatedTopic (Just t) (Just u)) =
  38. Just $ Action t 2 $ openUrlAction u
  39. topicToResult _ = Nothing
  40. duckduckgo :: Plugin
  41. duckduckgo s | s == "" = mempty
  42. | otherwise = do
  43. DDGResponse r <- getDDGInstantResponse s
  44. return $ catMaybes $ topicToResult <$> r