1 (* Copyright 2001, 2002 b8_bavard, b8_fee_carabine, INRIA *)
3 This file is part of mldonkey.
5 mldonkey is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 mldonkey is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with mldonkey; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 open CommonInteractive
33 open DonkeyComplexOptions
35 let start_session = ref (BasicSocket.last_time
())
37 let stats_array = Array.init brand_count
(fun _
->
38 { dummy_stats
with brand_seen
= 0 }
40 let stats_mod_array = Array.init brand_mod_count
(fun _
->
41 { dummy_stats
with brand_seen
= 0 }
45 let i = brand_to_int c
.client_brand
in
46 stats_array.(i).brand_seen
<- stats_array.(i).brand_seen
+ 1;
47 !!gstats_array
.(i).brand_seen
<- !!gstats_array
.(i).brand_seen
+ 1;
48 check_client_country_code c
;
49 CommonStats.country_seen c
.client_country_code
;
51 if !!emule_mods_count
then begin
52 let i = brand_mod_to_int c
.client_brand_mod
in
53 stats_mod_array.(i).brand_seen
<- stats_mod_array.(i).brand_seen
+ 1;
54 !!gstats_mod_array
.(i).brand_seen
<- !!gstats_mod_array
.(i).brand_seen
+ 1
58 let i = brand_to_int c
.client_brand
in
59 stats_array.(i).brand_banned
<- stats_array.(i).brand_banned
+ 1;
60 !!gstats_array
.(i).brand_banned
<- !!gstats_array
.(i).brand_banned
+ 1;
62 if !!emule_mods_count
then begin
63 let i = brand_mod_to_int c
.client_brand_mod
in
64 stats_mod_array.(i).brand_banned
<- stats_mod_array.(i).brand_banned
+ 1;
65 !!gstats_mod_array
.(i).brand_banned
<- !!gstats_mod_array
.(i).brand_banned
+ 1
68 let count_filerequest c
=
69 let i = brand_to_int c
.client_brand
in
70 stats_array.(i).brand_filerequest
<- stats_array.(i).brand_filerequest
+ 1;
71 !!gstats_array
.(i).brand_filerequest
<- !!gstats_array
.(i).brand_filerequest
+ 1;
73 if !!emule_mods_count
then begin
74 let i = brand_mod_to_int c
.client_brand_mod
in
75 stats_mod_array.(i).brand_filerequest
<- stats_mod_array.(i).brand_filerequest
+ 1;
76 !!gstats_mod_array
.(i).brand_filerequest
<- !!gstats_mod_array
.(i).brand_filerequest
+ 1
79 let count_download c v
=
80 let i = brand_to_int c
.client_brand
in
81 stats_array.(i).brand_download
<- stats_array.(i).brand_download
++ v
;
82 !!gstats_array
.(i).brand_download
<- !!gstats_array
.(i).brand_download
++ v
;
84 if !!emule_mods_count
then begin
85 let i = brand_mod_to_int c
.client_brand_mod
in
86 stats_mod_array.(i).brand_download
<- stats_mod_array.(i).brand_download
++ v
;
87 !!gstats_mod_array
.(i).brand_download
<- !!gstats_mod_array
.(i).brand_download
++ v
;
90 c
.client_total_downloaded
<- c
.client_total_downloaded
++ v
;
91 c
.client_session_downloaded
<- c
.client_session_downloaded
++ v
;
92 donkey_download_counter
:= !donkey_download_counter
++ v
;
93 check_client_country_code c
;
94 global_count_download network c
.client_country_code v
96 let count_upload c v
=
97 let i = brand_to_int c
.client_brand
in
98 stats_array.(i).brand_upload
<- stats_array.(i).brand_upload
++ v
;
99 !!gstats_array
.(i).brand_upload
<- !!gstats_array
.(i).brand_upload
++ v
;
101 if !!emule_mods_count
then begin
102 let i = brand_mod_to_int c
.client_brand_mod
in
103 stats_mod_array.(i).brand_upload
<- stats_mod_array.(i).brand_upload
++ v
;
104 !!gstats_mod_array
.(i).brand_upload
<- !!gstats_mod_array
.(i).brand_upload
++ v
;
107 c
.client_total_uploaded
<- c
.client_total_uploaded
++ v
;
108 c
.client_session_uploaded
<- c
.client_session_uploaded
++ v
;
109 donkey_upload_counter
:= !donkey_upload_counter
++ v
;
110 check_client_country_code c
;
111 global_count_upload network c
.client_country_code v
113 let print_stats_mods o style
=
114 let buf = o
.conn_buf
in
116 let u1 = BasicSocket.last_time
() - !start_session in
117 let u2 = (guptime
() + u1) in
119 let t1 = build_title
"eMule Mods" "Session" u1 in
120 let t2 = build_title
"eMule Mods" "Total" u2 in
122 let l = brand_mod_list
in
125 | Old
-> print_stats_old
buf stats_mod_array l t1 u1
127 if !!emule_mods_count
then begin
129 if use_html_mods o
then begin
130 print_stats_html_mods
buf stats_mod_array l t1 u1;
131 print_stats_html_mods
buf !!gstats_mod_array
l t2 u2
133 print_stats_ascii
buf stats_mod_array l t1 u1;
134 print_stats_ascii
buf !!gstats_mod_array
l t2 u2
140 if use_html_mods o
then begin
141 Printf.bprintf
buf "\\<div class=\\\"cs\\\"\\>";
142 html_mods_table_header
buf "emodsTable" "cs" [];
143 Printf.bprintf
buf "\\<tr class=\\\"dl-1\\\"\\>";
145 ("", "sr", "eMule mods statistics are disabled, to activate set emule_mods_count true in the \\<a href=\\\"/submit?q=voo+8\\\"\\>misc options\\</a\\> tab." );
147 Printf.bprintf
buf "\\</tr\\>\\</table\\>\\</div\\>\\</div\\>\n"
149 Printf.bprintf
buf "eMule mods statistics are disabled, to activate set emule_mods_count true \n"
153 let print_stats o style mods
=
154 let buf = o
.conn_buf
in
156 let u1 = BasicSocket.last_time
() - !start_session in
157 let u2 = (guptime
() + u1) in
159 let t1 = build_title
"eDonkey" "Session" u1 in
160 let t2 = build_title
"eDonkey" "Total" u2 in
162 let l = brand_list
in
164 if mods
then print_stats_mods o style
else
166 | Old
-> print_stats_old
buf stats_array l t1 u1
168 if use_html_mods o
then begin
169 print_stats_html_mods
buf stats_array l t1 u1;
170 print_stats_html_mods
buf !!gstats_array
l t2 u2
172 print_stats_ascii
buf stats_array l t1 u1;
173 print_stats_ascii
buf !!gstats_array
l t2 u2
177 network
.op_network_display_stats
<- (fun o
-> print_stats o New
false);
179 network
.op_network_stat_info_list
<- (fun _ ->
181 let l1 = stats_list brand_list
stats_array in
182 let l2 = stats_list brand_list
!!gstats_array
in
183 let u1 = BasicSocket.last_time
() - !start_session in
184 let u2 = (guptime
() + u1) in
185 r := [("Session clients", u1, l1); ("Global clients", u2, l2)];
186 if !!emule_mods_count
then begin
187 let l3 = stats_list brand_mod_list
stats_mod_array in
188 let l4 = stats_list brand_mod_list
!!gstats_mod_array
in
189 r := !r @ [ ("Session mods", u1, l3); ("Global mods", u2, l4)]
196 "client_stats", "Network/Donkey",Arg_none
(fun o
->
197 print_stats o Old
false;
199 ), ":\t\t\t\tshow breakdown of download/upload by clients brand";
201 "cs", "Network/Donkey",Arg_none
(fun o
->
202 print_stats o New
false;
204 ), ":\t\t\t\t\tshow table of download/upload by ED2K clients brand";
206 "csm", "Network/Donkey",Arg_none
(fun o
->
207 print_stats o New
true;
209 ), ":\t\t\t\t\tshow table of download/upload by eMule MODs";
210 "reset_stats", "Network/Donkey",Arg_none
(fun o
->
212 Array.iteri
(fun x
_ ->
213 stats_array.(x
).brand_seen
<- 0;
214 stats_array.(x
).brand_banned
<- 0;
215 stats_array.(x
).brand_filerequest
<- 0;
216 stats_array.(x
).brand_download
<- 0L;
217 stats_array.(x
).brand_upload
<- 0L;
220 Array.iteri
(fun x
_ ->
221 stats_mod_array.(x
).brand_seen
<- 0;
222 stats_mod_array.(x
).brand_banned
<- 0;
223 stats_mod_array.(x
).brand_filerequest
<- 0;
224 stats_mod_array.(x
).brand_download
<- Int64.zero
;
225 stats_mod_array.(x
).brand_upload
<- Int64.zero
228 start_session := BasicSocket.last_time
();
231 ), ":\t\t\t\treset session statistics";
235 let save_download_history file =
237 let buf = Buffer.create 100 in
239 (* Some opcode for edonkey downloads *)
240 buf_int8
buf 153; (* opcode = stats *)
241 buf_md4
buf !!client_md4
; (* client md4, and NOT IP *)
243 let time = Unix.time () in
244 let time = Unix.localtime
time in
245 (* date on 5 bytes *)
246 buf_int8
buf time.Unix.tm_hour
;
247 buf_int8
buf time.Unix.tm_mday
;
248 buf_int8
buf time.Unix.tm_mon
;
249 buf_int16
buf time.Unix.tm_year
;
250 (* ANONYMISED Informations on the downloads: *)
251 (* Send the SHA1 hash of the MD4+size, so that they cannot be recovered,
252 but they can be used to compare downloads. *)
253 let m = Printf.sprintf
"%s%Ld"
254 (Md4.Md4.direct_to_string file
.file_md4
) (file_size file
) in
255 let m = Md4.Sha1.string m in (* compute SHA1 of the string *)
257 Buffer.add_string
buf (Md4.Sha1.direct_to_string
m);
259 (* Send the magnitude of the size (power of 10) *)
260 let size = ref (file_size file
) in
262 while !size <> Int64.zero
do
269 let current = ref [] in
271 Intmap.iter
(fun _ c
->
273 match c
.client_kind
with
274 Indirect_location
(name
, md4
) ->
275 Printf.sprintf
"%s%s" name
276 (Md4.Md4.direct_to_string md4
)
277 | Known_location
(ip
,port
) ->
278 Printf.sprintf
"%s%d"
279 (Ip.to_string ip
) port
282 (* ANONYMISATION of the source: we compute the Sha1 digest of the source,
283 which cannot be recovered from this information *)
284 let location = Md4.Sha1.string location in (* compute SHA1 of the string *)
285 current := location :: !current;
286 ) file
.file_locations
;
288 buf_list
(fun buf s
->
289 Buffer.add_string
buf (Md4.Sha1.direct_to_string s
)
293 let file_history = "downloads.stats" in
294 let oc = append_out
file_history in
295 output_string
oc (Buffer.contents
buf);