pinboard 0.7.5 → 0.8.5
raw patch · 4 files changed
+106/−71 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Pinboard.ApiTypes: fromDoneResult :: DoneResult -> ()
- Pinboard.ApiTypes: fromJsonTagMap :: JsonTagMap -> TagMap
- Pinboard.ApiTypes: fromTextResult :: TextResult -> Text
- Pinboard.ApiTypes: fromUpdateTime :: UpdateTime -> UTCTime
- Pinboard.ApiTypes: instance Data DoneResult
- Pinboard.ApiTypes: instance Data JsonTagMap
- Pinboard.ApiTypes: instance Data Note
- Pinboard.ApiTypes: instance Data NoteList
- Pinboard.ApiTypes: instance Data NoteListItem
- Pinboard.ApiTypes: instance Data Post
- Pinboard.ApiTypes: instance Data PostDates
- Pinboard.ApiTypes: instance Data Posts
- Pinboard.ApiTypes: instance Data Suggested
- Pinboard.ApiTypes: instance Data TextResult
- Pinboard.ApiTypes: instance Data UpdateTime
- Pinboard.ApiTypes: instance Eq DoneResult
- Pinboard.ApiTypes: instance Eq JsonTagMap
- Pinboard.ApiTypes: instance Eq Note
- Pinboard.ApiTypes: instance Eq NoteList
- Pinboard.ApiTypes: instance Eq NoteListItem
- Pinboard.ApiTypes: instance Eq Post
- Pinboard.ApiTypes: instance Eq PostDates
- Pinboard.ApiTypes: instance Eq Posts
- Pinboard.ApiTypes: instance Eq Suggested
- Pinboard.ApiTypes: instance Eq TextResult
- Pinboard.ApiTypes: instance Eq UpdateTime
- Pinboard.ApiTypes: instance FromJSON DoneResult
- Pinboard.ApiTypes: instance FromJSON JsonTagMap
- Pinboard.ApiTypes: instance FromJSON Note
- Pinboard.ApiTypes: instance FromJSON NoteList
- Pinboard.ApiTypes: instance FromJSON NoteListItem
- Pinboard.ApiTypes: instance FromJSON Post
- Pinboard.ApiTypes: instance FromJSON PostDates
- Pinboard.ApiTypes: instance FromJSON Posts
- Pinboard.ApiTypes: instance FromJSON Suggested
- Pinboard.ApiTypes: instance FromJSON TextResult
- Pinboard.ApiTypes: instance FromJSON UpdateTime
- Pinboard.ApiTypes: instance Ord DoneResult
- Pinboard.ApiTypes: instance Ord Note
- Pinboard.ApiTypes: instance Ord NoteList
- Pinboard.ApiTypes: instance Ord NoteListItem
- Pinboard.ApiTypes: instance Ord Post
- Pinboard.ApiTypes: instance Ord PostDates
- Pinboard.ApiTypes: instance Ord Posts
- Pinboard.ApiTypes: instance Ord Suggested
- Pinboard.ApiTypes: instance Ord TextResult
- Pinboard.ApiTypes: instance Ord UpdateTime
- Pinboard.ApiTypes: instance Show DoneResult
- Pinboard.ApiTypes: instance Show JsonTagMap
- Pinboard.ApiTypes: instance Show Note
- Pinboard.ApiTypes: instance Show NoteList
- Pinboard.ApiTypes: instance Show NoteListItem
- Pinboard.ApiTypes: instance Show Post
- Pinboard.ApiTypes: instance Show PostDates
- Pinboard.ApiTypes: instance Show Posts
- Pinboard.ApiTypes: instance Show Suggested
- Pinboard.ApiTypes: instance Show TextResult
- Pinboard.ApiTypes: instance Show UpdateTime
- Pinboard.ApiTypes: instance ToJSON JsonTagMap
- Pinboard.ApiTypes: instance ToJSON Note
- Pinboard.ApiTypes: instance ToJSON NoteList
- Pinboard.ApiTypes: instance ToJSON NoteListItem
- Pinboard.ApiTypes: instance ToJSON Post
- Pinboard.ApiTypes: instance ToJSON PostDates
- Pinboard.ApiTypes: instance ToJSON Posts
- Pinboard.ApiTypes: instance ToJSON Suggested
- Pinboard.ApiTypes: instance ToJSON [Suggested]
- Pinboard.ApiTypes: instance Typeable DoneResult
- Pinboard.ApiTypes: instance Typeable JsonTagMap
- Pinboard.ApiTypes: instance Typeable Note
- Pinboard.ApiTypes: instance Typeable NoteList
- Pinboard.ApiTypes: instance Typeable NoteListItem
- Pinboard.ApiTypes: instance Typeable Post
- Pinboard.ApiTypes: instance Typeable PostDates
- Pinboard.ApiTypes: instance Typeable Posts
- Pinboard.ApiTypes: instance Typeable Suggested
- Pinboard.ApiTypes: instance Typeable TextResult
- Pinboard.ApiTypes: instance Typeable UpdateTime
- Pinboard.ApiTypes: noteCreatedAt :: Note -> UTCTime
- Pinboard.ApiTypes: noteHash :: Note -> Text
- Pinboard.ApiTypes: noteId :: Note -> Text
- Pinboard.ApiTypes: noteLength :: Note -> Int
- Pinboard.ApiTypes: noteListCount :: NoteList -> Int
- Pinboard.ApiTypes: noteListItemCreatedAt :: NoteListItem -> UTCTime
- Pinboard.ApiTypes: noteListItemHash :: NoteListItem -> Text
- Pinboard.ApiTypes: noteListItemId :: NoteListItem -> Text
- Pinboard.ApiTypes: noteListItemLength :: NoteListItem -> Int
- Pinboard.ApiTypes: noteListItemTitle :: NoteListItem -> Text
- Pinboard.ApiTypes: noteListItemUpdatedAt :: NoteListItem -> UTCTime
- Pinboard.ApiTypes: noteListItems :: NoteList -> [NoteListItem]
- Pinboard.ApiTypes: noteText :: Note -> Text
- Pinboard.ApiTypes: noteTitle :: Note -> Text
- Pinboard.ApiTypes: noteUpdatedAt :: Note -> UTCTime
- Pinboard.ApiTypes: postDatesCount :: PostDates -> [DateCount]
- Pinboard.ApiTypes: postDatesTag :: PostDates -> Text
- Pinboard.ApiTypes: postDatesUser :: PostDates -> Text
- Pinboard.ApiTypes: postDescription :: Post -> Text
- Pinboard.ApiTypes: postExtended :: Post -> Text
- Pinboard.ApiTypes: postHash :: Post -> Text
- Pinboard.ApiTypes: postHref :: Post -> Text
- Pinboard.ApiTypes: postMeta :: Post -> Text
- Pinboard.ApiTypes: postShared :: Post -> Bool
- Pinboard.ApiTypes: postTags :: Post -> [Tag]
- Pinboard.ApiTypes: postTime :: Post -> UTCTime
- Pinboard.ApiTypes: postToread :: Post -> Bool
- Pinboard.ApiTypes: postsDate :: Posts -> UTCTime
- Pinboard.ApiTypes: postsPosts :: Posts -> [Post]
- Pinboard.ApiTypes: postsUser :: Posts -> Text
- Pinboard.Client: apiToken :: PinboardConfig -> ByteString
- Pinboard.Client: debug :: PinboardConfig -> Bool
- Pinboard.Client.Error: errorCode :: PinboardError -> Maybe PinboardErrorCode
- Pinboard.Client.Error: errorHTTP :: PinboardError -> Maybe PinboardErrorHTTPCode
- Pinboard.Client.Error: errorMsg :: PinboardError -> Text
- Pinboard.Client.Error: errorParam :: PinboardError -> Maybe Text
- Pinboard.Client.Error: errorType :: PinboardError -> PinboardErrorType
- Pinboard.Client.Error: instance Show PinboardError
- Pinboard.Client.Error: instance Show PinboardErrorCode
- Pinboard.Client.Error: instance Show PinboardErrorHTTPCode
- Pinboard.Client.Error: instance Show PinboardErrorType
- Pinboard.Client.Types: apiToken :: PinboardConfig -> ByteString
- Pinboard.Client.Types: debug :: PinboardConfig -> Bool
- Pinboard.Client.Types: instance Eq Param
- Pinboard.Client.Types: instance Eq ResultFormatType
- Pinboard.Client.Types: instance Show Param
- Pinboard.Client.Types: instance Show PinboardConfig
- Pinboard.Client.Types: instance Show PinboardRequest
- Pinboard.Client.Types: instance Show ResultFormatType
- Pinboard.Client.Types: requestParams :: PinboardRequest -> [Param]
- Pinboard.Client.Types: requestPath :: PinboardRequest -> Text
- Pinboard.Client.Types: type Pinboard = EitherT PinboardError (ReaderT (PinboardConfig, Manager) IO)
+ Pinboard.ApiTypes: [fromDoneResult] :: DoneResult -> ()
+ Pinboard.ApiTypes: [fromJsonTagMap] :: JsonTagMap -> TagMap
+ Pinboard.ApiTypes: [fromTextResult] :: TextResult -> Text
+ Pinboard.ApiTypes: [fromUpdateTime] :: UpdateTime -> UTCTime
+ Pinboard.ApiTypes: [noteCreatedAt] :: Note -> UTCTime
+ Pinboard.ApiTypes: [noteHash] :: Note -> Text
+ Pinboard.ApiTypes: [noteId] :: Note -> Text
+ Pinboard.ApiTypes: [noteLength] :: Note -> Int
+ Pinboard.ApiTypes: [noteListCount] :: NoteList -> Int
+ Pinboard.ApiTypes: [noteListItemCreatedAt] :: NoteListItem -> UTCTime
+ Pinboard.ApiTypes: [noteListItemHash] :: NoteListItem -> Text
+ Pinboard.ApiTypes: [noteListItemId] :: NoteListItem -> Text
+ Pinboard.ApiTypes: [noteListItemLength] :: NoteListItem -> Int
+ Pinboard.ApiTypes: [noteListItemTitle] :: NoteListItem -> Text
+ Pinboard.ApiTypes: [noteListItemUpdatedAt] :: NoteListItem -> UTCTime
+ Pinboard.ApiTypes: [noteListItems] :: NoteList -> [NoteListItem]
+ Pinboard.ApiTypes: [noteText] :: Note -> Text
+ Pinboard.ApiTypes: [noteTitle] :: Note -> Text
+ Pinboard.ApiTypes: [noteUpdatedAt] :: Note -> UTCTime
+ Pinboard.ApiTypes: [postDatesCount] :: PostDates -> [DateCount]
+ Pinboard.ApiTypes: [postDatesTag] :: PostDates -> Text
+ Pinboard.ApiTypes: [postDatesUser] :: PostDates -> Text
+ Pinboard.ApiTypes: [postDescription] :: Post -> Text
+ Pinboard.ApiTypes: [postExtended] :: Post -> Text
+ Pinboard.ApiTypes: [postHash] :: Post -> Text
+ Pinboard.ApiTypes: [postHref] :: Post -> Text
+ Pinboard.ApiTypes: [postMeta] :: Post -> Text
+ Pinboard.ApiTypes: [postShared] :: Post -> Bool
+ Pinboard.ApiTypes: [postTags] :: Post -> [Tag]
+ Pinboard.ApiTypes: [postTime] :: Post -> UTCTime
+ Pinboard.ApiTypes: [postToread] :: Post -> Bool
+ Pinboard.ApiTypes: [postsDate] :: Posts -> UTCTime
+ Pinboard.ApiTypes: [postsPosts] :: Posts -> [Post]
+ Pinboard.ApiTypes: [postsUser] :: Posts -> Text
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.DoneResult
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.JsonTagMap
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.TextResult
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.FromJSON Pinboard.ApiTypes.UpdateTime
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.JsonTagMap
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance Data.Aeson.Types.Class.ToJSON [Pinboard.ApiTypes.Suggested]
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.DoneResult
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.JsonTagMap
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.TextResult
+ Pinboard.ApiTypes: instance Data.Data.Data Pinboard.ApiTypes.UpdateTime
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.DoneResult
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.JsonTagMap
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.TextResult
+ Pinboard.ApiTypes: instance GHC.Classes.Eq Pinboard.ApiTypes.UpdateTime
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.DoneResult
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.TextResult
+ Pinboard.ApiTypes: instance GHC.Classes.Ord Pinboard.ApiTypes.UpdateTime
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.DoneResult
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.JsonTagMap
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.Note
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.NoteList
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.NoteListItem
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.Post
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.PostDates
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.Posts
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.Suggested
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.TextResult
+ Pinboard.ApiTypes: instance GHC.Show.Show Pinboard.ApiTypes.UpdateTime
+ Pinboard.Client: [apiToken] :: PinboardConfig -> ByteString
+ Pinboard.Client: [debug] :: PinboardConfig -> Bool
+ Pinboard.Client.Error: [errorCode] :: PinboardError -> Maybe PinboardErrorCode
+ Pinboard.Client.Error: [errorHTTP] :: PinboardError -> Maybe PinboardErrorHTTPCode
+ Pinboard.Client.Error: [errorMsg] :: PinboardError -> Text
+ Pinboard.Client.Error: [errorParam] :: PinboardError -> Maybe Text
+ Pinboard.Client.Error: [errorType] :: PinboardError -> PinboardErrorType
+ Pinboard.Client.Error: instance GHC.Show.Show Pinboard.Client.Error.PinboardError
+ Pinboard.Client.Error: instance GHC.Show.Show Pinboard.Client.Error.PinboardErrorCode
+ Pinboard.Client.Error: instance GHC.Show.Show Pinboard.Client.Error.PinboardErrorHTTPCode
+ Pinboard.Client.Error: instance GHC.Show.Show Pinboard.Client.Error.PinboardErrorType
+ Pinboard.Client.Types: [apiToken] :: PinboardConfig -> ByteString
+ Pinboard.Client.Types: [debug] :: PinboardConfig -> Bool
+ Pinboard.Client.Types: [requestParams] :: PinboardRequest -> [Param]
+ Pinboard.Client.Types: [requestPath] :: PinboardRequest -> Text
+ Pinboard.Client.Types: instance GHC.Classes.Eq Pinboard.Client.Types.Param
+ Pinboard.Client.Types: instance GHC.Classes.Eq Pinboard.Client.Types.ResultFormatType
+ Pinboard.Client.Types: instance GHC.Show.Show Pinboard.Client.Types.Param
+ Pinboard.Client.Types: instance GHC.Show.Show Pinboard.Client.Types.PinboardConfig
+ Pinboard.Client.Types: instance GHC.Show.Show Pinboard.Client.Types.PinboardRequest
+ Pinboard.Client.Types: instance GHC.Show.Show Pinboard.Client.Types.ResultFormatType
+ Pinboard.Client.Types: type MonadPinboard m = (MonadIO m, MonadReader (PinboardConfig, Manager) m, MonadError PinboardError m)
+ Pinboard.Client.Types: type PinboardT m a = ReaderT (PinboardConfig, Manager) (ExceptT PinboardError m) a
- Pinboard.Api: addPost :: Url -> Description -> Maybe Extended -> Maybe [Tag] -> Maybe DateTime -> Maybe Replace -> Maybe Shared -> Maybe ToRead -> Pinboard ()
+ Pinboard.Api: addPost :: MonadPinboard m => Url -> Description -> Maybe Extended -> Maybe [Tag] -> Maybe DateTime -> Maybe Replace -> Maybe Shared -> Maybe ToRead -> m ()
- Pinboard.Api: addPostRec :: Post -> Replace -> Pinboard ()
+ Pinboard.Api: addPostRec :: MonadPinboard m => Post -> Replace -> m ()
- Pinboard.Api: deletePost :: Url -> Pinboard ()
+ Pinboard.Api: deletePost :: MonadPinboard m => Url -> m ()
- Pinboard.Api: deleteTag :: Tag -> Pinboard ()
+ Pinboard.Api: deleteTag :: MonadPinboard m => Tag -> m ()
- Pinboard.Api: getNote :: NoteId -> Pinboard Note
+ Pinboard.Api: getNote :: MonadPinboard m => NoteId -> m Note
- Pinboard.Api: getNoteList :: Pinboard NoteList
+ Pinboard.Api: getNoteList :: MonadPinboard m => m NoteList
- Pinboard.Api: getPostsAll :: Maybe [Tag] -> Maybe StartOffset -> Maybe NumResults -> Maybe FromDateTime -> Maybe ToDateTime -> Maybe Meta -> Pinboard [Post]
+ Pinboard.Api: getPostsAll :: MonadPinboard m => Maybe [Tag] -> Maybe StartOffset -> Maybe NumResults -> Maybe FromDateTime -> Maybe ToDateTime -> Maybe Meta -> m [Post]
- Pinboard.Api: getPostsDates :: Maybe [Tag] -> Pinboard PostDates
+ Pinboard.Api: getPostsDates :: MonadPinboard m => Maybe [Tag] -> m PostDates
- Pinboard.Api: getPostsForDate :: Maybe [Tag] -> Maybe Date -> Maybe Url -> Pinboard Posts
+ Pinboard.Api: getPostsForDate :: MonadPinboard m => Maybe [Tag] -> Maybe Date -> Maybe Url -> m Posts
- Pinboard.Api: getPostsMRUTime :: Pinboard UTCTime
+ Pinboard.Api: getPostsMRUTime :: MonadPinboard m => m UTCTime
- Pinboard.Api: getPostsRecent :: Maybe [Tag] -> Maybe Count -> Pinboard Posts
+ Pinboard.Api: getPostsRecent :: MonadPinboard m => Maybe [Tag] -> Maybe Count -> m Posts
- Pinboard.Api: getSuggestedTags :: Url -> Pinboard [Suggested]
+ Pinboard.Api: getSuggestedTags :: MonadPinboard m => Url -> m [Suggested]
- Pinboard.Api: getTags :: Pinboard TagMap
+ Pinboard.Api: getTags :: MonadPinboard m => m TagMap
- Pinboard.Api: getUserApiToken :: Pinboard Text
+ Pinboard.Api: getUserApiToken :: MonadPinboard m => m Text
- Pinboard.Api: getUserSecretRssKey :: Pinboard Text
+ Pinboard.Api: getUserSecretRssKey :: MonadPinboard m => m Text
- Pinboard.Api: renameTag :: Old -> New -> Pinboard ()
+ Pinboard.Api: renameTag :: MonadPinboard m => Old -> New -> m ()
- Pinboard.Client: decodeJSONResponse :: FromJSON a => ByteString -> Either PinboardError a
+ Pinboard.Client: decodeJSONResponse :: (MonadError PinboardError m, FromJSON a) => ByteString -> m a
- Pinboard.Client: mgrFail :: PinboardErrorType -> SomeException -> IO (Either PinboardError b)
+ Pinboard.Client: mgrFail :: MonadIO m => PinboardErrorType -> SomeException -> m (Either PinboardError b)
- Pinboard.Client: mgrOpen :: IO (Either SomeException Manager)
+ Pinboard.Client: mgrOpen :: MonadIO m => m (Either SomeException Manager)
- Pinboard.Client: mgrOpenRaw :: IO Manager
+ Pinboard.Client: mgrOpenRaw :: MonadIO m => m Manager
- Pinboard.Client: parseJSONResponse :: FromJSON a => Response ByteString -> Either PinboardError a
+ Pinboard.Client: parseJSONResponse :: (MonadError PinboardError m, FromJSON a) => Response ByteString -> m a
- Pinboard.Client: pinboardJson :: FromJSON a => PinboardRequest -> Pinboard a
+ Pinboard.Client: pinboardJson :: (MonadPinboard m, FromJSON a) => PinboardRequest -> m a
- Pinboard.Client: runPinboard :: PinboardConfig -> Pinboard a -> IO (Either PinboardError a)
+ Pinboard.Client: runPinboard :: MonadIO m => PinboardConfig -> PinboardT m a -> m (Either PinboardError a)
- Pinboard.Client: runPinboardSingleJson :: FromJSON a => PinboardConfig -> PinboardRequest -> IO (Either PinboardError a)
+ Pinboard.Client: runPinboardSingleJson :: (MonadIO m, FromJSON a) => PinboardConfig -> PinboardRequest -> m (Either PinboardError a)
- Pinboard.Client: runPinboardSingleRaw :: PinboardConfig -> PinboardRequest -> (Response ByteString -> a) -> IO (Either PinboardError a)
+ Pinboard.Client: runPinboardSingleRaw :: MonadIO m => PinboardConfig -> PinboardRequest -> (Response ByteString -> a) -> m (Either PinboardError a)
- Pinboard.Client: runPinboardSingleRawBS :: PinboardConfig -> PinboardRequest -> IO (Either PinboardError ByteString)
+ Pinboard.Client: runPinboardSingleRawBS :: MonadIO m => PinboardConfig -> PinboardRequest -> m (Either PinboardError ByteString)
- Pinboard.Client: sendPinboardRequest :: PinboardRequest -> PinboardConfig -> Manager -> (Response ByteString -> a) -> IO a
+ Pinboard.Client: sendPinboardRequest :: MonadIO m => PinboardRequest -> PinboardConfig -> Manager -> (Response ByteString -> a) -> m a
Files
- pinboard.cabal +1/−1
- src/Pinboard/Api.hs +45/−29
- src/Pinboard/Client.hs +43/−38
- src/Pinboard/Client/Types.hs +17/−3
pinboard.cabal view
@@ -1,5 +1,5 @@ name: pinboard-version: 0.7.5+version: 0.8.5 synopsis: Access to the Pinboard API license: MIT license-file: LICENSE
src/Pinboard/Api.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ConstraintKinds #-} ------------------------------------------- -- |@@ -38,10 +40,9 @@ ) where import Pinboard.Client (pinboardJson)-import Pinboard.Client.Types (Pinboard) import Data.Text (Text) import Data.Time (UTCTime)-import Pinboard.Client.Types (ResultFormatType (..))+import Pinboard.Client.Types (MonadPinboard, ResultFormatType (..)) import Pinboard.ApiTypes import Pinboard.ApiRequest @@ -52,59 +53,66 @@ -- | posts/recent : Returns a list of the user's most recent posts, filtered by tag. getPostsRecent- :: Maybe [Tag] -- ^ filter by up to three tags+ :: MonadPinboard m+ => Maybe [Tag] -- ^ filter by up to three tags -> Maybe Count -- ^ number of results to return. Default is 15, max is 100 - -> Pinboard Posts+ -> m Posts getPostsRecent tags count = pinboardJson $ getPostsRecentRequest FormatJson tags count -- | posts/all : Returns all bookmarks in the user's account. getPostsAll- :: Maybe [Tag] -- ^ filter by up to three tags+ :: MonadPinboard m+ => Maybe [Tag] -- ^ filter by up to three tags -> Maybe StartOffset -- ^ offset value (default is 0) -> Maybe NumResults -- ^ number of results to return. Default is all -> Maybe FromDateTime -- ^ return only bookmarks created after this time -> Maybe ToDateTime -- ^ return only bookmarks created before this time -> Maybe Meta -- ^ include a change detection signature for each bookmark- -> Pinboard [Post]+ -> m [Post] getPostsAll tags start results fromdt todt meta = pinboardJson $ getPostsAllRequest FormatJson tags start results fromdt todt meta -- | posts/get : Returns one or more posts on a single day matching the arguments. -- If no date or url is given, date of most recent bookmark will be used. getPostsForDate- :: Maybe [Tag] -- ^ filter by up to three tags+ :: MonadPinboard m+ => Maybe [Tag] -- ^ filter by up to three tags -> Maybe Date -- ^ return results bookmarked on this day -> Maybe Url -- ^ return bookmark for this URL- -> Pinboard Posts+ -> m Posts getPostsForDate tags date url = pinboardJson $ getPostsForDateRequest FormatJson tags date url -- | posts/dates : Returns a list of dates with the number of posts at each date. getPostsDates- :: Maybe [Tag] -- ^ filter by up to three tags- -> Pinboard PostDates+ :: MonadPinboard m+ => Maybe [Tag] -- ^ filter by up to three tags+ -> m PostDates getPostsDates tags = pinboardJson $ getPostsDatesRequest FormatJson tags -- | posts/update : Returns the most recent time a bookmark was added, updated or deleted.-getPostsMRUTime :: Pinboard UTCTime+getPostsMRUTime :: MonadPinboard m => m UTCTime getPostsMRUTime = fromUpdateTime <$> pinboardJson (getPostsMRUTimeRequest FormatJson) -- | posts/suggest : Returns a list of popular tags and recommended tags for a given URL. -- Popular tags are tags used site-wide for the url; -- Recommended tags are drawn from the user's own tags. getSuggestedTags- :: Url- -> Pinboard [Suggested]+ :: MonadPinboard m+ => Url+ -> m [Suggested] getSuggestedTags url = pinboardJson $ getSuggestedTagsRequest FormatJson url -- | posts/delete : Delete an existing bookmark. deletePost - :: Url- -> Pinboard ()+ :: MonadPinboard m+ => Url+ -> m () deletePost url = fromDoneResult <$> (pinboardJson $ deletePostRequest FormatJson url) -- | posts/add : Add or Update a bookmark addPost- :: Url -- ^ the URL of the item+ :: MonadPinboard m+ => Url -- ^ the URL of the item -> Description -- ^ Title of the item. This field is unfortunately named 'description' for backwards compatibility with the delicious API -> Maybe Extended -- ^ Description of the item. Called 'extended' for backwards compatibility with delicious API -> Maybe [Tag] -- ^ List of up to 100 tags@@ -112,14 +120,15 @@ -> Maybe Replace -- ^ Replace any existing bookmark with this URL. Default is yes. If set to no, will fail if bookmark exists -> Maybe Shared -- ^ Make bookmark public. Default is "yes" unless user has enabled the "save all bookmarks as private" user setting, in which case default is "no" -> Maybe ToRead -- ^ Marks the bookmark as unread. Default is "no"- -> Pinboard ()+ -> m () addPost url descr ext tags ctime repl shared toread = fromDoneResult <$> (pinboardJson $ addPostRequest FormatJson url descr ext tags ctime repl shared toread) -- | posts/add : Add or Update a bookmark, from a Post record addPostRec- :: Post -- ^ a Post record+ :: MonadPinboard m+ => Post -- ^ a Post record -> Replace -- ^ Replace any existing bookmark with the Posts URL. If set to no, will fail if bookmark exists - -> Pinboard ()+ -> m () addPostRec post replace = fromDoneResult <$> (pinboardJson $ addPostRecRequest FormatJson post replace) -- TAGS ----------------------------------------------------------------------@@ -128,22 +137,25 @@ -- | tags/get : Returns a full list of the user's tags along with the number of -- times they were used. getTags - :: Pinboard TagMap+ :: MonadPinboard m+ => m TagMap getTags = fromJsonTagMap <$> (pinboardJson $ getTagsRequest FormatJson ) -- | tags/delete : Delete an existing tag. deleteTag - :: Tag - -> Pinboard ()+ :: MonadPinboard m+ => Tag + -> m () deleteTag tag = fromDoneResult <$> (pinboardJson $ deleteTagRequest FormatJson tag) -- | tags/rename : Rename an tag, or fold it in to an existing tag renameTag - :: Old -- ^ note: match is not case sensitive+ :: MonadPinboard m+ => Old -- ^ note: match is not case sensitive -> New -- ^ if empty, nothing will happen- -> Pinboard ()+ -> m () renameTag old new = fromDoneResult <$> (pinboardJson $ renameTagRequest FormatJson old new) @@ -151,12 +163,14 @@ -- | user/secret : Returns the user's secret RSS key (for viewing private feeds) getUserSecretRssKey - :: Pinboard Text+ :: MonadPinboard m+ => m Text getUserSecretRssKey = fromTextResult <$> (pinboardJson $ getUserSecretRssKeyRequest FormatJson ) -- | user/api_token : Returns the user's API token (for making API calls without a password) getUserApiToken - :: Pinboard Text+ :: MonadPinboard m+ => m Text getUserApiToken = fromTextResult <$> (pinboardJson $ getUserApiTokenRequest FormatJson ) @@ -164,12 +178,14 @@ -- | notes/list : Returns a list of the user's notes (note text detail is not included) getNoteList - :: Pinboard NoteList+ :: MonadPinboard m+ => m NoteList getNoteList = pinboardJson $ getNoteListRequest FormatJson -- | notes/id : Returns an individual user note. The hash property is a 20 character long sha1 hash of the note text. getNote - :: NoteId- -> Pinboard Note+ :: MonadPinboard m+ => NoteId+ -> m Note getNote noteid = pinboardJson $ getNoteRequest FormatJson noteid
src/Pinboard/Client.hs view
@@ -2,6 +2,8 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ConstraintKinds #-} ------------------------------------------------------------------------------ -- | @@ -49,13 +51,15 @@ import Control.Exception (catch, SomeException, try, bracket)-import Control.Monad.IO.Class (MonadIO (liftIO))-import Control.Monad.Reader (ask, runReaderT)-import Control.Monad.Trans.Either (runEitherT, hoistEither)+import Control.Monad.IO.Class+import Control.Monad.Reader+import Control.Monad.Except+ import Data.ByteString.Char8 (pack) import Data.Monoid ((<>)) import Data.Aeson (FromJSON, eitherDecodeStrict') + import Network (withSocketsDo) import Network.HTTP.Types (urlEncode) import Network.HTTP.Types.Status (statusCode)@@ -83,38 +87,38 @@ -------------------------------------------------------------------------------- -- | Execute computations in the Pinboard monad runPinboard- :: PinboardConfig- -> Pinboard a- -> IO (Either PinboardError a)-runPinboard config requests = - bracket mgrOpen return (either (mgrFail ConnectionFailure) go)- where go mgr = runReaderT (runEitherT requests) (config, mgr) - `catch` mgrFail UnknownErrorType+ :: MonadIO m+ => PinboardConfig+ -> PinboardT m a+ -> m (Either PinboardError a)+runPinboard config requests = mgrOpenRaw >>= go+ where go mgr = runExceptT $ runReaderT requests (config, mgr) -- | Create a Pinboard value from a PinboardRequest w/ json deserialization-pinboardJson :: FromJSON a => PinboardRequest -> Pinboard a+pinboardJson :: (MonadPinboard m, FromJSON a) => PinboardRequest -> m a pinboardJson req = do (config, mgr) <- ask- result <- liftIO $ sendPinboardRequest (ensureResultFormatType FormatJson req) config mgr parseJSONResponse- hoistEither result-+ res <- sendPinboardRequest (ensureResultFormatType FormatJson req) config mgr parseJSONResponse+ res -------------------------------------------------------------------------------- runPinboardSingleRaw- :: PinboardConfig + :: MonadIO m+ => PinboardConfig -> PinboardRequest -> (Response LBS.ByteString -> a)- -> IO (Either PinboardError a)+ -> m (Either PinboardError a) runPinboardSingleRaw config req handler = - bracket mgrOpen return (either (mgrFail ConnectionFailure) go)+ liftIO $ bracket mgrOpen return (either (mgrFail ConnectionFailure) go) where go mgr = (Right <$> sendPinboardRequest req config mgr handler) `catch` mgrFail UnknownErrorType runPinboardSingleRawBS- :: PinboardConfig + :: MonadIO m+ => PinboardConfig -> PinboardRequest- -> IO (Either PinboardError LBS.ByteString)+ -> m (Either PinboardError LBS.ByteString) runPinboardSingleRawBS config req = do res <- runPinboardSingleRaw config req id return $ do@@ -122,58 +126,59 @@ responseBody r <$ checkStatusCodeResponse r runPinboardSingleJson- :: FromJSON a+ :: (MonadIO m, FromJSON a) => PinboardConfig -> PinboardRequest- -> IO (Either PinboardError a)+ -> m (Either PinboardError a) runPinboardSingleJson config = runPinboard config . pinboardJson -------------------------------------------------------------------------------- sendPinboardRequest- :: PinboardRequest + :: MonadIO m+ => PinboardRequest -> PinboardConfig -> Manager -> (Response LBS.ByteString -> a)- -> IO a+ -> m a sendPinboardRequest PinboardRequest{..} PinboardConfig{..} man handler = do let url = T.concat [ requestPath , "?" , T.decodeUtf8 $ paramsToByteString $ ("auth_token", urlEncode False apiToken) : encodeParams requestParams ] req <- buildReq $ T.unpack url- res <- httpLbs req man+ res <- liftIO $ httpLbs req man return $ handler res -------------------------------------------------------------------------------- -buildReq :: String -> IO Request+buildReq :: MonadIO m => String -> m Request buildReq url = do- req <- parseUrl $ "https://api.pinboard.in/v1/" <> url+ req <- liftIO $ parseUrl $ "https://api.pinboard.in/v1/" <> url return $ req - { requestHeaders = [("User-Agent","pinboard.hs/0.7.5")]+ { requestHeaders = [("User-Agent","pinboard.hs/0.8.5")] , checkStatus = \_ _ _ -> Nothing } -------------------------------------------------------------------------------- parseJSONResponse- :: (FromJSON a)+ :: (MonadError PinboardError m, FromJSON a) => Response LBS.ByteString- -> Either PinboardError a+ -> m a parseJSONResponse response = - either (Left . addErrMsg (toText (responseBody response))) + either (throwError . addErrMsg (toText (responseBody response))) (const $ decodeJSONResponse (responseBody response)) (checkStatusCodeResponse response) decodeJSONResponse- :: FromJSON a + :: (MonadError PinboardError m, FromJSON a) => LBS.ByteString - -> Either PinboardError a+ -> m a decodeJSONResponse s = let r = eitherDecodeStrict' (LBS.toStrict s) - in either (Left . createParserErr . toText) Right r+ in either (throwError . createParserErr . toText) (return . id) r -------------------------------------------------------------------------------- @@ -208,14 +213,14 @@ -------------------------------------------------------------------------------- -mgrOpenRaw :: IO Manager-mgrOpenRaw = withSocketsDo . newManager +mgrOpenRaw :: MonadIO m => m Manager+mgrOpenRaw = liftIO $ withSocketsDo . newManager $ managerSetProxy (proxyEnvironment Nothing) tlsManagerSettings -mgrOpen :: IO (Either SomeException Manager)-mgrOpen = try mgrOpenRaw+mgrOpen :: MonadIO m => m (Either SomeException Manager)+mgrOpen = liftIO $ try mgrOpenRaw -mgrFail :: PinboardErrorType -> SomeException -> IO (Either PinboardError b)+mgrFail :: MonadIO m => PinboardErrorType -> SomeException -> m (Either PinboardError b) mgrFail e msg = return $ Left $ PinboardError e (toText msg) Nothing Nothing Nothing
src/Pinboard/Client/Types.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE OverloadedStrings #-} -- |@@ -7,7 +9,8 @@ -- Stability : experimental -- Portability : POSIX module Pinboard.Client.Types- ( Pinboard+ ( PinboardT+ , MonadPinboard , PinboardRequest (..) , PinboardConfig (..) , ResultFormatType (..)@@ -16,17 +19,28 @@ ) where import Control.Monad.Reader (ReaderT)-import Control.Monad.Trans.Either (EitherT) import Data.ByteString (ByteString) import Data.Text (Text) import Network.HTTP.Client (Manager) import Pinboard.Client.Error (PinboardError (..)) import Data.Time.Calendar(Day) import Data.Time.Clock(UTCTime)+import Control.Monad.Reader.Class(MonadReader)+import Control.Monad.Error.Class(MonadError)+import Control.Monad.IO.Class(MonadIO)+import Control.Monad.Except(ExceptT) ------------------------------------------------------------------------------ -type Pinboard = EitherT PinboardError (ReaderT (PinboardConfig, Manager) IO)+type PinboardT m a = ReaderT (PinboardConfig, Manager) (ExceptT PinboardError m) a++-- |Typeclass alias for the return type of the API functions (keeps the+-- signatures less verbose)+type MonadPinboard m =+ ( MonadIO m+ , MonadReader (PinboardConfig, Manager) m+ , MonadError PinboardError m+ ) ------------------------------------------------------------------------------