Advertisement
SirNickolas

Codeforces API usage

Oct 22nd, 2017
1,340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
D 2.53 KB | None | 0 0
  1. import std.datetime;
  2. import std.exception;
  3. import std.format;
  4. import std.json;
  5.  
  6. enum {
  7.     apiUrl = "http://codeforces.com/api/%s",
  8.     callLimit = 5,
  9.     callLimitInterval = 1010.msecs,
  10. }
  11.  
  12. enum {
  13.     minRelativeTime = Duration.zero,
  14.     maxRelativeTime = (6 * 4).weeks,
  15. }
  16.  
  17. class CfApiBaseException: Exception {
  18.     mixin basicExceptionCtors;
  19. }
  20.  
  21. class CfApiException: CfApiBaseException {
  22.     mixin basicExceptionCtors;
  23. }
  24.  
  25. JSONValue cfCall(Args...)(in char[ ] method, in auto ref Args args) {
  26.     import core.thread;
  27.     import requests;
  28.  
  29.     static SysTime[callLimit] queue;
  30.     static int qpos = 0;
  31.  
  32.     auto now = Clock.currTime();
  33.     const elapsed = now - queue[qpos];
  34.     if (elapsed < callLimitInterval) {
  35.         Thread.sleep(callLimitInterval - elapsed);
  36.         now = Clock.currTime();
  37.     }
  38.     queue[qpos++] = now;
  39.     qpos %= callLimit;
  40.  
  41.     const response = getContent(format!apiUrl(method), args).data!string.parseJSON();
  42.     const status = response["status"];
  43.     if (status != JSONValue("OK")) {
  44.         if (status == JSONValue("FAILED"))
  45.             throw new CfApiException(response["comment"].str);
  46.         else
  47.             throw new CfApiBaseException(format!"%s: %s"(status, response["comment"]));
  48.     }
  49.     return response["result"];
  50. }
  51.  
  52. void main() {
  53.     import std.algorithm.sorting;
  54.     import std.array;
  55.     import std.stdio;
  56.  
  57.     int[string] users;
  58.     writeln("Getting contest list...");
  59.     stdout.flush();
  60.     foreach (contest; cfCall("contest.list").array) {
  61.         const relativeTime = contest["relativeTimeSeconds"].integer.seconds;
  62.         if (relativeTime < minRelativeTime)
  63.             continue;
  64.         if (relativeTime > maxRelativeTime)
  65.             break;
  66.  
  67.         const id = contest["id"].integer;
  68.         writefln!"%s (%s)..."(contest["name"], id);
  69.         stdout.flush();
  70.         try
  71.             foreach (submission; cfCall("contest.status", "contestId", id).array)
  72.                 if (submission["programmingLanguage"].str == "D")
  73.                     foreach (member; submission["author"]["members"].array)
  74.                         users[member["handle"].str]++;
  75.         catch (CfApiException e) {
  76.             //`contest.list` may return contests unavailable for inspection. Yes, that's weird.
  77.             if (e.msg != format!"contestId: Contest with id %s not found"(id))
  78.                 throw e;
  79.             writeln("[Not found]");
  80.         }
  81.     }
  82.     writefln!"{%(%(\"%s\": %s%),\n %)}"(
  83.         users.byPair().array().multiSort!(`a[1] > b[1]`, `a[0] < b[0]`));
  84. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement