Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

229
LINES

< > BotCompany Repo | #1002157 // Cookie + IP-Based Double Visitor Counter Bot

JavaX source code (desktop) [tags: butter use-pretranspiled] - run with: x30.jar - homepage

Download Jar. Libraryless. Click here for Pure Java version (13781L/82K).

!7

// TODO: use concepts DB

static S cookieName = "cookie";
static int cookieDays = 32, cookieLength = 20;

static int cookieCounter = 1;

static long countingForUnixDay;
static new L<S> ips;
static new L<S> cookies;
static long cookieLess;
static new L<Uaip> uaips;
static new MultiSet<S> referers;

sbool saveReferers = false;

static Lock lock = lock();

static new ThreadLocal<S> cookieFromUser;
static new ThreadLocal<S> cookieSent;
  
static class Uaip {
  S ua, ip;
  bool hasCookie;
  *() {}
  *(S *ua, S *ip, bool *hasCookie) {}
}

static class Data {
  long day, ips, cookies, cookieLess;
  new L<Uaip> uaips;
  
  *(long *day, long *ips, long *cookies, long *cookieLess) {}
  *() {}
}

//static PersistentLog<Data> stats;

static ReliableSingleThread_Multi<S> rstSaveVars = new(60000, lambda1 save);

p {
  //stats = new PersistentLog("stats.log");
  load("cookieCounter");
  load("countingForUnixDay");
  load("ips");
  load("cookies");
  load("cookieLess");
  load("uaips");
  if (saveReferers) load("referers");
}

set flag NoNanoHTTPD. html {
  lock lock;
  if (eq(uri, "/referers"))
    ret hmobilefix() + h3("Referers!") + htable(
      renderMapForTable(orderMapByDescendingValue(referers.asMap()), "Referer", "Count", true));
      
  if (eq(uri, "/requests"))
    ret str(getOpt(getOpt(mainBot(), 'serveHttp_server), 'requests));

  if (eq(uri, "/requests-plus-serving")) {
    O server = getOpt(mainBot(), 'serveHttp_server);
    int serving = l(getOpt(server, 'currentlyServing));
    ret getOpt(server, 'requests) + (serving != 0 ? " [" + serving + "]" : "");
  }
    
  /*if (eq(uri, "/stats")) {
    ret 
      htag("p", "IPs in the day: " + l(ips) + ", cookies in the day: " + l(cookies) + ", cookieless today: " + cookieLess + ". Total cookies given out since all time: " + cookieCounter) +
      htag("pre", fromLines(reversedList(toLines(stats.fileContents()))));
  }*/
  
  if (eq(uri, "/uaips")) {
    int n = toInt(params.get("n"));
    L<S> lines = map sfu(dropFirst(n, cloneList(uaips)));
    S after = params.get('after);
    if (nempty(after)) lines = subList(lines, indexOf(lines, after)+1);
    ret serveText(lines(lines));
  }

  O session = call(getMainBot(), "getSession");
  O cookieHandler = call(getMainBot(), "getCookies");
  S cookie = cast call(cookieHandler, "read", cookieName);
  cookieFromUser.set(cookie);
  
  // rotate if day changed
  long day = unixDay();
  if (day != countingForUnixDay) {
    if (countingForUnixDay != 0) {
      // archive
      print("Archiving stats for unix day " + countingForUnixDay + "!");
      //stats.add(today());
      appendToTextFile("stats.log", structure(today());
    }

    // rotate
    countingForUnixDay = day;
    saveLater("countingForUnixDay");
    ips.clear();
    saveLater("ips");
    cookies.clear();
    saveLater("cookies");
    cookieLess = 0;
    saveLater("cookieLess");
    uaips = new L;
    saveLater("uaips");
  }
  
  // save only cookies returned by user
  if (!cookies.contains(cookie)) {
    cookies.add(cookie);
    saveLater("cookies");
  } else {
    ++cookieLess;
    saveLater("cookieLess");
  }
  
  // record IP
  Map headers = cast call(session, "getHeaders");
  S remoteAddr = cast headers.get("remote-addr");
  S client = cast headers.get("x-forwarded-for");
  if (nempty(client)) remoteAddr += "," + client;
  if (!empty(remoteAddr) && !ips.contains(remoteAddr)) {
    ips.add(remoteAddr);
    saveLater("ips");
  }

  // add uaip
  S ua = cast headers.get("user-agent");
  addUAIP(ua, remoteAddr, nempty(cookie));
  
  // referer
  if (saveReferers) {
    S referer = cast headers.get("referer");
    if (nempty(referer)) {
      referers.add(referer);
      saveLater("referers"); // TODO: rotate etc.
    }
  }
    
  boolean isNew = false;
  if (cookie == null) {
    isNew = true;
    //cookie = "Cookie " + (cookieCounter++);
    if (empty((S) headers.get("x-no-cookies")))
      cookie = randomID(cookieLength);
    //saveLater("cookieCounter");
  }
  
  if (cookie != null) {
    cookieSent.set(cookie);
    O cookieObject = call(cookieHandler, "set", cookieName, cookie, cookieDays); // hopefully this refreshes the expiration?
    S domain = domain();
    if (isAGIBlueDomain(domain))
      setOpt(cookieObject, domain := theAGIBlueDomain());
    setOpt(cookieObject, path := "/");
    print("Setting path for cookie object " + cookieObject + ": " + getOpt(cookieObject, 'path));
  }
  
  S s = cookie == null ? "" : "Your " + (isNew ? "new " : "recurring ") + "cookie is: " + cookie;
  s += "<br>";
  /*Data y = yesterday();
  S yesterday = y == null ? "" : " (" + y.cookies + "/" + y.ips + " yesterday)";
  s += l(cookies) + " cookies, " + l(ips) + " IPs" + yesterday + " seen today. " + cookieLess + " requests.";*/
  ret s;
}

synchronized answer {
  if (subBot_master()) if "clear referers" {
    lock lock;
    referers.clear();
    saveLater("referers");
    ret "OK";
  }
  
  if "visitors today" {
    ret structure(today());
  }
  
  /*if "visitors yesterday" {
    Data data = yesterday();
    if (data == null)
      ret "There was no yesterday.";
    ret structure(data);
  }*/
  
  /*if "visitors last * days" {
    int i = max(0, l(stats)-parseInt(m.unq(0))+1);
    
    new L<Map> stats_;
    for (Map map : objectToMap(concatLists(
      subList(stats, i),
      litlist(today())
    )))
      stats_.add(mapWithoutKey(map, "uaips")); // drop the long stuff

    ret "```" + structureLines(stats_) + "```";
  }*/
  
  if "uaips today"
    ret sfu(cloneList(uaips));
}

static Data today() {
  Data d = new Data(countingForUnixDay, l(ips), l(cookies), cookieLess);
  d.uaips = cloneList(uaips);
  ret d;
}

/*static synchronized Data yesterday() {
  ret last(stats);
}*/

static void addUAIP(S ua, S ip, bool hasCookie) {
  for (Uaip x : uaips)
    if (eq(x.ua, ua) && eq(x.ip, ip) && hasCookie == x.hasCookie)
      ret;
  uaips.add(new Uaip(ua, ip, hasCookie));
  saveLater("uaips");
}

sS cookieFromUser() { ret cookieFromUser!; }
sS cookieSent() { ret cookieSent!; }

svoid saveLater(S var) {
  rstSaveVars.add(var);
}

Author comment

Began life as a copy of #1002155

download  show line numbers  debug dex  old transpilations   

Travelled to 18 computer(s): aoiabmzegqzx, bhatertpkbcr, bvmoasoxxqgd, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, jtubtzbbkimh, lpdgvwnxivlt, mqqgnosmbjvj, nsosnbthvwzj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1002157
Snippet name: Cookie + IP-Based Double Visitor Counter Bot
Eternal ID of this version: #1002157/43
Text MD5: a0e605dac80d3bd975ed347ea5cb905e
Transpilation MD5: a4443d249ab6e673ef5d65b0b191af59
Author: stefan
Category: javax
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-02-07 22:19:58
Source code size: 6305 bytes / 229 lines
Pitched / IR pitched: No / No
Views / Downloads: 1148 / 10885
Version history: 42 change(s)
Referenced in: #1002017 - Eleutheria Main, including Slack Bot (LIVE)
#1002153 - TinyBrain.de Homepage Bot (old)
#1002213 - Eleutheria Homepage (with template & talk to bot)
#1002278 - Eleutheria Main 2 (developing)
#1002576 - Eleu Web Serving (Include)
#1002591 - Eleu Sister Main for tinybrain.de
#1003229 - registerVisitor - call visitors bot if there to register current http request. returns visitor stats
#1007863 - cookieFromUser
#1008360 - cookieSent
#1013896 - Eleutheria Main for butter.botcompany.de + Stefan's OS (LIVE)
#1022823 - Eleutheria Main for butter.botcompany.de as Dyn Module [dev.]
#1023951 - agi.blue Standalone with GUI [OK]
#1024026 - Eleutheria Main for butter.botcompany.de (backup without Stefan's OS)
#1029953 - Eleu Web Serving (transpilation test)
#3000169 - Answer for stefanreich
#3000174 - Answer for stefanreich
#3000175 - Answer for stefanreich
#3000176 - Answer for stefanreich
#3000177 - Answer for stefanreich
#3000179 - Answer for stefanreich
#3000180 - Answer for stefanreich
#3000181 - Answer for stefanreich
#3000182 - Answer for stefanreich
#3000184 - Answer for stefanreich
#3000185 - Answer for stefanreich
#3000195 - Answer for stefanreich (>> y)
#3000196 - Answer for stefanreich (>> y)
#3000197 - Answer for stefanreich (>> program data sizes)
#3000198 - Answer for stefanreich (>> program data sizes)
#3000199 - Answer for stefanreich (>> program data sizes)
#3000200 - Answer for stefanreich (>> program data sizes)
#3000201 - Answer for stefanreich (>> list all files)
#3000202 - Answer for stefanreich (>> T conversion bot)
#3000203 - Answer for stefanreich (>> timing hello bot)
#3000208 - Answer for bgrgndz (>> list sub bots)
#3000209 - Answer for bgrgndz (>> list sub bots)
#3000238 - Answer for stefanreich (>> t power bot)
#3000369 - Answer for Stefan (>> list sub bots)
#3000376 - Answer for stefanreich (>> list sub bots)
#3000377 - Answer for stefanreich (>> timing eleu?)
#3000380 - Answer for stefanreich (>> list sub bots)
#3000381 - Answer for speedforce (>> list sub bots)
#3000382 - Answer for ferdie (>> t = 1, f = 0)
#3000383 - Answer for funkoverflow (>> t=1, f=0 okay)