packages feed

twitter-conduit 0.5.1 → 0.6.0

raw patch · 36 files changed

+1230/−1176 lines, 36 filesdep −hlintdep ~aesondep ~basesetup-changed

Dependencies removed: hlint

Dependency ranges changed: aeson, base

Files

ChangeLog.md view
@@ -1,3 +1,8 @@+## 0.6.0++* Support extended tweets [#83](https://github.com/himura/twitter-conduit/pull/83)+* Remove deprecated module `Web.Twitter.Conduit.ParametersDeprecated` [#81](https://github.com/himura/twitter-conduit/pull/81)+ ## 0.5.1  * Add result_type to searchTweets [#78](https://github.com/himura/twitter-conduit/pull/78).
Setup.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE CPP #-}+ module Main (main) where+ #ifndef MIN_VERSION_cabal_doctest #define MIN_VERSION_cabal_doctest(x,y,z) 0 #endif@@ -17,7 +19,8 @@ import Warning () #endif import Distribution.Simple+ main :: IO () main = defaultMain-#endif +#endif
Warning.hs view
@@ -1,5 +1,8 @@ module Warning-  {-# WARNING ["You are configuring this package without cabal-doctest installed.",-               "The doctests test-suite will not work as a result.",-               "To fix this, install cabal-doctest before configuring."] #-}-  () where+    {-# WARNING+        [ "You are configuring this package without cabal-doctest installed."+        , "The doctests test-suite will not work as a result."+        , "To fix this, install cabal-doctest before configuring."+        ]+        #-}+    () where
Web/Twitter/Conduit.hs view
@@ -9,46 +9,44 @@ -- Portability: portable -- -- A client library for Twitter APIs (see <https://dev.twitter.com/>).--module Web.Twitter.Conduit-       (-       -- * How to use this library-       -- $howto+module Web.Twitter.Conduit (+    -- * How to use this library+    -- $howto -       -- * Re-exports-         module Web.Twitter.Conduit.Api-       , module Web.Twitter.Conduit.Cursor-       , module Web.Twitter.Conduit.Request-       , module Web.Twitter.Conduit.Response-       , module Web.Twitter.Conduit.Stream-       , module Web.Twitter.Conduit.Types+    -- * Re-exports+    module Web.Twitter.Conduit.Api,+    module Web.Twitter.Conduit.Cursor,+    module Web.Twitter.Conduit.Request,+    module Web.Twitter.Conduit.Response,+    module Web.Twitter.Conduit.Stream,+    module Web.Twitter.Conduit.Types, -       -- * 'Web.Twitter.Conduit.Base'-       , call-       , call'-       , callWithResponse-       , callWithResponse'-       , sourceWithMaxId-       , sourceWithMaxId'-       , sourceWithCursor-       , sourceWithCursor'-       , sourceWithSearchResult-       , sourceWithSearchResult'+    -- * 'Web.Twitter.Conduit.Base'+    call,+    call',+    callWithResponse,+    callWithResponse',+    sourceWithMaxId,+    sourceWithMaxId',+    sourceWithCursor,+    sourceWithCursor',+    sourceWithSearchResult,+    sourceWithSearchResult', -       -- * 'Web.Twitter.Conduit.Parameters'-       , ListParam(..)-       , MediaData(..)-       , UserListParam(..)-       , UserParam(..)+    -- * 'Web.Twitter.Conduit.Parameters'+    ListParam (..),+    MediaData (..),+    UserListParam (..),+    UserParam (..), -       -- * re-exports-       , OAuth (..)-       , Credential (..)-       , def-       , Manager-       , newManager-       , tlsManagerSettings-       ) where+    -- * re-exports+    OAuth (..),+    Credential (..),+    def,+    Manager,+    newManager,+    tlsManagerSettings,+) where  import Web.Twitter.Conduit.Api import Web.Twitter.Conduit.Base@@ -64,12 +62,13 @@ import Web.Authenticate.OAuth  -- for haddock++import Control.Lens+import Control.Monad.IO.Class import Data.Conduit import qualified Data.Conduit.List as CL import qualified Data.Text as T import qualified Data.Text.IO as T-import Control.Monad.IO.Class-import Control.Lens  {-# ANN module "HLint: ignore Use import/export shortcut" #-} @@ -81,7 +80,7 @@ -- and <http://hackage.haskell.org/package/conduit conduit>. -- All of following examples import modules as below: ----- > {-# LANGUAGE OverloadedStrings #-}+-- > {\-# LANGUAGE OverloadedStrings #-\} -- > -- > import Web.Twitter.Conduit -- > import Web.Twitter.Types.Lens
Web/Twitter/Conduit/Api.hs view
@@ -4,158 +4,162 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} -module Web.Twitter.Conduit.Api-       (-       -- * Status-         statusesMentionsTimeline-       , statusesUserTimeline-       , statusesHomeTimeline-       , statusesRetweetsOfMe-       , statusesRetweetsId-       , statusesShowId-       , statusesDestroyId-       , statusesUpdate-       , statusesRetweetId-       , statusesUpdateWithMedia-       , statusesLookup+module Web.Twitter.Conduit.Api (+    -- * Status+    statusesMentionsTimeline,+    statusesUserTimeline,+    statusesHomeTimeline,+    statusesRetweetsOfMe,+    statusesRetweetsId,+    statusesShowId,+    statusesDestroyId,+    statusesUpdate,+    statusesRetweetId,+    statusesUpdateWithMedia,+    statusesLookup, -       -- * Search-       , SearchTweets-       , searchTweets-       , search+    -- * Search+    SearchTweets,+    searchTweets,+    search, -       -- * Direct Messages-       , DirectMessages-       , directMessages-       , DirectMessagesSent-       , directMessagesSent-       , DirectMessagesShow-       , directMessagesShow-       , DirectMessagesDestroy-       , directMessagesDestroy-       , DirectMessagesNew-       , directMessagesNew+    -- * Direct Messages+    DirectMessages,+    directMessages,+    DirectMessagesSent,+    directMessagesSent,+    DirectMessagesShow,+    directMessagesShow,+    DirectMessagesDestroy,+    directMessagesDestroy,+    DirectMessagesNew,+    directMessagesNew, -       -- * Friends & Followers-       , FriendshipsNoRetweetsIds-       , friendshipsNoRetweetsIds-       , FriendsIds-       , friendsIds-       , FollowersIds-       , followersIds-       , FriendshipsIncoming-       , friendshipsIncoming-       , FriendshipsOutgoing-       , friendshipsOutgoing-       , FriendshipsCreate-       , friendshipsCreate-       , FriendshipsDestroy-       , friendshipsDestroy-       -- , friendshipsUpdate-       -- , friendshipsShow-       , FriendsList-       , friendsList-       , FollowersList-       , followersList-       -- , friendshipsLookup+    -- * Friends & Followers+    FriendshipsNoRetweetsIds,+    friendshipsNoRetweetsIds,+    FriendsIds,+    friendsIds,+    FollowersIds,+    followersIds,+    FriendshipsIncoming,+    friendshipsIncoming,+    FriendshipsOutgoing,+    friendshipsOutgoing,+    FriendshipsCreate,+    friendshipsCreate,+    FriendshipsDestroy,+    friendshipsDestroy,+    -- , friendshipsUpdate+    -- , friendshipsShow+    FriendsList,+    friendsList,+    FollowersList,+    followersList,+    -- , friendshipsLookup -       -- * Users-       -- , accountSettings-       , AccountVerifyCredentials-       , accountVerifyCredentials-       -- , accountSettingsUpdate-       -- , accountUpdateDeliveryDevice-       , AccountUpdateProfile-       , accountUpdateProfile-       -- , accountUpdateProfileBackgroundImage-       -- , accountUpdateProfileColors-       -- , accoutUpdateProfileImage-       -- , blocksList-       -- , blocksIds-       -- , blocksCreate-       -- , blocksDestroy+    -- * Users -       , UsersLookup-       , usersLookup-       , UsersShow-       , usersShow-       -- , usersSearch-       -- , usersContributees-       -- , usersContributors-       -- , accuntRemoveProfileBanner-       -- , accuntUpdateProfileBanner-       -- , usersProfileBanner-       -- , mutesUsersCreate-       -- , mutesUsersDestroy-       -- , mutesUsersIds-       -- , mutesUsersList+    -- , accountSettings+    AccountVerifyCredentials,+    accountVerifyCredentials,+    -- , accountSettingsUpdate+    -- , accountUpdateDeliveryDevice+    AccountUpdateProfile,+    accountUpdateProfile,+    -- , accountUpdateProfileBackgroundImage+    -- , accountUpdateProfileColors+    -- , accoutUpdateProfileImage+    -- , blocksList+    -- , blocksIds+    -- , blocksCreate+    -- , blocksDestroy -       -- * Suggested Users-       -- , usersSuggestionsSlug-       -- , usersSuggestions-       -- , usersSuggestionsSlugMembers+    UsersLookup,+    usersLookup,+    UsersShow,+    usersShow,+    -- , usersSearch+    -- , usersContributees+    -- , usersContributors+    -- , accuntRemoveProfileBanner+    -- , accuntUpdateProfileBanner+    -- , usersProfileBanner+    -- , mutesUsersCreate+    -- , mutesUsersDestroy+    -- , mutesUsersIds+    -- , mutesUsersList -       -- * Favorites-       , FavoritesList-       , favoritesList-       , FavoritesDestroy-       , favoritesDestroy-       , FavoritesCreate-       , favoritesCreate+    -- * Suggested Users -       -- * Lists-       -- , listsList-       , ListsStatuses-       , listsStatuses-       , ListsMembersDestroy-       , listsMembersDestroy-       , ListsMemberships-       , listsMemberships-       , ListsSubscribers-       , listsSubscribers-       -- , listsSubscribersCreate-       -- , listsSubscribersShow-       -- , listsSubscribersDestroy-       , ListsMembersCreateAll-       , listsMembersCreateAll-       -- , listsMembersShow-       , ListsMembers-       , listsMembers-       , ListsMembersCreate-       , listsMembersCreate-       , ListsDestroy-       , listsDestroy-       , ListsUpdate-       , listsUpdate-       , ListsCreate-       , listsCreate-       , ListsShow-       , listsShow-       , ListsSubscriptions-       , listsSubscriptions-       , ListsMembersDestroyAll-       , listsMembersDestroyAll-       , ListsOwnerships-       , listsOwnerships+    -- , usersSuggestionsSlug+    -- , usersSuggestions+    -- , usersSuggestionsSlugMembers -       -- * Saved Searches-       -- savedSearchesList-       -- savedSearchesShowId-       -- savedSearchesCreate-       -- savedSearchesDestroyId+    -- * Favorites+    FavoritesList,+    favoritesList,+    FavoritesDestroy,+    favoritesDestroy,+    FavoritesCreate,+    favoritesCreate, -       -- * Places & Geo-       -- geoIdPlaceId-       -- geoReverseGeocode-       -- geoSearch-       -- geoSimilarPlaces-       -- geoPlace+    -- * Lists -       -- * media-       , MediaUpload-       , mediaUpload-       ) where+    -- , listsList+    ListsStatuses,+    listsStatuses,+    ListsMembersDestroy,+    listsMembersDestroy,+    ListsMemberships,+    listsMemberships,+    ListsSubscribers,+    listsSubscribers,+    -- , listsSubscribersCreate+    -- , listsSubscribersShow+    -- , listsSubscribersDestroy+    ListsMembersCreateAll,+    listsMembersCreateAll,+    -- , listsMembersShow+    ListsMembers,+    listsMembers,+    ListsMembersCreate,+    listsMembersCreate,+    ListsDestroy,+    listsDestroy,+    ListsUpdate,+    listsUpdate,+    ListsCreate,+    listsCreate,+    ListsShow,+    listsShow,+    ListsSubscriptions,+    listsSubscriptions,+    ListsMembersDestroyAll,+    listsMembersDestroyAll,+    ListsOwnerships,+    listsOwnerships, +    -- * Saved Searches++    -- savedSearchesList+    -- savedSearchesShowId+    -- savedSearchesCreate+    -- savedSearchesDestroyId++    -- * Places & Geo++    -- geoIdPlaceId+    -- geoReverseGeocode+    -- geoSearch+    -- geoSimilarPlaces+    -- geoPlace++    -- * media+    MediaUpload,+    mediaUpload,+) where+ import Web.Twitter.Conduit.Base import Web.Twitter.Conduit.Cursor import Web.Twitter.Conduit.Parameters@@ -164,11 +168,11 @@ import qualified Web.Twitter.Conduit.Status as Status import Web.Twitter.Types -import Network.HTTP.Client.MultipartFormData-import qualified Data.Text as T+import Data.Aeson import Data.Default+import qualified Data.Text as T import Data.Time.Calendar (Day)-import Data.Aeson+import Network.HTTP.Client.MultipartFormData  -- $setup -- >>> :set -XOverloadedStrings -XOverloadedLabels@@ -187,23 +191,29 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/search/tweets.json" [("q","search text")] -- >>> searchTweets "search text" & #lang ?~ "ja" & #count ?~ 100 -- APIRequest "GET" "https://api.twitter.com/1.1/search/tweets.json" [("count","100"),("lang","ja"),("q","search text")]-searchTweets :: T.Text -- ^ search string-             -> APIRequest SearchTweets (SearchResult [Status])+searchTweets ::+    -- | search string+    T.Text ->+    APIRequest SearchTweets (SearchResult [Status]) searchTweets q = APIRequest "GET" (endpoint ++ "search/tweets.json") [("q", PVString q)]-type SearchTweets = '[-      "lang" ':= T.Text-    , "locale" ':= T.Text-    , "result_type" ':= T.Text-    , "count" ':= Integer-    , "until" ':= Day-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "include_entities" ':= Bool-    ] +type SearchTweets =+    '[ "lang" ':= T.Text+     , "locale" ':= T.Text+     , "result_type" ':= T.Text+     , "count" ':= Integer+     , "until" ':= Day+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Alias of 'searchTweets', for backward compatibility-search :: T.Text -- ^ search string-       -> APIRequest SearchTweets (SearchResult [Status])+search ::+    -- | search string+    T.Text ->+    APIRequest SearchTweets (SearchResult [Status]) search = searchTweets {-# DEPRECATED search "Please use Web.Twitter.Conduit.searchTweets" #-} @@ -221,14 +231,15 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/events/list.json" [("count","50")] directMessages :: APIRequest DirectMessages (WithCursor T.Text EventsCursorKey DirectMessage) directMessages = APIRequest "GET" (endpoint ++ "direct_messages/events/list.json") def-type DirectMessages = '[-      "count" ':= Integer-    , "include_entities" ':= Bool-    , "skip_status" ':= Bool-    , "full_text" ':= Bool-    , "cursor" ':= T.Text-    ] +type DirectMessages =+    '[ "count" ':= Integer+     , "include_entities" ':= Bool+     , "skip_status" ':= Bool+     , "full_text" ':= Bool+     , "cursor" ':= T.Text+     ]+ -- | Returns query data which asks recent direct messages sent by the authenticating user. -- -- You can perform a query using 'call':@@ -243,16 +254,17 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/sent.json" [("count","100")] directMessagesSent :: APIRequest DirectMessagesSent [DirectMessage] directMessagesSent = APIRequest "GET" (endpoint ++ "direct_messages/sent.json") def-type DirectMessagesSent = '[-      "since_id" ':= Integer-    , "max_id" ':= Integer-    , "count" ':= Integer-    , "include_entities" ':= Bool-    , "page" ':= Integer-    , "skip_status" ':= Bool-    , "full_text" ':= Bool-    ] +type DirectMessagesSent =+    '[ "since_id" ':= Integer+     , "max_id" ':= Integer+     , "count" ':= Integer+     , "include_entities" ':= Bool+     , "page" ':= Integer+     , "skip_status" ':= Bool+     , "full_text" ':= Bool+     ]+ -- | Returns query data which asks a single direct message, specified by an id parameter. -- -- You can perform a query using 'call':@@ -265,10 +277,11 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/direct_messages/show.json" [("id","1234567890")] directMessagesShow :: StatusId -> APIRequest DirectMessagesShow DirectMessage directMessagesShow sId = APIRequest "GET" (endpoint ++ "direct_messages/show.json") [("id", PVInteger sId)]-type DirectMessagesShow = '[-      "full_text" ':= Bool-    ] +type DirectMessagesShow =+    '[ "full_text" ':= Bool+     ]+ -- | Returns post data which destroys the direct message specified in the required ID parameter. -- -- You can perform a query using 'call':@@ -281,11 +294,13 @@ -- APIRequest "DELETE" "https://api.twitter.com/1.1/direct_messages/events/destroy.json" [("id","1234567890")] directMessagesDestroy :: StatusId -> APIRequest DirectMessagesDestroy NoContent directMessagesDestroy sId = APIRequest "DELETE" (endpoint ++ "direct_messages/events/destroy.json") [("id", PVInteger sId)]+ type DirectMessagesDestroy = EmptyParams  newtype DirectMessagesNewResponse = DirectMessagesNewResponse     { directMessageBody :: DirectMessage-    } deriving (Show, Eq)+    }+    deriving (Show, Eq)  instance FromJSON DirectMessagesNewResponse where     parseJSON = withObject "DirectMessagesNewResponse" $ \o -> DirectMessagesNewResponse <$> o .: "event"@@ -306,16 +321,17 @@   where     body =         object-            [ "event" .=-              object-                  [ "type" .= ("message_create" :: String)-                  , "message_create" .=-                    object-                        [ "target" .= object ["recipient_id" .= up]-                        , "message_data" .= object ["text" .= msg]-                        ]-                  ]+            [ "event"+                .= object+                    [ "type" .= ("message_create" :: String)+                    , "message_create"+                        .= object+                            [ "target" .= object ["recipient_id" .= up]+                            , "message_data" .= object ["text" .= msg]+                            ]+                    ]             ]+ type DirectMessagesNew = EmptyParams  type RecipientId = Integer@@ -332,6 +348,7 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/no_retweets/ids.json" [] friendshipsNoRetweetsIds :: APIRequest FriendshipsNoRetweetsIds [UserId] friendshipsNoRetweetsIds = APIRequest "GET" (endpoint ++ "friendships/no_retweets/ids.json") []+ type FriendshipsNoRetweetsIds = EmptyParams  -- | Returns query data which asks a collection of user IDs for every user the specified user is following.@@ -354,11 +371,12 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/friends/ids.json" [("count","5000"),("screen_name","thimura")] friendsIds :: UserParam -> APIRequest FriendsIds (WithCursor Integer IdsCursorKey UserId) friendsIds q = APIRequest "GET" (endpoint ++ "friends/ids.json") (mkUserParam q)-type FriendsIds = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    ] +type FriendsIds =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     ]+ -- | Returns query data which asks a collection of user IDs for every user following the specified user. -- -- You can perform a query using 'call':@@ -379,11 +397,12 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/followers/ids.json" [("count","5000"),("screen_name","thimura")] followersIds :: UserParam -> APIRequest FollowersIds (WithCursor Integer IdsCursorKey UserId) followersIds q = APIRequest "GET" (endpoint ++ "followers/ids.json") (mkUserParam q)-type FollowersIds = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    ] +type FollowersIds =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     ]+ -- | Returns a collection of numeric IDs for every user who has a pending request to follow the authenticating user. -- -- You can perform a request by using 'call':@@ -402,10 +421,11 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/incoming.json" [] friendshipsIncoming :: APIRequest FriendshipsIncoming (WithCursor Integer IdsCursorKey UserId) friendshipsIncoming = APIRequest "GET" (endpoint ++ "friendships/incoming.json") def-type FriendshipsIncoming = '[-      "cursor" ':= Integer-    ] +type FriendshipsIncoming =+    '[ "cursor" ':= Integer+     ]+ -- | Returns a collection of numeric IDs for every protected user for whom the authenticating user has a pending follow request. -- -- You can perform a request by using 'call':@@ -424,10 +444,11 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/friendships/outgoing.json" [] friendshipsOutgoing :: APIRequest FriendshipsOutgoing (WithCursor Integer IdsCursorKey UserId) friendshipsOutgoing = APIRequest "GET" (endpoint ++ "friendships/outgoing.json") def-type FriendshipsOutgoing = '[-      "cursor" ':= Integer-    ] +type FriendshipsOutgoing =+    '[ "cursor" ':= Integer+     ]+ -- | Returns post data which follows the user specified in the ID parameter. -- -- You can perform request by using 'call':@@ -442,10 +463,11 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/friendships/create.json" [("user_id","69179963")] friendshipsCreate :: UserParam -> APIRequest FriendshipsCreate User friendshipsCreate user = APIRequest "POST" (endpoint ++ "friendships/create.json") (mkUserParam user)-type FriendshipsCreate = '[-      "follow" ':= Bool-    ] +type FriendshipsCreate =+    '[ "follow" ':= Bool+     ]+ -- | Returns post data which unfollows the user specified in the ID parameter. -- -- You can perform request by using 'call':@@ -460,6 +482,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/friendships/destroy.json" [("user_id","69179963")] friendshipsDestroy :: UserParam -> APIRequest FriendshipsDestroy User friendshipsDestroy user = APIRequest "POST" (endpoint ++ "friendships/destroy.json") (mkUserParam user)+ type FriendshipsDestroy = EmptyParams  -- | Returns query data which asks a cursored collection of user objects for every user the specified users is following.@@ -482,13 +505,14 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/friends/list.json" [("user_id","69179963")] friendsList :: UserParam -> APIRequest FriendsList (WithCursor Integer UsersCursorKey User) friendsList q = APIRequest "GET" (endpoint ++ "friends/list.json") (mkUserParam q)-type FriendsList = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    , "skip_status" ':= Bool-    , "include_user_entities" ':= Bool-    ] +type FriendsList =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     , "skip_status" ':= Bool+     , "include_user_entities" ':= Bool+     ]+ -- | Returns query data which asks a cursored collection of user objects for users following the specified user. -- -- You can perform request by using 'call':@@ -509,13 +533,14 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/followers/list.json" [("user_id","69179963")] followersList :: UserParam -> APIRequest FollowersList (WithCursor Integer UsersCursorKey User) followersList q = APIRequest "GET" (endpoint ++ "followers/list.json") (mkUserParam q)-type FollowersList = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    , "skip_status" ':= Bool-    , "include_user_entities" ':= Bool-    ] +type FollowersList =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     , "skip_status" ':= Bool+     , "include_user_entities" ':= Bool+     ]+ -- | Returns query data asks that the credential is valid. -- -- You can perform request by using 'call':@@ -528,12 +553,13 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/account/verify_credentials.json" [] accountVerifyCredentials :: APIRequest AccountVerifyCredentials User accountVerifyCredentials = APIRequest "GET" (endpoint ++ "account/verify_credentials.json") []-type AccountVerifyCredentials = '[-      "include_entities" ':= Bool-    , "skip_status" ':= Bool-    , "include_email" ':= Bool-    ] +type AccountVerifyCredentials =+    '[ "include_entities" ':= Bool+     , "skip_status" ':= Bool+     , "include_email" ':= Bool+     ]+ -- | Returns user object with updated fields. -- Note that while no specific parameter is required, you need to provide at least one parameter before executing the query. --@@ -547,16 +573,17 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/account/update_profile.json" [("url","http://www.example.com")] accountUpdateProfile :: APIRequest AccountUpdateProfile User accountUpdateProfile = APIRequest "POST" (endpoint ++ "account/update_profile.json") []-type AccountUpdateProfile = '[-      "include_entities" ':= Bool-    , "skip_status" ':= Bool-    , "name" ':= T.Text-    , "url" ':= URIString-    , "location" ':= T.Text-    , "description" ':= T.Text-    , "profile_link_color" ':= T.Text-    ] +type AccountUpdateProfile =+    '[ "include_entities" ':= Bool+     , "skip_status" ':= Bool+     , "name" ':= T.Text+     , "url" ':= URIString+     , "location" ':= T.Text+     , "description" ':= T.Text+     , "profile_link_color" ':= T.Text+     ]+ -- | Returns query data asks user objects. -- -- You can perform request by using 'call':@@ -569,10 +596,11 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/users/lookup.json" [("screen_name","thimura,twitterapi")] usersLookup :: UserListParam -> APIRequest UsersLookup [User] usersLookup q = APIRequest "GET" (endpoint ++ "users/lookup.json") (mkUserListParam q)-type UsersLookup = '[-      "include_entities" ':= Bool-    ] +type UsersLookup =+    '[ "include_entities" ':= Bool+     ]+ -- | Returns query data asks the user specified by user id or screen name parameter. -- -- You can perform request by using 'call':@@ -585,10 +613,11 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/users/show.json" [("screen_name","thimura")] usersShow :: UserParam -> APIRequest UsersShow User usersShow q = APIRequest "GET" (endpoint ++ "users/show.json") (mkUserParam q)-type UsersShow = '[-      "include_entities" ':= Bool-    ] +type UsersShow =+    '[ "include_entities" ':= Bool+     ]+ -- | Returns the 20 most recent Tweets favorited by the specified user. -- -- You can perform request by using 'call':@@ -608,13 +637,15 @@   where     mkParam Nothing = []     mkParam (Just usr) = mkUserParam usr-type FavoritesList = '[-      "count" ':= Integer-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "include_entities" ':= Bool-    ] +type FavoritesList =+    '[ "count" ':= Integer+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns post data which favorites the status specified in the ID parameter as the authenticating user. -- -- You can perform request by using 'call':@@ -627,11 +658,13 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/favorites/create.json" [("id","1234567890")] favoritesCreate :: StatusId -> APIRequest FavoritesCreate Status favoritesCreate sid = APIRequest "POST" (endpoint ++ "favorites/create.json") [("id", PVInteger sid)]-type FavoritesCreate = '[-      "include_entities" ':= Bool-    ] --- | Returns post data unfavorites the status specified in the ID paramter as the authenticating user.+type FavoritesCreate =+    '[ "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]++-- | Returns post data unfavorites the status specified in the ID parameter as the authenticating user. -- -- You can perform request by using 'call': --@@ -643,10 +676,12 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/favorites/destroy.json" [("id","1234567890")] favoritesDestroy :: StatusId -> APIRequest FavoritesDestroy Status favoritesDestroy sid = APIRequest "POST" (endpoint ++ "favorites/destroy.json") [("id", PVInteger sid)]-type FavoritesDestroy = '[-      "include_entities" ':= Bool-    ] +type FavoritesDestroy =+    '[ "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns the query parameter which fetches a timeline of tweets authored by members of the specified list. -- -- You can perform request by using 'call':@@ -666,14 +701,16 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/statuses.json" [("list_id","20849097")] listsStatuses :: ListParam -> APIRequest ListsStatuses [Status] listsStatuses q = APIRequest "GET" (endpoint ++ "lists/statuses.json") (mkListParam q)-type ListsStatuses = '[-      "since_id" ':= Integer-    , "max_id" ':= Integer-    , "count" ':= Integer-    , "include_entities" ':= Bool-    , "include_rts" ':= Bool-    ] +type ListsStatuses =+    '[ "since_id" ':= Integer+     , "max_id" ':= Integer+     , "count" ':= Integer+     , "include_entities" ':= Bool+     , "include_rts" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns the post parameter which removes the specified member from the list. -- -- You can perform request by using 'call':@@ -688,6 +725,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/destroy.json" [("list_id","20849097"),("user_id","69179963")] listsMembersDestroy :: ListParam -> UserParam -> APIRequest ListsMembersDestroy List listsMembersDestroy list user = APIRequest "POST" (endpoint ++ "lists/members/destroy.json") (mkListParam list ++ mkUserParam user)+ type ListsMembersDestroy = EmptyParams  -- | Returns the request parameters which asks the lists the specified user has been added to.@@ -707,11 +745,12 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/memberships.json" [("user_id","69179963")] listsMemberships :: Maybe UserParam -> APIRequest ListsMemberships (WithCursor Integer ListsCursorKey List) listsMemberships q = APIRequest "GET" (endpoint ++ "lists/memberships.json") $ maybe [] mkUserParam q-type ListsMemberships = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    ] +type ListsMemberships =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     ]+ -- | Returns the request parameter which asks the subscribers of the specified list. -- -- You can perform request by using 'call':@@ -726,12 +765,13 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/subscribers.json" [("list_id","20849097")] listsSubscribers :: ListParam -> APIRequest ListsSubscribers (WithCursor Integer UsersCursorKey User) listsSubscribers q = APIRequest "GET" (endpoint ++ "lists/subscribers.json") (mkListParam q)-type ListsSubscribers = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    , "skip_status" ':= Bool-    ] +type ListsSubscribers =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     , "skip_status" ':= Bool+     ]+ -- | Returns the request parameter which obtains a collection of the lists the specified user is subscribed to. -- -- You can perform request by using 'call':@@ -748,11 +788,12 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/subscriptions.json" [("user_id","69179963")] listsSubscriptions :: Maybe UserParam -> APIRequest ListsSubscriptions (WithCursor Integer ListsCursorKey List) listsSubscriptions q = APIRequest "GET" (endpoint ++ "lists/subscriptions.json") $ maybe [] mkUserParam q-type ListsSubscriptions = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    ] +type ListsSubscriptions =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     ]+ -- | Returns the request parameter which asks the lists owned by the specified Twitter user. -- -- You can perform request by using 'call':@@ -769,11 +810,12 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/ownerships.json" [("user_id","69179963")] listsOwnerships :: Maybe UserParam -> APIRequest ListsOwnerships (WithCursor Integer ListsCursorKey List) listsOwnerships q = APIRequest "GET" (endpoint ++ "lists/ownerships.json") $ maybe [] mkUserParam q-type ListsOwnerships = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    ] +type ListsOwnerships =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     ]+ -- | Adds multiple members to a list. -- -- You can perform request by using 'call':@@ -788,6 +830,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/create_all.json" [("list_id","20849097"),("user_id","69179963,6253282")] listsMembersCreateAll :: ListParam -> UserListParam -> APIRequest ListsMembersCreateAll List listsMembersCreateAll list users = APIRequest "POST" (endpoint ++ "lists/members/create_all.json") (mkListParam list ++ mkUserListParam users)+ type ListsMembersCreateAll = EmptyParams  -- | Adds multiple members to a list.@@ -804,6 +847,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/destroy_all.json" [("list_id","20849097"),("user_id","69179963,6253282")] listsMembersDestroyAll :: ListParam -> UserListParam -> APIRequest ListsMembersDestroyAll List listsMembersDestroyAll list users = APIRequest "POST" (endpoint ++ "lists/members/destroy_all.json") (mkListParam list ++ mkUserListParam users)+ type ListsMembersDestroyAll = EmptyParams  -- | Returns query data asks the members of the specified list.@@ -820,12 +864,13 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/members.json" [("list_id","20849097")] listsMembers :: ListParam -> APIRequest ListsMembers (WithCursor Integer UsersCursorKey User) listsMembers q = APIRequest "GET" (endpoint ++ "lists/members.json") (mkListParam q)-type ListsMembers = '[-      "count" ':= Integer-    , "cursor" ':= Integer-    , "skip_status" ':= Bool-    ] +type ListsMembers =+    '[ "count" ':= Integer+     , "cursor" ':= Integer+     , "skip_status" ':= Bool+     ]+ -- | Returns the post parameter which adds a member to a list. -- -- You can perform request by using 'call':@@ -840,6 +885,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/members/create.json" [("list_id","20849097"),("user_id","69179963")] listsMembersCreate :: ListParam -> UserParam -> APIRequest ListsMembersCreate List listsMembersCreate list user = APIRequest "POST" (endpoint ++ "lists/members/create.json") (mkListParam list ++ mkUserParam user)+ type ListsMembersCreate = EmptyParams  -- | Returns the post parameter which deletes the specified list.@@ -856,6 +902,7 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/destroy.json" [("list_id","20849097")] listsDestroy :: ListParam -> APIRequest ListsDestroy List listsDestroy list = APIRequest "POST" (endpoint ++ "lists/destroy.json") (mkListParam list)+ type ListsDestroy = EmptyParams  -- | Returns the post parameter which updates the specified list.@@ -868,16 +915,20 @@ -- -- >>> listsUpdate (ListNameParam "thimura/haskell") True (Just "Haskellers") -- APIRequest "POST" "https://api.twitter.com/1.1/lists/update.json" [("slug","haskell"),("owner_screen_name","thimura"),("description","Haskellers"),("mode","public")]-listsUpdate :: ListParam-            -> Bool -- ^ is public-            -> Maybe T.Text -- ^ description-            -> APIRequest ListsUpdate List+listsUpdate ::+    ListParam ->+    -- | is public+    Bool ->+    -- | description+    Maybe T.Text ->+    APIRequest ListsUpdate List listsUpdate list isPublic description = APIRequest "POST" (endpoint ++ "lists/update.json") (mkListParam list ++ p')   where     p = [("mode", PVString . mode $ isPublic)]-    p' = maybe id (\d -> (("description", PVString d):)) description p+    p' = maybe id (\d -> (("description", PVString d) :)) description p     mode True = "public"     mode False = "private"+ type ListsUpdate = EmptyParams  -- | Returns the post parameter which creates a new list for the authenticated user.@@ -894,16 +945,21 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/lists/create.json" [("name","haskell"),("mode","private")] -- >>> listsCreate "haskell" True (Just "Haskellers") -- APIRequest "POST" "https://api.twitter.com/1.1/lists/create.json" [("description","Haskellers"),("name","haskell"),("mode","public")]-listsCreate :: T.Text -- ^ list name-            -> Bool -- ^ whether public(True) or private(False)-            -> Maybe T.Text -- ^ the description to give the list-            -> APIRequest ListsCreate List+listsCreate ::+    -- | list name+    T.Text ->+    -- | whether public(True) or private(False)+    Bool ->+    -- | the description to give the list+    Maybe T.Text ->+    APIRequest ListsCreate List listsCreate name isPublic description = APIRequest "POST" (endpoint ++ "lists/create.json") p'   where     p = [("name", PVString name), ("mode", PVString . mode $ isPublic)]-    p' = maybe id (\d -> (("description", PVString d):)) description p+    p' = maybe id (\d -> (("description", PVString d) :)) description p     mode True = "public"     mode False = "private"+ type ListsCreate = EmptyParams  -- | Returns the request parameter which asks the specified list.@@ -920,6 +976,7 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/lists/show.json" [("list_id","20849097")] listsShow :: ListParam -> APIRequest ListsShow List listsShow q = APIRequest "GET" (endpoint ++ "lists/show.json") (mkListParam q)+ type ListsShow = EmptyParams  -- | Upload media and returns the media data.@@ -943,14 +1000,16 @@ -- -- >>> mediaUpload (MediaFromFile "/home/test/test.png") -- APIRequestMultipart "POST" "https://upload.twitter.com/1.1/media/upload.json" []-mediaUpload :: MediaData-            -> APIRequest MediaUpload UploadedMedia+mediaUpload ::+    MediaData ->+    APIRequest MediaUpload UploadedMedia mediaUpload mediaData =     APIRequestMultipart "POST" uri [] [mediaBody mediaData]   where     uri = "https://upload.twitter.com/1.1/media/upload.json"     mediaBody (MediaFromFile fp) = partFileSource "media" fp     mediaBody (MediaRequestBody filename filebody) = partFileRequestBody "media" filename filebody+ type MediaUpload = EmptyParams  statusesMentionsTimeline :: APIRequest Status.StatusesMentionsTimeline [Status]
Web/Twitter/Conduit/Base.hs view
@@ -9,26 +9,26 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -module Web.Twitter.Conduit.Base-       ( ResponseBodyType (..)-       , NoContent-       , getResponse-       , call-       , call'-       , callWithResponse-       , callWithResponse'-       , checkResponse-       , sourceWithMaxId-       , sourceWithMaxId'-       , sourceWithCursor-       , sourceWithCursor'-       , sourceWithSearchResult-       , sourceWithSearchResult'-       , endpoint-       , makeRequest-       , sinkJSON-       , sinkFromJSON-       ) where+module Web.Twitter.Conduit.Base (+    ResponseBodyType (..),+    NoContent,+    getResponse,+    call,+    call',+    callWithResponse,+    callWithResponse',+    checkResponse,+    sourceWithMaxId,+    sourceWithMaxId',+    sourceWithCursor,+    sourceWithCursor',+    sourceWithSearchResult,+    sourceWithSearchResult',+    endpoint,+    makeRequest,+    sinkJSON,+    sinkFromJSON,+) where  import Web.Twitter.Conduit.Cursor import Web.Twitter.Conduit.Request@@ -60,8 +60,9 @@ import Data.Monoid #endif -makeRequest :: APIRequest apiName responseType-            -> IO HTTP.Request+makeRequest ::+    APIRequest apiName responseType ->+    IO HTTP.Request makeRequest (APIRequest m u pa) = makeRequest' m u (makeSimpleQuery pa) makeRequest (APIRequestMultipart m u param prt) =     formDataBody body =<< makeRequest' m u []@@ -72,26 +73,30 @@     req <- makeRequest' m u (makeSimpleQuery param)     return $         req-        { HTTP.requestBody = HTTP.RequestBodyLBS $ encode body-        , HTTP.requestHeaders = ("Content-Type", "application/json") : HTTP.requestHeaders req-        }+            { HTTP.requestBody = HTTP.RequestBodyLBS $ encode body+            , HTTP.requestHeaders = ("Content-Type", "application/json") : HTTP.requestHeaders req+            } -makeRequest' :: HT.Method -- ^ HTTP request method (GET or POST)-             -> String -- ^ API Resource URL-             -> HT.SimpleQuery -- ^ Query-             -> IO HTTP.Request+makeRequest' ::+    -- | HTTP request method (GET or POST)+    HT.Method ->+    -- | API Resource URL+    String ->+    -- | Query+    HT.SimpleQuery ->+    IO HTTP.Request makeRequest' m url query = do     req <- HTTP.parseRequest url     let addParams =             if m == "POST"-            then HTTP.urlEncodedBody query-            else \r -> r { HTTP.queryString = HT.renderSimpleQuery False query }-    return $ addParams $ req { HTTP.method = m }+                then HTTP.urlEncodedBody query+                else \r -> r {HTTP.queryString = HT.renderSimpleQuery False query}+    return $ addParams $ req {HTTP.method = m}  class ResponseBodyType a where     parseResponseBody ::-           Response (C.ConduitM () ByteString (ResourceT IO) ())-        -> ResourceT IO (Response a)+        Response (C.ConduitM () ByteString (ResourceT IO) ()) ->+        ResourceT IO (Response a)  type NoContent = () instance ResponseBodyType NoContent where@@ -105,34 +110,37 @@ instance {-# OVERLAPPABLE #-} FromJSON a => ResponseBodyType a where     parseResponseBody = getValueOrThrow -getResponse :: MonadResource m-            => TWInfo-            -> HTTP.Manager-            -> HTTP.Request-            -> m (Response (C.ConduitM () ByteString m ()))-getResponse TWInfo{..} mgr req = do-    signedReq <- signOAuth (twOAuth twToken) (twCredential twToken) $ req { HTTP.proxy = twProxy }+getResponse ::+    MonadResource m =>+    TWInfo ->+    HTTP.Manager ->+    HTTP.Request ->+    m (Response (C.ConduitM () ByteString m ()))+getResponse TWInfo {..} mgr req = do+    signedReq <- signOAuth (twOAuth twToken) (twCredential twToken) $ req {HTTP.proxy = twProxy}     res <- HTTP.http signedReq mgr     return-        Response { responseStatus = HTTP.responseStatus res-                 , responseHeaders = HTTP.responseHeaders res-                 , responseBody = HTTP.responseBody res-                 }+        Response+            { responseStatus = HTTP.responseStatus res+            , responseHeaders = HTTP.responseHeaders res+            , responseBody = HTTP.responseBody res+            }  endpoint :: String endpoint = "https://api.twitter.com/1.1/"  getValue ::-            Response (C.ConduitM () ByteString (ResourceT IO) ())-         -> ResourceT IO (Response Value)+    Response (C.ConduitM () ByteString (ResourceT IO) ()) ->+    ResourceT IO (Response Value) getValue res = do     value <--      C.runConduit $ responseBody res C..| sinkJSON-    return $ res { responseBody = value }+        C.runConduit $ responseBody res C..| sinkJSON+    return $ res {responseBody = value} -checkResponse :: Response Value-              -> Either TwitterError Value-checkResponse Response{..} =+checkResponse ::+    Response Value ->+    Either TwitterError Value+checkResponse Response {..} =     case responseBody ^? key "errors" of         Just errs@(Array _) ->             case fromJSON errs of@@ -147,16 +155,17 @@   where     sci = HT.statusCode responseStatus -getValueOrThrow :: FromJSON a-                => Response (C.ConduitM () ByteString (ResourceT IO) ())-                -> ResourceT IO (Response a)+getValueOrThrow ::+    FromJSON a =>+    Response (C.ConduitM () ByteString (ResourceT IO) ()) ->+    ResourceT IO (Response a) getValueOrThrow res = do     res' <- getValue res     case checkResponse res' of         Left err -> throwM err         Right _ -> return ()     case fromJSON (responseBody res') of-        Success r -> return $ res' { responseBody = r }+        Success r -> return $ res' {responseBody = r}         Error err -> throwM $ FromJSONError err  -- | Perform an 'APIRequest' and then provide the response which is mapped to a suitable type of@@ -171,21 +180,25 @@ -- -- If you need raw JSON value which is parsed by <http://hackage.haskell.org/package/aeson aeson>, -- use 'call'' to obtain it.-call :: ResponseBodyType responseType-     => TWInfo -- ^ Twitter Setting-     -> HTTP.Manager-     -> APIRequest apiName responseType-     -> IO responseType+call ::+    ResponseBodyType responseType =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    IO responseType call = call'  -- | Perform an 'APIRequest' and then provide the response. -- The response of this function is not restrict to @responseType@, -- so you can choose an arbitrarily type of FromJSON instances.-call' :: ResponseBodyType value-      => TWInfo -- ^ Twitter Setting-      -> HTTP.Manager-      -> APIRequest apiName responseType-      -> IO value+call' ::+    ResponseBodyType value =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    IO value call' info mgr req = responseBody `fmap` callWithResponse' info mgr req  -- | Perform an 'APIRequest' and then provide the 'Response'.@@ -198,11 +211,13 @@ -- 'print' $ 'responseHeaders' res -- 'print' $ 'responseBody' res -- @-callWithResponse :: ResponseBodyType responseType-                 => TWInfo -- ^ Twitter Setting-                 -> HTTP.Manager-                 -> APIRequest apiName responseType-                 -> IO (Response responseType)+callWithResponse ::+    ResponseBodyType responseType =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    IO (Response responseType) callWithResponse = callWithResponse'  -- | Perform an 'APIRequest' and then provide the 'Response'.@@ -217,11 +232,12 @@ -- 'print' $ 'responseHeaders' res -- 'print' $ 'responseBody' (res :: Value) -- @-callWithResponse' :: ResponseBodyType value-                  => TWInfo-                  -> HTTP.Manager-                  -> APIRequest apiName responseType-                  -> IO (Response value)+callWithResponse' ::+    ResponseBodyType value =>+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    IO (Response value) callWithResponse' info mgr req =     runResourceT $ do         res <- getResponse info mgr =<< liftIO (makeRequest req)@@ -230,15 +246,17 @@ -- | A wrapper function to perform multiple API request with changing @max_id@ parameter. -- -- This function cooperate with instances of 'HasMaxIdParam'.-sourceWithMaxId :: ( MonadIO m-                   , FromJSON responseType-                   , AsStatus responseType-                   , HasParam "max_id" Integer supports-                   )-                => TWInfo -- ^ Twitter Setting-                -> HTTP.Manager-                -> APIRequest supports [responseType]-                -> C.ConduitT () responseType m ()+sourceWithMaxId ::+    ( MonadIO m+    , FromJSON responseType+    , AsStatus responseType+    , HasParam "max_id" Integer supports+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports [responseType] ->+    C.ConduitT () responseType m () sourceWithMaxId info mgr = loop   where     loop req = do@@ -255,13 +273,15 @@ -- so you can choose an arbitrarily type of FromJSON instances. -- -- This function cooperate with instances of 'HasMaxIdParam'.-sourceWithMaxId' :: ( MonadIO m-                    , HasParam "max_id" Integer supports-                    )-                 => TWInfo -- ^ Twitter Setting-                 -> HTTP.Manager-                 -> APIRequest supports [responseType]-                 -> C.ConduitT () Value m ()+sourceWithMaxId' ::+    ( MonadIO m+    , HasParam "max_id" Integer supports+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports [responseType] ->+    C.ConduitT () Value m () sourceWithMaxId' info mgr = loop   where     loop req = do@@ -275,15 +295,17 @@ -- | A wrapper function to perform multiple API request with changing @cursor@ parameter. -- -- This function cooperate with instances of 'HasCursorParam'.-sourceWithCursor :: ( MonadIO m-                    , FromJSON responseType-                    , CursorKey ck-                    , HasParam "cursor" Integer supports-                    )-                 => TWInfo -- ^ Twitter Setting-                 -> HTTP.Manager-                 -> APIRequest supports (WithCursor Integer ck responseType)-                 -> C.ConduitT () responseType m ()+sourceWithCursor ::+    ( MonadIO m+    , FromJSON responseType+    , CursorKey ck+    , HasParam "cursor" Integer supports+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports (WithCursor Integer ck responseType) ->+    C.ConduitT () responseType m () sourceWithCursor info mgr req = loop (Just (-1))   where     loop Nothing = CL.sourceNull@@ -298,18 +320,21 @@ -- so you can choose an arbitrarily type of FromJSON instances. -- -- This function cooperate with instances of 'HasCursorParam'.-sourceWithCursor' :: ( MonadIO m-                     , CursorKey ck-                     , HasParam "cursor" Integer supports-                     )-                  => TWInfo -- ^ Twitter Setting-                  -> HTTP.Manager-                  -> APIRequest supports (WithCursor Integer ck responseType)-                  -> C.ConduitT () Value m ()+sourceWithCursor' ::+    ( MonadIO m+    , CursorKey ck+    , HasParam "cursor" Integer supports+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports (WithCursor Integer ck responseType) ->+    C.ConduitT () Value m () sourceWithCursor' info mgr req = loop (Just (-1))   where-    relax :: APIRequest apiName (WithCursor Integer ck responseType)-          -> APIRequest apiName (WithCursor Integer ck Value)+    relax ::+        APIRequest apiName (WithCursor Integer ck responseType) ->+        APIRequest apiName (WithCursor Integer ck Value)     relax = coerce     loop Nothing = CL.sourceNull     loop (Just 0) = CL.sourceNull@@ -319,17 +344,20 @@         loop $ nextCursor res  -- | A wrapper function to perform multiple API request with @SearchResult@.-sourceWithSearchResult :: ( MonadIO m-                          , FromJSON responseType-                          )-                       => TWInfo -- ^ Twitter Setting-                       -> HTTP.Manager-                       -> APIRequest supports (SearchResult [responseType])-                       -> m (SearchResult (C.ConduitT () responseType m ()))+sourceWithSearchResult ::+    ( MonadIO m+    , FromJSON responseType+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports (SearchResult [responseType]) ->+    m (SearchResult (C.ConduitT () responseType m ())) sourceWithSearchResult info mgr req = do     res <- liftIO $ call info mgr req-    let body = CL.sourceList (res ^. searchResultStatuses) <>-               loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)+    let body =+            CL.sourceList (res ^. searchResultStatuses)+                <> loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)     return $ res & searchResultStatuses .~ body   where     origQueryMap = req ^. params . to M.fromList@@ -342,21 +370,25 @@         loop $ res ^. searchResultSearchMetadata . searchMetadataNextResults  -- | A wrapper function to perform multiple API request with @SearchResult@.-sourceWithSearchResult' :: ( MonadIO m-                           )-                        => TWInfo -- ^ Twitter Setting-                        -> HTTP.Manager-                        -> APIRequest supports (SearchResult [responseType])-                        -> m (SearchResult (C.ConduitT () Value m ()))+sourceWithSearchResult' ::+    ( MonadIO m+    ) =>+    -- | Twitter Setting+    TWInfo ->+    HTTP.Manager ->+    APIRequest supports (SearchResult [responseType]) ->+    m (SearchResult (C.ConduitT () Value m ())) sourceWithSearchResult' info mgr req = do     res <- liftIO $ call info mgr $ relax req-    let body = CL.sourceList (res ^. searchResultStatuses) <>-               loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)+    let body =+            CL.sourceList (res ^. searchResultStatuses)+                <> loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)     return $ res & searchResultStatuses .~ body   where     origQueryMap = req ^. params . to M.fromList-    relax :: APIRequest apiName (SearchResult [responseType])-          -> APIRequest apiName (SearchResult [Value])+    relax ::+        APIRequest apiName (SearchResult [responseType]) ->+        APIRequest apiName (SearchResult [Value])     relax = coerce     loop Nothing = CL.sourceNull     loop (Just nextResultsStr) = do@@ -366,13 +398,17 @@         CL.sourceList (res ^. searchResultStatuses)         loop $ res ^. searchResultSearchMetadata . searchMetadataNextResults -sinkJSON :: ( MonadThrow m-            ) => C.ConduitT ByteString o m Value+sinkJSON ::+    ( MonadThrow m+    ) =>+    C.ConduitT ByteString o m Value sinkJSON = CA.sinkParser json -sinkFromJSON :: ( FromJSON a-                , MonadThrow m-                ) => C.ConduitT ByteString o m a+sinkFromJSON ::+    ( FromJSON a+    , MonadThrow m+    ) =>+    C.ConduitT ByteString o m a sinkFromJSON = do     v <- sinkJSON     case fromJSON v of
Web/Twitter/Conduit/Cursor.hs view
@@ -1,15 +1,16 @@-{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -module Web.Twitter.Conduit.Cursor-       ( CursorKey (..)-       , IdsCursorKey-       , UsersCursorKey-       , ListsCursorKey-       , EventsCursorKey-       , WithCursor (..)-       ) where+module Web.Twitter.Conduit.Cursor (+    CursorKey (..),+    IdsCursorKey,+    UsersCursorKey,+    ListsCursorKey,+    EventsCursorKey,+    WithCursor (..),+) where  import Data.Aeson import Data.Text (Text)@@ -18,21 +19,30 @@ -- $setup -- >>> type UserId = Integer +{- ORMOLU_DISABLE -} class CursorKey a where+#if MIN_VERSION_aeson(2, 0, 0)+    cursorKey :: a -> Key+#else     cursorKey :: a -> Text+#endif+{- ORMOLU_ENABLE -}  -- | Phantom type to specify the key which point out the content in the response. data IdsCursorKey+ instance CursorKey IdsCursorKey where     cursorKey = const "ids"  -- | Phantom type to specify the key which point out the content in the response. data UsersCursorKey+ instance CursorKey UsersCursorKey where     cursorKey = const "users"  -- | Phantom type to specify the key which point out the content in the response. data ListsCursorKey+ instance CursorKey ListsCursorKey where     cursorKey = const "lists" @@ -65,12 +75,16 @@     { previousCursor :: Maybe cursorType     , nextCursor :: Maybe cursorType     , contents :: [wrapped]-    } deriving Show+    }+    deriving (Show) -instance (FromJSON wrapped, FromJSON ct, CursorKey c) =>-         FromJSON (WithCursor ct c wrapped) where-    parseJSON (Object o) = checkError o >>-      WithCursor <$> o .:? "previous_cursor"-                 <*> o .:? "next_cursor"-                 <*> o .:  cursorKey (undefined :: c)+instance+    (FromJSON wrapped, FromJSON ct, CursorKey c) =>+    FromJSON (WithCursor ct c wrapped)+    where+    parseJSON (Object o) =+        checkError o+            >> WithCursor <$> o .:? "previous_cursor"+            <*> o .:? "next_cursor"+            <*> o .: cursorKey (undefined :: c)     parseJSON _ = mempty
Web/Twitter/Conduit/Lens.hs view
@@ -1,61 +1,59 @@ {-# LANGUAGE RankNTypes #-} -module Web.Twitter.Conduit.Lens-       (-       -- * 'TT.Response'-         TT.Response-       , responseStatus-       , responseBody-       , responseHeaders-       -- * 'TT.TwitterErrorMessage'-       , TT.TwitterErrorMessage-       , twitterErrorMessage-       , twitterErrorCode+module Web.Twitter.Conduit.Lens (+    -- * 'TT.Response'+    TT.Response,+    responseStatus,+    responseBody,+    responseHeaders, -       -- * 'TT.WithCursor'-       , TT.WithCursor-       , previousCursor-       , nextCursor-       , contents+    -- * 'TT.TwitterErrorMessage'+    TT.TwitterErrorMessage,+    twitterErrorMessage,+    twitterErrorCode, -       -- * Re-exports-       , TT.TwitterError(..)-       , TT.CursorKey (..)-       , TT.IdsCursorKey-       , TT.UsersCursorKey-       , TT.ListsCursorKey-       ) where+    -- * 'TT.WithCursor'+    TT.WithCursor,+    previousCursor,+    nextCursor,+    contents, +    -- * Re-exports+    TT.TwitterError (..),+    TT.CursorKey (..),+    TT.IdsCursorKey,+    TT.UsersCursorKey,+    TT.ListsCursorKey,+) where+ import Control.Lens import Data.Text (Text)-import Network.HTTP.Types (Status, ResponseHeaders)+import Network.HTTP.Types (ResponseHeaders, Status) import qualified Web.Twitter.Conduit.Cursor as TT import qualified Web.Twitter.Conduit.Response as TT  -- * Lenses for 'TT.Response' responseStatus :: forall responseType. Lens' (TT.Response responseType) Status-responseStatus afb s = (\b -> s { TT.responseStatus = b }) <$> afb (TT.responseStatus s)+responseStatus afb s = (\b -> s {TT.responseStatus = b}) <$> afb (TT.responseStatus s)  responseHeaders :: forall responseType. Lens' (TT.Response responseType) ResponseHeaders-responseHeaders afb s = (\b -> s {TT.responseHeaders = b }) <$> afb (TT.responseHeaders s)+responseHeaders afb s = (\b -> s {TT.responseHeaders = b}) <$> afb (TT.responseHeaders s)  responseBody :: forall a b. Lens (TT.Response a) (TT.Response b) a b-responseBody afb s = (\b -> s { TT.responseBody = b }) <$> afb (TT.responseBody s)-+responseBody afb s = (\b -> s {TT.responseBody = b}) <$> afb (TT.responseBody s) -- * Lenses for 'TT.TwitterErrorMessage'  twitterErrorCode :: Lens' TT.TwitterErrorMessage Int-twitterErrorCode afb s = (\b -> s { TT.twitterErrorCode = b }) <$> afb (TT.twitterErrorCode s)+twitterErrorCode afb s = (\b -> s {TT.twitterErrorCode = b}) <$> afb (TT.twitterErrorCode s)  twitterErrorMessage :: Lens' TT.TwitterErrorMessage Text-twitterErrorMessage afb s = (\b -> s { TT.twitterErrorMessage = b }) <$> afb (TT.twitterErrorMessage s)-+twitterErrorMessage afb s = (\b -> s {TT.twitterErrorMessage = b}) <$> afb (TT.twitterErrorMessage s) -- * Lenses for 'TT.WithCursor' previousCursor :: forall cursorType cursorKey wrapped. Lens' (TT.WithCursor cursorType cursorKey wrapped) (Maybe cursorType)-previousCursor afb s = (\b -> s { TT.previousCursor = b }) <$> afb (TT.previousCursor s)+previousCursor afb s = (\b -> s {TT.previousCursor = b}) <$> afb (TT.previousCursor s)  nextCursor :: forall cursorType cursorKey wrapped. Lens' (TT.WithCursor cursorType cursorKey wrapped) (Maybe cursorType)-nextCursor afb s = (\b -> s { TT.nextCursor = b }) <$> afb (TT.nextCursor s)+nextCursor afb s = (\b -> s {TT.nextCursor = b}) <$> afb (TT.nextCursor s)  contents :: forall cursorType cursorKey a b. Lens (TT.WithCursor cursorType cursorKey a) (TT.WithCursor cursorType cursorKey b) [a] [b]-contents afb s = (\b -> s { TT.contents = b }) <$> afb (TT.contents s)+contents afb s = (\b -> s {TT.contents = b}) <$> afb (TT.contents s)
Web/Twitter/Conduit/Parameters.hs view
@@ -1,31 +1,35 @@ {-# LANGUAGE OverloadedStrings #-} -module Web.Twitter.Conduit.Parameters-       ( UserParam(..)-       , UserListParam(..)-       , ListParam(..)-       , MediaData(..)-       , mkUserParam-       , mkUserListParam-       , mkListParam-       ) where+module Web.Twitter.Conduit.Parameters (+    UserParam (..),+    UserListParam (..),+    ListParam (..),+    MediaData (..),+    TweetMode (..),+    mkUserParam,+    mkUserListParam,+    mkListParam,+) where  import qualified Data.Text as T import Network.HTTP.Client (RequestBody)-import Web.Twitter.Conduit.Request.Internal (APIQuery, PV(..))+import Web.Twitter.Conduit.Request.Internal (APIQuery, PV (..), ParameterValue (..)) import Web.Twitter.Types  -- $setup -- >>> import Web.Twitter.Conduit.Request.Internal +-- Required parameters+ data UserParam = UserIdParam UserId | ScreenNameParam String-               deriving (Show, Eq)+    deriving (Show, Eq) data UserListParam = UserIdListParam [UserId] | ScreenNameListParam [String]-                   deriving (Show, Eq)+    deriving (Show, Eq) data ListParam = ListIdParam Integer | ListNameParam String-               deriving (Show, Eq)-data MediaData = MediaFromFile FilePath-               | MediaRequestBody FilePath RequestBody+    deriving (Show, Eq)+data MediaData+    = MediaFromFile FilePath+    | MediaRequestBody FilePath RequestBody  -- | converts 'UserParam' to 'HT.SimpleQuery'. --@@ -34,7 +38,7 @@ -- >>> makeSimpleQuery . mkUserParam $ ScreenNameParam "thimura" -- [("screen_name","thimura")] mkUserParam :: UserParam -> APIQuery-mkUserParam (UserIdParam uid) =  [("user_id", PVInteger uid)]+mkUserParam (UserIdParam uid) = [("user_id", PVInteger uid)] mkUserParam (ScreenNameParam sn) = [("screen_name", PVString . T.pack $ sn)]  -- | converts 'UserListParam' to 'HT.SimpleQuery'.@@ -46,7 +50,7 @@ -- >>> makeSimpleQuery . mkUserListParam $ ScreenNameListParam ["thimura", "NikaidouShinku"] -- [("screen_name","thimura,NikaidouShinku")] mkUserListParam :: UserListParam -> APIQuery-mkUserListParam (UserIdListParam uids) =  [("user_id", PVIntegerArray uids)]+mkUserListParam (UserIdListParam uids) = [("user_id", PVIntegerArray uids)] mkUserListParam (ScreenNameListParam sns) = [("screen_name", PVStringArray (map T.pack sns))]  -- | converts 'ListParam' to 'HT.SimpleQuery'.@@ -56,10 +60,19 @@ -- >>> makeSimpleQuery . mkListParam $ ListNameParam "thimura/haskell" -- [("slug","haskell"),("owner_screen_name","thimura")] mkListParam :: ListParam -> APIQuery-mkListParam (ListIdParam lid) =  [("list_id", PVInteger lid)]+mkListParam (ListIdParam lid) = [("list_id", PVInteger lid)] mkListParam (ListNameParam listname) =-    [("slug", PVString (T.pack lstName)),-     ("owner_screen_name", PVString (T.pack screenName))]+    [ ("slug", PVString (T.pack lstName))+    , ("owner_screen_name", PVString (T.pack screenName))+    ]   where     (screenName, ln) = span (/= '/') listname     lstName = drop 1 ln++-- Optional parameters++data TweetMode = Extended deriving (Show, Eq)++instance ParameterValue TweetMode where+    wrap Extended = PVString "extended"+    unwrap = const Extended
− Web/Twitter/Conduit/ParametersDeprecated.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TypeFamilies #-}--module Web.Twitter.Conduit.ParametersDeprecated where--import Data.Text (Text)-import Web.Twitter.Types-import Data.Time.Calendar (Day)-import Web.Twitter.Conduit.Request.Internal-import Control.Lens--count :: (Parameters p, HasParam "count" Integer (SupportParameters p)) => Lens' p (Maybe Integer)-count = rawParam "count"--sinceId :: (Parameters p, HasParam "since_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)-sinceId = rawParam "since_id"--maxId :: (Parameters p, HasParam "max_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)-maxId = rawParam "max_id"--page :: (Parameters p, HasParam "page" Integer (SupportParameters p)) => Lens' p (Maybe Integer)-page = rawParam "page"--trimUser :: (Parameters p, HasParam "trim_user" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-trimUser = rawParam "trim_user"--excludeReplies :: (Parameters p, HasParam "exclude_replies" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-excludeReplies = rawParam "exclude_replies"--contributorDetails :: (Parameters p, HasParam "contributor_details" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-contributorDetails = rawParam "contributor_details"--includeEntities :: (Parameters p, HasParam "include_entities" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeEntities = rawParam "include_entities"--includeEmail :: (Parameters p, HasParam "include_email" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeEmail = rawParam "include_email"--includeUserEntities :: (Parameters p, HasParam "include_user_entities" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeUserEntities = rawParam "include_user_entities"--includeRts :: (Parameters p, HasParam "include_rts" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeRts = rawParam "include_rts"--includeMyRetweet :: (Parameters p, HasParam "include_my_retweet" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeMyRetweet = rawParam "include_my_retweet"--includeExtAltText :: (Parameters p, HasParam "include_ext_alt_text" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-includeExtAltText = rawParam "include_ext_alt_text"--inReplyToStatusId :: (Parameters p, HasParam "in_reply_to_status_id" Integer (SupportParameters p)) => Lens' p (Maybe Integer)-inReplyToStatusId = rawParam "in_reply_to_status_id"--displayCoordinates :: (Parameters p, HasParam "display_coordinates" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-displayCoordinates = rawParam "display_coordinates"--possiblySensitive :: (Parameters p, HasParam "possibly_sensitive" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-possiblySensitive = rawParam "possibly_sensitive"--lang :: (Parameters p, HasParam "lang" Text (SupportParameters p)) => Lens' p (Maybe Text)-lang = rawParam "lang"--language :: (Parameters p, HasParam "language" Text (SupportParameters p)) => Lens' p (Maybe Text)-language = rawParam "language"--locale :: (Parameters p, HasParam "locale" Text (SupportParameters p)) => Lens' p (Maybe Text)-locale = rawParam "locale"--filterLevel :: (Parameters p, HasParam "filter_level" Text (SupportParameters p)) => Lens' p (Maybe Text)-filterLevel = rawParam "filter_level"--stallWarnings :: (Parameters p, HasParam "stall_warnings" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-stallWarnings = rawParam "stall_warnings"--replies :: (Parameters p, HasParam "replies" Text (SupportParameters p)) => Lens' p (Maybe Text)-replies = rawParam "replies"--until :: (Parameters p, HasParam "until" Day (SupportParameters p)) => Lens' p (Maybe Day)-until = rawParam "until"--skipStatus :: (Parameters p, HasParam "skip_status" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-skipStatus = rawParam "skip_status"--follow :: (Parameters p, HasParam "follow" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-follow = rawParam "follow"--map :: (Parameters p, HasParam "map" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-map = rawParam "map"--mediaIds :: (Parameters p, HasParam "media_ids" [Integer] (SupportParameters p)) => Lens' p (Maybe [Integer])-mediaIds = rawParam "media_ids"--description :: (Parameters p, HasParam "description" Text (SupportParameters p)) => Lens' p (Maybe Text)-description = rawParam "description"--name :: (Parameters p, HasParam "name" Text (SupportParameters p)) => Lens' p (Maybe Text)-name = rawParam "name"--profileLinkColor :: (Parameters p, HasParam "profile_link_color" Text (SupportParameters p)) => Lens' p (Maybe Text)-profileLinkColor = rawParam "profile_link_color"--location :: (Parameters p, HasParam "location" Text (SupportParameters p)) => Lens' p (Maybe Text)-location = rawParam "location"--url :: (Parameters p, HasParam "url" URIString (SupportParameters p)) => Lens' p (Maybe URIString)-url = rawParam "url"--fullText :: (Parameters p, HasParam "full_text" Bool (SupportParameters p)) => Lens' p (Maybe Bool)-fullText = rawParam "full_text"--with :: (Parameters p, HasParam "with" Text (SupportParameters p)) => Lens' p (Maybe Text)-with = rawParam "with"
Web/Twitter/Conduit/Request.hs view
@@ -3,10 +3,10 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE TypeFamilies #-} -module Web.Twitter.Conduit.Request-       ( HasParam-       , APIRequest(..)-       ) where+module Web.Twitter.Conduit.Request (+    HasParam,+    APIRequest (..),+) where  import Data.Aeson import GHC.TypeLits (Symbol)@@ -51,22 +51,23 @@ -- [("max_id",PVInteger {unPVInteger = 1234567890})] data APIRequest (supports :: [Param Symbol *]) responseType     = APIRequest-      { _method :: HT.Method-      , _url :: String-      , _params :: APIQuery-      }+        { _method :: HT.Method+        , _url :: String+        , _params :: APIQuery+        }     | APIRequestMultipart-      { _method :: HT.Method-      , _url :: String-      , _params :: APIQuery-      , _part :: [Part]-      }+        { _method :: HT.Method+        , _url :: String+        , _params :: APIQuery+        , _part :: [Part]+        }     | APIRequestJSON-      { _method :: HT.Method-      , _url :: String-      , _params :: APIQuery-      , _body :: Value-      }+        { _method :: HT.Method+        , _url :: String+        , _params :: APIQuery+        , _body :: Value+        }+ instance Parameters (APIRequest supports responseType) where     type SupportParameters (APIRequest supports responseType) = supports 
Web/Twitter/Conduit/Request/Internal.hs view
@@ -37,12 +37,12 @@ type APIQueryItem = (ByteString, PV)  data PV-    = PVInteger { unPVInteger :: Integer }-    | PVBool { unPVBool :: Bool }-    | PVString { unPVString :: Text }-    | PVIntegerArray { unPVIntegerArray :: [Integer] }-    | PVStringArray { unPVStringArray :: [Text] }-    | PVDay { unPVDay :: Day }+    = PVInteger {unPVInteger :: Integer}+    | PVBool {unPVBool :: Bool}+    | PVString {unPVString :: Text}+    | PVIntegerArray {unPVIntegerArray :: [Integer]}+    | PVStringArray {unPVStringArray :: [Text]}+    | PVDay {unPVDay :: Day}     deriving (Show, Eq)  class Parameters req where@@ -84,24 +84,29 @@ paramValueBS (PVDay day) = S8.pack . show $ day  rawParam ::-       (Parameters p, ParameterValue a)-    => ByteString -- ^ key-    -> Lens' p (Maybe a)+    (Parameters p, ParameterValue a) =>+    -- | key+    ByteString ->+    Lens' p (Maybe a) rawParam key = lens getter setter-   where-     getter = preview $ params . to (lookup key) . _Just . to unwrap-     setter = flip (over params . replace key)-     replace k (Just v) = ((k, wrap v):) . dropAssoc k-     replace k Nothing = dropAssoc k-     dropAssoc k = filter ((/= k) . fst)+  where+    getter = preview $ params . to (lookup key) . _Just . to unwrap+    setter = flip (over params . replace key)+    replace k (Just v) = ((k, wrap v) :) . dropAssoc k+    replace k Nothing = dropAssoc k+    dropAssoc k = filter ((/= k) . fst) -instance ( Parameters req-         , ParameterValue a-         , KnownSymbol label-         , HasParam label a (SupportParameters req)-         , Functor f-         , lens ~ ((Maybe a -> f (Maybe a)) -> req -> f req)) =>-         IsLabel label lens where+{- ORMOLU_DISABLE -}+instance+    ( Parameters req+    , ParameterValue a+    , KnownSymbol label+    , HasParam label a (SupportParameters req)+    , Functor f+    , lens ~ ((Maybe a -> f (Maybe a)) -> req -> f req)+    ) =>+    IsLabel label lens where+ #if MIN_VERSION_base(4, 10, 0)     fromLabel = rawParam key #else@@ -109,3 +114,4 @@ #endif       where         key = S8.pack (symbolVal (Proxy :: Proxy label))+{- ORMOLU_ENABLE -}
Web/Twitter/Conduit/Response.hs view
@@ -2,23 +2,24 @@ {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE OverloadedStrings #-} -module Web.Twitter.Conduit.Response-       ( Response (..)-       , TwitterError (..)-       , TwitterErrorMessage (..)-       ) where+module Web.Twitter.Conduit.Response (+    Response (..),+    TwitterError (..),+    TwitterErrorMessage (..),+) where  import Control.Exception import Data.Aeson import Data.Data import qualified Data.Text as T-import Network.HTTP.Types (Status, ResponseHeaders, Status, ResponseHeaders)+import Network.HTTP.Types (ResponseHeaders, Status)  data Response responseType = Response     { responseStatus :: Status     , responseHeaders :: ResponseHeaders     , responseBody :: responseType-    } deriving (Show, Eq, Typeable, Functor, Foldable, Traversable)+    }+    deriving (Show, Eq, Typeable, Functor, Foldable, Traversable)  data TwitterError     = FromJSONError String@@ -35,15 +36,16 @@ data TwitterErrorMessage = TwitterErrorMessage     { twitterErrorCode :: Int     , twitterErrorMessage :: T.Text-    } deriving (Show, Data, Typeable)+    }+    deriving (Show, Data, Typeable)  instance Eq TwitterErrorMessage where-    TwitterErrorMessage { twitterErrorCode = a } == TwitterErrorMessage { twitterErrorCode = b }-        = a == b+    TwitterErrorMessage {twitterErrorCode = a} == TwitterErrorMessage {twitterErrorCode = b} =+        a == b  instance Ord TwitterErrorMessage where-    compare TwitterErrorMessage { twitterErrorCode = a } TwitterErrorMessage { twitterErrorCode = b }-        = a `compare` b+    compare TwitterErrorMessage {twitterErrorCode = a} TwitterErrorMessage {twitterErrorCode = b} =+        a `compare` b  instance Enum TwitterErrorMessage where     fromEnum = twitterErrorCode@@ -52,6 +54,6 @@ instance FromJSON TwitterErrorMessage where     parseJSON (Object o) =         TwitterErrorMessage-        <$> o .:  "code"-        <*> o .:  "message"+            <$> o .: "code"+            <*> o .: "message"     parseJSON v = fail $ "unexpected: " ++ show v
Web/Twitter/Conduit/Status.hs view
@@ -2,47 +2,47 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeOperators #-} -module Web.Twitter.Conduit.Status-       (-       -- * Timelines-         StatusesMentionsTimeline-       , mentionsTimeline-       , StatusesUserTimeline-       , userTimeline-       , StatusesHomeTimeline-       , homeTimeline-       , StatusesRetweetsOfMe-       , retweetsOfMe-       -- * Tweets-       , StatusesRetweetsId-       , retweetsId-       , StatusesShowId-       , showId-       , StatusesDestroyId-       , destroyId-       , StatusesUpdate-       , update-       , StatusesRetweetId-       , retweetId-       , MediaData (..)-       , StatusesUpdateWithMedia-       , updateWithMedia-       -- , oembed-       -- , retweetersIds-       , StatusesLookup-       , lookup-       ) where+module Web.Twitter.Conduit.Status (+    -- * Timelines+    StatusesMentionsTimeline,+    mentionsTimeline,+    StatusesUserTimeline,+    userTimeline,+    StatusesHomeTimeline,+    homeTimeline,+    StatusesRetweetsOfMe,+    retweetsOfMe, -import Prelude hiding ( lookup )+    -- * Tweets+    StatusesRetweetsId,+    retweetsId,+    StatusesShowId,+    showId,+    StatusesDestroyId,+    destroyId,+    StatusesUpdate,+    update,+    StatusesRetweetId,+    retweetId,+    MediaData (..),+    StatusesUpdateWithMedia,+    updateWithMedia,+    -- , oembed+    -- , retweetersIds+    StatusesLookup,+    lookup,+) where+ import Web.Twitter.Conduit.Base+import Web.Twitter.Conduit.Parameters import Web.Twitter.Conduit.Request import Web.Twitter.Conduit.Request.Internal-import Web.Twitter.Conduit.Parameters import Web.Twitter.Types+import Prelude hiding (lookup) +import Data.Default import qualified Data.Text as T import Network.HTTP.Client.MultipartFormData-import Data.Default  -- $setup -- >>> :set -XOverloadedStrings -XOverloadedLabels@@ -62,16 +62,17 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/mentions_timeline.json" [] mentionsTimeline :: APIRequest StatusesMentionsTimeline [Status] mentionsTimeline = APIRequest "GET" (endpoint ++ "statuses/mentions_timeline.json") def-type StatusesMentionsTimeline = '[-      "count" ':= Integer-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "trim_user" ':= Bool-    , "contributor_details" ':= Bool-    , "include_entities" ':= Bool-    , "tweet_mode" ':= T.Text-    ] +type StatusesMentionsTimeline =+    '[ "count" ':= Integer+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "trim_user" ':= Bool+     , "contributor_details" ':= Bool+     , "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns query data asks a collection of the most recent Tweets posted by the user indicated by the screen_name or user_id parameters. -- -- You can perform a search query using 'call':@@ -86,17 +87,18 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/user_timeline.json" [("count","200"),("include_rts","true"),("screen_name","thimura")] userTimeline :: UserParam -> APIRequest StatusesUserTimeline [Status] userTimeline q = APIRequest "GET" (endpoint ++ "statuses/user_timeline.json") (mkUserParam q)-type StatusesUserTimeline = '[-      "count" ':= Integer-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "trim_user" ':= Bool-    , "exclude_replies" ':= Bool-    , "contributor_details" ':= Bool-    , "include_rts" ':= Bool-    , "tweet_mode" ':= T.Text-    ] +type StatusesUserTimeline =+    '[ "count" ':= Integer+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "trim_user" ':= Bool+     , "exclude_replies" ':= Bool+     , "contributor_details" ':= Bool+     , "include_rts" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns query data asks a collection of the most recentTweets and retweets posted by the authenticating user and the users they follow. -- -- You can perform a search query using 'call':@@ -111,17 +113,18 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/home_timeline.json" [("count","200")] homeTimeline :: APIRequest StatusesHomeTimeline [Status] homeTimeline = APIRequest "GET" (endpoint ++ "statuses/home_timeline.json") def-type StatusesHomeTimeline = '[-      "count" ':= Integer-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "trim_user" ':= Bool-    , "exclude_replies" ':= Bool-    , "contributor_details" ':= Bool-    , "include_entities" ':= Bool-    , "tweet_mode" ':= T.Text-    ] +type StatusesHomeTimeline =+    '[ "count" ':= Integer+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "trim_user" ':= Bool+     , "exclude_replies" ':= Bool+     , "contributor_details" ':= Bool+     , "include_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns query data asks the most recent tweets authored by the authenticating user that have been retweeted by others. -- -- You can perform a search query using 'call':@@ -136,16 +139,17 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets_of_me.json" [("count","100")] retweetsOfMe :: APIRequest StatusesRetweetsOfMe [Status] retweetsOfMe = APIRequest "GET" (endpoint ++ "statuses/retweets_of_me.json") def-type StatusesRetweetsOfMe = '[-      "count" ':= Integer-    , "since_id" ':= Integer-    , "max_id" ':= Integer-    , "trim_user" ':= Bool-    , "include_entities" ':= Bool-    , "include_user_entities" ':= Bool-    , "tweet_mode" ':= T.Text-    ] +type StatusesRetweetsOfMe =+    '[ "count" ':= Integer+     , "since_id" ':= Integer+     , "max_id" ':= Integer+     , "trim_user" ':= Bool+     , "include_entities" ':= Bool+     , "include_user_entities" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- * Tweets  -- | Returns query data that asks for the most recent retweets of the specified tweet@@ -162,12 +166,15 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/retweets/1234567890.json" [("count","100")] retweetsId :: StatusId -> APIRequest StatusesRetweetsId [RetweetedStatus] retweetsId status_id = APIRequest "GET" uri def-  where uri = endpoint ++ "statuses/retweets/" ++ show status_id ++ ".json"-type StatusesRetweetsId = '[-      "count" ':= Integer-    , "trim_user" ':= Bool-    ]+  where+    uri = endpoint ++ "statuses/retweets/" ++ show status_id ++ ".json" +type StatusesRetweetsId =+    '[ "count" ':= Integer+     , "trim_user" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns query data asks a single Tweet, specified by the id parameter. -- -- You can perform a search query using 'call':@@ -182,15 +189,17 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/show/1234567890.json" [("include_my_retweet","true")] showId :: StatusId -> APIRequest StatusesShowId Status showId status_id = APIRequest "GET" uri def-  where uri = endpoint ++ "statuses/show/" ++ show status_id ++ ".json"-type StatusesShowId = '[-      "trim_user" ':= Bool-    , "include_my_retweet" ':= Bool-    , "include_entities" ':= Bool-    , "include_ext_alt_text" ':= Bool-    , "tweet_mode" ':= T.Text-    ]+  where+    uri = endpoint ++ "statuses/show/" ++ show status_id ++ ".json" +type StatusesShowId =+    '[ "trim_user" ':= Bool+     , "include_my_retweet" ':= Bool+     , "include_entities" ':= Bool+     , "include_ext_alt_text" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns post data which destroys the status specified by the require ID parameter. -- -- You can perform a search query using 'call':@@ -203,12 +212,14 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/statuses/destroy/1234567890.json" [] destroyId :: StatusId -> APIRequest StatusesDestroyId Status destroyId status_id = APIRequest "POST" uri def-  where uri = endpoint ++ "statuses/destroy/" ++ show status_id ++ ".json"-type StatusesDestroyId = '[-      "trim_user" ':= Bool-    , "tweet_mode" ':= T.Text-    ]+  where+    uri = endpoint ++ "statuses/destroy/" ++ show status_id ++ ".json" +type StatusesDestroyId =+    '[ "trim_user" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns post data which updates the authenticating user's current status. -- To upload an image to accompany the tweet, use 'updateWithMedia'. --@@ -224,17 +235,19 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/statuses/update.json" [("in_reply_to_status_id","1234567890"),("status","Hello World")] update :: T.Text -> APIRequest StatusesUpdate Status update status = APIRequest "POST" uri [("status", PVString status)]-  where uri = endpoint ++ "statuses/update.json"-type StatusesUpdate = '[-      "in_reply_to_status_id" ':= Integer-    -- , "lat_long"-    -- , "place_id"-    , "display_coordinates" ':= Bool-    , "trim_user" ':= Bool-    , "media_ids" ':= [Integer]-    , "tweet_mode" ':= T.Text-    ]+  where+    uri = endpoint ++ "statuses/update.json" +type StatusesUpdate =+    '[ "in_reply_to_status_id" ':= Integer+     , -- , "lat_long"+       -- , "place_id"+       "display_coordinates" ':= Bool+     , "trim_user" ':= Bool+     , "media_ids" ':= [Integer]+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns post data which retweets a tweet, specified by ID. -- -- You can perform a search query using 'call':@@ -247,11 +260,14 @@ -- APIRequest "POST" "https://api.twitter.com/1.1/statuses/retweet/1234567890.json" [] retweetId :: StatusId -> APIRequest StatusesRetweetId RetweetedStatus retweetId status_id = APIRequest "POST" uri def-  where uri = endpoint ++ "statuses/retweet/" ++ show status_id ++ ".json"-type StatusesRetweetId = '[-      "trim_user" ':= Bool-    ]+  where+    uri = endpoint ++ "statuses/retweet/" ++ show status_id ++ ".json" +type StatusesRetweetId =+    '[ "trim_user" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns post data which updates the authenticating user's current status and attaches media for upload. -- -- You can perform a search query using 'call':@@ -262,24 +278,26 @@ -- -- >>> updateWithMedia "Hello World" (MediaFromFile "/home/fuga/test.jpeg") -- APIRequestMultipart "POST" "https://api.twitter.com/1.1/statuses/update_with_media.json" [("status","Hello World")]-updateWithMedia :: T.Text-                -> MediaData-                -> APIRequest StatusesUpdateWithMedia Status+updateWithMedia ::+    T.Text ->+    MediaData ->+    APIRequest StatusesUpdateWithMedia Status updateWithMedia tweet mediaData =     APIRequestMultipart "POST" uri [("status", PVString tweet)] [mediaBody mediaData]   where     uri = endpoint ++ "statuses/update_with_media.json"     mediaBody (MediaFromFile fp) = partFileSource "media[]" fp     mediaBody (MediaRequestBody filename filebody) = partFileRequestBody "media[]" filename filebody-type StatusesUpdateWithMedia = '[-      "possibly_sensitive" ':= Bool-    , "in_reply_to_status_id" ':= Integer-    -- , "lat_long"-    -- , "place_id"-    , "display_coordinates" ':= Bool-    , "tweet_mode" ':= T.Text-    ] +type StatusesUpdateWithMedia =+    '[ "possibly_sensitive" ':= Bool+     , "in_reply_to_status_id" ':= Integer+     , -- , "lat_long"+       -- , "place_id"+       "display_coordinates" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]+ -- | Returns fully-hydrated tweet objects for up to 100 tweets per request, as specified by comma-separated values passed to the id parameter. -- -- You can perform a request using 'call':@@ -296,9 +314,10 @@ -- APIRequest "GET" "https://api.twitter.com/1.1/statuses/lookup.json" [("include_entities","true"),("id","10,432656548536401920")] lookup :: [StatusId] -> APIRequest StatusesLookup [Status] lookup ids = APIRequest "GET" (endpoint ++ "statuses/lookup.json") [("id", PVIntegerArray ids)]-type StatusesLookup = '[-      "include_entities" ':= Bool-    , "trim_user" ':= Bool-    , "map" ':= Bool-    , "tweet_mode" ':= T.Text-    ]++type StatusesLookup =+    '[ "include_entities" ':= Bool+     , "trim_user" ':= Bool+     , "map" ':= Bool+     , "tweet_mode" ':= TweetMode+     ]
Web/Twitter/Conduit/Stream.hs view
@@ -1,34 +1,33 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DataKinds #-}-{-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeOperators #-} -module Web.Twitter.Conduit.Stream-       (-       -- * StreamingAPI-         Userstream-       , userstream-       , StatusesFilter-       , FilterParameter (..)-       , statusesFilter-       , statusesFilterByFollow-       , statusesFilterByTrack-       -- , statusesFilterByLocation-       -- , statusesSample-       -- , statusesFirehose-       -- , sitestream-       -- , sitestream'-       , stream-       , stream'-  ) where+module Web.Twitter.Conduit.Stream (+    -- * StreamingAPI+    Userstream,+    userstream,+    StatusesFilter,+    FilterParameter (..),+    statusesFilter,+    statusesFilterByFollow,+    statusesFilterByTrack,+    -- , statusesFilterByLocation+    -- , statusesSample+    -- , statusesFirehose+    -- , sitestream+    -- , sitestream'+    stream,+    stream',+) where -import Web.Twitter.Conduit.Types import Web.Twitter.Conduit.Base-import Web.Twitter.Types import Web.Twitter.Conduit.Request import Web.Twitter.Conduit.Request.Internal import Web.Twitter.Conduit.Response+import Web.Twitter.Conduit.Types+import Web.Twitter.Types  import Control.Monad.Catch import Control.Monad.IO.Class@@ -43,25 +42,25 @@ import qualified Network.HTTP.Conduit as HTTP  stream ::-          ( MonadResource m-          , FromJSON responseType-          , MonadThrow m-          )-       => TWInfo-       -> HTTP.Manager-       -> APIRequest apiName responseType-        -> m (C.ConduitM () responseType m ())+    ( MonadResource m+    , FromJSON responseType+    , MonadThrow m+    ) =>+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    m (C.ConduitM () responseType m ()) stream = stream'  stream' ::-           ( MonadResource m-           , FromJSON value-           , MonadThrow m-           )-        => TWInfo-        -> HTTP.Manager-        -> APIRequest apiName responseType-        -> m (C.ConduitM () value m ())+    ( MonadResource m+    , FromJSON value+    , MonadThrow m+    ) =>+    TWInfo ->+    HTTP.Manager ->+    APIRequest apiName responseType ->+    m (C.ConduitM () value m ()) stream' info mgr req = do     rsrc <- getResponse info mgr =<< liftIO (makeRequest req)     return $ responseBody rsrc C..| CL.sequence sinkFromJSONIgnoreSpaces@@ -70,16 +69,17 @@  userstream :: APIRequest Userstream StreamingAPI userstream = APIRequest "GET" "https://userstream.twitter.com/1.1/user.json" []-type Userstream = '[-      "language" ':= T.Text-    , "filter_level" ':= T.Text-    , "stall_warnings" ':= Bool-    , "replies" ':= T.Text-    ]+type Userstream =+    '[ "language" ':= T.Text+     , "filter_level" ':= T.Text+     , "stall_warnings" ':= Bool+     , "replies" ':= T.Text+     ]  -- https://dev.twitter.com/streaming/overview/request-parameters-data FilterParameter = Follow [UserId]-                     | Track [T.Text]+data FilterParameter+    = Follow [UserId]+    | Track [T.Text]  -- | Returns statuses/filter.json API query data. --@@ -110,11 +110,14 @@ -- -- >>> statusesFilterByTrack "haskell" -- APIRequest "POST" "https://stream.twitter.com/1.1/statuses/filter.json" [("track","haskell")]-statusesFilterByTrack :: T.Text -- ^ keyword-                      -> APIRequest StatusesFilter StreamingAPI+statusesFilterByTrack ::+    -- | keyword+    T.Text ->+    APIRequest StatusesFilter StreamingAPI statusesFilterByTrack keyword = statusesFilter [Track [keyword]]-type StatusesFilter = '[-      "language" ':= T.Text-    , "filter_level" ':= T.Text-    , "stall_warnings" ':= Bool-    ]++type StatusesFilter =+    '[ "language" ':= T.Text+     , "filter_level" ':= T.Text+     , "stall_warnings" ':= Bool+     ]
Web/Twitter/Conduit/Types.hs view
@@ -1,36 +1,41 @@ {-# LANGUAGE DeriveDataTypeable #-}-module Web.Twitter.Conduit.Types-       ( TWToken (..)-       , TWInfo (..)-       , twitterOAuth-       , setCredential-       ) where +module Web.Twitter.Conduit.Types (+    TWToken (..),+    TWInfo (..),+    twitterOAuth,+    setCredential,+) where+ import Data.Default import Data.Typeable (Typeable)-import Web.Authenticate.OAuth import Network.HTTP.Conduit+import Web.Authenticate.OAuth  data TWToken = TWToken     { twOAuth :: OAuth     , twCredential :: Credential-    } deriving (Show, Read, Eq, Typeable)+    }+    deriving (Show, Read, Eq, Typeable) instance Default TWToken where     def = TWToken twitterOAuth (Credential [])  data TWInfo = TWInfo     { twToken :: TWToken     , twProxy :: Maybe Proxy-    } deriving (Show, Read, Eq, Typeable)+    }+    deriving (Show, Read, Eq, Typeable) instance Default TWInfo where-    def = TWInfo-        { twToken = def-        , twProxy = Nothing-        }+    def =+        TWInfo+            { twToken = def+            , twProxy = Nothing+            }  twitterOAuth :: OAuth twitterOAuth =-    def { oauthServerName = "twitter"+    def+        { oauthServerName = "twitter"         , oauthRequestUri = "https://api.twitter.com/oauth/request_token"         , oauthAccessTokenUri = "https://api.twitter.com/oauth/access_token"         , oauthAuthorizeUri = "https://api.twitter.com/oauth/authorize"@@ -52,8 +57,8 @@ -- >>> twProxy twinfo2 == Just proxy -- True setCredential :: OAuth -> Credential -> TWInfo -> TWInfo-setCredential oa cred env-  = TWInfo-    { twToken = TWToken oa cred-    , twProxy = twProxy env-    }+setCredential oa cred env =+    TWInfo+        { twToken = TWToken oa cred+        , twProxy = twProxy env+        }
sample/Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
sample/common/Common.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}  module Common where @@ -21,14 +21,16 @@     consumerSecret <- getEnv' "OAUTH_CONSUMER_SECRET"     accessToken <- getEnv' "OAUTH_ACCESS_TOKEN"     accessSecret <- getEnv' "OAUTH_ACCESS_SECRET"-    let oauth = twitterOAuth-            { oauthConsumerKey = consumerKey-            , oauthConsumerSecret = consumerSecret-            }-        cred = Credential-            [ ("oauth_token", accessToken)-            , ("oauth_token_secret", accessSecret)-            ]+    let oauth =+            twitterOAuth+                { oauthConsumerKey = consumerKey+                , oauthConsumerSecret = consumerSecret+                }+        cred =+            Credential+                [ ("oauth_token", accessToken)+                , ("oauth_token_secret", accessSecret)+                ]     return (oauth, cred)   where     getEnv' = (S8.pack <$>) . getEnv@@ -36,18 +38,19 @@ getProxyEnv :: IO (Maybe Proxy) getProxyEnv = do     env <- M.fromList . over (mapped . _1) CI.mk <$> getEnvironment-    let u = M.lookup "https_proxy" env <|>-            M.lookup "http_proxy" env <|>-            M.lookup "proxy" env >>= URI.parseURI >>= URI.uriAuthority+    let u =+            M.lookup "https_proxy" env+                <|> M.lookup "http_proxy" env+                <|> M.lookup "proxy" env >>= URI.parseURI >>= URI.uriAuthority     return $ Proxy <$> (S8.pack . URI.uriRegName <$> u) <*> (parsePort . URI.uriPort <$> u)   where     parsePort :: String -> Int-    parsePort []       = 8080-    parsePort (':':xs) = read xs-    parsePort xs       = error $ "port number parse failed " ++ xs+    parsePort [] = 8080+    parsePort (':' : xs) = read xs+    parsePort xs = error $ "port number parse failed " ++ xs  getTWInfoFromEnv :: IO TWInfo getTWInfoFromEnv = do     pr <- getProxyEnv     (oa, cred) <- getOAuthTokens-    return $ (setCredential oa cred def) { twProxy = pr }+    return $ (setCredential oa cred def) {twProxy = pr}
sample/fav.hs view
@@ -2,8 +2,8 @@  module Main where -import Web.Twitter.Conduit import Common+import Web.Twitter.Conduit  import Control.Lens import System.Environment
sample/oauth_callback.hs view
@@ -7,19 +7,19 @@  module Main where -import Web.Scotty-import qualified Network.HTTP.Types as HT-import Web.Twitter.Conduit-import qualified Web.Authenticate.OAuth as OA-import qualified Data.Text.Lazy as LT+import Control.Monad.IO.Class import qualified Data.ByteString as S import qualified Data.ByteString.Char8 as S8+import Data.IORef import qualified Data.Map as M import Data.Maybe-import Data.IORef-import Control.Monad.IO.Class+import qualified Data.Text.Lazy as LT+import qualified Network.HTTP.Types as HT import System.Environment import System.IO.Unsafe+import qualified Web.Authenticate.OAuth as OA+import Web.Scotty+import Web.Twitter.Conduit  callback :: String callback = "http://localhost:3000/callback"@@ -30,10 +30,10 @@     consumerSecret <- getEnv "OAUTH_CONSUMER_SECRET"     return $         twitterOAuth-        { oauthConsumerKey = S8.pack consumerKey-        , oauthConsumerSecret = S8.pack consumerSecret-        , oauthCallback = Just $ S8.pack callback-        }+            { oauthConsumerKey = S8.pack consumerKey+            , oauthConsumerSecret = S8.pack consumerSecret+            , oauthCallback = Just $ S8.pack callback+            }  type OAuthToken = S.ByteString @@ -43,8 +43,8 @@ takeCredential :: OAuthToken -> IORef (M.Map OAuthToken Credential) -> IO (Maybe Credential) takeCredential k ioref =     atomicModifyIORef ioref $ \m ->-        let (res, newm) = M.updateLookupWithKey (\_ _ -> Nothing) k m in-        (newm, res)+        let (res, newm) = M.updateLookupWithKey (\_ _ -> Nothing) k m+         in (newm, res)  storeCredential :: OAuthToken -> Credential -> IORef (M.Map OAuthToken Credential) -> IO () storeCredential k cred ioref =@@ -59,7 +59,8 @@  makeMessage :: OAuth -> Credential -> S.ByteString makeMessage tokens (Credential cred) =-    S8.intercalate "\n"+    S8.intercalate+        "\n"         [ "export OAUTH_CONSUMER_KEY=\"" <> oauthConsumerKey tokens <> "\""         , "export OAUTH_CONSUMER_SECRET=\"" <> oauthConsumerSecret tokens <> "\""         , "export OAUTH_ACCESS_TOKEN=\"" <> fromMaybe "" (lookup "oauth_token" cred) <> "\""@@ -80,7 +81,6 @@                 let message = makeMessage tokens accessTokens                 liftIO . S8.putStrLn $ message                 text . LT.pack . S8.unpack $ message-             Nothing -> do                 status HT.status404                 text "temporary token is not found"
sample/oauth_pin.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}  -- Example: --   $ export OAUTH_CONSUMER_KEY="your consumer key"@@ -8,12 +8,12 @@  module Main where -import Web.Twitter.Conduit hiding (lookup)-import Web.Authenticate.OAuth as OA import qualified Data.ByteString.Char8 as S8 import Data.Maybe import System.Environment import System.IO (hFlush, stdout)+import Web.Authenticate.OAuth as OA+import Web.Twitter.Conduit  getTokens :: IO OAuth getTokens = do@@ -21,14 +21,16 @@     consumerSecret <- getEnv "OAUTH_CONSUMER_SECRET"     return $         twitterOAuth-        { oauthConsumerKey = S8.pack consumerKey-        , oauthConsumerSecret = S8.pack consumerSecret-        , oauthCallback = Just "oob"-        }+            { oauthConsumerKey = S8.pack consumerKey+            , oauthConsumerSecret = S8.pack consumerSecret+            , oauthCallback = Just "oob"+            } -authorize :: OAuth -- ^ OAuth Consumer key and secret-          -> Manager-          -> IO Credential+authorize ::+    -- | OAuth Consumer key and secret+    OAuth ->+    Manager ->+    IO Credential authorize oauth mgr = do     cred <- OA.getTemporaryCredential oauth mgr     let url = OA.authorizeUrl oauth cred
sample/oslist.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE OverloadedStrings #-}+ module Main where -import Web.Twitter.Conduit import Common+import Web.Twitter.Conduit  import Data.Conduit import qualified Data.Conduit.List as CL
sample/post.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE OverloadedStrings #-}+ module Main where -import Web.Twitter.Conduit import Common+import Web.Twitter.Conduit  import qualified Data.Text as T import qualified Data.Text.IO as T
sample/postWithMedia.hs view
@@ -1,8 +1,9 @@ {-# LANGUAGE OverloadedStrings #-}+ module Main where -import Web.Twitter.Conduit import Common+import Web.Twitter.Conduit  import qualified Data.Text as T import System.Environment
sample/postWithMultipleMedia.hs view
@@ -1,11 +1,11 @@-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE OverloadedStrings #-}  module Main where +import Common import Web.Twitter.Conduit import Web.Twitter.Types.Lens-import Common  import Control.Lens import Control.Monad@@ -16,7 +16,7 @@  main :: IO () main = do-    (status:filepathList) <- getArgs+    (status : filepathList) <- getArgs     when (length filepathList > 4) $ do         hPutStrLn stderr $ "You can upload upto 4 images in a single tweet, but we got " ++ show (length filepathList) ++ " images. abort."         exitFailure@@ -28,5 +28,5 @@         putStrLn $ "Upload completed: media_id: " ++ ret ^. uploadedMediaId . to show ++ ", filepath: " ++ filepath         return ret     putStrLn $ "Post message: " ++ status-    res <- call twInfo mgr $ statusesUpdate (T.pack status) & #media_ids ?~ (uploadedMediaList ^.. traversed .  uploadedMediaId)+    res <- call twInfo mgr $ statusesUpdate (T.pack status) & #media_ids ?~ (uploadedMediaList ^.. traversed . uploadedMediaId)     print res
sample/search.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE OverloadedStrings #-}+ module Main where +import Common import Web.Twitter.Conduit import Web.Twitter.Types.Lens-import Common  import Control.Lens import qualified Data.Text as T
sample/searchSource.hs view
@@ -1,9 +1,10 @@ {-# LANGUAGE OverloadedStrings #-}+ module Main where +import Common import Web.Twitter.Conduit import Web.Twitter.Types.Lens-import Common  import Control.Lens import Data.Conduit
sample/simple.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE OverloadedStrings #-}  module Main where @@ -17,15 +17,19 @@ import qualified Web.Authenticate.OAuth as OA  tokens :: OAuth-tokens = twitterOAuth-    { oauthConsumerKey = error "You MUST specify oauthConsumerKey parameter."-    , oauthConsumerSecret = error "You MUST specify oauthConsumerSecret parameter."-    }+tokens =+    twitterOAuth+        { oauthConsumerKey = error "You MUST specify oauthConsumerKey parameter."+        , oauthConsumerSecret = error "You MUST specify oauthConsumerSecret parameter."+        } -authorize :: OAuth -- ^ OAuth Consumer key and secret-          -> (String -> IO String) -- ^ PIN prompt-          -> Manager-          -> IO Credential+authorize ::+    -- | OAuth Consumer key and secret+    OAuth ->+    -- | PIN prompt+    (String -> IO String) ->+    Manager ->+    IO Credential authorize oauth getPIN mgr = do     cred <- OA.getTemporaryCredential oauth mgr     let url = OA.authorizeUrl oauth cred@@ -49,15 +53,17 @@     mgr <- newManager tlsManagerSettings     twInfo <- getTWInfo mgr     putStrLn $ "# your home timeline (up to 800 tweets):"-    runConduit $ sourceWithMaxId twInfo mgr (statusesHomeTimeline & #count ?~ 200)-        .| CL.isolate 800-        .| CL.mapM_-            (\status -> do-                 T.putStrLn $-                     T.concat-                         [ T.pack . show $ status ^. statusId-                         , ": "-                         , status ^. statusUser . userScreenName-                         , ": "-                         , status ^. statusText-                         ])+    runConduit $+        sourceWithMaxId twInfo mgr (statusesHomeTimeline & #count ?~ 200)+            .| CL.isolate 800+            .| CL.mapM_+                ( \status -> do+                    T.putStrLn $+                        T.concat+                            [ T.pack . show $ status ^. statusId+                            , ": "+                            , status ^. statusUser . userScreenName+                            , ": "+                            , status ^. statusText+                            ]+                )
sample/userstream.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE PatternGuards #-} +import Common import Web.Twitter.Conduit import Web.Twitter.Types.Lens-import Common  import Control.Lens import Control.Monad@@ -39,30 +39,35 @@         runConduit $ src .| CL.mapM_ (liftIO . printTL)  showStatus :: AsStatus s => s -> T.Text-showStatus s = T.concat [ s ^. user . userScreenName-                        , ":"-                        , s ^. text-                        ]+showStatus s =+    T.concat+        [ s ^. user . userScreenName+        , ":"+        , s ^. text+        ]  printTL :: StreamingAPI -> IO () printTL (SStatus s) = T.putStrLn . showStatus $ s-printTL (SRetweetedStatus s) = T.putStrLn $ T.concat [ s ^. user . userScreenName-                                                     , ": RT @"-                                                     , showStatus (s ^. rsRetweetedStatus)-                                                     ]+printTL (SRetweetedStatus s) =+    T.putStrLn $+        T.concat+            [ s ^. user . userScreenName+            , ": RT @"+            , showStatus (s ^. rsRetweetedStatus)+            ] printTL (SEvent event)-    | (event^.evEvent) == "favorite" || (event^.evEvent) == "unfavorite",-      Just (ETStatus st) <- event ^. evTargetObject = do-          let (fromUser, fromIcon) = evUserInfo (event^.evSource)-              (toUser, _toIcon) = evUserInfo (event^.evTarget)-              evUserInfo (ETUser u) = (u ^. userScreenName, u ^. userProfileImageURL)-              evUserInfo _ = ("", Nothing)-              header = T.concat [ event ^. evEvent, "[", fromUser, " -> ", toUser, "]"]-          T.putStrLn $ T.concat [ header, " :: ", showStatus st ]-          icon <- case fromIcon of-              Just iconUrl -> Just <$> fetchIcon (T.unpack fromUser) (T.unpack iconUrl)-              Nothing -> return Nothing-          notifySend header (showStatus st) icon+    | (event ^. evEvent) == "favorite" || (event ^. evEvent) == "unfavorite"+      , Just (ETStatus st) <- event ^. evTargetObject = do+        let (fromUser, fromIcon) = evUserInfo (event ^. evSource)+            (toUser, _toIcon) = evUserInfo (event ^. evTarget)+            evUserInfo (ETUser u) = (u ^. userScreenName, u ^. userProfileImageURL)+            evUserInfo _ = ("", Nothing)+            header = T.concat [event ^. evEvent, "[", fromUser, " -> ", toUser, "]"]+        T.putStrLn $ T.concat [header, " :: ", showStatus st]+        icon <- case fromIcon of+            Just iconUrl -> Just <$> fetchIcon (T.unpack fromUser) (T.unpack iconUrl)+            Nothing -> return Nothing+        notifySend header (showStatus st) icon printTL s = print s  notifySend :: T.Text -> T.Text -> Maybe FilePath -> IO ()@@ -70,9 +75,12 @@     let ic = maybe [] (\i -> ["-i", i]) icon     void $ rawSystem "notify-send" $ [T.unpack header, T.unpack content] ++ ic -fetchIcon :: String -- ^ screen name-          -> String -- ^ icon url-          -> IO String+fetchIcon ::+    -- | screen name+    String ->+    -- | icon url+    String ->+    IO String fetchIcon sn url = do     ipath <- iconPath     let fname = ipath </> sn ++ "__" ++ takeFileName url
tests/ApiSpec.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}  module ApiSpec where @@ -9,7 +9,7 @@ import Network.HTTP.Conduit import System.IO.Unsafe import TestUtils-import Web.Twitter.Conduit (call, sourceWithCursor, TWInfo)+import Web.Twitter.Conduit (TWInfo, call, sourceWithCursor) import Web.Twitter.Conduit.Api import Web.Twitter.Conduit.Lens import qualified Web.Twitter.Conduit.Parameters as Param@@ -27,6 +27,7 @@ spec :: Spec spec = do     unit+ #ifdef RUN_INTEGRATED_TEST     integrated #endif
tests/BaseSpec.hs view
@@ -2,8 +2,8 @@  module BaseSpec where -import Web.Twitter.Conduit.Response import Web.Twitter.Conduit.Base+import Web.Twitter.Conduit.Response  import Control.Applicative import Control.Lens@@ -80,9 +80,10 @@ data TestJSON = TestJSON     { testField :: T.Text     , testStatus :: Int-    } deriving (Show, Eq)+    }+    deriving (Show, Eq) instance FromJSON TestJSON where     parseJSON (Object o) =         TestJSON <$> o .: "test"-                 <*> o .: "status"+            <*> o .: "status"     parseJSON v = fail $ "Unexpected: " ++ show v
tests/StatusSpec.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE OverloadedStrings #-}  module StatusSpec where @@ -10,13 +10,13 @@ import Data.Time import Network.HTTP.Conduit import System.IO.Unsafe-import Web.Twitter.Conduit (call, accountVerifyCredentials, sourceWithMaxId, TWInfo)+import Web.Twitter.Conduit (TWInfo, accountVerifyCredentials, call, sourceWithMaxId) import qualified Web.Twitter.Conduit.Parameters as Param import Web.Twitter.Conduit.Status as Status import Web.Twitter.Types.Lens -import TestUtils import Test.Hspec+import TestUtils  twInfo :: TWInfo twInfo = unsafePerformIO getTWInfo@@ -32,6 +32,7 @@ spec :: Spec spec = do     unit+ #ifdef RUN_INTEGRATED_TEST     integrated #endif@@ -42,7 +43,7 @@ integrated :: Spec integrated = do     describe "mentionsTimeline" $ do-        it "returns the 20 most resent mentions for user" $ do+        it "returns the 20 most recent mentions for user" $ do             res <- call twInfo mgr mentionsTimeline             length res `shouldSatisfy` (> 0)             let mentionsScreenName = res ^.. traversed . statusEntities . _Just . enUserMentions . traversed . entityBody . userEntityUserScreenName@@ -55,13 +56,16 @@             length res `shouldSatisfy` (== 20)             res `shouldSatisfy` (allOf folded (^. statusUser . userScreenName . to (== "thimura")))         it "returns the recent tweets which include RTs when specified include_rts option" $ do-            res <- call twInfo mgr-                   $ userTimeline (Param.ScreenNameParam "thimura")-                   & #count ?~ 100 & #include_rts ?~ True+            res <-+                call twInfo mgr $+                    userTimeline (Param.ScreenNameParam "thimura")+                        & #count ?~ 100+                        & #include_rts ?~ True             res `shouldSatisfy` (anyOf (folded . statusRetweetedStatus . _Just . statusUser . userScreenName) (/= "thimura"))         it "iterate with sourceWithMaxId" $ do-            let src = sourceWithMaxId twInfo mgr $-                      userTimeline (Param.ScreenNameParam "thimura") & #count ?~ 200+            let src =+                    sourceWithMaxId twInfo mgr $+                        userTimeline (Param.ScreenNameParam "thimura") & #count ?~ 200             tl <- src $$ CL.isolate 600 =$ CL.consume             length tl `shouldSatisfy` (== 600) @@ -95,3 +99,9 @@             length res `shouldSatisfy` (== 2)             (res !! 0) ^. statusId `shouldBe` 438691466345340928             (res !! 1) ^. statusId `shouldBe` 477757405942411265++        it "handles extended tweets" $ do+            res <- call twInfo mgr $ Status.lookup [1128358947772145672]+            (res !! 0) ^. statusText `shouldBe` "Through the Twitter Developer Labs program, we'll soon preview new versions of GET /tweets and GET /users, followed\8230 https://t.co/9i4c5bUUCu"+            res <- call twInfo mgr $ Status.lookup [1128358947772145672] & #tweet_mode ?~ Param.Extended+            (res !! 0) ^. statusText `shouldBe` "Through the Twitter Developer Labs program, we'll soon preview new versions of GET /tweets and GET /users, followed by Tweet streaming, search &amp; metrics. More to come! \128073 https://t.co/rDE48yNiSw https://t.co/oFsvkpnDhS"
tests/TestUtils.hs view
@@ -12,14 +12,16 @@     consumerSecret <- getEnv' "OAUTH_CONSUMER_SECRET"     accessToken <- getEnv' "OAUTH_ACCESS_TOKEN"     accessSecret <- getEnv' "OAUTH_ACCESS_SECRET"-    let oauth = twitterOAuth-            { oauthConsumerKey = consumerKey-            , oauthConsumerSecret = consumerSecret-            }-        cred = Credential-            [ ("oauth_token", accessToken)-            , ("oauth_token_secret", accessSecret)-            ]+    let oauth =+            twitterOAuth+                { oauthConsumerKey = consumerKey+                , oauthConsumerSecret = consumerSecret+                }+        cred =+            Credential+                [ ("oauth_token", accessToken)+                , ("oauth_token_secret", accessSecret)+                ]     return (oauth, cred)   where     getEnv' = (S8.pack <$>) . getEnv
tests/doctests.hs view
@@ -1,6 +1,6 @@ module Main where -import Build_doctests (flags, pkgs, module_sources)+import Build_doctests (flags, module_sources, pkgs) import Data.Foldable (traverse_) import Test.DocTest (doctest) 
− tests/hlint.hs
@@ -1,20 +0,0 @@-module Main where--import Control.Monad-import Data.Maybe-import Language.Haskell.HLint-import System.Environment-import System.Exit--main :: IO ()-main = do-  args <- getArgs-  cabalMacros <- getCabalMacrosPath-  hints <- hlint $ ["Web", "--cpp-define=HLINT", "--cpp-ansi", "--cpp-file=" ++ cabalMacros] ++ args-  unless (null hints) exitFailure--getCabalMacrosPath :: IO FilePath-getCabalMacrosPath = do-    env <- getEnvironment-    let dist = fromMaybe "dist" $ lookup "HASKELL_DIST_DIR" env-    return $ dist ++ "/build/autogen/cabal_macros.h"
twitter-conduit.cabal view
@@ -1,156 +1,138 @@-name:              twitter-conduit-version:           0.5.1-license:           BSD3-license-file:      LICENSE-author:            HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA-maintainer:        Takahiro HIMURA <taka@himura.jp>-synopsis:          Twitter API package with conduit interface and Streaming API support.-category:          Web, Conduit-stability:         Experimental-cabal-version:     >= 1.10-build-type:        Custom-homepage:          https://github.com/himura/twitter-conduit--tested-with:       GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.3+cabal-version:      1.24+name:               twitter-conduit+version:            0.6.0+license:            BSD3+license-file:       LICENSE+maintainer:         Takahiro HIMURA <taka@himura.jp>+author:             HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA+stability:          Experimental+tested-with:        ghc ==8.8.4 ghc ==8.10.7 ghc ==9.0.1+homepage:           https://github.com/himura/twitter-conduit+synopsis:+    Twitter API package with conduit interface and Streaming API support.  description:-  This package provides bindings to Twitter's APIs (see <https://dev.twitter.com/>).-  .-  This package uses the http-conduit package for accessing the Twitter API (see <http://hackage.haskell.org/package/http-conduit>).-  This package also depends on the twitter-types package (see <http://hackage.haskell.org/package/twitter-types>).-  .-  You can find basic examples in the <https://github.com/himura/twitter-conduit/tree/master/sample> directory.-  .-  This package is under development. If you find something that has not been implemented yet, please send a pull request or open an issue on GitHub.+    This package provides bindings to Twitter's APIs (see <https://dev.twitter.com/>).+    .+    This package uses the http-conduit package for accessing the Twitter API (see <http://hackage.haskell.org/package/http-conduit>).+    This package also depends on the twitter-types package (see <http://hackage.haskell.org/package/twitter-types>).+    .+    You can find basic examples in the <https://github.com/himura/twitter-conduit/tree/master/sample> directory.+    .+    This package is under development. If you find something that has not been implemented yet, please send a pull request or open an issue on GitHub. +category:           Web, Conduit+build-type:         Custom extra-source-files:-  .gitignore-  README.md-  ChangeLog.md-  Warning.hs-  sample/LICENSE-  sample/twitter-conduit-sample.cabal-  sample/*.hs-  sample/common/*.hs-  tests/*.hs+    .gitignore+    README.md+    ChangeLog.md+    Warning.hs+    sample/LICENSE+    sample/twitter-conduit-sample.cabal+    sample/*.hs+    sample/common/*.hs+    tests/*.hs  source-repository head-  type: git-  location: git://github.com/himura/twitter-conduit.git+    type:     git+    location: git://github.com/himura/twitter-conduit.git +custom-setup+    setup-depends:+        base,+        Cabal >=1.24,+        cabal-doctest >=1 && <1.1+ flag run-integrated-test-  description: use debug output when running testsuites-  default: False+    description: use debug output when running testsuites+    default:     False  library-  ghc-options: -Wall--  build-depends:-      base >= 4.9 && < 5-    , aeson >= 0.7.0.5-    , attoparsec >= 0.10-    , authenticate-oauth >= 1.3-    , bytestring >= 0.10.2-    , conduit >= 1.3-    , conduit-extra >= 1.3-    , containers-    , data-default >= 0.3-    , exceptions >= 0.5-    , ghc-prim-    , http-client >= 0.5.0-    , http-conduit >= 2.3 && < 2.4-    , http-types-    , lens >= 4.4-    , lens-aeson >= 1-    , resourcet >= 1.0-    , text >= 0.11-    , time-    , transformers >= 0.2.2-    , twitter-types >= 0.9-    , twitter-types-lens >= 0.9--  exposed-modules:-    Web.Twitter.Conduit-    Web.Twitter.Conduit.Lens-    Web.Twitter.Conduit.Types-    Web.Twitter.Conduit.Api-    Web.Twitter.Conduit.Stream-    Web.Twitter.Conduit.Status-    Web.Twitter.Conduit.Base-    Web.Twitter.Conduit.Request-    Web.Twitter.Conduit.Request.Internal-    Web.Twitter.Conduit.Response-    Web.Twitter.Conduit.Cursor-    Web.Twitter.Conduit.Parameters-    Web.Twitter.Conduit.ParametersDeprecated--  default-language: Haskell2010--test-suite hlint-  type: exitcode-stdio-1.0-  main-is: hlint.hs-  hs-source-dirs: tests--  build-depends:-      base-    , hlint >= 1.7+    exposed-modules:+        Web.Twitter.Conduit+        Web.Twitter.Conduit.Lens+        Web.Twitter.Conduit.Types+        Web.Twitter.Conduit.Api+        Web.Twitter.Conduit.Stream+        Web.Twitter.Conduit.Status+        Web.Twitter.Conduit.Base+        Web.Twitter.Conduit.Request+        Web.Twitter.Conduit.Request.Internal+        Web.Twitter.Conduit.Response+        Web.Twitter.Conduit.Cursor+        Web.Twitter.Conduit.Parameters -  default-language: Haskell2010+    default-language: Haskell2010+    ghc-options:      -Wall+    build-depends:+        base >=4.9 && <5,+        aeson >=0.7.0.5,+        attoparsec >=0.10,+        authenticate-oauth >=1.3,+        bytestring >=0.10.2,+        conduit >=1.3,+        conduit-extra >=1.3,+        containers,+        data-default >=0.3,+        exceptions >=0.5,+        ghc-prim,+        http-client >=0.5.0,+        http-conduit >=2.3 && <2.4,+        http-types,+        lens >=4.4,+        lens-aeson >=1,+        resourcet >=1.0,+        text >=0.11,+        time,+        transformers >=0.2.2,+        twitter-types >=0.9,+        twitter-types-lens >=0.9  test-suite doctests-  type: exitcode-stdio-1.0-  main-is: doctests.hs-  hs-source-dirs: tests--  build-depends:-      base-    , doctest--  default-language: Haskell2010+    type:             exitcode-stdio-1.0+    main-is:          doctests.hs+    hs-source-dirs:   tests+    default-language: Haskell2010+    build-depends:+        base,+        doctest  test-suite spec_main-  type: exitcode-stdio-1.0-  main-is: spec_main.hs-  hs-source-dirs: tests--  if flag(run-integrated-test)-    CPP-Options: -DRUN_INTEGRATED_TEST--  build-tool-depends: hspec-discover:hspec-discover >= 2.3.0-  build-depends:-      base-    , aeson-    , attoparsec-    , authenticate-oauth-    , bytestring-    , conduit-    , conduit-extra-    , containers-    , data-default-    , hspec-    , http-client-    , http-conduit-    , http-types-    , lens-    , lens-aeson-    , resourcet-    , text-    , time-    , twitter-conduit-    , twitter-types-    , twitter-types-lens--  other-modules:-    Spec-    ApiSpec-    BaseSpec-    StatusSpec-    TestUtils+    type:               exitcode-stdio-1.0+    main-is:            spec_main.hs+    build-tool-depends: hspec-discover:hspec-discover >=2.3.0+    hs-source-dirs:     tests+    other-modules:+        Spec+        ApiSpec+        BaseSpec+        StatusSpec+        TestUtils -  default-language: Haskell2010+    default-language:   Haskell2010+    build-depends:+        base,+        aeson,+        attoparsec,+        authenticate-oauth,+        bytestring,+        conduit,+        conduit-extra,+        containers,+        data-default,+        hspec,+        http-client,+        http-conduit,+        http-types,+        lens,+        lens-aeson,+        resourcet,+        text,+        time,+        twitter-conduit,+        twitter-types,+        twitter-types-lens -custom-setup-  setup-depends:-      base-    , Cabal >= 1.24-    , cabal-doctest >= 1 && < 1.1+    if flag(run-integrated-test)+        cpp-options: -DRUN_INTEGRATED_TEST