Source Code
LastSeen is about as simple as an app can get. It leverages the integral caching and paging capabilities of Soapi.CS as well as the rich domain object model in conjunction with ASP.Net declarative databinding.
The core of the app is a simple data source that provides a list of sites and a list of the top 3000 (30 pages) of users for a site.
The context is served by a static request cache which will serve api data from memory and being static it will caches for all asp.net sessions ensuring that fresh data is fetched only when the cache duration has expired.
Combined with a declaritive page caching, the response times and API request usage are fully economized.
Except, that is, for the first person to request the page after the cache has expired. For huge sites like Stack Overflow, a refresh can take up to 15 seconds. For smaller sites like Stack Apps the refresh time is nearly unnoticeable.
public class WhoIsOnRightNowDataSource
{
private static readonly ApiContext Context;
static WhoIsOnRightNowDataSource()
{
Context = new ApiContext("mykey")
.Initialize(false);
}
public List<Site> AllSites()
{
return Context.Sites;
}
public List<User> LastSeen(string apiEndpoint)
{
return Context.Find(apiEndpoint).Users
.PageSize(100).PageCount(30)
.OrderByDescending(u => u.LastAccessDate)
.ToList();
}
}
This datasource is then declaratively bound to a DropDownList and a Gridview
<%@ Page Language="C#" %>
<%@ OutputCache Duration="60" VaryByParam="*" %>
<%@ Import Namespace="Soapi" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<div>
<asp:DropDownList ID="SitesDropDownList" runat="server" DataTextField="Name" DataValueField="ApiEndpoint"
DataSourceID="SitesDataSource" AutoPostBack="True" />
</div>
<br />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="UsersDataSource"
AllowPaging="True" PageSize="50">
<Columns>
<asp:TemplateField HeaderText="seen" SortExpression="LastAccessDate">
<EditItemTemplate>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# ((DateTime) Eval("LastAccessDate")).FormatElapsedTime() %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="name" SortExpression="DisplayName">
<EditItemTemplate>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("DisplayName") %>' ToolTip='User ID: <%# Eval("UserId") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Reputation" HeaderText="reputation" SortExpression="Reputation" />
</Columns>
</asp:GridView>
<br />
</div>
<asp:ObjectDataSource ID="SitesDataSource" runat="server" SelectMethod="AllSites"
TypeName="SoapiDemos35.WhoIsOnRightNowDataSource" />
<asp:ObjectDataSource ID="UsersDataSource" runat="server" SelectMethod="LastSeen"
TypeName="WhoIsOnRightNowDataSource">
<SelectParameters>
<asp:ControlParameter ControlID="SitesDropDownList" Name="apiEndpoint" PropertyName="SelectedValue"
Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
</form>
</body>
</html>
And that is it. No code behind.
Soapi.CS - it's as easy as breathing.... ;-)