packages feed

webfinger-client 0.1.0.0 → 0.2.0.0

raw patch · 3 files changed

+78/−28 lines, 3 filesdep +link-relations

Dependencies added: link-relations

Files

NEWS.md view
@@ -3,6 +3,30 @@   +webfinger-client 0.2.0.0 -- 2016-01-28+======================================++General, build and documentation changes:++* (None)++New APIs, features and enhancements:++* Allow to specify typed link relations in the query+* Return typed link relations in result++Bug fixes:++* (None)++Dependency changes:++* Add link-relations+++++ webfinger-client 0.1.0.0 -- 2015-12-12 ====================================== 
src/Web/Finger/Client.hs view
@@ -1,6 +1,6 @@ {- This file is part of webfinger-client.  -- - Written in 2015 by fr33domlover <fr33domlover@riseup.net>.+ - Written in 2015, 2016 by fr33domlover <fr33domlover@riseup.net>.  -  - ♡ Copying is an act of love. Please copy, reuse and share.  -@@ -22,6 +22,9 @@ -- To allow Language-hashed maps be FromJSON {-# LANGUAGE FlexibleInstances #-} +-- For avoiding redundant imports in base 4.8+{-# LANGUAGE CPP #-}+ module Web.Finger.Client     ( Account (..)     , Resource (..)@@ -35,19 +38,26 @@     ) where +#if !MIN_VERSION_base(4,8,0) import Control.Applicative+#endif+ import Control.Exception import Data.Aeson hiding (Result, Success) import Data.Aeson.Types (typeMismatch)+import Data.ByteString (ByteString) import Data.Default.Class import Data.Hashable+import Data.HashMap.Lazy (HashMap) import Data.Monoid ((<>))+import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8) import GHC.Generics (Generic)+import Web.LinkRelations (LinkRelation, fromByteString, toByteString)  import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Data.HashMap.Lazy as M-import qualified Data.Text as T import qualified Network.HTTP.Client as H import qualified Network.HTTP.Client.TLS as H import qualified Network.HTTP.Types as HT@@ -66,7 +76,8 @@   - Other Nodes -* [ ] Add a list of properties and link relations, the Python module has one...+* [x] Support typed link relations+* [ ] Support typed properties * [x] Add an HTTP Accept header containing the JRD MIME type, the python module   does it. But first read in the RFC to make sure it's ok -}@@ -74,20 +85,20 @@ -- | A given user at a given host. For example, /john@example.org/ means the -- user is /john/ and the host is /example.org/. data Account = Account-    { acctUser :: B.ByteString-    , acctHost :: B.ByteString+    { acctUser :: ByteString+    , acctHost :: ByteString     }  -- | A web resource about which you'd like to make a query. data Resource     = ResAccount Account     | ResUri U.URI-    | ResUriStr B.ByteString+    | ResUriStr ByteString  -- | HTTP user authentication details. data Auth = Auth-    { authUser     :: B.ByteString-    , authPassword :: B.ByteString+    { authUser     :: ByteString+    , authPassword :: ByteString     }  -- | A WebFinger query, for which the client can get a response.@@ -101,15 +112,16 @@       qryTarget   :: Resource       -- | A list of link relations by which to filter the link list in the       -- returned description. If you'd like to receive /all/ the links, leave-      -- this list empty.-    , qryLinkRels :: [B.ByteString]+      -- this list empty. Use 'Left' to specify a raw link relation string, and+      -- 'Right' to specify a known typed relation.+    , qryLinkRels :: [Either ByteString LinkRelation]       -- | You can explicitly specify a host (e.g. @www.example.org@) here, to       -- which the WebFinger query will be sent. If you don't specify a host       -- here, it will be extracted from the 'qryTarget' field (if it has a       -- host part). Therefore this field is useful in special cases where the       -- WebFinger server isn't the one referred by the target URI, or the URI       -- doesn't have a host.-    , qryHost     :: Maybe B.ByteString+    , qryHost     :: Maybe ByteString       -- | HTTP authentication details. If the WebFinger server requires a       -- username and password to access it, specify them here. For publicly       -- available WebFinger servers, pass 'Nothing'.@@ -128,7 +140,7 @@ -- written. data Language     -- | A specific language specified using a code, e.g. @en-us@.-    = LanguageCode T.Text+    = LanguageCode Text     -- | No specific language. However it doesn't mean that nothing is     -- specified. It means that "language undefined" is explicity specified.     | LanguageUndefined@@ -136,13 +148,13 @@  instance Hashable Language -toLang :: T.Text -> Language+toLang :: Text -> Language toLang t =     if t == "und"         then LanguageUndefined         else LanguageCode t -instance FromJSON (M.HashMap Language T.Text) where+instance FromJSON (HashMap Language Text) where     parseJSON v = M.fromList . map f . M.toList <$> parseJSON v         where         f (l, t) = (toLang l, t)@@ -159,30 +171,42 @@       -- /avatar/.       --       -- A link relation may be a URI or one of the registered relation type-      -- names.-      lnkRelation   :: T.Text --TODO: URI or registered relation type. Maybe parse it and give more typed info?+      -- names. If the relation type is recognized when parsing the server's+      -- response, you will get 'Right' a typed link relation here. Otherwise,+      -- e.g. if a non-URL private application-specific relation type is found,+      -- you will get 'Left' the raw relation type string.+      lnkRelation   :: Either Text LinkRelation       -- | The MIME type to be expected of the content behind the link URI. For       -- example, if the link refers to a user's avatar image, the MIME type       -- may be @image/png@ (i.e. an image file in PNG format).-    , lnkMediaType  :: Maybe T.Text+    , lnkMediaType  :: Maybe Text       -- | The link address itself. It is optional, because there may be cases       -- in which all the information about the link is provided by the       -- properties (the 'lnkProperties' field). For example, if the link is a       -- user's avatar image, the address may be       -- @https://example.org/users/john/avatar.png@.-    , lnkAddress    :: Maybe T.Text+    , lnkAddress    :: Maybe Text       -- | Optional title(s) for the link, possibly in various languages.-    , lnkTitles     :: M.HashMap Language T.Text+    , lnkTitles     :: HashMap Language Text       -- | Additional properties the link may have. Maps property names, which       -- are URIs, to string values.-    , lnkProperties :: M.HashMap T.Text (Maybe T.Text) --TODO use IANA database to parse known values?+    , lnkProperties :: HashMap Text (Maybe Text) --TODO use IANA database to parse known values?     }     deriving (Show) +parseRel :: Text -> Either Text LinkRelation+parseRel t =+    case fromByteString $ encodeUtf8 t of+        Nothing -> Left t+        Just lr -> Right lr++forF :: Functor f => f a -> (a -> b) -> f b+forF = flip fmap+ instance FromJSON Link where     parseJSON (Object o) =         Link <$>-        o .:  "rel"                    <*>+        o .:  "rel" `forF` parseRel    <*>         o .:? "type"                   <*>         o .:? "href"                   <*>         o .:? "titles"     .!= M.empty <*>@@ -194,13 +218,13 @@     { -- | A URI representing the resource being described. This is the same       -- resource specified in the query, but the URI may slightly differ (e.g.       -- appear in canonical form).-      desSubject    :: Maybe T.Text+      desSubject    :: Maybe Text       -- | List of URIs which identify the same resource as the 'desSubject'       -- URI.-    , desAliases    :: [T.Text]+    , desAliases    :: [Text]       -- | Additional information about the subject. Maps property names, which       -- are URIs, to string values.-    , desProperties :: M.HashMap T.Text (Maybe T.Text) --TODO use IANA database to parse known values?+    , desProperties :: HashMap Text (Maybe Text) --TODO use IANA database to parse known values?       -- | Links of various relation types from the subject resource to other       -- resources represented by URIs.     , desLinks      :: [Link]@@ -242,7 +266,7 @@ newManager = H.newManager H.tlsManagerSettings  -- | Try to get the host from a resource URI.-getHost :: U.URI -> Either String B.ByteString+getHost :: U.URI -> Either String ByteString getHost uri =     case U.uriAuthority uri of         Nothing -> Left "Resource URI has no authority part"@@ -250,7 +274,7 @@  -- | Determine URI and host from resource. If no host is found, return a -- message instead which explains why.-parseResource :: Resource -> (B.ByteString, Either String B.ByteString)+parseResource :: Resource -> (ByteString, Either String ByteString) parseResource (ResAccount a) =     ( "acct:" <> acctUser a <> "@" <> acctHost a -- escape user! do i need to espcape host?     , Right $ acctHost a                         -- do i need to escape host? does http-client do it anyway?@@ -305,7 +329,8 @@                             Nothing               -> req                             Just (Auth user pass) -> H.applyBasicAuth user pass req                     res = ("resource", Just uri)-                    rels = map ((,) "rel" . Just) $ qryLinkRels q+                    toBS = either id toByteString+                    rels = map ((,) "rel" . Just . toBS) $ qryLinkRels q                     params = res : rels                     req'' = H.setQueryString params req'                 eresp <- try (H.httpLbs req'' manager)
webfinger-client.cabal view
@@ -1,5 +1,5 @@ name:                webfinger-client-version:             0.1.0.0+version:             0.2.0.0 synopsis:            WebFinger client library description:   This is a client library for querying a@@ -33,6 +33,7 @@                      , http-client          >=0.3.6                      , http-client-tls      >=0.2.2                      , http-types+                     , link-relations                      , text                      , unordered-containers >=0.2.5                      , uri-bytestring       >=0.1.7