2 * Jirafeau, your web file repository
3 * Copyright (C) 2015 Jerome Jutteau <j.jutteau@gmail.com>
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
10 * This program 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 Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 function show_link (url
, reference
, delete_code
, crypt_key
, date
)
22 document
.getElementById('uploading').style
.display
= 'none';
23 document
.getElementById('upload').style
.display
= 'none';
24 document
.getElementById('upload_finished').style
.display
= '';
25 document
.title
= 'Jirafeau - 100%';
28 var download_link
= url
+ 'f.php?h=' + reference
;
29 var download_link_href
= url
+ 'f.php?h=' + reference
;
30 if (crypt_key
.length
> 0)
32 download_link
+= '&k=' + crypt_key
;
33 download_link_href
+= '&k=' + crypt_key
;
35 if (!!document
.getElementById('upload_finished_download_page'))
37 document
.getElementById('upload_link').innerHTML
= download_link
;
38 document
.getElementById('upload_link').href
= download_link_href
;
42 var filename
= document
.getElementById('file_select').files
[0].name
;
43 var b
= encodeURIComponent("Download file \"" + filename
+ "\":") + "%0D";
44 b
+= encodeURIComponent(download_link_href
) + "%0D";
46 b
+= "%0D" + encodeURIComponent("This file will be available until " + date
) + "%0D";
47 document
.getElementById('upload_link_email').href
= "mailto:?body=" + b
+ "&subject=" + encodeURIComponent(filename
);
50 var delete_link
= url
+ 'f.php?h=' + reference
+ '&d=' + delete_code
;
51 var delete_link_href
= url
+ 'f.php?h=' + reference
+ '&d=' + delete_code
;
52 document
.getElementById('delete_link').innerHTML
= delete_link
;
53 document
.getElementById('delete_link').href
= delete_link_href
;
58 document
.getElementById('date').innerHTML
= date
;
59 document
.getElementById('validity').style
.display
= '';
62 document
.getElementById('validity').style
.display
= 'none';
64 // Preview link (if allowed)
65 if (!!document
.getElementById('preview_link'))
67 document
.getElementById('upload_finished_preview').style
.display
= 'none';
68 var preview_link
= url
+ 'f.php?h=' + reference
+ '&p=1';
69 var preview_link_href
= url
+ 'f.php?h=' + reference
+ '&p=1';
70 if (crypt_key
.length
> 0)
72 preview_link
+= '&k=' + crypt_key
;
73 preview_link_href
+= '&k=' + crypt_key
;
76 // Test if content can be previewed
77 type
= document
.getElementById('file_select').files
[0].type
;
78 if (type
.indexOf("image") > -1 ||
79 type
.indexOf("audio") > -1 ||
80 type
.indexOf("text") > -1 ||
81 type
.indexOf("video") > -1)
83 document
.getElementById('preview_link').innerHTML
= preview_link
;
84 document
.getElementById('preview_link').href
= preview_link_href
;
85 document
.getElementById('upload_finished_preview').style
.display
= '';
89 // Direct download link
90 var direct_download_link
= url
+ 'f.php?h=' + reference
+ '&d=1';
91 var direct_download_link_href
= url
+ 'f.php?h=' + reference
+ '&d=1';
92 if (crypt_key
.length
> 0)
94 direct_download_link
+= '&k=' + crypt_key
;
95 direct_download_link_href
+= '&k=' + crypt_key
;
97 document
.getElementById('direct_link').innerHTML
= direct_download_link
;
98 document
.getElementById('direct_link').href
= direct_download_link_href
;
101 // Hide preview and direct download link if password is set
102 if (document
.getElementById('input_key').value
.length
> 0)
104 if (!!document
.getElementById('preview_link'))
105 document
.getElementById('upload_finished_preview').style
.display
= 'none';
106 document
.getElementById('upload_direct_download').style
.display
= 'none';
110 function show_upload_progression (percentage
, speed
, time_left
)
112 document
.getElementById('uploaded_percentage').innerHTML
= percentage
;
113 document
.getElementById('uploaded_speed').innerHTML
= speed
;
114 document
.getElementById('uploaded_time').innerHTML
= time_left
;
115 document
.title
= 'Jirafeau - ' + percentage
;
118 function hide_upload_progression ()
120 document
.getElementById('uploaded_percentage').style
.display
= 'none';
121 document
.getElementById('uploaded_speed').style
.display
= 'none';
122 document
.getElementById('uploaded_time').style
.display
= 'none';
123 document
.title
= 'Jirafeau';
126 function upload_progress (e
)
128 if (!e
.lengthComputable
)
131 // Init time estimation if needed
132 if (upload_time_estimation_total_size
== 0)
133 upload_time_estimation_total_size
= e
.total
;
135 // Compute percentage
136 var p
= Math
.round (e
.loaded
* 100 / e
.total
);
139 p_str
= p
.toString() + '%';
140 // Update estimation speed
141 upload_time_estimation_add(e
.loaded
);
143 var speed_str
= upload_time_estimation_speed_string();
144 speed_str
= upload_speed_refresh_limiter(speed_str
);
146 var time_str
= chrono_update(upload_time_estimation_time());
148 show_upload_progression (p_str
, speed_str
, time_str
);
151 function control_selected_file_size(max_size
, error_str
)
153 f_size
= document
.getElementById('file_select').files
[0].size
;
154 if (max_size
> 0 && f_size
> max_size
* 1024 * 1024)
156 pop_failure(error_str
);
157 document
.getElementById('send').style
.display
= 'none';
161 document
.getElementById('options').style
.display
= '';
162 document
.getElementById('send').style
.display
= '';
163 document
.getElementById('error_pop').style
.display
= 'none';
167 function pop_failure (e
)
169 var text
= "An error occured";
170 if (typeof e
!== 'undefined')
172 text
= "<p>" + text
+ "</p>";
173 document
.getElementById('error_pop').innerHTML
= e
;
175 document
.getElementById('uploading').style
.display
= 'none';
176 document
.getElementById('error_pop').style
.display
= '';
177 document
.getElementById('upload').style
.display
= '';
178 document
.getElementById('send').style
.display
= '';
181 function classic_upload (url
, file
, time
, password
, one_time
, upload_password
)
183 // Delay time estimation init as we can't have file size
184 upload_time_estimation_init(0);
186 var req
= new XMLHttpRequest ();
187 req
.upload
.addEventListener ("progress", upload_progress
, false);
188 req
.addEventListener ("error", pop_failure
, false);
189 req
.addEventListener ("abort", pop_failure
, false);
190 req
.onreadystatechange = function ()
192 if (req
.readyState
== 4 && req
.status
== 200)
194 var res
= req
.responseText
;
200 res
= res
.split ("\n");
204 if (time
== 'minute')
205 d
.setSeconds (d
.getSeconds() + 60);
206 else if (time
== 'hour')
207 d
.setSeconds (d
.getSeconds() + 3600);
208 else if (time
== 'day')
209 d
.setSeconds (d
.getSeconds() + 86400);
210 else if (time
== 'week')
211 d
.setSeconds (d
.getSeconds() + 604800);
212 else if (time
== 'month')
213 d
.setSeconds (d
.getSeconds() + 2419200);
214 else if (time
== 'year')
215 d
.setSeconds (d
.getSeconds() + 29030400);
218 show_link (url
, res
[0], res
[1], res
[2], d
.toString());
221 show_link (url
, res
[0], res
[1], res
[2]);
224 req
.open ("POST", url
+ 'script.php' , true);
226 var form
= new FormData();
227 form
.append ("file", file
);
229 form
.append ("time", time
);
231 form
.append ("key", password
);
233 form
.append ("one_time_download", '1');
234 if (upload_password
.length
> 0)
235 form
.append ("upload_password", upload_password
);
240 function check_html5_file_api ()
242 if (window
.File
&& window
.FileReader
&& window
.FileList
&& window
.Blob
)
247 var async_global_transfered
= 0;
248 var async_global_url
= '';
249 var async_global_file
;
250 var async_global_ref
= '';
251 var async_global_max_size
= 0;
252 var async_global_time
;
253 var async_global_transfering
= 0;
255 function async_upload_start (url
, max_size
, file
, time
, password
, one_time
, upload_password
)
257 async_global_transfered
= 0;
258 async_global_url
= url
;
259 async_global_file
= file
;
260 async_global_max_size
= max_size
;
261 async_global_time
= time
;
263 var req
= new XMLHttpRequest ();
264 req
.addEventListener ("error", pop_failure
, false);
265 req
.addEventListener ("abort", pop_failure
, false);
266 req
.onreadystatechange = function ()
268 if (req
.readyState
== 4 && req
.status
== 200)
270 var res
= req
.responseText
;
276 res
= res
.split ("\n");
277 async_global_ref
= res
[0];
279 async_upload_push (code
);
282 req
.open ("POST", async_global_url
+ 'script.php?init_async' , true);
284 var form
= new FormData();
285 form
.append ("filename", async_global_file
.name
);
286 form
.append ("type", async_global_file
.type
);
288 form
.append ("time", time
);
290 form
.append ("key", password
);
292 form
.append ("one_time_download", '1');
293 if (upload_password
.length
> 0)
294 form
.append ("upload_password", upload_password
);
296 // Start time estimation
297 upload_time_estimation_init(async_global_file
.size
);
302 function async_upload_progress (e
)
304 if (!e
.lengthComputable
&& async_global_file
.size
!= 0)
307 // Compute percentage
308 var p
= Math
.round ((e
.loaded
+ async_global_transfered
) * 100 / (async_global_file
.size
));
311 p_str
= p
.toString() + '%';
312 // Update estimation speed
313 upload_time_estimation_add(e
.loaded
+ async_global_transfered
);
315 var speed_str
= upload_time_estimation_speed_string();
316 speed_str
= upload_speed_refresh_limiter(speed_str
);
318 var time_str
= chrono_update(upload_time_estimation_time());
320 show_upload_progression (p_str
, speed_str
, time_str
);
323 function async_upload_push (code
)
325 if (async_global_transfered
== async_global_file
.size
)
327 hide_upload_progression ();
328 async_upload_end (code
);
331 var req
= new XMLHttpRequest ();
332 req
.upload
.addEventListener ("progress", async_upload_progress
, false);
333 req
.addEventListener ("error", pop_failure
, false);
334 req
.addEventListener ("abort", pop_failure
, false);
335 req
.onreadystatechange = function ()
337 if (req
.readyState
== 4 && req
.status
== 200)
339 var res
= req
.responseText
;
345 res
= res
.split ("\n");
347 async_global_transfered
= async_global_transfering
;
348 async_upload_push (code
);
351 req
.open ("POST", async_global_url
+ 'script.php?push_async' , true);
353 var chunk_size
= parseInt (async_global_max_size
* 0.50);
354 var start
= async_global_transfered
;
355 var end
= start
+ chunk_size
;
356 if (end
>= async_global_file
.size
)
357 end
= async_global_file
.size
;
358 var blob
= async_global_file
.slice (start
, end
);
359 async_global_transfering
= end
;
361 var form
= new FormData();
362 form
.append ("ref", async_global_ref
);
363 form
.append ("data", blob
);
364 form
.append ("code", code
);
368 function async_upload_end (code
)
370 var req
= new XMLHttpRequest ();
371 req
.addEventListener ("error", pop_failure
, false);
372 req
.addEventListener ("abort", pop_failure
, false);
373 req
.onreadystatechange = function ()
375 if (req
.readyState
== 4 && req
.status
== 200)
377 var res
= req
.responseText
;
383 res
= res
.split ("\n");
384 if (async_global_time
!= 'none')
387 if (async_global_time
== 'minute')
388 d
.setSeconds (d
.getSeconds() + 60);
389 else if (async_global_time
== 'hour')
390 d
.setSeconds (d
.getSeconds() + 3600);
391 else if (async_global_time
== 'day')
392 d
.setSeconds (d
.getSeconds() + 86400);
393 else if (async_global_time
== 'week')
394 d
.setSeconds (d
.getSeconds() + 604800);
395 else if (async_global_time
== 'month')
396 d
.setSeconds (d
.getSeconds() + 2419200);
397 else if (async_global_time
== 'year')
398 d
.setSeconds (d
.getSeconds() + 29030400);
401 show_link (async_global_url
, res
[0], res
[1], res
[2], d
.toString());
404 show_link (async_global_url
, res
[0], res
[1], res
[2]);
407 req
.open ("POST", async_global_url
+ 'script.php?end_async' , true);
409 var form
= new FormData();
410 form
.append ("ref", async_global_ref
);
411 form
.append ("code", code
);
415 function upload (url
, max_size
)
417 if (check_html5_file_api ()
418 && document
.getElementById('file_select').files
[0].size
>= max_size
)
420 async_upload_start (url
,
422 document
.getElementById('file_select').files
[0],
423 document
.getElementById('select_time').value
,
424 document
.getElementById('input_key').value
,
425 document
.getElementById('one_time_download').checked
,
426 document
.getElementById('upload_password').value
432 document
.getElementById('file_select').files
[0],
433 document
.getElementById('select_time').value
,
434 document
.getElementById('input_key').value
,
435 document
.getElementById('one_time_download').checked
,
436 document
.getElementById('upload_password').value
441 var upload_time_estimation_total_size
= 42;
442 var upload_time_estimation_transfered_size
= 42;
443 var upload_time_estimation_transfered_date
= 42;
444 var upload_time_estimation_moving_average_speed
= 42;
446 function upload_time_estimation_init(total_size
)
448 upload_time_estimation_total_size
= total_size
;
449 upload_time_estimation_transfered_size
= 0;
450 upload_time_estimation_moving_average_speed
= 0;
452 upload_time_estimation_transfered_date
= d
.getTime();
455 function upload_time_estimation_add(total_transfered_size
)
457 // Let's compute the current speed
459 var speed
= upload_time_estimation_moving_average_speed
;
460 if (d
.getTime() - upload_time_estimation_transfered_date
!= 0)
461 speed
= (total_transfered_size
- upload_time_estimation_transfered_size
)
462 / (d
.getTime() - upload_time_estimation_transfered_date
);
463 // Let's compute moving average speed on 30 values
464 var m
= (upload_time_estimation_moving_average_speed
* 29 + speed
) / 30;
465 // Update global values
466 upload_time_estimation_transfered_size
= total_transfered_size
;
467 upload_time_estimation_transfered_date
= d
.getTime();
468 upload_time_estimation_moving_average_speed
= m
;
471 function upload_time_estimation_speed_string()
474 var s
= upload_time_estimation_moving_average_speed
* 1000;
482 else if (s
< 1000000)
484 res
= Math
.floor(s
/100) / 10;
489 res
= Math
.floor(s
/100000) / 10;
495 return res
.toString() + ' ' + scale
;
498 function milliseconds_to_time_string (milliseconds
)
500 function numberEnding (number
) {
501 return (number
> 1) ? 's' : '';
504 var temp
= Math
.floor(milliseconds
/ 1000);
505 var years
= Math
.floor(temp
/ 31536000);
507 return years
+ ' year' + numberEnding(years
);
509 var days
= Math
.floor((temp
%= 31536000) / 86400);
511 return days
+ ' day' + numberEnding(days
);
513 var hours
= Math
.floor((temp
%= 86400) / 3600);
515 return hours
+ ' hour' + numberEnding(hours
);
517 var minutes
= Math
.floor((temp
%= 3600) / 60);
519 return minutes
+ ' minute' + numberEnding(minutes
);
521 var seconds
= temp
% 60;
523 return seconds
+ ' second' + numberEnding(seconds
);
525 return 'less than a second';
528 function upload_time_estimation_time()
530 // Estimate remaining time
531 if (upload_time_estimation_moving_average_speed
== 0)
533 return (upload_time_estimation_total_size
- upload_time_estimation_transfered_size
)
534 / upload_time_estimation_moving_average_speed
;
537 var chrono_last_update
= 0;
538 var chrono_time_ms
= 0;
539 var chrono_time_ms_last_update
= 0;
540 function chrono_update(time_ms
)
544 // Don't update too often
545 if (d
.getTime() - chrono_last_update
< 3000 &&
546 chrono_time_ms_last_update
> 0)
547 chrono
= chrono_time_ms
;
550 chrono_last_update
= d
.getTime();
551 chrono_time_ms
= time_ms
;
553 chrono_time_ms_last_update
= d
.getTime();
556 // Adjust chrono for smooth estimation
557 chrono
= chrono
- (d
.getTime() - chrono_time_ms_last_update
);
559 // Let's update chronometer
562 time_str
= milliseconds_to_time_string (chrono
);
566 var upload_speed_refresh_limiter_last_update
= 0;
567 var upload_speed_refresh_limiter_last_value
= '';
568 function upload_speed_refresh_limiter(speed_str
)
571 if (d
.getTime() - upload_speed_refresh_limiter_last_update
> 1500)
573 upload_speed_refresh_limiter_last_value
= speed_str
;
574 upload_speed_refresh_limiter_last_update
= d
.getTime();
576 return upload_speed_refresh_limiter_last_value
;