module Web.Tweet
(
basicTweet
, tweetData
, thread
, module Web.Tweet.Types
, signRequest
, urlString
) where
import Network.HTTP.Client
import Network.HTTP.Client.TLS
import Network.HTTP.Types.Status (statusCode)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.Char (toLower)
import Web.Tweet.Types
import Web.Tweet.Utils
import Control.Monad
import Data.List.Split (chunksOf)
import Data.Maybe
import Control.Lens
import Web.Authenticate.OAuth
import Web.Tweet.Sign
thread :: String -> [String] -> Maybe Int -> Int -> FilePath -> IO ()
thread contents hs idNum num filepath = do
let handleStr = concatMap (((++) " ") . ((++) "@")) hs
let content = (take num) . (chunksOf (140(length handleStr))) $ contents
print $ urlString (Tweet { _status = content !! 0, _trimUser = True, _handles = hs, _replyID = idNum})
let f = (\str i -> (flip tweetData filepath) (Tweet { _status = str, _trimUser = True, _handles = hs, _replyID = if i == 0 then Nothing else Just i }))
let initial = f (content !! 0)
void $ foldr ((>=>) . f) initial (drop 1 content) $ maybe 0 id idNum
reply :: String -> [String] -> Maybe Int -> FilePath -> IO ()
reply contents hs idNum filepath = thread contents hs idNum 1 filepath
basicTweet :: String -> FilePath -> IO Int
basicTweet contents = tweetData (mkTweet contents)
mkTweet :: String -> Tweet
mkTweet contents = over (status) (const (contents)) $ def
tweetData :: Tweet -> FilePath -> IO Int
tweetData tweet filepath = do
let requestString = urlString tweet
manager <- newManager tlsManagerSettings
initialRequest <- parseRequest ("https://api.twitter.com/1.1/statuses/update.json" ++ requestString)
request <- signRequest filepath $ initialRequest { method = "POST" }
response request manager
response :: Request -> Manager -> IO Int
response request manager = do
response <- httpLbs request manager
putStrLn $ "The status code was: " ++ show (statusCode $ responseStatus response)
BSL.putStrLn $ responseBody response
return $ (read . (takeWhile (/=',')) . (drop 52)) (BSL.unpack $ responseBody response)
urlString :: Tweet -> String
urlString tweet = concat [ "?status="
, BS.unpack (tweetEncode tweet)
, "&trim_user="
, map toLower (show trim)
, (if isJust (_replyID tweet) then "&in_reply_to_status_id=" else "")
, reply ]
where trim = _trimUser tweet
reply = maybe "" id (fmap show $ _replyID $ tweet)
tweetEncode :: Tweet -> BS.ByteString
tweetEncode tweet = paramEncode $ handleStr `BS.append` content
where content = BS.pack . _status $ tweet
handleStr = BS.pack $ concatMap ((++ " ") . ((++) "@")) hs
hs = _handles tweet