JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
metaform: fix download_tar() (stylus not less)
[wfpl.git] / uploader.php
1 <?php
2
3 #  Copyright (C) 2007 Jason Woofenden
4 #
5 #  This program is free software: you can redistribute it and/or modify
6 #  it under the terms of the GNU General Public License as published by
7 #  the Free Software Foundation, either version 3 of the License, or
8 #  (at your option) any later version.
9 #  
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 General Public License for more details.
14 #  
15 #  You should have received a copy of the GNU General Public License
16 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
19 require_once(__DIR__ . '/template.php');
20 require_once(__DIR__ . '/encode.php');
21 require_once(__DIR__ . '/session.php');
22 require_once(__DIR__ . '/upload.php'); # FIXME for path_to() which should be somewhere else
23
24 # This function is for making an uploader with a progress bar.
25 #
26 # Parameter: (optional)
27 #     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.))
28 #
29 # You must also set $GLOBALS['wfpl_uploader_port'] to an available port for the upload receiver to run on.
30 #
31 # Returns: (an array containing)
32 #     html
33 #     css
34 #     javascript
35 #     filename
36
37 function uploader($progress_url = '') {
38         if(!$filename) {
39                 $filename = strtolower(session_generate_key());
40         }
41         if(!$progress_url) {
42                 $progress_url = this_url();
43                 $q = strpos($progress_url, '?');
44                 if($q) {
45                         $progress_url = substr($progress_url, 0, $q);
46                 }
47                 $progress_url .= '?wfpl_upload_progress=' . enc_url_val($filename);
48         }
49         if(!$GLOBALS['wfpl_uploader_host']) {
50                 $GLOBALS['wfpl_uploader_host'] = this_host();
51         }
52
53         $html = new tem();
54         $html->load('code/wfpl/uploader/uploader.html');
55         $html->set('filename', $filename);
56         $html->set('host', $GLOBALS['wfpl_uploader_host']);
57         $html->set('port', $GLOBALS['wfpl_uploader_port']);
58         $html->show('main');
59         $html = $html->get('main');
60
61         $css = read_whole_file('code/wfpl/uploader/uploader.css');
62
63         $javascript = new tem();
64         $javascript->load('code/wfpl/uploader/progress.js');
65         $javascript->set('url', $progress_url);
66         $javascript = $javascript->run();
67
68         uploader_daemon_start($GLOBALS['wfpl_uploader_port']);
69
70         return array($html, $css, $javascript, $filename);
71 }
72
73 function uploader_move($tmp_filename, $filename) {
74         $tmp_path = $GLOBALS['wfpl_uploader_path'] . '/partial/' . $tmp_filename;
75         $out_path = $GLOBALS['wfpl_uploader_path'] . '/' . $filename;
76         unlink($GLOBALS['wfpl_uploader_path'] . '/progress/' . $tmp_filename);
77         rename($tmp_path, $out_path);
78 }
79
80 # start a daemon to accept file uploads and give progress indicators
81 # if the port is used (eg if the daemon is already running) this will do nothing.
82 function uploader_daemon_start($port) {
83         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 &');
84 }
85
86 /* call this to respond to the javascript async request for progress on the upload */
87 function wfpl_uploader_progress() {
88         if(!isset($_REQUEST['wfpl_upload_progress'])) {
89                 return;
90         }
91
92         # allow this script to run for 8 hours
93         set_time_limit(28800);
94
95         $file = $_REQUEST['wfpl_upload_progress'];
96         $file = strtolower($file);
97         $file = ereg_replace('[^a-z0-9.-]', '_', $file);
98         $file = ereg_replace('^[.-]', '_', $file);
99         $file = $GLOBALS['wfpl_uploader_path'] . "/progress/$file";
100         
101         $waited = 0;
102         while(!file_exists($file)) {
103                 usleep(500000);
104                 ++$waited;
105                 if($waited > 100) {
106                         return;
107                 }
108         }
109
110         $progress_sent = 0;
111         while(true) {
112                 clearstatcache();
113                 $stats = stat($file);
114                 if($stats !== false) {
115                         $progress = $stats['size'];
116                         if($progress > $progress_sent) {
117                                 print(substr('............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................', 0, $progress - $progress_sent));
118                                 flush();
119                                 $progress_sent = $progress;
120                                 if($progress == 1000) {
121                                         return;
122                                 }
123                         }
124                 }
125                 usleep(500000); # wait half a second
126         }
127 }