alfred 0.3 → 0.3.1
raw patch · 3 files changed
+70/−53 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- alfred.cabal +1/−1
- src/Alfred.hs +38/−35
- src/Alfred/Query.hs +31/−17
alfred.cabal view
@@ -1,5 +1,5 @@ Name: alfred-Version: 0.3+Version: 0.3.1 Synopsis: utility library for Alfred version 2 Description: A utility library for writing workflows for Alfred version 2
src/Alfred.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE OverloadedStrings, NamedFieldPuns #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverloadedStrings #-} -------------------------------------------------------------------------------- -- |@@ -12,21 +13,22 @@ -- This module provides utility functions to interact with Alfred -- version 2. It is intended to be used for writing "script filters" -- used in Alfred workflows.--- +-- -- For example the following excerpt defines a script for Google -- search with auto completion:--- +-- -- @ -- import Alfred -- import Alfred.Query -- import qualified Data.Text as T -- import Data.Text (Text)--- --- runQuery :: String -> IO (Text,[Text])--- runQuery query = jsonQuery suggestURL query--- --- suggestURL = "http://suggestqueries.google.com/complete/search?output=toolbar&client=firefox&hl=en&q="--- +-- import Data.Text.Encoding+--+-- runQuery :: Query (Text,[Text])+-- runQuery = jsonQuery suggestURL+--+-- suggestURL = "http://google.com/complete/search?client=firefox&q="+-- -- mkItems :: Renderer [Text] -- mkItems = searchRenderer Search { -- searchURL = \s -> T.concat ["https://www.google.com/search?q=", s],@@ -35,8 +37,8 @@ -- -- main = runScript (transformQuery snd runQuery) mkItems -- @--- --+-- -------------------------------------------------------------------------------- @@ -53,15 +55,15 @@ , Search (..) , Search' (..)) where -import Text.XML.Generator+import Control.Applicative+import Data.ByteString (ByteString) import qualified Data.ByteString as B+import Data.List+import Data.Monoid import Data.Text (Text) import qualified Data.Text as T-import Data.ByteString (ByteString)-import Data.Monoid import System.Environment-import Data.List-import Control.Applicative+import Text.XML.Generator import Alfred.Query @@ -69,14 +71,14 @@ -- the result of a script filter. data Item = Item {- uid :: Maybe Text- , arg :: Text- , isFile :: Bool- , valid :: Maybe Bool+ uid :: Maybe Text+ , arg :: Text+ , isFile :: Bool+ , valid :: Maybe Bool , autocomplete :: Maybe Text- , title :: Text- , subtitle :: Text- , icon :: Maybe Icon+ , title :: Text+ , subtitle :: Text+ , icon :: Maybe Icon } -- | Default item.@@ -104,13 +106,13 @@ -- | Render an item as XML element. xmlItem :: Item -> Xml Elem-xmlItem (Item uid arg file val auto title sub icon) = +xmlItem (Item uid arg file val auto title sub icon) = xelem "item" $ (uid' <> xattr "arg" arg <> val' <> auto' <> file') <#> (xelemWithText "title" title <> xelemWithText "subtitle" sub <> icon')- + where uid' = case uid of Nothing -> mempty; Just uid -> xattr "uid" uid- val' = case val of + val' = case val of Nothing -> mempty Just val -> xattr "valid" (if val then "yes" else "no") file' = if file then xattr "type" "file" else mempty@@ -119,7 +121,7 @@ -- | Render items as an XML element. xmlItems :: Items -> Xml Elem-xmlItems = xelem "items" . mconcat . map xmlItem +xmlItems = xelem "items" . mconcat . map xmlItem -- | Render items as an XML 'ByteString'.@@ -180,14 +182,14 @@ -- | This data type represents advanced standard search scripts used -- by 'searchRenderer''.-data Search' a = Search' {simpleSearch :: Search, +data Search' a = Search' {simpleSearch :: Search, resultURL :: a -> Text, resultTitle :: a -> Text} -- | This function produces a rendering function for standard search -- scripts. For example a Google search rendering function is defined -- as follows:--- +-- -- @ -- mkItems :: Renderer [Text] -- mkItems = searchRenderer Search {@@ -195,20 +197,21 @@ -- notFound = \s -> T.concat ["No suggestion. Google for ", s, "."], -- found = \s -> T.concat ["Search results for ", s]} -- @--- +-- searchRenderer :: Search -> Renderer [Text]-searchRenderer s = searchRenderer' Search' {simpleSearch = s, resultURL = searchURL s, resultTitle = id}+searchRenderer s = searchRenderer' Search' { simpleSearch = s, resultURL = searchURL s . escapeText+ , resultTitle = id} -- | This function produces a rendering function for standard search -- scripts. As opposed to the simpler variant 'searchRenderer', this -- function works on arbitrary query result types. For example a DBLP -- search rendering function is defined as follows:--- +-- -- @ -- mkItems :: Renderer [(Text, Text)]--- mkItems = searchRenderer' Search'{ +-- mkItems = searchRenderer' Search'{ -- simpleSearch = Search { -- searchURL = \s -> T.concat ["http://dblp.uni-trier.de/search/author?author=", s], -- notFound = \s -> T.concat ["No suggestion. Search DBLP for ", s, "."],@@ -216,7 +219,7 @@ -- resultURL = \(_,r) -> T.concat ["http://dblp.uni-trier.de/pers/hd/",r,".html"], -- resultTitle = fst} -- @--- +-- -- In the above example the query result type is @(Text,Text)@ where -- the first component is the name of the result and the second -- component is used to construct a URL that leads directly to the@@ -224,8 +227,8 @@ searchRenderer' :: Search' a -> Renderer [a]-searchRenderer' Search' {simpleSearch = Search {searchURL, found, notFound}, resultURL, resultTitle} s res = - case res of +searchRenderer' Search' {simpleSearch = Search {searchURL, found, notFound}, resultURL, resultTitle} s res =+ case res of (Right suggs) -> case suggs of [] -> [Item {uid=Nothing,arg=searchURL2 (escapeText s),isFile=False, valid=Nothing,autocomplete=Nothing,title=s,
src/Alfred/Query.hs view
@@ -1,7 +1,21 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeSynonymInstances #-} -module Alfred.Query +--------------------------------------------------------------------------------+-- |+-- Module : Alfred.Query+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@di.ku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This module provides utility functions to query web APIs. These+-- queries can then be used to feed Alfred with suggestions.+--+--------------------------------------------------------------------------------++module Alfred.Query ( jsonQuery , jsonQuery' , xmlQuery@@ -13,16 +27,16 @@ , Query' ) where -import Network.HTTP+import Data.Aeson import Network.BufferType+import Network.HTTP import Network.URI hiding (escapeString)-import Data.Aeson import qualified Data.Text as T +import Data.ByteString import Data.Text (Text) import System.IO.Error-import Data.ByteString import Text.XML.Expat.Tree @@ -40,14 +54,14 @@ -- as an argument and appends it to the base url to obtain the url -- that is used for the query. The result is then parsed as a JSON -- object. For example, for a Google search:--- +-- -- @ -- runQuery :: Query (Text,[Text]) -- runQuery = jsonQuery suggestURL--- +-- -- suggestURL = "http://google.com/complete/search?client=firefox&q=" -- @--- +-- jsonQuery :: FromJSON a => Text -> Query a jsonQuery = jsonQuery' id@@ -58,20 +72,20 @@ -- 'ByteString' that is returned by the query. This can be helpful if -- the source does not provide valid UTF-8 formatted JSON. For -- example, for a Google search:--- +-- -- @ -- runQuery :: Query (Text,[Text]) -- runQuery = jsonQuery' (encodeUtf8 . decodeLatin1) suggestURL--- +-- -- suggestURL = "http://google.com/complete/search?client=firefox&q=" -- @--- +-- jsonQuery' :: FromJSON a => (ByteString -> ByteString) -> Text -> Query a-jsonQuery' convert = genericQuery mkJSONRequest result +jsonQuery' convert = genericQuery mkJSONRequest result where result res = case eitherDecodeStrict (convert $ rspBody res) of- Left msg -> return $ Left $ T.concat + Left msg -> return $ Left $ T.concat ["JSON decoding error: ", T.pack msg, "\n", T.pack $ show $ rspBody res] Right res -> return (Right res) @@ -93,16 +107,16 @@ -- @ -- runQuery :: Query (Node Text Text) -- runQuery query = xmlQuery suggestURL query--- +-- -- suggestURL = "http://dblp.uni-trier.de/search/author?xauthor=" -- @--- +-- xmlQuery :: (GenericXMLString a, GenericXMLString b) => Text -> Query (Node a b) xmlQuery = genericQuery mkXMLRequest result where result res = case parse' defaultParseOptions (rspBody res) of- Left msg -> return $ Left $ T.concat + Left msg -> return $ Left $ T.concat ["XML decoding error: ", T.pack $ show msg ,"\n", T.pack $ show (rspBody res)] Right tree -> return (Right tree) @@ -111,7 +125,7 @@ -- used. xmlQueryLazy :: (GenericXMLString a, GenericXMLString b) => Text -> Query (Node a b) xmlQueryLazy = genericQuery mkXMLRequest result- where result res = let (tree, _) = parse defaultParseOptions (rspBody res) + where result res = let (tree, _) = parse defaultParseOptions (rspBody res) in return (Right tree) -- | Generic function to construct queries.