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.