packages feed

twitter-0.1: Twitter/Client.hs

module Twitter.Client where

import Network.Curl
import Text.JSON
import Text.JSON.String
import Data.Time.Format
import Data.Time.Clock
import Data.Time.LocalTime
import System.Locale
import Data.Maybe (fromJust)

timeline_url = "http://twitter.com/statuses/friends_timeline.json"
post_url = "http://twitter.com/statuses/update.xml"
options auth = [CurlUserPwd auth, CurlVerbose False]

data Tweet = Tweet { user    :: TwitterUser
                   , message :: String
                   , time    :: LocalTime
                   }
 deriving Show
data TwitterUser = TwitterUser {name :: String, screenName :: String, url :: Maybe String}
 deriving Show

getTweets :: String -> IO (Maybe [Tweet])
getTweets auth = do
  (code, feed) <- curlGetString timeline_url (options auth)
  tz <- getCurrentTimeZone
  return $ case runGetJSON readJSArray feed of
      (Right (JSArray tweets')) -> Just $ map (processTweet tz) tweets'
      _                         -> Nothing

processTweet tz (JSObject o) = Tweet user msg time
 where
  user   = parseUser $ "user" `lookup` obj
  time   = pTime tz $ cleanString "created_at" obj
  msg    = cleanString "text" obj
  obj    = fromJSObject o

pTime :: TimeZone -> String -> LocalTime
pTime tz s = utcToLocalTime tz $ fromJust $ parseTime defaultTimeLocale "%c" s
  
parseUser (Just (JSObject o)) = TwitterUser name screenName url
 where name       = cleanString       "name" obj
       screenName = cleanString       "screen_name" obj
       url        = cleanMaybeString  "url" obj
       obj = fromJSObject o

cleanString s obj = fromJSString msg
 where (Just (JSString msg)) = s `lookup` obj

cleanMaybeString s obj = 
 case s `lookup` obj of
   (Just (JSString msg)) -> Just $ fromJSString msg
   _ -> Nothing

say :: String -> String -> IO ()
say auth msg = curlMultiPost post_url (options auth) [multiformString "status" msg]