twitter-conduit 0.0.2 → 0.0.2.1
raw patch · 12 files changed
+305/−8 lines, 12 filesdep +http-clientdep +shakespearedep −http-client-multipartdep −shakespeare-textdep ~conduitdep ~http-conduitdep ~resourcet
Dependencies added: http-client, shakespeare
Dependencies removed: http-client-multipart, shakespeare-text
Dependency ranges changed: conduit, http-conduit, resourcet
Files
- .gitignore +26/−0
- .travis.yml +1/−0
- README.md +86/−0
- Web/Twitter/Conduit.hs +2/−2
- sample/Common.hs +62/−0
- sample/fav.hs +18/−0
- sample/oslist.hs +28/−0
- sample/post.hs +18/−0
- sample/postWithMedia.hs +15/−0
- sample/search.hs +20/−0
- sample/unfav.hs +17/−0
- twitter-conduit.cabal +12/−6
+ .gitignore view
@@ -0,0 +1,26 @@+# General+\#*#+.*~+*~+.#*+*.swp+.DS_Store+.gdb_history+TAGS+# Object files+*.a+*.o+*.so+*.hi+*.p_hi+a.out+# autotool+autom4te.cache+stamp-h1+# misc+*.sqlite+Main+dist/+cabal-dev/+cabal.sandbox.config+.cabal-sandbox
+ .travis.yml view
@@ -0,0 +1,1 @@+language: haskell
+ README.md view
@@ -0,0 +1,86 @@+# twitter-conduit: An Conduit based Twitter API library for Haskell #++[](https://travis-ci.org/himura/twitter-conduit)++## About ##++This is an conduit based Twitter API library for Haskell, including Streaming API supports.++Documentation is available in [hackage](http://hackage.haskell.org/package/twitter-conduit).++## Usage ##++ $ cabal update+ $ cabal install twitter-conduit++## Quick Start ##++For a runnable example, see [sample/simple.hs](https://github.com/himura/twitter-conduit/blob/master/sample/simple.hs).+You can find other various examples in [sample](https://github.com/himura/twitter-conduit/tree/master/sample/) directory.++## Run Samples ##++### Build ###++If you would like to use cabal sandbox, prepare sandbox as below:++~~~~+$ cabal sandbox init+~~~~++and then,++~~~~+$ cabal configure -fbuild-samples+$ cabal build+~~~~++### Run ###++First, you must obtain consumer key and secret from [Twitter Application Management](https://apps.twitter.com/) page,+and you have to set those values to environment variables as shown below:++~~~~+$ export OAUTH_CONSUMER_KEY="YOUR APPLICATION CONSUMER KEY"+$ export OAUTH_CONSUMER_SECRET="YOUR APPLICATION CONSUMER SECRET"+~~~~++Before you run examples, you must prepare OAuth access token and secret.+You can obtain access token and secret by using either PIN or web callback.++If you would like to use the PIN method, you run simply as below, and follow instructions:++~~~~+$ cabal run oauth_pin+~~~~++On the other hand, If you would like to use the callback method, do as follows:++~~~~+$ cabal run oauth_callback+~~~~++and open http://localhost:3000/signIn in your browser.++In both cases, you can obtain OAUTH_ACCESSS_TOKEN and OAUTH_ACCESS_SECRET variables,+then you should set those values to environment variables as shown below:++~~~~+$ export OAUTH_ACCESS_TOKEN="YOUR ACCESS TOKEN"+$ export OAUTH_ACCESS_SECRET="YOUR ACCESS SECRET"+~~~~++Finally, you can access Twitter UserStream as follows:++~~~~+$ cabal run userstream+~~~~++## Examples ##++TODO++## Authors and Credits ##++`twitter-conduit` initially was written by Takahiro Himura.+We would like to thank everyone who supported and contributed to the development of this library.
Web/Twitter/Conduit.hs view
@@ -158,9 +158,9 @@ -- $= CL.isolate 60 -- $$ CL.mapM_ $ \status -> liftIO $ do -- T.putStrLn $ T.concat [ T.pack . show $ status ^. statusId--- , ": "+-- , \": \" -- , status ^. statusUser . userScreenName--- , ": "+-- , \": \" -- , status ^. statusText -- ] -- @
+ sample/Common.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++module Common where++import Web.Twitter.Conduit++import Web.Authenticate.OAuth as OA+import qualified Network.URI as URI+import Network.HTTP.Conduit+import qualified Data.Map as M+import qualified Data.ByteString.Char8 as S8+import qualified Data.CaseInsensitive as CI+import Control.Applicative+import Control.Monad.IO.Class+import Control.Monad.Base+import Control.Monad.Trans.Resource+import System.Environment+import Control.Monad.Logger+import Control.Lens++getOAuthTokens :: IO (OAuth, Credential)+getOAuthTokens = do+ consumerKey <- getEnv' "OAUTH_CONSUMER_KEY"+ 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)+ ]+ return (oauth, cred)+ where+ getEnv' = (S8.pack <$>) . getEnv++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+ 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++runTwitterFromEnv :: (MonadIO m, MonadBaseControl IO m) => TW (ResourceT m) a -> m a+runTwitterFromEnv task = do+ pr <- liftBase getProxyEnv+ (oa, cred) <- liftBase getOAuthTokens+ let env = (setCredential oa cred def) { twProxy = pr }+ runTW env task++runTwitterFromEnv' :: (MonadIO m, MonadBaseControl IO m) => TW (ResourceT (NoLoggingT m)) a -> m a+runTwitterFromEnv' = runNoLoggingT . runTwitterFromEnv
+ sample/fav.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE OverloadedStrings #-}++module Main where++import Control.Monad.IO.Class+import Web.Twitter.Conduit+import System.Environment+import Common+import Control.Lens++main :: IO ()+main = runTwitterFromEnv' $ do+ [statusIdStr] <- liftIO getArgs+ let sId = read statusIdStr+ targetStatus <- call $ showId sId+ liftIO . putStrLn $ "Favorite Tweet: " ++ targetStatus ^. to show+ res <- call $ favoritesCreate sId+ liftIO $ print res
+ sample/oslist.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import qualified Data.Conduit as C+import qualified Data.Conduit.List as CL+import qualified Data.Map as M+import Control.Monad.IO.Class+import System.Environment++import Web.Twitter.Conduit+import Common++main :: IO ()+main = runTwitterFromEnv' $ do+ [screenName] <- liftIO getArgs+ let sn = ScreenNameParam screenName+ folids <- sourceWithCursor (followersIds sn) C.$$ CL.consume+ friids <- sourceWithCursor (friendsIds sn) C.$$ CL.consume++ let folmap = M.fromList $ map (flip (,) True) folids+ os = filter (\uid -> M.notMember uid folmap) friids+ bo = filter (\usr -> M.member usr folmap) friids++ liftIO $ putStrLn "one sided:"+ liftIO $ print os++ liftIO $ putStrLn "both following:"+ liftIO $ print bo
+ sample/post.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import qualified Data.Text as T+import qualified Data.Text.IO as T+import Data.Monoid+import Control.Applicative+import Control.Monad.IO.Class+import Web.Twitter.Conduit+import System.Environment+import Common++main :: IO ()+main = runTwitterFromEnv' $ do+ status <- T.concat . map T.pack <$> liftIO getArgs+ liftIO $ T.putStrLn $ "Post message: " <> status+ res <- call $ update status+ liftIO $ print res
+ sample/postWithMedia.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import qualified Data.Text as T+import Control.Monad.IO.Class+import Web.Twitter.Conduit+import System.Environment+import Common++main :: IO ()+main = runTwitterFromEnv' $ do+ [status, filepath] <- liftIO getArgs+ liftIO $ putStrLn $ "Post message: " ++ status+ res <- call $ updateWithMedia (T.pack status) (MediaFromFile filepath)+ liftIO $ print res
+ sample/search.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Control.Monad.IO.Class+import System.Environment++import Web.Twitter.Conduit+import Common+import qualified Data.Text as T+import Control.Lens++main :: IO ()+main = runTwitterFromEnv' $ do+ [keyword] <- liftIO getArgs++ res <- call . search $ T.pack keyword+ let metadata = res ^. searchResultSearchMetadata+ liftIO . putStrLn $ "search completed in: " ++ metadata ^. searchMetadataCompletedIn . to show+ liftIO . putStrLn $ "search result max id: " ++ metadata ^. searchMetadataMaxId . to show+ liftIO . print $ res ^. searchResultStatuses
+ sample/unfav.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Control.Monad.IO.Class+import Web.Twitter.Conduit+import System.Environment+import Common+import Control.Lens++main :: IO ()+main = runTwitterFromEnv' $ do+ [statusIdStr] <- liftIO getArgs+ let sId = read statusIdStr+ targetStatus <- call $ showId sId+ liftIO . putStrLn $ "Unfavorite Tweet: " ++ targetStatus ^. to show+ res <- call $ favoritesDestroy sId+ liftIO $ print res
twitter-conduit.cabal view
@@ -1,5 +1,5 @@ name: twitter-conduit-version: 0.0.2+version: 0.0.2.1 license: BSD3 license-file: LICENSE author: HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA@@ -21,6 +21,12 @@ . 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. +extra-source-files:+ .gitignore+ .travis.yml+ README.md+ sample/*.hs+ source-repository head type: git location: git://github.com/himura/twitter-conduit.git@@ -41,14 +47,14 @@ , monad-control >= 0.3 , lens >= 4.0 , authenticate-oauth >= 1.3- , resourcet >= 0.4.3- , conduit >= 1.0+ , resourcet >= 0.4.3 && < 0.5+ , conduit >= 1.0 && < 1.1 , failure >= 0.2 , monad-logger- , shakespeare-text+ , shakespeare >= 2.0 , http-types- , http-conduit >= 2.0- , http-client-multipart+ , http-conduit >= 2.0 && < 2.1+ , http-client >= 0.3 , aeson >= 0.7 , attoparsec >= 0.10 , attoparsec-conduit >= 1.0