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

patrick-canterino.de