2 * Jirafeau, your web file repository
3 * Copyright (C) 2015 Jerome Jutteau <j.jutteau@gmail.com>
4 * Copyright (C) 2015 Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 function show_link (url
, reference
, delete_code
, crypt_key
, date
)
23 document
.getElementById('uploading').style
.display
= 'none';
24 document
.getElementById('upload').style
.display
= 'none';
25 document
.getElementById('upload_finished').style
.display
= '';
26 document
.title
= 'Jirafeau - 100%';
29 var download_link
= url
+ 'f.php?h=' + reference
;
30 var download_link_href
= url
+ 'f.php?h=' + reference
;
31 if (crypt_key
.length
> 0)
33 download_link
+= '&k=' + crypt_key
;
34 download_link_href
+= '&k=' + crypt_key
;
36 if (!!document
.getElementById('upload_finished_download_page'))
38 document
.getElementById('upload_link').innerHTML
= download_link
;
39 document
.getElementById('upload_link').href
= download_link_href
;
43 var filename
= document
.getElementById('file_select').files
[0].name
;
44 var b
= encodeURIComponent("Download file \"" + filename
+ "\":") + "%0D";
45 b
+= encodeURIComponent(download_link_href
) + "%0D";
47 b
+= "%0D" + encodeURIComponent("This file will be available until " + date
) + "%0D";
48 document
.getElementById('upload_link_email').href
= "mailto:?body=" + b
+ "&subject=" + encodeURIComponent(filename
);
51 var delete_link
= url
+ 'f.php?h=' + reference
+ '&d=' + delete_code
;
52 var delete_link_href
= url
+ 'f.php?h=' + reference
+ '&d=' + delete_code
;
53 document
.getElementById('delete_link').innerHTML
= delete_link
;
54 document
.getElementById('delete_link').href
= delete_link_href
;
59 document
.getElementById('date').innerHTML
= date
;
60 document
.getElementById('validity').style
.display
= '';
63 document
.getElementById('validity').style
.display
= 'none';
65 // Preview link (if allowed)
66 if (!!document
.getElementById('preview_link'))
68 document
.getElementById('upload_finished_preview').style
.display
= 'none';
69 var preview_link
= url
+ 'f.php?h=' + reference
+ '&p=1';
70 var preview_link_href
= url
+ 'f.php?h=' + reference
+ '&p=1';
71 if (crypt_key
.length
> 0)
73 preview_link
+= '&k=' + crypt_key
;
74 preview_link_href
+= '&k=' + crypt_key
;
77 // Test if content can be previewed
78 type
= document
.getElementById('file_select').files
[0].type
;
79 if (type
.indexOf("image") > -1 ||
80 type
.indexOf("audio") > -1 ||
81 type
.indexOf("text") > -1 ||
82 type
.indexOf("video") > -1)
84 document
.getElementById('preview_link').innerHTML
= preview_link
;
85 document
.getElementById('preview_link').href
= preview_link_href
;
86 document
.getElementById('upload_finished_preview').style
.display
= '';
90 // Direct download link
91 var direct_download_link
= url
+ 'f.php?h=' + reference
+ '&d=1';
92 var direct_download_link_href
= url
+ 'f.php?h=' + reference
+ '&d=1';
93 if (crypt_key
.length
> 0)
95 direct_download_link
+= '&k=' + crypt_key
;
96 direct_download_link_href
+= '&k=' + crypt_key
;
98 document
.getElementById('direct_link').innerHTML
= direct_download_link
;
99 document
.getElementById('direct_link').href
= direct_download_link_href
;
102 // Hide preview and direct download link if password is set
103 if (document
.getElementById('input_key').value
.length
> 0)
105 if (!!document
.getElementById('preview_link'))
106 document
.getElementById('upload_finished_preview').style
.display
= 'none';
107 document
.getElementById('upload_direct_download').style
.display
= 'none';
111 function show_upload_progression (percentage
, speed
, time_left
)
113 document
.getElementById('uploaded_percentage').innerHTML
= percentage
;
114 document
.getElementById('uploaded_speed').innerHTML
= speed
;
115 document
.getElementById('uploaded_time').innerHTML
= time_left
;
116 document
.title
= 'Jirafeau - ' + percentage
;
119 function hide_upload_progression ()
121 document
.getElementById('uploaded_percentage').style
.display
= 'none';
122 document
.getElementById('uploaded_speed').style
.display
= 'none';
123 document
.getElementById('uploaded_time').style
.display
= 'none';
124 document
.title
= 'Jirafeau';
127 function upload_progress (e
)
129 if (e
== undefined || e
== null || !e
.lengthComputable
)
132 // Init time estimation if needed
133 if (upload_time_estimation_total_size
== 0)
134 upload_time_estimation_total_size
= e
.total
;
136 // Compute percentage
137 var p
= Math
.round (e
.loaded
* 100 / e
.total
);
140 p_str
= p
.toString() + '%';
141 // Update estimation speed
142 upload_time_estimation_add(e
.loaded
);
144 var speed_str
= upload_time_estimation_speed_string();
145 speed_str
= upload_speed_refresh_limiter(speed_str
);
147 var time_str
= chrono_update(upload_time_estimation_time());
149 show_upload_progression (p_str
, speed_str
, time_str
);
152 function control_selected_file_size(max_size
, error_str
)
154 f_size
= document
.getElementById('file_select').files
[0].size
;
155 if (max_size
> 0 && f_size
> max_size
* 1024 * 1024)
157 pop_failure(error_str
);
158 document
.getElementById('send').style
.display
= 'none';
162 document
.getElementById('options').style
.display
= '';
163 document
.getElementById('send').style
.display
= '';
164 document
.getElementById('error_pop').style
.display
= 'none';
165 document
.getElementById('file_select').style
.left
= 'inherit';
166 document
.getElementById('file_select').style
.height
= 'inherit';
167 document
.getElementById('file_select').style
.opacity
= '1';
171 function pop_failure (e
)
173 var text
= "An error occured";
174 if (typeof e
!== 'undefined')
176 text
= "<p>" + text
+ "</p>";
177 document
.getElementById('error_pop').innerHTML
= e
;
179 document
.getElementById('uploading').style
.display
= 'none';
180 document
.getElementById('error_pop').style
.display
= '';
181 document
.getElementById('upload').style
.display
= '';
182 document
.getElementById('send').style
.display
= '';
185 function add_time_string_to_date(d
, time
)
187 if(typeof(d
) != 'object' || !(d
instanceof Date
))
192 if (time
== 'minute')
194 d
.setSeconds (d
.getSeconds() + 60);
199 d
.setSeconds (d
.getSeconds() + 3600);
204 d
.setSeconds (d
.getSeconds() + 86400);
209 d
.setSeconds (d
.getSeconds() + 604800);
214 d
.setSeconds (d
.getSeconds() + 2419200);
219 d
.setSeconds (d
.getSeconds() + 29030400);
225 function classic_upload (url
, file
, time
, password
, one_time
, upload_password
)
227 // Delay time estimation init as we can't have file size
228 upload_time_estimation_init(0);
230 var req
= new XMLHttpRequest ();
231 req
.upload
.addEventListener ("progress", upload_progress
, false);
232 req
.addEventListener ("error", pop_failure
, false);
233 req
.addEventListener ("abort", pop_failure
, false);
234 req
.onreadystatechange = function ()
236 if (req
.readyState
== 4 && req
.status
== 200)
238 var res
= req
.responseText
;
244 res
= res
.split ("\n");
248 if(!add_time_string_to_date(d
, time
))
250 show_link (url
, res
[0], res
[1], res
[2], d
.toString());
253 show_link (url
, res
[0], res
[1], res
[2]);
256 req
.open ("POST", url
+ 'script.php' , true);
258 var form
= new FormData();
259 form
.append ("file", file
);
261 form
.append ("time", time
);
263 form
.append ("key", password
);
265 form
.append ("one_time_download", '1');
266 if (upload_password
.length
> 0)
267 form
.append ("upload_password", upload_password
);
272 function check_html5_file_api ()
274 return window
.File
&& window
.FileReader
&& window
.FileList
&& window
.Blob
;
277 var async_global_transfered
= 0;
278 var async_global_url
= '';
279 var async_global_file
;
280 var async_global_ref
= '';
281 var async_global_max_size
= 0;
282 var async_global_time
;
283 var async_global_transfering
= 0;
285 function async_upload_start (url
, max_size
, file
, time
, password
, one_time
, upload_password
)
287 async_global_transfered
= 0;
288 async_global_url
= url
;
289 async_global_file
= file
;
290 async_global_max_size
= max_size
;
291 async_global_time
= time
;
293 var req
= new XMLHttpRequest ();
294 req
.addEventListener ("error", pop_failure
, false);
295 req
.addEventListener ("abort", pop_failure
, false);
296 req
.onreadystatechange = function ()
298 if (req
.readyState
== 4 && req
.status
== 200)
300 var res
= req
.responseText
;
306 res
= res
.split ("\n");
307 async_global_ref
= res
[0];
309 async_upload_push (code
);
312 req
.open ("POST", async_global_url
+ 'script.php?init_async' , true);
314 var form
= new FormData();
315 form
.append ("filename", async_global_file
.name
);
316 form
.append ("type", async_global_file
.type
);
318 form
.append ("time", time
);
320 form
.append ("key", password
);
322 form
.append ("one_time_download", '1');
323 if (upload_password
.length
> 0)
324 form
.append ("upload_password", upload_password
);
326 // Start time estimation
327 upload_time_estimation_init(async_global_file
.size
);
332 function async_upload_progress (e
)
334 if (e
== undefined || e
== null || !e
.lengthComputable
&& async_global_file
.size
!= 0)
337 // Compute percentage
338 var p
= Math
.round ((e
.loaded
+ async_global_transfered
) * 100 / (async_global_file
.size
));
341 p_str
= p
.toString() + '%';
342 // Update estimation speed
343 upload_time_estimation_add(e
.loaded
+ async_global_transfered
);
345 var speed_str
= upload_time_estimation_speed_string();
346 speed_str
= upload_speed_refresh_limiter(speed_str
);
348 var time_str
= chrono_update(upload_time_estimation_time());
350 show_upload_progression (p_str
, speed_str
, time_str
);
353 function async_upload_push (code
)
355 if (async_global_transfered
== async_global_file
.size
)
357 hide_upload_progression ();
358 async_upload_end (code
);
361 var req
= new XMLHttpRequest ();
362 req
.upload
.addEventListener ("progress", async_upload_progress
, false);
363 req
.addEventListener ("error", pop_failure
, false);
364 req
.addEventListener ("abort", pop_failure
, false);
365 req
.onreadystatechange = function ()
367 if (req
.readyState
== 4 && req
.status
== 200)
369 var res
= req
.responseText
;
375 res
= res
.split ("\n");
377 async_global_transfered
= async_global_transfering
;
378 async_upload_push (code
);
381 req
.open ("POST", async_global_url
+ 'script.php?push_async' , true);
383 var chunk_size
= parseInt (async_global_max_size
* 0.50);
384 var start
= async_global_transfered
;
385 var end
= start
+ chunk_size
;
386 if (end
>= async_global_file
.size
)
387 end
= async_global_file
.size
;
388 var blob
= async_global_file
.slice (start
, end
);
389 async_global_transfering
= end
;
391 var form
= new FormData();
392 form
.append ("ref", async_global_ref
);
393 form
.append ("data", blob
);
394 form
.append ("code", code
);
398 function async_upload_end (code
)
400 var req
= new XMLHttpRequest ();
401 req
.addEventListener ("error", pop_failure
, false);
402 req
.addEventListener ("abort", pop_failure
, false);
403 req
.onreadystatechange = function ()
405 if (req
.readyState
== 4 && req
.status
== 200)
407 var res
= req
.responseText
;
413 res
= res
.split ("\n");
414 if (async_global_time
!= 'none')
417 if(!add_time_string_to_date(d
, async_global_time
))
419 show_link (async_global_url
, res
[0], res
[1], res
[2], d
.toString());
422 show_link (async_global_url
, res
[0], res
[1], res
[2]);
425 req
.open ("POST", async_global_url
+ 'script.php?end_async' , true);
427 var form
= new FormData();
428 form
.append ("ref", async_global_ref
);
429 form
.append ("code", code
);
433 function upload (url
, max_size
)
435 if (check_html5_file_api ()
436 && document
.getElementById('file_select').files
[0].size
>= max_size
)
438 async_upload_start (url
,
440 document
.getElementById('file_select').files
[0],
441 document
.getElementById('select_time').value
,
442 document
.getElementById('input_key').value
,
443 document
.getElementById('one_time_download').checked
,
444 document
.getElementById('upload_password').value
450 document
.getElementById('file_select').files
[0],
451 document
.getElementById('select_time').value
,
452 document
.getElementById('input_key').value
,
453 document
.getElementById('one_time_download').checked
,
454 document
.getElementById('upload_password').value
459 var upload_time_estimation_total_size
= 42;
460 var upload_time_estimation_transfered_size
= 42;
461 var upload_time_estimation_transfered_date
= 42;
462 var upload_time_estimation_moving_average_speed
= 42;
464 function upload_time_estimation_init(total_size
)
466 upload_time_estimation_total_size
= total_size
;
467 upload_time_estimation_transfered_size
= 0;
468 upload_time_estimation_moving_average_speed
= 0;
470 upload_time_estimation_transfered_date
= d
.getTime();
473 function upload_time_estimation_add(total_transfered_size
)
475 // Let's compute the current speed
477 var speed
= upload_time_estimation_moving_average_speed
;
478 if (d
.getTime() - upload_time_estimation_transfered_date
!= 0)
479 speed
= (total_transfered_size
- upload_time_estimation_transfered_size
)
480 / (d
.getTime() - upload_time_estimation_transfered_date
);
481 // Let's compute moving average speed on 30 values
482 var m
= (upload_time_estimation_moving_average_speed
* 29 + speed
) / 30;
483 // Update global values
484 upload_time_estimation_transfered_size
= total_transfered_size
;
485 upload_time_estimation_transfered_date
= d
.getTime();
486 upload_time_estimation_moving_average_speed
= m
;
489 function upload_time_estimation_speed_string()
492 var s
= upload_time_estimation_moving_average_speed
* 1000;
500 else if (s
< 1000000)
502 res
= Math
.floor(s
/100) / 10;
507 res
= Math
.floor(s
/100000) / 10;
512 return res
.toString() + ' ' + scale
;
515 function milliseconds_to_time_string (milliseconds
)
517 function numberEnding (number
) {
518 return (number
> 1) ? 's' : '';
521 var temp
= Math
.floor(milliseconds
/ 1000);
522 var years
= Math
.floor(temp
/ 31536000);
524 return years
+ ' year' + numberEnding(years
);
526 var days
= Math
.floor((temp
%= 31536000) / 86400);
528 return days
+ ' day' + numberEnding(days
);
530 var hours
= Math
.floor((temp
%= 86400) / 3600);
532 return hours
+ ' hour' + numberEnding(hours
);
534 var minutes
= Math
.floor((temp
%= 3600) / 60);
536 return minutes
+ ' minute' + numberEnding(minutes
);
538 var seconds
= temp
% 60;
540 return seconds
+ ' second' + numberEnding(seconds
);
542 return 'less than a second';
545 function upload_time_estimation_time()
547 // Estimate remaining time
548 if (upload_time_estimation_moving_average_speed
== 0)
550 return (upload_time_estimation_total_size
- upload_time_estimation_transfered_size
)
551 / upload_time_estimation_moving_average_speed
;
554 var chrono_last_update
= 0;
555 var chrono_time_ms
= 0;
556 var chrono_time_ms_last_update
= 0;
557 function chrono_update(time_ms
)
561 // Don't update too often
562 if (d
.getTime() - chrono_last_update
< 3000 &&
563 chrono_time_ms_last_update
> 0)
564 chrono
= chrono_time_ms
;
567 chrono_last_update
= d
.getTime();
568 chrono_time_ms
= time_ms
;
570 chrono_time_ms_last_update
= d
.getTime();
573 // Adjust chrono for smooth estimation
574 chrono
= chrono
- (d
.getTime() - chrono_time_ms_last_update
);
576 // Let's update chronometer
579 time_str
= milliseconds_to_time_string (chrono
);
583 var upload_speed_refresh_limiter_last_update
= 0;
584 var upload_speed_refresh_limiter_last_value
= '';
585 function upload_speed_refresh_limiter(speed_str
)
588 if (d
.getTime() - upload_speed_refresh_limiter_last_update
> 1500)
590 upload_speed_refresh_limiter_last_value
= speed_str
;
591 upload_speed_refresh_limiter_last_update
= d
.getTime();
593 return upload_speed_refresh_limiter_last_value
;