Monday, November 08, 2010 at 12:01 AM.
system.verbs.apps.twitter.getListOpml
on getListOpml (adrlistinfo, title=nil) {
<<Changes
<<11/8/09; 9:43:37 AM by DW
<<Implements the "xSocial" namespace as described here: http://scripting.com/stories/2009/11/08/aSocialNamespace.html
<<11/3/09; 2:39:38 PM by DW
<<Change interface, now it just takes the address of the list. This allows it to come from a cache.
<<11/1/09; 7:54:57 PM by DW
<<Change the URL in the <docs> element from a dummy url to the address of the OPML 2.0 spec.
<<11/1/09; 7:49:01 PM by DW
<<Change parameter list to be consistent with the list glue scripts.
<<10/31/09; 8:26:16 AM by DW
<<Experimental. Return the list in OPML format.
local (xmltext = "", indentlevel = 0, now = clock.now (), listinfo);
<<twitter.getListMembers (listname, @listinfo, username, password, whoseList)
bundle { //fill xmltext
on add (s) {
xmltext = xmltext + (string.filledstring ("\t", indentlevel) + s + "\r\n");};
on encode (s) {
if system.environment.isMac {
return (xml.entityEncode (latinToMac.macToLatin (s), true))}
else {
return (xml.entityEncode (s, true))}};
add ("<?xml version=\"1.0\"?>");
bundle { //comment at top of OPML
local (cautionstring = "");
<<if adrdata^.prefs.flOpmlCaution
<<cautionstring = "\r\r Important: Don't build systems that depend on this service, it's just a test."
add ("<!-- OPML generated by " + frontier.getprogramname () + " on " + now + " Pacific." + cautionstring + " -->")};
add ("<opml version=\"2.0\" xmlns:xSocial=\"http://scripting.com/stories/2009/11/08/aSocialNamespace.html\">"); indentlevel++;
bundle { //<head> section
add ("<head>"); indentlevel++;
<<if username == nil
<<username = user.twitter.prefs.username
if title != nil {
<<title = encode ("The \"" + listname + "\" list from Twitter user: \"" + username + "\"")
add ("<title>" + encode (title) + "</title>")};
add ("<docs>http://opml.org/spec2</docs>");
add ("<dateCreated>" + date.netstandardstring (now) + "</dateCreated>");
add ("<dateModified>" + date.netstandardstring (now) + "</dateModified>");
add ("</head>"); indentlevel--};
bundle { //<body> section
local (adrmember);
add ("<body>"); indentlevel++;
for adrmember in adrlistinfo {
local (t, s = "");
new (tabletype, @t);
t.type = "rss";
t.text = encode (adrmember^.username);
t.xmlUrl = encode ("http://twitter.com/statuses/user_timeline/" + adrmember^.userId + ".rss");
t.htmlUrl = encode ("http://twitter.com/" + adrmember^.userscreenname);
t.title = t.text;
t.["xSocial:userId"] = adrmember^.userId;
t.["xSocial:userName"] = adrmember^.userName;
t.["xSocial:userDescription"] = adrmember^.userDescription;
t.["xSocial:userLocation"] = adrmember^.userLocation;
t.["xSocial:userUrl"] = adrmember^.userUrl;
t.["xSocial:userStatuses"] = adrmember^.userCtStatuses;
t.["xSocial:userFollows"] = adrmember^.userFollows;
t.["xSocial:userFollowedBy"] = adrmember^.userFollowedBy;
t.["xSocial:userProfileImageUrl"] = adrmember^.userProfileImageUrl;
t.["xSocial:userScreenName"] = adrmember^.userScreenName;
for adrt in @t {
s = s + nameof (adrt^) + "=\"" + encode (adrt^) + "\" "};
add ("<outline " + s + "/>")};
add ("</body>"); indentlevel--};
add ("</opml>"); indentlevel--};
return (xmltext)};
bundle { //test code
local (s = getListOpml (@listBrowserData.cache.["davewiner/entourage"].listdata, "Members of @davewiner's \"entourage\" list."));
workspace.ftptoscripting (s, "misc/xTwitterList.opml");
webbrowser.openurl ("http://scripting.com/misc/xTwitterList.opml")}
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.