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

patrick-canterino.de