]> gitweb.michael.orlitzky.com - dead/halcyon.git/blobdiff - src/Twitter/Http.hs
Clean up a bunch of code and comments.
[dead/halcyon.git] / src / Twitter / Http.hs
index bff4288776ad59a80e5aa822253f4b510bac1984..eec7ab7187c56145ea5cce09603056e659b6c3c2 100644 (file)
@@ -1,69 +1,95 @@
-module Twitter.Http
+module Twitter.Http (
+  get_user_new_statuses,
+  get_user_timeline,
+  http_get )
 where
 
-import Network.Curl
-import System.IO (hPutStrLn, stderr)
+import qualified Data.ByteString.Lazy as B ( ByteString )
+import qualified Data.ByteString.Char8 as BC ( pack )
+import Network.HTTP.Client (
+  httpLbs,
+  newManager,
+  parseUrl,
+  responseBody )
+import Network.HTTP.Client.TLS ( tlsManagerSettings )
+import Web.Authenticate.OAuth (
+  OAuth(..),
+  Credential,
+  newCredential,
+  newOAuth,
+  signOAuth )
 
--- |The API URL of username's timeline.
+import Configuration ( Cfg(..) )
+
+
+-- | The API URL of username's timeline.
 --
 -- See,
 --
---   <http://dev.twitter.com/doc/get/statuses/user_timeline>
+--   <https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline>
 --
 user_timeline_url :: String -> String
 user_timeline_url username =
-    concat [ "http://api.twitter.com/1/statuses/user_timeline.xml",
-             "?screen_name=" ++ username,
-             "&include_rts=true",
-             "&count=10" ]
+  concat [ "https://api.twitter.com/",
+           "1.1/",
+           "statuses/",
+           "user_timeline.json?",
+           "screen_name=",
+           username,
+           "&include_rts=true&",
+           "count=10" ]
 
-status_url :: Integer -> String
-status_url status_id =
-    concat [ "http://api.twitter.com/1/statuses/show/",
-             (show status_id),
-             ".xml" ]
 
--- |Given username's last status id, constructs the API URL for
--- username's new statuses. Essentially, 'user_timeline_url' with a
--- "since_id" parameter tacked on.
+-- | Given username's last status id, constructs the API URL for
+--   username's new statuses. Essentially, 'user_timeline_url' with a
+--   \"since_id\" parameter tacked on.
+--
 user_new_statuses_url :: String -> Integer -> String
 user_new_statuses_url username last_status_id =
-    concat [ user_timeline_url username,
-             "&since_id=" ++ (show last_status_id) ]
+  url ++ "&since_id=" ++ since_id
+  where
+    url = user_timeline_url username
+    since_id = show last_status_id
 
 
-get_status :: Integer -> IO (Maybe String)
-get_status status_id = do
-    let uri = (status_url status_id)
-    status <- (http_get uri)
-    return status
+-- | Return's username's timeline.
+--
+get_user_timeline :: Cfg -> String -> IO B.ByteString
+get_user_timeline cfg username = do
+  let uri = user_timeline_url username
+  http_get cfg uri
 
 
--- |Return's username's timeline, or 'Nothing' if there was an error.
-get_user_timeline :: String -> IO (Maybe String)
-get_user_timeline username = do
-  let uri = (user_timeline_url username)
-  timeline <- (http_get uri)
-  return timeline
+-- | Returns the JSON representing all of username's statuses that are
+--   newer than @last_status_id@.
+--
+get_user_new_statuses :: Cfg -> String -> Integer -> IO B.ByteString
+get_user_new_statuses cfg username last_status_id = do
+  let uri = user_new_statuses_url username last_status_id
+  http_get cfg uri
 
 
--- Returns the XML representing all of username's statuses that are
--- newer than last_status_id.
-get_user_new_statuses :: String -> Integer -> IO (Maybe String)
-get_user_new_statuses username last_status_id = do
-  let uri = (user_new_statuses_url username last_status_id)
-  new_statuses <- (http_get uri)
-  return new_statuses
+-- | Retrieve a URL, or crash. The request is signed using all of the
+--   OAuth junk contained in the configuration.
+--
+http_get :: Cfg -> String -> IO B.ByteString
+http_get cfg url = do
+  manager <- newManager tlsManagerSettings
+  request <- parseUrl url
+  signed_request <- signOAuth oauth credential request
+  response <- httpLbs signed_request manager
+  return $ responseBody response
 
+  where
+    consumer_key' = BC.pack (consumer_key cfg)
+    consumer_secret' = BC.pack (consumer_secret cfg)
+    access_token' = BC.pack (access_token cfg)
+    access_secret' = BC.pack (access_secret cfg)
 
--- |Uses the CURL API to retrieve uri. Returns 'Nothing' if there was
--- an error.
-http_get :: String -> IO (Maybe String)
-http_get uri = withCurlDo $ do
-  resp <- curlGetString uri [CurlTimeout 45]
+    oauth :: OAuth
+    oauth = newOAuth {
+              oauthConsumerKey = consumer_key',
+              oauthConsumerSecret = consumer_secret' }
 
-  case resp of
-    (CurlOK, body) -> return (Just body)
-    (code, _) -> do
-        hPutStrLn stderr ("HTTP Error: " ++ (show code))
-        return Nothing
+    credential :: Credential
+    credential = newCredential access_token' access_secret'