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 | } |
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] |