Take the 2-minute tour ×
Stack Apps is a question and answer site for apps, scripts, and development with the Stack Exchange API. It's 100% free, no registration required.

This Soapi.JS script, if abused is likely to provoke frowns from those whom you would like to see smiles.

Note: the dataset is only valid if the entire user base is pulled, and on just about any other site there are far too many users for the execution to be even remotely considered non-abusive or even remotely useful.

So - bottom line is: you could have figured it out yourself, so no harm in me posting it.

Let's just say it is an example of how to get cached/throttled paged results from the api with JavaScript.


OOPS Busted abusing the API!!!

 Dont try this on stack overflow or really any other site with more than a couple thousand users. Really
Page 26 of 26
52 seconds Jeff Atwood
74 seconds Bill the Lizard
3 minutes rchern
3 minutes Don
3 minutes Nippysaurus
5 minutes Steffen Opel
7 minutes Ivo Trompert
12 minutes code poet
13 minutes Roger Pate
14 minutes Adam Smith
17 minutes ahsteele
18 minutes Mark Hurd
....

<!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>
    <title></title>

    <script src="http://soapi.info/code/js/stable/3rd-party/jquery-1.4.1.js" type="text/javascript"></script>

    <script src="http://soapi.info/code/js/stable/scripts/Soapi.js" type="text/javascript"></script>

    <script type="text/javascript">

        // Soapi JavaScript Library
        // http://stackapps.com/questions/494
        // http://soapi.info/

        $(function() {

            var apiKey = '';

            Soapi.RouteFactory("api.stackapps.com", apiKey).Users()
            .getPagedResponse(function(data) {

                var table = $("#status").append("<table>");

                for (var i in data.items.sort(function(a, b) {
                    return b.last_access_date - a.last_access_date
                })) {
                    var timeAgo = Soapi.Utilities.getTimeAgo(data.items[i].last_access_date);
                    var who = data.items[i].display_name;
                    table.append("<tr><td>" + timeAgo + "</td><td>" + who + "</td></tr>");
                }
            }, null, function(data) {
                $("#status")
                .html("Page " + data.page + " of " + (Math.floor(data.total / data.pagesize) + 1));
            });
        });
    </script>

</head>
<body>
    <p>
        Dont try this on stack overflow or really any other site with more than a couple
        thousand users. Really</p>
    <div id="status">
    </div>
</body>
</html>
share|improve this question
    
Pretty impressive stuff, you really move fast and clean ;) –  Steffen Opel Jul 25 '10 at 13:39
    
@steffen - aww shucks - you are making me blush. –  Sky Sanders Jul 25 '10 at 13:48
    
So all it does is tell you when every user was last seen? –  Nathan Osman Jul 25 '10 at 16:25
    
@geo - yea, all this line of code, Soapi.RouteFactory("api.stackapps.com", apiKey).Users().getPagedResponse( function(data) {/* data.items == all users on stackapps */ }); does is return an array of all the users on stackapps while observing a 1 minute cached duration and complying with the throttle guidelines. –  Sky Sanders Jul 25 '10 at 17:34
    
@code: Don't misunderstand me, I'm not criticizing it. I'm in awe that such a small piece of code does so much. –  Nathan Osman Jul 25 '10 at 19:53
    
@geo - i am just bustin your balls. I don't misunderstand you. Actually, I think I understand you quite well. no worries. –  Sky Sanders Jul 25 '10 at 20:09
add comment

2 Answers 2

Similar code for StackWrap4J:

List<Users> allUsers = new UsersList(
      new StackWrapper("api.stackapps.com"), 
      new UserQuery()
);

You can then iterate through allUsers and see their lastAccessDate. The currently released version will plow through the allowed calls per second, but v1.0.1 will properly throttle the requests.

share|improve this answer
2  
I just noticed you are using a composition paradigm rather that the more imperative syntax that most of us are. I think I like the way that looks and I can immediately see some benefits. It it the case that your UserQuery is simply a property bag with parameters and such –  Sky Sanders Jul 26 '10 at 4:43
    
@code Yeah, we like it too. It seems to simplify worrying about all of the possible parameters for all of the different routes. –  jjnguy Jul 26 '10 at 13:13
    
on second look, i wonder if your UserQuery could be characterized as a parameter bag? –  Sky Sanders Aug 16 '10 at 23:02
    
@code, I'm not versed on design patterns...but, yeah. It's basically a parameter bag. (Not sure if that's a bad thing...) –  jjnguy Aug 17 '10 at 0:41
    
not a bad thing at all - ultimately beneath the layers of abstraction in soapi, something similar is happening. Whereas you use UserQuery, I use UsersParameters and reading your code with my eyes painted a different picture, which I also found interesting. –  Sky Sanders Aug 17 '10 at 1:02
add comment

C# / Soapi.CS


using Soapi.CS


Context.Official.StackApps.Users
    .PageSize(100).PageCount(0)
    .OrderByDescending(u => u.LastAccessDate)
    .ToList().ForEach(u =>
        Console.WriteLine("{0}\t{1}",
        u.LastAccessDate.FormatElapsedTime(), u.DisplayName));

Output:

59 seconds ago    Greg Bray
4 minutes ago    Don
5 minutes ago    Lance Roberts
5 minutes ago    CharlesB
5 minutes ago    Ben Rowe
7 minutes ago    pkaeding
8 minutes ago    George Edison
12 minutes ago    Jeff Atwood
12 minutes ago    Sam Saffron
13 minutes ago    Kevin Montrose
13 minutes ago    code poet
14 minutes ago    Mark Hurd
21 minutes ago    jjnguy
21 minutes ago    ahsteele
23 minutes ago    Steffen Opel
24 minutes ago    MattB
24 minutes ago    Roger Pate
33 minutes ago    Matt S.
35 minutes ago    UncleZeiv
42 minutes ago    Dennis Williamson
an hour ago    Tamschi
an hour ago    swanson
an hour ago    Troy Hunt
an hour ago    Joshua
an hour ago    Scott Saad
an hour ago    mlaw
an hour ago    Leonard Thieu
an hour ago    Dori
an hour ago    Waleed Al-Balooshi
an hour ago    Peter Jaric
1 hours ago    Kevin Y
1 hours ago    sideproject
1 hours ago    kajaco
1 hours ago    Doug
1 hours ago    Michael B.
1 hours ago    AidenMontgomery
1 hours ago    jtimberman
2 hours ago    systempuntoout
2 hours ago    SztupY
2 hours ago    Soviut
2 hours ago    Bill the Lizard
2 hours ago    KeithB
2 hours ago    Boris Terzic
2 hours ago    Jonathan
2 hours ago    lfoust
2 hours ago    csgillespie
2 hours ago    Jason Merrill
2 hours ago    Adam Wright
2 hours ago    conmulligan
2 hours ago    tonklon
2 hours ago    David Fullerton
3 hours ago    Maxim Zaslavsky
3 hours ago    David
3 hours ago    Sorskoot
3 hours ago    user2958
3 hours ago    Sandor Drieënhuizen
3 hours ago    RegDwight
3 hours ago    cori
3 hours ago    Greg Roberts
3 hours ago    neo
3 hours ago    Felix
3 hours ago    oivvio
3 hours ago    chanchal1987
3 hours ago    David Kaneda
4 hours ago    carson
4 hours ago    Ivo Flipse
4 hours ago    AaronSieb
4 hours ago    Dan Atkinson
4 hours ago    Ryan Duffield
4 hours ago    Freddie
5 hours ago    Justin Ethier
5 hours ago    Jeremy
5 hours ago    Jarret Hardie
5 hours ago    Adam
5 hours ago    Terry Wilcox
5 hours ago    David Basarab
5 hours ago    Chris Tybur
6 hours ago    Dave DeLong
6 hours ago    Humpton
6 hours ago    Jeff Yates
6 hours ago    Midhat
6 hours ago    Jason
6 hours ago    Paolo Bergantino
6 hours ago    Sanction10
6 hours ago    Artefacto
6 hours ago    Lucas Jones
6 hours ago    Hasturkun
6 hours ago    AnonJr
6 hours ago    Edan Maor
6 hours ago    Daniel
7 hours ago    Sam Hasler
7 hours ago    Jawa
7 hours ago    Vladislav Tserman
7 hours ago    Tim Büthe
7 hours ago    FordBucha
... 2900 other users
2 months ago    Eric
2 months ago    Batgar

Requests generated (elapsed time 3 seconds)

#   Result  Protocol    Host    URL Body    Caching Content-Type    Process Comments    Custom  
1   200 HTTP    api.stackapps.com   /1.0/users?pagesize=100&key=foo-bar-fu  34,610  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
2   200 HTTP    api.stackapps.com   /1.0/users?page=2&pagesize=100&key=foo-bar-fu   29,498  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
3   200 HTTP    api.stackapps.com   /1.0/users?page=3&pagesize=100&key=foo-bar-fu   25,432  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
4   200 HTTP    api.stackapps.com   /1.0/users?page=4&pagesize=100&key=foo-bar-fu   30,206  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
5   200 HTTP    api.stackapps.com   /1.0/users?page=5&pagesize=100&key=foo-bar-fu   25,294  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
6   200 HTTP    api.stackapps.com   /1.0/users?page=6&pagesize=100&key=foo-bar-fu   27,335  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
7   200 HTTP    api.stackapps.com   /1.0/users?page=7&pagesize=100&key=foo-bar-fu   26,925  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
8   200 HTTP    api.stackapps.com   /1.0/users?page=8&pagesize=100&key=foo-bar-fu   26,287  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
9   200 HTTP    api.stackapps.com   /1.0/users?page=9&pagesize=100&key=foo-bar-fu   24,423  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
10  200 HTTP    api.stackapps.com   /1.0/users?page=10&pagesize=100&key=foo-bar-fu  27,587  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
11  200 HTTP    api.stackapps.com   /1.0/users?page=11&pagesize=100&key=foo-bar-fu  25,370  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
12  200 HTTP    api.stackapps.com   /1.0/users?page=12&pagesize=100&key=foo-bar-fu  27,375  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
13  200 HTTP    api.stackapps.com   /1.0/users?page=13&pagesize=100&key=foo-bar-fu  26,469  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
14  200 HTTP    api.stackapps.com   /1.0/users?page=14&pagesize=100&key=foo-bar-fu  27,050  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
15  200 HTTP    api.stackapps.com   /1.0/users?page=15&pagesize=100&key=foo-bar-fu  25,317  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
16  200 HTTP    api.stackapps.com   /1.0/users?page=16&pagesize=100&key=foo-bar-fu  24,794  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
17  200 HTTP    api.stackapps.com   /1.0/users?page=17&pagesize=100&key=foo-bar-fu  23,604  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
18  200 HTTP    api.stackapps.com   /1.0/users?page=20&pagesize=100&key=foo-bar-fu  24,952  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
19  200 HTTP    api.stackapps.com   /1.0/users?page=18&pagesize=100&key=foo-bar-fu  25,322  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
20  200 HTTP    api.stackapps.com   /1.0/users?page=19&pagesize=100&key=foo-bar-fu  25,732  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
21  200 HTTP    api.stackapps.com   /1.0/users?page=21&pagesize=100&key=foo-bar-fu  20,903  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
22  200 HTTP    api.stackapps.com   /1.0/users?page=22&pagesize=100&key=foo-bar-fu  19,582  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
23  200 HTTP    api.stackapps.com   /1.0/users?page=23&pagesize=100&key=foo-bar-fu  19,149  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
24  200 HTTP    api.stackapps.com   /1.0/users?page=24&pagesize=100&key=foo-bar-fu  19,628  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
25  200 HTTP    api.stackapps.com   /1.0/users?page=25&pagesize=100&key=foo-bar-fu  21,179  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
26  200 HTTP    api.stackapps.com   /1.0/users?page=28&pagesize=100&key=foo-bar-fu  20,692  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
27  200 HTTP    api.stackapps.com   /1.0/users?page=26&pagesize=100&key=foo-bar-fu  19,142  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
28  200 HTTP    api.stackapps.com   /1.0/users?page=27&pagesize=100&key=foo-bar-fu  22,512  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
29  200 HTTP    api.stackapps.com   /1.0/users?page=29&pagesize=100&key=foo-bar-fu  17,528  private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            
30  200 HTTP    api.stackapps.com   /1.0/users?page=30&pagesize=100&key=foo-bar-fu  7,239   private     application/json; charset=utf-8 jetbrains.resharper.taskrunner.msil:6940            

share|improve this answer
add comment

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .