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).

1  
!7
2  
3  
// TODO: use concepts DB
4  
5  
static S cookieName = "cookie";
6  
static int cookieDays = 32, cookieLength = 20;
7  
8  
static int cookieCounter = 1;
9  
10  
static long countingForUnixDay;
11  
static new L<S> ips;
12  
static new L<S> cookies;
13  
static long cookieLess;
14  
static new L<Uaip> uaips;
15  
static new MultiSet<S> referers;
16  
17  
sbool saveReferers = false;
18  
19  
static Lock lock = lock();
20  
21  
static new ThreadLocal<S> cookieFromUser;
22  
static new ThreadLocal<S> cookieSent;
23  
  
24  
static class Uaip {
25  
  S ua, ip;
26  
  bool hasCookie;
27  
  *() {}
28  
  *(S *ua, S *ip, bool *hasCookie) {}
29  
}
30  
31  
static class Data {
32  
  long day, ips, cookies, cookieLess;
33  
  new L<Uaip> uaips;
34  
  
35  
  *(long *day, long *ips, long *cookies, long *cookieLess) {}
36  
  *() {}
37  
}
38  
39  
//static PersistentLog<Data> stats;
40  
41  
static ReliableSingleThread_Multi<S> rstSaveVars = new(60000, lambda1 save);
42  
43  
p {
44  
  //stats = new PersistentLog("stats.log");
45  
  load("cookieCounter");
46  
  load("countingForUnixDay");
47  
  load("ips");
48  
  load("cookies");
49  
  load("cookieLess");
50  
  load("uaips");
51  
  if (saveReferers) load("referers");
52  
}
53  
54  
set flag NoNanoHTTPD. html {
55  
  lock lock;
56  
  if (eq(uri, "/referers"))
57  
    ret hmobilefix() + h3("Referers!") + htable(
58  
      renderMapForTable(orderMapByDescendingValue(referers.asMap()), "Referer", "Count", true));
59  
      
60  
  if (eq(uri, "/requests"))
61  
    ret str(getOpt(getOpt(mainBot(), 'serveHttp_server), 'requests));
62  
63  
  if (eq(uri, "/requests-plus-serving")) {
64  
    O server = getOpt(mainBot(), 'serveHttp_server);
65  
    int serving = l(getOpt(server, 'currentlyServing));
66  
    ret getOpt(server, 'requests) + (serving != 0 ? " [" + serving + "]" : "");
67  
  }
68  
    
69  
  /*if (eq(uri, "/stats")) {
70  
    ret 
71  
      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) +
72  
      htag("pre", fromLines(reversedList(toLines(stats.fileContents()))));
73  
  }*/
74  
  
75  
  if (eq(uri, "/uaips")) {
76  
    int n = toInt(params.get("n"));
77  
    L<S> lines = map sfu(dropFirst(n, cloneList(uaips)));
78  
    S after = params.get('after);
79  
    if (nempty(after)) lines = subList(lines, indexOf(lines, after)+1);
80  
    ret serveText(lines(lines));
81  
  }
82  
83  
  O session = call(getMainBot(), "getSession");
84  
  O cookieHandler = call(getMainBot(), "getCookies");
85  
  S cookie = cast call(cookieHandler, "read", cookieName);
86  
  cookieFromUser.set(cookie);
87  
  
88  
  // rotate if day changed
89  
  long day = unixDay();
90  
  if (day != countingForUnixDay) {
91  
    if (countingForUnixDay != 0) {
92  
      // archive
93  
      print("Archiving stats for unix day " + countingForUnixDay + "!");
94  
      //stats.add(today());
95  
      appendToTextFile("stats.log", structure(today());
96  
    }
97  
98  
    // rotate
99  
    countingForUnixDay = day;
100  
    saveLater("countingForUnixDay");
101  
    ips.clear();
102  
    saveLater("ips");
103  
    cookies.clear();
104  
    saveLater("cookies");
105  
    cookieLess = 0;
106  
    saveLater("cookieLess");
107  
    uaips = new L;
108  
    saveLater("uaips");
109  
  }
110  
  
111  
  // save only cookies returned by user
112  
  if (!cookies.contains(cookie)) {
113  
    cookies.add(cookie);
114  
    saveLater("cookies");
115  
  } else {
116  
    ++cookieLess;
117  
    saveLater("cookieLess");
118  
  }
119  
  
120  
  // record IP
121  
  Map headers = cast call(session, "getHeaders");
122  
  S remoteAddr = cast headers.get("remote-addr");
123  
  S client = cast headers.get("x-forwarded-for");
124  
  if (nempty(client)) remoteAddr += "," + client;
125  
  if (!empty(remoteAddr) && !ips.contains(remoteAddr)) {
126  
    ips.add(remoteAddr);
127  
    saveLater("ips");
128  
  }
129  
130  
  // add uaip
131  
  S ua = cast headers.get("user-agent");
132  
  addUAIP(ua, remoteAddr, nempty(cookie));
133  
  
134  
  // referer
135  
  if (saveReferers) {
136  
    S referer = cast headers.get("referer");
137  
    if (nempty(referer)) {
138  
      referers.add(referer);
139  
      saveLater("referers"); // TODO: rotate etc.
140  
    }
141  
  }
142  
    
143  
  boolean isNew = false;
144  
  if (cookie == null) {
145  
    isNew = true;
146  
    //cookie = "Cookie " + (cookieCounter++);
147  
    if (empty((S) headers.get("x-no-cookies")))
148  
      cookie = randomID(cookieLength);
149  
    //saveLater("cookieCounter");
150  
  }
151  
  
152  
  if (cookie != null) {
153  
    cookieSent.set(cookie);
154  
    O cookieObject = call(cookieHandler, "set", cookieName, cookie, cookieDays); // hopefully this refreshes the expiration?
155  
    S domain = domain();
156  
    if (isAGIBlueDomain(domain))
157  
      setOpt(cookieObject, domain := theAGIBlueDomain());
158  
    setOpt(cookieObject, path := "/");
159  
    print("Setting path for cookie object " + cookieObject + ": " + getOpt(cookieObject, 'path));
160  
  }
161  
  
162  
  S s = cookie == null ? "" : "Your " + (isNew ? "new " : "recurring ") + "cookie is: " + cookie;
163  
  s += "<br>";
164  
  /*Data y = yesterday();
165  
  S yesterday = y == null ? "" : " (" + y.cookies + "/" + y.ips + " yesterday)";
166  
  s += l(cookies) + " cookies, " + l(ips) + " IPs" + yesterday + " seen today. " + cookieLess + " requests.";*/
167  
  ret s;
168  
}
169  
170  
synchronized answer {
171  
  if (subBot_master()) if "clear referers" {
172  
    lock lock;
173  
    referers.clear();
174  
    saveLater("referers");
175  
    ret "OK";
176  
  }
177  
  
178  
  if "visitors today" {
179  
    ret structure(today());
180  
  }
181  
  
182  
  /*if "visitors yesterday" {
183  
    Data data = yesterday();
184  
    if (data == null)
185  
      ret "There was no yesterday.";
186  
    ret structure(data);
187  
  }*/
188  
  
189  
  /*if "visitors last * days" {
190  
    int i = max(0, l(stats)-parseInt(m.unq(0))+1);
191  
    
192  
    new L<Map> stats_;
193  
    for (Map map : objectToMap(concatLists(
194  
      subList(stats, i),
195  
      litlist(today())
196  
    )))
197  
      stats_.add(mapWithoutKey(map, "uaips")); // drop the long stuff
198  
199  
    ret "```" + structureLines(stats_) + "```";
200  
  }*/
201  
  
202  
  if "uaips today"
203  
    ret sfu(cloneList(uaips));
204  
}
205  
206  
static Data today() {
207  
  Data d = new Data(countingForUnixDay, l(ips), l(cookies), cookieLess);
208  
  d.uaips = cloneList(uaips);
209  
  ret d;
210  
}
211  
212  
/*static synchronized Data yesterday() {
213  
  ret last(stats);
214  
}*/
215  
216  
static void addUAIP(S ua, S ip, bool hasCookie) {
217  
  for (Uaip x : uaips)
218  
    if (eq(x.ua, ua) && eq(x.ip, ip) && hasCookie == x.hasCookie)
219  
      ret;
220  
  uaips.add(new Uaip(ua, ip, hasCookie));
221  
  saveLater("uaips");
222  
}
223  
224  
sS cookieFromUser() { ret cookieFromUser!; }
225  
sS cookieSent() { ret cookieSent!; }
226  
227  
svoid saveLater(S var) {
228  
  rstSaveVars.add(var);
229  
}

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: 1147 / 10885
Version history: 42 change(s)
Referenced in: [show references]