]> git.p6c8.net - jirafeau.git/blob - lib/functions.js.php
e981e359d00f2acf864f51fa32cc8268755b630d
[jirafeau.git] / lib / functions.js.php
1 <?php
2 /*
3 * Jirafeau, your web file repository
4 * Copyright (C) 2015 Jerome Jutteau <j.jutteau@gmail.com>
5 * Copyright (C) 2015 Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20 header('Content-Type: text/javascript');
21 define ('JIRAFEAU_ROOT', dirname (__FILE__) . '/../');
22 require (JIRAFEAU_ROOT . 'lib/config.original.php');
23 require (JIRAFEAU_ROOT . 'lib/settings.php');
24 require (JIRAFEAU_ROOT . 'lib/functions.php');
25 require (JIRAFEAU_ROOT . 'lib/lang.php');
26 ?>
27
28 function translate (expr)
29 {
30 var lang_array = <?php echo json_lang_generator () ?>;
31 if (lang_array.hasOwnProperty(expr))
32 return lang_array[expr];
33 return expr;
34 }
35
36 function show_link (url, reference, delete_code, crypt_key, date)
37 {
38 // Upload finished
39 document.getElementById('uploading').style.display = 'none';
40 document.getElementById('upload').style.display = 'none';
41 document.getElementById('upload_finished').style.display = '';
42 document.title = 'Jirafeau - 100%';
43
44 // Download page
45 var download_link = url + 'f.php?h=' + reference;
46 var download_link_href = url + 'f.php?h=' + reference;
47 if (crypt_key.length > 0)
48 {
49 download_link += '&amp;k=' + crypt_key;
50 download_link_href += '&k=' + crypt_key;
51 }
52 if (!!document.getElementById('upload_finished_download_page'))
53 {
54 document.getElementById('upload_link').innerHTML = download_link;
55 document.getElementById('upload_link').href = download_link_href;
56 }
57
58 // Email link
59 var filename = document.getElementById('file_select').files[0].name;
60 var b = encodeURIComponent("Download file \"" + filename + "\":") + "%0D";
61 b += encodeURIComponent(download_link_href) + "%0D";
62 if (date)
63 b += "%0D" + encodeURIComponent("This file will be available until " + date) + "%0D";
64 document.getElementById('upload_link_email').href = "mailto:?body=" + b + "&subject=" + encodeURIComponent(filename);
65
66 // Delete link
67 var delete_link = url + 'f.php?h=' + reference + '&amp;d=' + delete_code;
68 var delete_link_href = url + 'f.php?h=' + reference + '&d=' + delete_code;
69 document.getElementById('delete_link').innerHTML = delete_link;
70 document.getElementById('delete_link').href = delete_link_href;
71
72 // Validity date
73 if (date)
74 {
75 document.getElementById('date').innerHTML = date;
76 document.getElementById('validity').style.display = '';
77 }
78 else
79 document.getElementById('validity').style.display = 'none';
80
81 // Preview link (if allowed)
82 if (!!document.getElementById('preview_link'))
83 {
84 document.getElementById('upload_finished_preview').style.display = 'none';
85 var preview_link = url + 'f.php?h=' + reference + '&amp;p=1';
86 var preview_link_href = url + 'f.php?h=' + reference + '&p=1';
87 if (crypt_key.length > 0)
88 {
89 preview_link += '&amp;k=' + crypt_key;
90 preview_link_href += '&k=' + crypt_key;
91 }
92
93 // Test if content can be previewed
94 type = document.getElementById('file_select').files[0].type;
95 if (type.indexOf("image") > -1 ||
96 type.indexOf("audio") > -1 ||
97 type.indexOf("text") > -1 ||
98 type.indexOf("video") > -1)
99 {
100 document.getElementById('preview_link').innerHTML = preview_link;
101 document.getElementById('preview_link').href = preview_link_href;
102 document.getElementById('upload_finished_preview').style.display = '';
103 }
104 }
105
106 // Direct download link
107 var direct_download_link = url + 'f.php?h=' + reference + '&amp;d=1';
108 var direct_download_link_href = url + 'f.php?h=' + reference + '&d=1';
109 if (crypt_key.length > 0)
110 {
111 direct_download_link += '&amp;k=' + crypt_key;
112 direct_download_link_href += '&k=' + crypt_key;
113 }
114 document.getElementById('direct_link').innerHTML = direct_download_link;
115 document.getElementById('direct_link').href = direct_download_link_href;
116
117
118 // Hide preview and direct download link if password is set
119 if (document.getElementById('input_key').value.length > 0)
120 {
121 if (!!document.getElementById('preview_link'))
122 document.getElementById('upload_finished_preview').style.display = 'none';
123 document.getElementById('upload_direct_download').style.display = 'none';
124 }
125 }
126
127 function show_upload_progression (percentage, speed, time_left)
128 {
129 document.getElementById('uploaded_percentage').innerHTML = percentage;
130 document.getElementById('uploaded_speed').innerHTML = speed;
131 document.getElementById('uploaded_time').innerHTML = time_left;
132 document.title = 'Jirafeau - ' + percentage;
133 }
134
135 function hide_upload_progression ()
136 {
137 document.getElementById('uploaded_percentage').style.display = 'none';
138 document.getElementById('uploaded_speed').style.display = 'none';
139 document.getElementById('uploaded_time').style.display = 'none';
140 document.title = 'Jirafeau';
141 }
142
143 function upload_progress (e)
144 {
145 if (e == undefined || e == null || !e.lengthComputable)
146 return;
147
148 // Init time estimation if needed
149 if (upload_time_estimation_total_size == 0)
150 upload_time_estimation_total_size = e.total;
151
152 // Compute percentage
153 var p = Math.round (e.loaded * 100 / e.total);
154 var p_str = ' ';
155 if (p != 100)
156 p_str = p.toString() + '%';
157 // Update estimation speed
158 upload_time_estimation_add(e.loaded);
159 // Get speed string
160 var speed_str = upload_time_estimation_speed_string();
161 speed_str = upload_speed_refresh_limiter(speed_str);
162 // Get time string
163 var time_str = chrono_update(upload_time_estimation_time());
164
165 show_upload_progression (p_str, speed_str, time_str);
166 }
167
168 function control_selected_file_size(max_size, error_str)
169 {
170 f_size = document.getElementById('file_select').files[0].size;
171 if (max_size > 0 && f_size > max_size * 1024 * 1024)
172 {
173 pop_failure(error_str);
174 document.getElementById('send').style.display = 'none';
175 }
176 else
177 {
178 document.getElementById('options').style.display = '';
179 document.getElementById('send').style.display = '';
180 document.getElementById('error_pop').style.display = 'none';
181 document.getElementById('file_select').style.left = 'inherit';
182 document.getElementById('file_select').style.height = 'inherit';
183 document.getElementById('file_select').style.opacity = '1';
184 }
185 }
186
187 function pop_failure (e)
188 {
189 var text = "An error occured";
190 if (typeof e !== 'undefined')
191 text = e;
192 text = "<p>" + text + "</p>";
193 document.getElementById('error_pop').innerHTML = e;
194
195 document.getElementById('uploading').style.display = 'none';
196 document.getElementById('error_pop').style.display = '';
197 document.getElementById('upload').style.display = '';
198 document.getElementById('send').style.display = '';
199 }
200
201 function add_time_string_to_date(d, time)
202 {
203 if(typeof(d) != 'object' || !(d instanceof Date))
204 {
205 return false;
206 }
207
208 if (time == 'minute')
209 {
210 d.setSeconds (d.getSeconds() + 60);
211 return true;
212 }
213 if (time == 'hour')
214 {
215 d.setSeconds (d.getSeconds() + 3600);
216 return true;
217 }
218 if (time == 'day')
219 {
220 d.setSeconds (d.getSeconds() + 86400);
221 return true;
222 }
223 if (time == 'week')
224 {
225 d.setSeconds (d.getSeconds() + 604800);
226 return true;
227 }
228 if (time == 'month')
229 {
230 d.setSeconds (d.getSeconds() + 2419200);
231 return true;
232 }
233 if (time == 'year')
234 {
235 d.setSeconds (d.getSeconds() + 29030400);
236 return true;
237 }
238 return false;
239 }
240
241 function classic_upload (url, file, time, password, one_time, upload_password)
242 {
243 // Delay time estimation init as we can't have file size
244 upload_time_estimation_init(0);
245
246 var req = new XMLHttpRequest ();
247 req.upload.addEventListener ("progress", upload_progress, false);
248 req.addEventListener ("error", pop_failure, false);
249 req.addEventListener ("abort", pop_failure, false);
250 req.onreadystatechange = function ()
251 {
252 if (req.readyState == 4 && req.status == 200)
253 {
254 var res = req.responseText;
255 if (res == "Error")
256 {
257 pop_failure ();
258 return;
259 }
260 res = res.split ("\n");
261 if (time != 'none')
262 {
263 var d = new Date();
264 if(!add_time_string_to_date(d, time))
265 return;
266 show_link (url, res[0], res[1], res[2], d.toString());
267 }
268 else
269 show_link (url, res[0], res[1], res[2]);
270 }
271 }
272 req.open ("POST", url + 'script.php' , true);
273
274 var form = new FormData();
275 form.append ("file", file);
276 if (time)
277 form.append ("time", time);
278 if (password)
279 form.append ("key", password);
280 if (one_time)
281 form.append ("one_time_download", '1');
282 if (upload_password.length > 0)
283 form.append ("upload_password", upload_password);
284
285 req.send (form);
286 }
287
288 function check_html5_file_api ()
289 {
290 return window.File && window.FileReader && window.FileList && window.Blob;
291 }
292
293 var async_global_transfered = 0;
294 var async_global_url = '';
295 var async_global_file;
296 var async_global_ref = '';
297 var async_global_max_size = 0;
298 var async_global_time;
299 var async_global_transfering = 0;
300
301 function async_upload_start (url, max_size, file, time, password, one_time, upload_password)
302 {
303 async_global_transfered = 0;
304 async_global_url = url;
305 async_global_file = file;
306 async_global_max_size = max_size;
307 async_global_time = time;
308
309 var req = new XMLHttpRequest ();
310 req.addEventListener ("error", pop_failure, false);
311 req.addEventListener ("abort", pop_failure, false);
312 req.onreadystatechange = function ()
313 {
314 if (req.readyState == 4 && req.status == 200)
315 {
316 var res = req.responseText;
317 if (res == "Error")
318 {
319 pop_failure ();
320 return;
321 }
322 res = res.split ("\n");
323 async_global_ref = res[0];
324 var code = res[1];
325 async_upload_push (code);
326 }
327 }
328 req.open ("POST", async_global_url + 'script.php?init_async' , true);
329
330 var form = new FormData();
331 form.append ("filename", async_global_file.name);
332 form.append ("type", async_global_file.type);
333 if (time)
334 form.append ("time", time);
335 if (password)
336 form.append ("key", password);
337 if (one_time)
338 form.append ("one_time_download", '1');
339 if (upload_password.length > 0)
340 form.append ("upload_password", upload_password);
341
342 // Start time estimation
343 upload_time_estimation_init(async_global_file.size);
344
345 req.send (form);
346 }
347
348 function async_upload_progress (e)
349 {
350 if (e == undefined || e == null || !e.lengthComputable && async_global_file.size != 0)
351 return;
352
353 // Compute percentage
354 var p = Math.round ((e.loaded + async_global_transfered) * 100 / (async_global_file.size));
355 var p_str = ' ';
356 if (p != 100)
357 p_str = p.toString() + '%';
358 // Update estimation speed
359 upload_time_estimation_add(e.loaded + async_global_transfered);
360 // Get speed string
361 var speed_str = upload_time_estimation_speed_string();
362 speed_str = upload_speed_refresh_limiter(speed_str);
363 // Get time string
364 var time_str = chrono_update(upload_time_estimation_time());
365
366 show_upload_progression (p_str, speed_str, time_str);
367 }
368
369 function async_upload_push (code)
370 {
371 if (async_global_transfered == async_global_file.size)
372 {
373 hide_upload_progression ();
374 async_upload_end (code);
375 return;
376 }
377 var req = new XMLHttpRequest ();
378 req.upload.addEventListener ("progress", async_upload_progress, false);
379 req.addEventListener ("error", pop_failure, false);
380 req.addEventListener ("abort", pop_failure, false);
381 req.onreadystatechange = function ()
382 {
383 if (req.readyState == 4 && req.status == 200)
384 {
385 var res = req.responseText;
386 if (res == "Error")
387 {
388 pop_failure ();
389 return;
390 }
391 res = res.split ("\n");
392 var code = res[0]
393 async_global_transfered = async_global_transfering;
394 async_upload_push (code);
395 }
396 }
397 req.open ("POST", async_global_url + 'script.php?push_async' , true);
398
399 var chunk_size = parseInt (async_global_max_size * 0.50);
400 var start = async_global_transfered;
401 var end = start + chunk_size;
402 if (end >= async_global_file.size)
403 end = async_global_file.size;
404 var blob = async_global_file.slice (start, end);
405 async_global_transfering = end;
406
407 var form = new FormData();
408 form.append ("ref", async_global_ref);
409 form.append ("data", blob);
410 form.append ("code", code);
411 req.send (form);
412 }
413
414 function async_upload_end (code)
415 {
416 var req = new XMLHttpRequest ();
417 req.addEventListener ("error", pop_failure, false);
418 req.addEventListener ("abort", pop_failure, false);
419 req.onreadystatechange = function ()
420 {
421 if (req.readyState == 4 && req.status == 200)
422 {
423 var res = req.responseText;
424 if (res == "Error")
425 {
426 pop_failure ();
427 return;
428 }
429 res = res.split ("\n");
430 if (async_global_time != 'none')
431 {
432 var d = new Date();
433 if(!add_time_string_to_date(d, async_global_time))
434 return;
435 show_link (async_global_url, res[0], res[1], res[2], d.toString());
436 }
437 else
438 show_link (async_global_url, res[0], res[1], res[2]);
439 }
440 }
441 req.open ("POST", async_global_url + 'script.php?end_async' , true);
442
443 var form = new FormData();
444 form.append ("ref", async_global_ref);
445 form.append ("code", code);
446 req.send (form);
447 }
448
449 function upload (url, max_size)
450 {
451 if (check_html5_file_api ()
452 && document.getElementById('file_select').files[0].size >= max_size)
453 {
454 async_upload_start (url,
455 max_size,
456 document.getElementById('file_select').files[0],
457 document.getElementById('select_time').value,
458 document.getElementById('input_key').value,
459 document.getElementById('one_time_download').checked,
460 document.getElementById('upload_password').value
461 );
462 }
463 else
464 {
465 classic_upload (url,
466 document.getElementById('file_select').files[0],
467 document.getElementById('select_time').value,
468 document.getElementById('input_key').value,
469 document.getElementById('one_time_download').checked,
470 document.getElementById('upload_password').value
471 );
472 }
473 }
474
475 var upload_time_estimation_total_size = 42;
476 var upload_time_estimation_transfered_size = 42;
477 var upload_time_estimation_transfered_date = 42;
478 var upload_time_estimation_moving_average_speed = 42;
479
480 function upload_time_estimation_init(total_size)
481 {
482 upload_time_estimation_total_size = total_size;
483 upload_time_estimation_transfered_size = 0;
484 upload_time_estimation_moving_average_speed = 0;
485 var d = new Date();
486 upload_time_estimation_transfered_date = d.getTime();
487 }
488
489 function upload_time_estimation_add(total_transfered_size)
490 {
491 // Let's compute the current speed
492 var d = new Date();
493 var speed = upload_time_estimation_moving_average_speed;
494 if (d.getTime() - upload_time_estimation_transfered_date != 0)
495 speed = (total_transfered_size - upload_time_estimation_transfered_size)
496 / (d.getTime() - upload_time_estimation_transfered_date);
497 // Let's compute moving average speed on 30 values
498 var m = (upload_time_estimation_moving_average_speed * 29 + speed) / 30;
499 // Update global values
500 upload_time_estimation_transfered_size = total_transfered_size;
501 upload_time_estimation_transfered_date = d.getTime();
502 upload_time_estimation_moving_average_speed = m;
503 }
504
505 function upload_time_estimation_speed_string()
506 {
507 // speed ms -> s
508 var s = upload_time_estimation_moving_average_speed * 1000;
509 var res = 0;
510 var scale = '';
511 if (s <= 1000)
512 {
513 res = s.toString();
514 scale = "o/s";
515 }
516 else if (s < 1000000)
517 {
518 res = Math.floor(s/100) / 10;
519 scale = "Ko/s";
520 }
521 else
522 {
523 res = Math.floor(s/100000) / 10;
524 scale = "Mo/s";
525 }
526 if (res == 0)
527 return '';
528 return res.toString() + ' ' + scale;
529 }
530
531 function milliseconds_to_time_string (milliseconds)
532 {
533 function numberEnding (number) {
534 return (number > 1) ? 's' : '';
535 }
536
537 var temp = Math.floor(milliseconds / 1000);
538 var years = Math.floor(temp / 31536000);
539 if (years) {
540 return years + ' ' + translate ('year') + numberEnding(years);
541 }
542 var days = Math.floor((temp %= 31536000) / 86400);
543 if (days) {
544 return days + ' ' + translate ('day') + numberEnding(days);
545 }
546 var hours = Math.floor((temp %= 86400) / 3600);
547 if (hours) {
548 return hours + ' ' + translate ('hour') + numberEnding(hours);
549 }
550 var minutes = Math.floor((temp %= 3600) / 60);
551 if (minutes) {
552 return minutes + ' ' + translate ('minute') + numberEnding(minutes);
553 }
554 var seconds = temp % 60;
555 if (seconds) {
556 return seconds + ' ' + translate ('second') + numberEnding(seconds);
557 }
558 return translate ('less than a second');
559 }
560
561 function upload_time_estimation_time()
562 {
563 // Estimate remaining time
564 if (upload_time_estimation_moving_average_speed == 0)
565 return 0;
566 return (upload_time_estimation_total_size - upload_time_estimation_transfered_size)
567 / upload_time_estimation_moving_average_speed;
568 }
569
570 var chrono_last_update = 0;
571 var chrono_time_ms = 0;
572 var chrono_time_ms_last_update = 0;
573 function chrono_update(time_ms)
574 {
575 var d = new Date();
576 var chrono = 0;
577 // Don't update too often
578 if (d.getTime() - chrono_last_update < 3000 &&
579 chrono_time_ms_last_update > 0)
580 chrono = chrono_time_ms;
581 else
582 {
583 chrono_last_update = d.getTime();
584 chrono_time_ms = time_ms;
585 chrono = time_ms;
586 chrono_time_ms_last_update = d.getTime();
587 }
588
589 // Adjust chrono for smooth estimation
590 chrono = chrono - (d.getTime() - chrono_time_ms_last_update);
591
592 // Let's update chronometer
593 var time_str = '';
594 if (chrono > 0)
595 time_str = milliseconds_to_time_string (chrono);
596 return time_str;
597 }
598
599 var upload_speed_refresh_limiter_last_update = 0;
600 var upload_speed_refresh_limiter_last_value = '';
601 function upload_speed_refresh_limiter(speed_str)
602 {
603 var d = new Date();
604 if (d.getTime() - upload_speed_refresh_limiter_last_update > 1500)
605 {
606 upload_speed_refresh_limiter_last_value = speed_str;
607 upload_speed_refresh_limiter_last_update = d.getTime();
608 }
609 return upload_speed_refresh_limiter_last_value;
610 }

patrick-canterino.de