Monday, November 08, 2010 at 12:01 AM.
system.verbs.apps.twitter.getUserTimeLine
on getUserTimeLine (screenname, adrtable, urlparam=nil, since=nil, maxcount=20) { <<Changes <<5/21/09; 3:31:21 PM by DW <<Extract user information from each status record. <<3/12/09; 5:53:29 AM by DW <<Laconica doesn't support in_reply_to_screen_name; add workaround. <<1/5/09; 6:04:51 PM by DW <<Add optional "maxcount" parameter, indicates the maximum number of posts to retrieve, defaults to 20. <<1/4/09; 4:34:39 PM by DW <<Add optional "since" param to get all posts since a certain date-time. Loop over "pages" of results so we aren't limited to 20 at a time. Major upgrade. <<1/4/09; 11:45:39 AM by DW <<Add support for inReplyToScreenName and createdAt. <<8/16/08; 11:46:58 AM by DW <<Add support for inReplyToStatusId and inReplyToUserId in timelines. <<7/17/08; 10:08:25 PM by DW <<Add optional url parameter so the caller can provide it (so the same code can be used with an app that clones the Twitter API). <<4/28/07; 11:05:43 AM by DW <<Created. I just need a simple routine that returns the unauthenticated public statuses from a given user, who may have no relationship to me. Trying to do this by adding parameters to getTimeline proved very frustrating. If you just enter the url in a brower, you get exactly what you need. local (pagenum = 1, cttotalstatuses = 0, flmaxed = false); new (tabletype, adrtable); on decode (s) { s = xml.entitydecode (s, flAlphaEntities:true); return (s)}; loop { local (url); if urlparam == nil { //use twitter.com url = "http://twitter.com/statuses/user_timeline/[[screenname]].xml"} else { url = urlparam}; url = string.replace (url, "[[screenname]]", screenname); bundle { //add pagenum url = url + "?page=" + pagenum++}; bundle { //add optional params if since != nil { url = url + "&since=" + string.urlencode (date.netstandardstring (since))}}; local (xmltext = tcp.httpreadurl (url), xstruct, adr, ctstatuses=0); xml.compile (xmltext, @xstruct); <<scratchpad.xstructusertimeline = xstruct local (adrstatuses = xml.getaddress (@xstruct, "statuses")); for adr in adrstatuses { if nameof (adr^) contains "status" { local (id = xml.getvalue (adr, "id")); local (adrsub = @adrtable^.[id]); new (tabletype, adrsub); adrsub^.text = decode (xml.getvalue (adr, "text")); adrsub^.inReplyToStatusId = xml.getvalue (adr, "in_reply_to_status_id"); //8/16/08 by DW adrsub^.inReplyToUserId = xml.getvalue (adr, "in_reply_to_user_id"); //8/16/08 by DW bundle { //get inReplyToScreenName -- identica doesn't return this, but twitter does, 3/12/09 by DW try { adrsub^.inReplyToScreenName = xml.getvalue (adr, "in_reply_to_screen_name")} //1/4/09 by DW else { adrsub^.inReplyToScreenName = ""}}; adrsub^.createdAt = twitter.getTwitterTime (xml.getvalue (adr, "created_at")); //1/4/09 by DW twitter.extractUserInfo (adr, adrsub, false); //5/21/09 by DW ctstatuses++; if ++cttotalstatuses >= maxcount { //1/5/09 by DW flmaxed = true; break}}}; if ctstatuses == 0 { //none were returned, don't ask for another page break}; if flmaxed { //1/5/09 by DW break}}}; <<bundle //old pre-looping code <<if url == nil //use twitter.com <<url = "http://twitter.com/statuses/user_timeline/[[screenname]].xml" <<url = string.replace (url, "[[screenname]]", screenname) <<bundle //add optional params <<if since != nil <<url = url + "?since=" + string.urlencode (date.netstandardstring (since)) <<local (xmltext = tcp.httpreadurl (url), xstruct, adr) <<xml.compile (xmltext, @xstruct) <<scratchpad.xuserstruct = xstruct <<new (tabletype, adrtable) <<for adr in xml.getaddress (@xstruct, "statuses") <<if nameof (adr^) contains "status" <<local (id = xml.getvalue (adr, "id")) <<local (adrsub = @adrtable^.[id]) <<new (tabletype, adrsub) <<adrsub^.text = decode (xml.getvalue (adr, "text")) <<adrsub^.inReplyToStatusId = xml.getvalue (adr, "in_reply_to_status_id") //8/16/08 by DW <<adrsub^.inReplyToUserId = xml.getvalue (adr, "in_reply_to_user_id") //8/16/08 by DW <<adrsub^.inReplyToScreenName = xml.getvalue (adr, "in_reply_to_screen_name") //1/4/09 by DW <<adrsub^.createdAt = twitter.getTwitterTime (xml.getvalue (adr, "created_at")) //1/4/09 by DW bundle { //test code getUserTimeLine ("arrington", @scratchpad.arrtimeline, maxcount:18)} <<getUserTimeLine ("davewiner", @scratchpad.dwtimeline, maxcount:18)
This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.