Monday, November 08, 2010 at 12:01 AM.
system.verbs.apps.FriendFeed.getUserUpdates
on getUserUpdates (who, adrtable, flNewOnly=false, appName="", flRoom=false, username=nil, remotekey=nil) {
<<Changes
<<1/27/09; 10:29:01 AM by DW
<<Make it possible for this routine to be used to access rooms and private spaces.
<<Changed the name of the first parameter from username to who -- this is whose updates we're going to retrieve.
<<Add new optional parameter, flRoom, defaults false. If true, "who" is the name of FriendFeed room.
<<Add two optional parameters, username and remotekey, default to nil, allows this to be used for authenticated requests.
<<7/21/08; 6:01:09 AM by DW
<<No messages on tcp.httpreadurl call.
<<7/15/08; 1:02:27 PM by DW
<<Only call filemenu.savemyroot if flNewOnly is true.
<<7/15/08; 12:33:20 PM by DW
<<Add call to filemenu.savemyroot at the end to make sure all the saved guids are safe on disk.
<<7/15/08; 12:06:56 PM by DW
<<Change the name of the data file to friendFeedData.root.
<<7/15/08; 9:31:39 AM by DW
<<Created. If flNewOnly is true, we do something really neat. We keep a data file around that tracks which items have been seen and which haven't. You must give us an appname, so your getting doesn't interfere with other app's.
local (url, adruser);
bundle { //set url, 1/27/09 by DW
if flRoom {
url = "http://friendfeed.com/api/feed/room/" + who + "?output=rss"}
else {
url = "http://friendfeed.com/api/feed/user/" + who + "?output=rss"}};
bundle { //open data file, if we're only returning new items
if appname == "" {
flNewOnly = false};
if flNewOnly {
local (adrdata = frontier.opendatafile ("friendFeedData"));
if not defined (adrdata^.userUpdates) {
new (tabletype, @adrdata^.userUpdates)};
local (adrapp = @adrdata^.userUpdates.[appName]);
if not defined (adrapp^) {
new (tabletype, adrapp)};
adruser = @adrapp^.[who];
if not defined (adruser^) {
new (tabletype, adruser)}}};
new (tabletype, adrtable); //start with an empty result
local (xmltext = tcp.httpreadurl (url, flMessages:false, username:username, password:remotekey), xstruct, now = clock.now ());
xml.compile (xmltext, @xstruct);
<<scratchpad.xstruct = xstruct
local (adrrss = xml.getaddress (@xstruct, "rss"));
local (adrchannel = xml.getaddress (adrrss, "channel"), adritem);
for adritem in adrchannel {
if nameof (adritem^) endswith "item" {
local (guid = xml.getvalue (adritem, "guid"));
<<msg (guid)
if flNewOnly {
local (adrguid = @adruser^.[guid]);
if defined (adrguid^) { //already seen
continue};
adrguid^ = now};
local (adrsub = @adrtable^.[guid]);
new (tabletype, adrsub);
adrsub^.title = xml.getvalue (adritem, "title");
adrsub^.link = xml.getvalue (adritem, "link");
adrsub^.pubDate = date (xml.getvalue (adritem, "pubDate"));
local (adruser = xml.getaddress (adritem, "user"));
adrsub^.userName = xml.getvalue (adruser, "name");
adrsub^.userNickname = xml.getvalue (adruser, "nickname");
adrsub^.userProfileUrl = xml.getvalue (adruser, "profileUrl");
local (adrservice = xml.getaddress (adritem, "service"));
adrsub^.serviceId = xml.getvalue (adrservice, "id");
adrsub^.serviceName = xml.getvalue (adrservice, "name");
adrsub^.serviceIconUrl = xml.getvalue (adrservice, "iconUrl");
adrsub^.serviceProfileUrl = xml.getvalue (adrservice, "profileUrl");
bundle { //entryType -- some services don't have them
try {
adrsub^.serviceEntryType = xml.getvalue (adrservice, "entryType")}
else {
adrsub^.serviceEntryType = ""}}}};
if flNewOnly {
filemenu.savemyroot (adruser)}};
bundle { //test code
getuserupdates ("instant-outline-beta", @scratchpad.ffupdates, flRoom:true, username:"davew", remotekey:user.FriendFeed.prefs.remotekey);
<<getuserupdates ("davew", @scratchpad.ffupdates)
<<getuserupdates ("davew", @scratchpad.ffupdates, true, "testing")
edit (@scratchpad.ffupdates)}
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.