]> gitweb.michael.orlitzky.com - dead/halcyon.git/blob - src/Twitter/Http.hs
14b03825a4d924663c8fd9ff4d17d56b1b9f56c0
[dead/halcyon.git] / src / Twitter / Http.hs
1 module Twitter.Http
2 where
3
4 import Network.Curl
5 import System.IO (hPutStrLn, stderr)
6
7 -- |The API URL of username's timeline.
8 --
9 -- See,
10 --
11 -- <http://dev.twitter.com/doc/get/statuses/user_timeline>
12 --
13 user_timeline_url :: String -> String
14 user_timeline_url username =
15 concat [ "http://api.twitter.com/1/statuses/user_timeline.xml",
16 "?screen_name=" ++ username,
17 "&include_rts=true",
18 "&count=10" ]
19
20 status_url :: Integer -> String
21 status_url status_id =
22 concat [ "http://api.twitter.com/1/statuses/show/",
23 (show status_id),
24 ".xml" ]
25
26 -- |Given username's last status id, constructs the API URL for
27 -- username's new statuses. Essentially, 'user_timeline_url' with a
28 -- "since_id" parameter tacked on.
29 user_new_statuses_url :: String -> Integer -> String
30 user_new_statuses_url username last_status_id =
31 concat [ user_timeline_url username,
32 "&since_id=" ++ (show last_status_id) ]
33
34
35 get_status :: Integer -> IO (Maybe String)
36 get_status status_id = do
37 let uri = (status_url status_id)
38 status <- (http_get uri)
39 return status
40
41
42 -- |Return's username's timeline, or 'Nothing' if there was an error.
43 get_user_timeline :: String -> IO (Maybe String)
44 get_user_timeline username = do
45 let uri = (user_timeline_url username)
46 timeline <- (http_get uri)
47 return timeline
48
49
50 -- | Returns the XML representing all of username's statuses that are
51 -- newer than last_status_id.
52 get_user_new_statuses :: String -> Integer -> IO (Maybe String)
53 get_user_new_statuses username last_status_id = do
54 let uri = (user_new_statuses_url username last_status_id)
55 new_statuses <- (http_get uri)
56 return new_statuses
57
58
59 -- | Options that will be passed to every curl request.
60 curl_options :: [CurlOption]
61 curl_options =
62 [ CurlTimeout 45,
63 -- The Global cache is not thread-friendly.
64 CurlDNSUseGlobalCache False,
65 -- And we don't want to use a DNS cache anyway.
66 CurlDNSCacheTimeout 0 ]
67
68
69 -- | Uses the CURL API to retrieve uri. Returns 'Nothing' if there was
70 -- an error.
71 http_get :: String -> IO (Maybe String)
72 http_get uri =
73 withCurlDo $ do
74 -- Create a Curl instance.
75 curl <- initialize
76
77 -- Perform the request, and get back a CurlResponse object.
78 -- The cast is needed to specify how we would like our headers
79 -- and body returned (Strings).
80 resp <- do_curl_ curl uri curl_options :: IO CurlResponse
81
82 -- Pull out the response code as a CurlCode.
83 let code = respCurlCode resp
84
85 case code of
86 CurlOK -> return $ Just (respBody resp)
87 error_code -> do
88 hPutStrLn stderr ("HTTP Error: " ++ (show error_code))
89 -- If an error occurred, we want to dump as much information as
90 -- possible. If this becomes a problem, we can use respGetInfo to
91 -- query the response object for more information
92 return Nothing