File Coverage

blib/lib/Apache/AxKit/Plugin/Upload.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Apache::AxKit::Plugin::Upload;
2 1     1   6912 use strict;
  1         3  
  1         45  
3              
4 1     1   1604 use Apache::Constants qw(:common);
  0            
  0            
5             use Number::Format;
6             use Fcntl qw(LOCK_EX LOCK_NB O_RDWR O_CREAT);
7             use IO::Handle;
8              
9             BEGIN {
10             our $VERSION = 0.2;
11             }
12              
13             eval {
14             require Time::HiRes;
15             };
16             if (!$@) {
17             use Time::HiRes;
18             }
19              
20             my ($start, $sizetotal, $file, $location, $nf, $custom, $running, $lock);
21              
22             sub print_html {
23             my ($now, $sizedone) = @_;
24             my $elapsed = $now-$start;
25              
26             my $todo = 0;
27             $todo = ($sizetotal - $sizedone) * $elapsed / $sizedone if $sizedone > 0;
28              
29             my $percent = 0;
30             $percent = int($sizedone*100/$sizetotal) if $sizetotal > 0;
31             my $showpercent = ($percent?$percent:1);
32             #warn("printing: $percent");
33              
34             my $speed = 0;
35             $speed = $nf->format_bytes($sizedone / $elapsed,1) if $elapsed > 0;
36              
37             $sizedone = $nf->format_bytes($sizedone,1);
38             my $sizetotal = $nf->format_bytes($sizetotal,1);
39             $elapsed = sprintf("%i:%02i",int($elapsed/60),$elapsed%60);
40             $todo = sprintf("%i:%02i",int($todo/60),$todo%60);
41              
42             local(*FH);
43             open(FH, ">$file.tmp") || warn("could not open $file.tmp: $!");
44              
45             if (!$custom && $percent == 100) {
46             print FH << "EOF";
47            
48            
49             Upload Status
50            
51            
52            
53            
54             $percent\%
55            
56            
57            
58            
 
59            
60            
61            
62            
63            
64              
65             $sizedone / $sizetotal, ${speed}b/s, $todo
66            
67            
68            
69            
70            
71             EOF
72             } else {
73             print FH << "EOF";
74            
75            
76             Upload Status
77            
78            
79            
80            
81            
82             $percent\%
83            
84            
85            
86            
 
87            
88            
89            
90            
91            
92              
93             $sizedone / $sizetotal, ${speed}b/s, $todo
94            
95            
96            
97            
98             EOF
99             }
100             rename("$file.tmp",$file);
101             }
102              
103             sub init {
104             my ($r,$upload_id) = @_;
105             my $destdir = $r->dir_config('AxUploadStatusDir') || return 0;
106             $destdir = $r->document_root.'/'.$destdir if substr($destdir,0,1) ne '/';
107             my $destloc = $r->dir_config('AxUploadStatusLocation') || return 0;
108             my $format = lc($r->dir_config('AxUploadFormat')) || 'html';
109             $location = "$destloc/$upload_id.$format";
110             $file = "$destdir/$upload_id.$format";
111             local(*FH);
112             open(FH, ">$file.tmp") || warn("could not open $file.tmp: $!");
113             print FH << "EOF";
114            
115            
116             Upload Status
117            
118            
119            
120              
121            
122            
123             EOF
124             close(FH);
125             rename("$file.tmp",$file);
126             }
127              
128             sub progress {
129             my ($done, $total, $message) = @_;
130             my $now = time();
131             my $elapsed = $now-$start;
132              
133             my $todo = 0;
134             $todo = ($total - $done) * $elapsed / $done if $done > 0;
135            
136             my $percent = 0;
137             $percent = int($done*100/$total) if $total > 0;
138             my $showpercent = ($percent?$percent:1);
139            
140             $todo = sprintf("%i:%02i",int($todo/60),$todo%60);
141            
142             local(*FH);
143             open(FH, ">$file.tmp") || warn("could not open $file.tmp: $!");
144             if ($percent == 100) {
145             print FH << "EOF";
146            
147            
148             Upload Status
149            
150            
151            
152            
153             $percent\%
154            
155            
156            
157            
 
158            
159            
160            
161            
162            
163              
164             $message
165            
166            
167            
168            
169            
170             EOF
171             close($lock);
172             } else {
173             print FH << "EOF";
174            
175            
176             Upload Status
177            
178            
179            
180            
181            
182             $percent\%
183            
184            
185            
186            
 
187            
188            
189            
190            
191            
192              
193             $message
194            
195            
196            
197            
198             EOF
199             }
200             close(FH);
201             rename("$file.tmp",$file);
202             }
203              
204             sub is_running {
205             my ($r,$upload_id) = @_;
206             return 0 if ($running eq $upload_id);
207             my $destdir = $r->dir_config('AxUploadStatusDir') || return 0;
208             $destdir = $r->document_root.'/'.$destdir if substr($destdir,0,1) ne '/';
209             my $format = lc($r->dir_config('AxUploadFormat')) || 'html';
210             $file = $destdir."/".$upload_id.".".$format;
211             local (*FH);
212             sysopen(FH,$file.".lck",O_RDWR) || return undef;
213             my $unlocked = flock(FH,LOCK_EX|LOCK_NB);
214             close(FH);
215             return !$unlocked;
216             }
217              
218             sub upload_handler_html {
219             my ($upload, $buf, $len, $hook_data) = @_;
220             my ($sizedone, $lasttime) = @$hook_data;
221             my $now = time();
222              
223             $sizedone += $len;
224             $$hook_data[0] = $sizedone;
225              
226             #warn("now: $now, done: $sizedone, last: $lasttime");
227             return if (int($now) == $lasttime);
228             $$hook_data[1] = int($now);
229              
230             print_html($now, $sizedone);
231             }
232              
233             sub handler {
234             my ($r) = @_;
235              
236             my %args = $r->args;
237             my $upload_id = $args{'axkit_upload_id'};
238             $running = '';
239              
240             my $destdir = $r->dir_config('AxUploadStatusDir') || return OK;
241             $destdir = $r->document_root.'/'.$destdir if substr($destdir,0,1) ne '/';
242             my $destloc = $r->dir_config('AxUploadStatusLocation') || return OK;
243             my $format = lc($r->dir_config('AxUploadFormat')) || 'html';
244             $custom = $r->dir_config('AxUploadCustom');
245             $file = "$destdir/$upload_id.$format";
246             $location = "$destloc/$upload_id.$format";
247             return OK unless $upload_id;
248             return OK unless $r->method eq 'POST';
249             $lock = new IO::Handle;
250             sysopen($lock,$file.".lck",O_RDWR|O_CREAT) || return OK;
251             my $unlocked = flock($lock,LOCK_EX|LOCK_NB);
252             return OK if !$unlocked;
253              
254             $running = $upload_id;
255             # from Apache::RequestNotes
256             my $maxsize = $r->dir_config('MaxPostSize') || 1024;
257             my $uploads = $r->dir_config('DisableUploads') =~ m/Off/i ? 0 : 1;
258              
259             $nf = new Number::Format(split(/ /,$r->dir_config('AxUploadNumberFormat')));
260              
261             $sizetotal = $r->header_in('Content-Length');
262             $start = time();
263             AxKit::Debug(3,"[Upload] managing upload: $sizetotal bytes, status in $destdir/$upload_id.$format");
264              
265             print_html($start, 0);
266              
267             my $apr = Apache::Request->instance($r,
268             POST_MAX => $maxsize,
269             DISABLE_UPLOADS => $uploads,
270             HOOK_DATA => [ $file, $location, $nf, $sizetotal, 0, $start, -1 ],
271             UPLOAD_HOOK => \&upload_handler_html,
272             );
273             $apr->parse;
274              
275             print_html(time(), $sizetotal);
276              
277             $start = time();
278             return OK;
279             }
280              
281             1;
282             __END__