JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added progress-bar uploader.php
[wfpl.git] / uploader.php
1 <?php
2
3 require_once('code/wfpl/template.php');
4 require_once('code/wfpl/encode.php');
5 require_once('code/wfpl/session.php');
6 require_once('code/wfpl/upload.php'); # FIXME for path_to() which should be somewhere else
7
8 # This function is for making an uploader with a progress bar.
9 #
10 # Parameter: (optional)
11 #     progress_url: URL javascript should use to get progress updates (defaults to this_url() with the query string replaced with ?wfpl_upload_progress=FILENAME (where FILENAME is the first parameter.))
12 #
13 # You must also set $GLOBALS['wfpl_uploader_port'] to an available port for the upload receiver to run on.
14 #
15 # Returns: (an array containing)
16 #     html
17 #     css
18 #     javascript
19 #     filename
20
21 function uploader($progress_url = '') {
22         if(!$filename) {
23                 $filename = strtolower(session_generate_key());
24         }
25         if(!$progress_url) {
26                 $progress_url = this_url();
27                 $q = strpos($progress_url, '?');
28                 if($q) {
29                         $progress_url = substr($progress_url, 0, $q);
30                 }
31                 $progress_url .= '?wfpl_upload_progress=' . enc_url_val($filename);
32         }
33         if(!$GLOBALS['wfpl_uploader_host']) {
34                 $GLOBALS['wfpl_uploader_host'] = this_host();
35         }
36
37         $html = new tem();
38         $html->load('code/wfpl/uploader/uploader.html');
39         $html->set('filename', $filename);
40         $html->set('host', $GLOBALS['wfpl_uploader_host']);
41         $html->set('port', $GLOBALS['wfpl_uploader_port']);
42         $html->show('main');
43         $html = $html->get('main');
44
45         $css = read_whole_file('code/wfpl/uploader/uploader.css');
46
47         $javascript = new tem();
48         $javascript->load('code/wfpl/uploader/progress.js');
49         $javascript->set('url', $progress_url);
50         $javascript = $javascript->run();
51
52         uploader_daemon_start($GLOBALS['wfpl_uploader_port']);
53
54         return array($html, $css, $javascript, $filename);
55 }
56
57 function uploader_move($tmp_filename, $filename) {
58         $tmp_path = $GLOBALS['wfpl_uploader_path'] . '/partial/' . $tmp_filename;
59         $out_path = $GLOBALS['wfpl_uploader_path'] . '/' . $filename;
60         unlink($GLOBALS['wfpl_uploader_path'] . '/progress/' . $tmp_filename);
61         rename($tmp_path, $out_path);
62 }
63
64 # start a daemon to accept file uploads and give progress indicators
65 # if the port is used (eg if the daemon is already running) this will do nothing.
66 function uploader_daemon_start($port) {
67         exec(path_to('tcpserver') . " -q -R -H -llocalhost 0 $port " . path_to('perl') . ' code/wfpl/uploader/daemon.pl ' . $GLOBALS['wfpl_uploader_path'] . ' >/dev/null 2>/dev/null < /dev/null &');
68 }
69
70 /* call this to respond to the javascript async request for progress on the upload */
71 function wfpl_uploader_progress() {
72         if(!isset($_REQUEST['wfpl_upload_progress'])) {
73                 return;
74         }
75
76         # allow this script to run for 8 hours
77         set_time_limit(28800);
78
79         $file = $_REQUEST['wfpl_upload_progress'];
80         $file = strtolower($file);
81         $file = ereg_replace('[^a-z0-9.-]', '_', $file);
82         $file = ereg_replace('^[.-]', '_', $file);
83         $file = $GLOBALS['wfpl_uploader_path'] . "/progress/$file";
84         
85         $waited = 0;
86         while(!file_exists($file)) {
87                 usleep(500000);
88                 ++$waited;
89                 if($waited > 100) {
90                         return;
91                 }
92         }
93
94         $progress_sent = 0;
95         while(true) {
96                 clearstatcache();
97                 $stats = stat($file);
98                 if($stats !== false) {
99                         $progress = $stats['size'];
100                         if($progress > $progress_sent) {
101                                 print(substr('............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................', 0, $progress - $progress_sent));
102                                 flush();
103                                 $progress_sent = $progress;
104                                 if($progress == 1000) {
105                                         return;
106                                 }
107                         }
108                 }
109                 usleep(500000); # wait half a second
110         }
111 }