File Coverage

blib/lib/MIME/Lite/HTML.pm
Criterion Covered Total %
statement 254 342 74.2
branch 90 170 52.9
condition 60 106 56.6
subroutine 28 31 90.3
pod 11 21 52.3
total 443 670 66.1


line stmt bran cond sub pod time code
1             package MIME::Lite::HTML;
2              
3             # module MIME::Lite::HTML : Provide routine to transform a HTML page in
4             # a MIME::Lite mail
5             # Copyright 2001/2011 A.Barbet alian@cpan.org. All rights reserved.
6              
7             # $Log: HTML.pm,v $
8             # Revision 1.24 2011/10/07 11:27:42 alian
9             #
10              
11             # Revision 1.24 2011/10/07 11:27:42 alian
12             # - Fix rt#67695 Add feature: "ExternImages" parameter to constructor (tbriggs)
13             # - Fix rt#68303 Outdated COPYING file
14             # - Fix rt#52907 CSS (and likely other) links match double-quote only
15             # - Fix rt#41447 Unable to call replace function
16             # - Fix rt#40164 Removing script code often fails
17             # - Fix bug when HTTP result is gzip format (use decoded_content, tks to E.Bataille
18             #
19             # Revision 1.23 2008/10/14 11:27:42 alian
20             # - Fix rt#36006: cid has no effect on background images
21             # - Fix rt#36005: include_javascript does not remove closing tag ""
22             # - Fix rt#29033: eliminate nested subs
23              
24             # Revision 1.22 2006/09/06 14:46:42 alian
25             # - Fix rt#19656: unknown URI schemes cause rewrite to fail
26             # - Fix rt#17385: make test semi-panics
27             # - Fix rt#7841: Text-Only Encoding Ignored
28             # - Fix rt#21339: no license or copyright information provided
29             # - Fix rt#19655: include_css is far too aggressive
30             #
31             # Revision 1.21 2004/04/15 22:59:33 alian
32             # fix for 1.20 and bad ref for tests
33             #
34             # Revision 1.20 2004/04/14 21:26:51 alian
35             # - fix error on last version
36             #
37             # Revision 1.19 2004/03/16 15:18:57 alian
38             # - Add Url param in new for direct call of parse & send
39             # - Correct a problem in parsing of html elem background
40             # - Re-indent some methods
41             #
42             # Revision 1.18 2003/08/08 09:37:42 alian
43             # Fix test case and cid method
44             #
45             # Revision 1.17 2003/08/07 16:55:08 alian
46             # - Fix test case (hostname)
47             # - Update POD documentation
48             #
49             # Revision 1.16 2003/08/07 00:07:57 alian
50             # - Use pack for include type == cid: RFC says no '/'.
51             # Tks to Cláudio Valente for report.
52             # - Add a __END__ statement before POD documentation.
53             #
54             # Revision 1.15 2002/10/19 17:54:32 alian
55             # - Correct bug with relative anchor '/'. Tks to Keith D. Zimmerman for
56             # report.
57             #
58             # See Changes files for older changes
59              
60 3     3   201553 use LWP::UserAgent;
  3         215117  
  3         164  
61 3     3   4257 use HTML::LinkExtor;
  3         82170  
  3         189  
62 3     3   3051 use URI::URL;
  3         13939  
  3         181  
63 3     3   4341 use MIME::Lite;
  3         40130  
  3         88  
64 3     3   17 use strict;
  3         8  
  3         97  
65 3     3   18 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  3         6  
  3         425  
66              
67             require Exporter;
68              
69             @ISA = qw(Exporter);
70             @EXPORT = qw();
71             $VERSION = ('$Revision: 1.24 $ ' =~ /(\d+\.\d+)/)[0];
72              
73             my $LOGINDETAILS;
74              
75              
76             #------------------------------------------------------------------------------
77             # redefine get_basic_credentials
78             #------------------------------------------------------------------------------
79             {
80             package RequestAgent;
81 3     3   16 use vars qw(@ISA);
  3         5  
  3         16111  
82             @ISA = qw(LWP::UserAgent);
83              
84             sub new {
85 68     68   1316 my $self = LWP::UserAgent::new(@_);
86 68         197185 $self;
87             }
88              
89             sub get_basic_credentials {
90 0     0   0 my($self, $realm, $uri) = @_;
91             # Use parameter of MIME-Lite-HTML, key LoginDetails
92 0 0       0 if (defined $LOGINDETAILS) { return split(':', $LOGINDETAILS, 2); }
  0 0       0  
93             # Ask user on STDIN
94             elsif (-t) {
95 0         0 my $netloc = $uri->host_port;
96 0         0 print "Enter username for $realm at $netloc: ";
97 0         0 my $user = ;
98 0         0 chomp($user);
99             # 403 if no user given
100 0 0       0 return (undef, undef) unless length $user;
101 0         0 print "Password: ";
102 0         0 system("stty -echo");
103 0         0 my $password = ;
104 0         0 system("stty echo");
105 0         0 print "\n"; # because we disabled echo
106 0         0 chomp($password);
107 0         0 return ($user, $password);
108             }
109             # Damm we got 403 with CGI (use param LoginDetails) ...
110 0         0 else { return (undef, undef) }
111             }
112             }
113              
114             #------------------------------------------------------------------------------
115             # new
116             #------------------------------------------------------------------------------
117             sub new {
118 68     68 1 653002 my $class = shift;
119 68         268 my $self = {};
120 68         546 bless $self, $class;
121 68         1001 my %param = @_;
122             # Agent name
123 68         675 $self->{_AGENT} = new RequestAgent;
124 68         522 $self->{_AGENT}->agent("MIME-Lite-HTML $VERSION");
125 68         5763 $self->{_AGENT}->from('mime-lite-html@alianwebserver.com' );
126              
127             # remove javascript code or no ?
128 68 50       4200 if ($param{'remove_jscript'}) {
129 0         0 $self->{_remove_jscript} = 1;
130 68         202 } else { $self->{_remove_jscript} = 0; }
131              
132             # Set debug level
133 68 100       661 if ($param{'Debug'}) {
134 64         167 $self->{_DEBUG} = 1;
135 64         357 delete $param{'Debug'};
136             }
137              
138             # Set Login information
139 68 50       905 if ($param{'LoginDetails'}) {
140 0         0 $LOGINDETAILS = $param{'LoginDetails'};
141 0         0 delete $param{'LoginDetails'};
142             }
143             # Set type of include to do
144 68 100       1030 if ($param{'IncludeType'}) {
  1         9  
145 67 50 100     1279 die "IncludeType must be in 'extern', 'cid' or 'location'\n" if
      66        
146             ( ($param{'IncludeType'} ne 'extern') and
147             ($param{'IncludeType'} ne 'cid') and
148             ($param{'IncludeType'} ne 'location'));
149 67         309 $self->{_include} = $param{'IncludeType'};
150 67         204 delete $param{'IncludeType'};
151             } # Defaut type: use a Content-Location field
152             else {$self->{_include}='location';}
153            
154             # Get regexps for images that should be external
155 68 50       313 if (defined $param{'ExternImages'}) {
156 0         0 $self->{_externimages} = $param{'ExternImages'};
157             }
158              
159             ## Added by Michalis@linuxmail.org to manipulate non-us mails
160 68 50       198 if ($param{'TextCharset'}) {
161 0         0 $self->{_textcharset}=$param{'TextCharset'};
162 0         0 delete $param{'TextCharset'};
163 68         242 } else { $self->{_textcharset}='iso-8859-1'; }
164 68 50       149 if ($param{'HTMLCharset'}) {
165 0         0 $self->{_htmlcharset}=$param{'HTMLCharset'};
166 0         0 delete $param{'HTMLCharset'};
167 68         220 } else { $self->{_htmlcharset}='iso-8859-1'; }
168 68 50       198 if ($param{'TextEncoding'}) {
169 0         0 $self->{_textencoding}=$param{'TextEncoding'};
170 0         0 delete $param{'TextEncoding'};
171 68         188 } else { $self->{_textencoding}='7bit'; }
172 68 50       144 if ($param{'HTMLEncoding'}) {
173 0         0 $self->{_htmlencoding}=$param{'HTMLEncoding'};
174 0         0 delete $param{'HTMLEncoding'};
175 68         385 } else { $self->{_htmlencoding}='quoted-printable'; }
176             ## End. Default values remain as they were initially set.
177             ## No need to change existing scripts if you send US-ASCII.
178             ## If you DON't send us-ascii, you wouldn't be able to use
179             ## MIME::Lite::HTML anyway :-)
180              
181             # Set proxy to use to get file
182 68 50       281 if ($param{'Proxy'}) {
183 0         0 $self->{_AGENT}->proxy('http',$param{'Proxy'}) ;
184 0 0       0 print "Set proxy for http : ", $param{'Proxy'},"\n"
185             if ($self->{_DEBUG});
186 0         0 delete $param{'Proxy'};
187             }
188              
189             # Set hash to use with template
190 68 50       322 if ($param{'HashTemplate'}) {
191 0         0 $param{'HashTemplate'} = ref($param{'HashTemplate'}) eq "HASH"
192 0 0       0 ? $param{'HashTemplate'} : %{$param{'HashTemplate'}};
193 0         0 $self->{_HASH_TEMPLATE}= $param{'HashTemplate'};
194 0         0 delete $param{'HashTemplate'};
195             }
196              
197             # Ok I hope I known what I do ;-)
198 68         908 MIME::Lite->quiet(1);
199              
200             # direct call of new parse & send
201 68         674 my $url;
202 68 50       803 if ($param{'Url'}) {
203 0         0 $url = $param{'Url'};
204 0         0 delete $param{'Url'};
205             }
206 68         208 $self->{_param} = \%param;
207 68 50       167 if ($url) {
208 0         0 my $m = $self->parse($url);
209 0         0 $m->send;
210             }
211              
212 68         207 return $self;
213             }
214              
215             #------------------------------------------------------------------------------
216             # absUrl
217             #------------------------------------------------------------------------------
218             sub absUrl($$) {
219             # rt 19656 : unknown URI schemes cause rewrite to fail
220 1656     1656 0 2555 my $rep = eval { URI::WithBase->new($_[0], $_[1])->abs; };
  1656         6335  
221 1656 100       414423 return ($rep ? $rep : $_[0]);
222             }
223              
224             # Replace in HTML link with image with cid:key
225             sub pattern_image_cid {
226 24     24 0 34 my $sel = shift;
227 24         112 return '
228             }
229             # Replace relative url for image with absolute
230             sub pattern_image {
231 48     48 0 249 return '
232             }
233              
234             sub pattern_href {
235 558     558 0 1561 my ($url,$balise, $sep)=@_;
236 558         9118 my $b=" $balise=\"$url\"";
237 558 50 33     9762 $b.=$sep if ($sep ne '"' and $sep ne "'");
238 558         53326 return $b;
239             }
240              
241             #------------------------------------------------------------------------------
242             # parse
243             #------------------------------------------------------------------------------
244             sub parse
245             {
246 63     63 1 20359 my($self,$url_page,$url_txt,$url1)=@_;
247 63         334 my ($type,@mail,$gabarit,$gabarit_txt,$racinePage);
248              
249             # Get content of $url_page with LWP
250 63 50 33     2785 if ($url_page && $url_page=~/^(https?|ftp|file|nntp):\/\//)
251 0         0 {
252 63 50       9004 print "Get ", $url_page,"\n" if $self->{_DEBUG};
253 63         1246 my $req = new HTTP::Request('GET' => $url_page);
254 63         30133 my $res = $self->{_AGENT}->request($req);
255 63 50       384164 if (!$res->is_success)
  0         0  
256 63         1285 {$self->set_err("Can't fetch $url_page (".$res->message.")");}
257             else {$gabarit = $res->content;}
258 63   33     2337 $racinePage=$url1 || $res->base;
259             }
260 0         0 else {$gabarit=$url_page;$racinePage=$url1;}
261              
262             # Get content of $url_txt with LWP if needed
263 63 100       35103 if ($url_txt)
264             {
265 42 100       281 if ($url_txt=~/^(https?|ftp|file|nntp):\/\//)
266 21         41 {
267 21 50       8391 print "Get ", $url_txt,"\n" if $self->{_DEBUG};
268 21         230 my $req2 = new HTTP::Request('GET' => $url_txt);
269 21         4991 my $res3 = $self->{_AGENT}->request($req2);
270 21 50       39837 if (!$res3->is_success)
  0         0  
271 21         428 {$self->set_err("Can't fetch $url_txt (".$res3->message.")");}
272             else {$gabarit_txt = $res3->content;}
273             }
274             else {$gabarit_txt=$url_txt;}
275             }
276 63 50       666 goto BUILD_MESSAGE unless $gabarit;
277              
278             # Get all multimedia part (img, flash) for later create a MIME part
279             # for each of them
280 63         1754 my $analyseur = HTML::LinkExtor->new;
281 63         11265 $analyseur->parse($gabarit);
282 63         80302 my @l = $analyseur->links;
283              
284             # Include external CSS files
285 63         1638 $gabarit = $self->include_css($gabarit,$racinePage);
286              
287             # Include external Javascript files
288 63         606 $gabarit = $self->include_javascript($gabarit,$racinePage);
289              
290             # Include form images
291 63         291 ($gabarit,@mail) = $self->input_image($gabarit,$racinePage);
292              
293             # Change target action for form
294 63         592 $gabarit = $self->link_form($gabarit,$racinePage);
295              
296             # Scan each part found by linkExtor
297 63         178 my (%images_read,%url_remplace);
298 63         684 foreach my $url (@l) {
299            
300 1584         14846 my $urlAbs = absUrl($$url[2],$racinePage);
301 1584         44621 chomp $urlAbs; # Sometime a strange cr/lf occur
302              
303             # Replace relative href found to absolute one
304 1584 100 66     62067 if ( ($$url[0] eq 'a') && ($$url[1] eq 'href') && ($$url[2]) &&
    50 66        
    100 33        
    50 66        
    50 100        
    100 33        
      33        
      33        
      66        
      33        
      33        
      33        
      66        
      66        
      66        
      100        
305             (($$url[2]!~m!^http://!) && # un lien non absolu
306             ($$url[2]!~m!^mailto:!) && # pas les mailto
307             ($$url[2]!~m!^\#!)) && # ni les ancres
308             (!$url_remplace{$urlAbs}) ) # ni les urls deja remplacees
309             {
310 513         109342 $gabarit=~s/\s href \s* = \s* [\"']? \Q$$url[2]\E ([\"'>])
  540         1562  
311             /pattern_href($urlAbs,"href",$1)/giemx;
312 513 50       7749 print "Replace ",$$url[2]," with ",$urlAbs,"\n"
313             if ($self->{_DEBUG});
314 513         113985 $url_remplace{$urlAbs}=1;
315             }
316              
317             # For frame & iframe
318             elsif ( (lc($$url[0] eq 'iframe') || lc($$url[0] eq 'frame')) &&
319             (lc($$url[1]) eq 'src') && ($$url[2]) )
320             {
321 0         0 $gabarit=~s/\s src \s* = \s* [\"']? \Q$$url[2]\E ([\"'>])
  0         0  
322             /pattern_href($urlAbs,"src",$1)/giemx;
323 0 0       0 print "Replace ",$$url[2]," with ",$urlAbs,"\n"
324             if ($self->{_DEBUG});
325 0         0 $url_remplace{$urlAbs}=1;
326             }
327              
328             # For background images
329             elsif ((lc($$url[1]) eq 'background') && ($$url[2])) {
330             # Replace relative url with absolute
331 18 100       99 my $v = ($self->{_include} eq 'cid') ?
332             "cid:".$self->cid($urlAbs) : $urlAbs;
333 18         981 $gabarit=~s/background \s* = \s* [\"']? \Q$$url[2]\E ([\"'>])
  18         46  
334             /pattern_href($v,"background",$1)/giemx;
335             # Exit with extern configuration, don't include image
336             # else add part to mail
337 18 100 100     148 if (($self->{_include} ne 'extern')&&(!$images_read{$urlAbs})
      66        
338             and not $self->_matches_extern_images( $urlAbs ) )
339             {
340 6         27 $images_read{$urlAbs} = 1;
341 6         87 push(@mail, $self->create_image_part($urlAbs));
342             }
343             }
344              
345             # For flash part (embed)
346             elsif (lc($$url[0]) eq 'embed' && $$url[4])
347             {
348             # rebuild $urlAbs
349 0         0 $urlAbs = absUrl($$url[4],$racinePage);
350             # Replace relative url with absolute
351 0 0       0 my $v = ($self->{_include} eq 'cid') ?
352             "cid:$urlAbs" : $urlAbs;
353 0         0 $gabarit=~s/src \s = \s [\"'] \Q$$url[4]\E ([\"'>])
  0         0  
354             /pattern_href($v,"src",$1)/giemx;
355             # Exit with extern configuration, don't include image
356 0 0 0     0 if (($self->{_include} ne 'extern')&&(!$images_read{$urlAbs})
      0        
357             and not $self->_matches_extern_images( $urlAbs ) )
358             {
359 0         0 $images_read{$urlAbs}=1;
360 0         0 push(@mail, $self->create_image_part($urlAbs));
361             }
362             }
363              
364             # For flash part (object)
365             # Need to add "param" to Tagset.pm in the linkElements definition:
366             # 'param' => ['name', 'value'],
367             # Tks to tosh@c4.ca for that
368             elsif (lc($$url[0]) eq 'param' && lc($$url[2]) eq 'movie'
369             && $$url[4]) {
370             # rebuild $urlAbs
371 0         0 $urlAbs = absUrl($$url[4],$racinePage);
372             # Replace relative url with absolute
373 0 0       0 my $v = ($self->{_include} eq 'cid') ?
374             "cid:".$self->cid($urlAbs) : $urlAbs;
375 0         0 $gabarit=~s/value \s* = \s* [\"'] \Q$$url[4]\E ([\"'>])
  0         0  
376             /pattern_href($v,"value",$1)/giemx;
377             # Exit with extern configuration, don't include image
378 0 0 0     0 if (($self->{_include} ne 'extern')&&(!$images_read{$urlAbs})
      0        
379             and not $self->_matches_extern_images($urlAbs))
380             {
381 0         0 $images_read{$urlAbs}=1;
382 0         0 push(@mail, $self->create_image_part($urlAbs));
383             }
384             }
385              
386             # For new images create part
387             # Exit with extern configuration, don't include image
388             elsif ( ($self->{_include} ne 'extern') &&
389             ( not $self->_matches_extern_images( $urlAbs ) ) &&
390             ((lc($$url[0]) eq 'img') || (lc($$url[0]) eq 'src')) &&
391             (!$images_read{$urlAbs})) {
392            
393 36         607 $images_read{$urlAbs}=1;
394 36         599 push(@mail, $self->create_image_part($urlAbs));
395             }
396             }
397              
398             # If cid choice, put a cid + absolute url on each link image
399 63 100       266 if ($self->{_include} eq 'cid')
  21         704  
400 42         1762 {$gabarit=~s/]*) src\s*=\s*(["']?) ([^"'> ]* )(["']?)
401 24         785 /pattern_image_cid($self,$1,$3,$racinePage)/iegx;}
402             # Else just make a absolute url
403             else {$gabarit=~s/]*) src\s*=\s*(["']?)([^"'> ]*) (["']?)
404 48         1904 /pattern_image($1,$3,$racinePage)/iegx;}
405              
406 63         675 BUILD_MESSAGE:
407             # Substitue value in template if needed
408 63 50       10039 if (scalar keys %{$self->{_HASH_TEMPLATE}}!=0)
409             {
410 0 0       0 $gabarit=$self->fill_template($gabarit,$self->{_HASH_TEMPLATE})
411             if ($gabarit);
412 0         0 $gabarit_txt=$self->fill_template($gabarit_txt,
413             $self->{_HASH_TEMPLATE});
414             }
415              
416             # Create MIME-Lite object
417 63   100     891 $self->build_mime_object($gabarit, $gabarit_txt || undef, \@mail);
418              
419 63         3448 return $self->{_MAIL};
420             }
421              
422             #------------------------------------------------------------------------------
423             # size
424             #------------------------------------------------------------------------------
425             sub size {
426 126     126 1 1138922 my ($self)=shift;
427 126         2320 return length($self->{_MAIL}->as_string);
428             }
429              
430              
431             #------------------------------------------------------------------------------
432             # _matches_extern_images
433             #
434             # For a given image, does it match any of the regexps in $self->{_externimages} ?
435             #------------------------------------------------------------------------------
436             sub _matches_extern_images {
437            
438 708     708   2528 my ( $self, $image ) = @_;
439            
440 708   50     2963 my $regexps = $self->{_externimages} || [ ];
441            
442 708         1717 foreach my $regexp ( @$regexps ) {
443 0 0       0 if ( $image =~ /$regexp/ ) {
444 0         0 return 1;
445             }
446             }
447 708         8452 return 0;
448             }
449              
450              
451             #------------------------------------------------------------------------------
452             # build_mime_object
453             #------------------------------------------------------------------------------
454             sub build_mime_object {
455 63     63 1 909 my ($self,$html,$txt,$ref_mail)=@_;
456 63         113 my ($txt_part, $part,$mail);
457             # Create part for HTML if needed
458 63 50       177 if ($html) {
459 63 100 100     419 my $ref = ($txt || @$ref_mail) ? {} : $self->{_param};
460 63         740 $part = new MIME::Lite(%$ref,
461             'Type' => 'TEXT',
462             'Encoding' => $self->{_htmlencoding},
463             'Data' => $html);
464 63         33154 $part->attr("content-type"=> "text/html; charset=".$self->{_htmlcharset});
465             # Remove some header for Eudora client in HTML and related part
466 63         1677 $part->replace("MIME-Version" => "");
467 63         3424 $part->replace('X-Mailer' =>"");
468 63         2886 $part->replace('Content-Disposition' =>"");
469             # only html, no images & no txt
470 63 100 100     3089 $mail = $part unless ($txt || @$ref_mail);
471             }
472              
473             # Create part for text if needed
474 63 100       177 if ($txt) {
475 42 50       202 my $ref = ($html ? {} : $self->{_param} );
476 42         317 $txt_part = new MIME::Lite (%$ref,
477             'Type' => 'TEXT',
478             'Data' => $txt,
479             'Encoding' => $self->{_textencoding});
480 42         14967 $txt_part->attr("content-type" =>
481             "text/plain; charset=".$self->{_textcharset});
482             # Remove some header for Eudora client
483 42         647 $txt_part->replace("MIME-Version" => "");
484 42         1809 $txt_part->replace("X-Mailer" => "");
485 42         1461 $txt_part->replace("Content-Disposition" => "");
486             # only text, no html
487 42 50       1532 $mail = $txt_part unless $html;
488             }
489              
490             # If images and html and no text, multipart/related
491 63 100 100     848 if (@$ref_mail and !$txt) {
    100 100        
    100 66        
492 6         21 my $ref=$self->{_param};
493 6         24 $$ref{'Type'} = "multipart/related";
494 6         43 $mail = new MIME::Lite (%$ref);
495             # Attach HTML part to related part
496 6         3135 $mail->attach($part);
497             # Attach each image to related part
498 6         90 foreach (@$ref_mail) {$mail->attach($_);} # Attach list of part
  14         103  
499 6         180 $mail->replace("Content-Disposition" => "");
500             }
501              
502             # Else if html and text and no images, multipart/alternative
503             elsif ($txt and !@$ref_mail) {
504 30         88 my $ref=$self->{_param};
505 30         79 $$ref{'Type'} = "multipart/alternative";
506 30         279 $mail = new MIME::Lite (%$ref);
507 30         15783 $mail->attach($txt_part); # Attach text part
508 30         499 $mail->attach($part); # Attach HTML part
509             }
510              
511             # Else (html, txt and images) mutilpart/alternative
512             elsif ($txt && @$ref_mail) {
513 12         30 my $ref=$self->{_param};
514 12         31 $$ref{'Type'} = "multipart/alternative";
515 12         79 $mail = new MIME::Lite (%$ref);
516             # Create related part
517 12         79258 my $rel = new MIME::Lite ('Type'=>'multipart/related');
518 12         3543 $rel->replace("Content-transfer-encoding" => "");
519 12         604 $rel->replace("MIME-Version" => "");
520 12         496 $rel->replace("X-Mailer" => "");
521             # Attach text part to alternative part
522 12         423 $mail->attach($txt_part);
523             # Attach HTML part to related part
524 12         263 $rel->attach($part);
525             # Attach each image to related part
526 12         129 foreach (@$ref_mail) {$rel->attach($_);}
  28         216  
527             # Attach related part to alternative part
528 12         350 $mail->attach($rel);
529             }
530 63         871 $mail->replace('X-Mailer' => "MIME::Lite::HTML $VERSION");
531 63         2678 $self->{_MAIL} = $mail;
532             }
533              
534             #------------------------------------------------------------------------------
535             # include_css
536             #------------------------------------------------------------------------------
537             sub pattern_css {
538 108     108 0 889 my ($self,$url,$milieu,$fin,$root)=@_;
539             # if not stylesheet - rt19655
540 108 50 66     1291 if ($milieu!~/stylesheet/i && $fin!~/stylesheet/i) {
541 54         1529 return "";
542             }
543             # Don't store tag. Tks to doggy@miniasp.com
544 54 50 33     865 if ( $fin =~ m/shortcut/i || $milieu =~ m/shortcut/i )
545 0         0 { return ""; }
546             # Complete url
547 54         1230 my $ur = URI::URL->new($url, $root)->abs;
548 54 50       40222 print "Include CSS file $ur\n" if $self->{_DEBUG};
549 54         16720 my $res2 = $self->{_AGENT}->request(new HTTP::Request('GET' => $ur));
550 54 50       144063 print "Ok file downloaded\n" if $self->{_DEBUG};
551 54         391 return '\n";
554             }
555              
556             sub include_css(\%$$) {
557 63     63 1 131 my ($self,$gabarit,$root)=@_;
558 63         1891 $gabarit=~s/]*?)
559             href\s*=\s*["']?([^\"\' ]*)["']?([^>]*)>
560 108         46838 /$self->pattern_css($2,$1,$3,$root)/iegmx;
561              
562 63 50       23323 print "Done CSS\n" if ($self->{_DEBUG});
563 63         294 return $gabarit;
564             }
565              
566              
567             #------------------------------------------------------------------------------
568             # include_javascript
569             #------------------------------------------------------------------------------
570             sub pattern_js {
571 36     36 0 163 my ($self,$url,$milieu,$fin,$root)=@_;
572 36         353 my $ur = URI::URL->new($url, $root)->abs;
573 36 50       19924 print "Include Javascript file $ur\n" if $self->{_DEBUG};
574 36         5710 my $res2 = $self->{_AGENT}->request(new HTTP::Request('GET' => $ur));
575 36         72555 my $content = $res2->decoded_content;
576 36 50       14960 print "Ok file downloaded\n" if $self->{_DEBUG};
577 36 50       1261 return ($self->{_remove_jscript} ? ' ' : "\n"."\n".
578             '\n");
581             }
582              
583             sub include_javascript(\%$$) {
584 63     63 1 163 my ($self,$gabarit,$root)=@_;
585 63         1799 $gabarit=~s/]*)src\s*=\s*"?([^\" ]*js)"?([^>]*)>[^<]*<\/script>
586 36         205 /$self->pattern_js($2,$1,$3,$root)/iegmx;
587 63 50       2255 if ($self->{_remove_jscript}) {
588 0         0 $gabarit=~s/]*)>[\s\S]*?<\/script>//iegmx;
589             }
590 63 50       7842 print "Done Javascript\n" if $self->{_DEBUG};
591 63         240 return $gabarit;
592             }
593              
594              
595             #------------------------------------------------------------------------------
596             # input_image
597             #------------------------------------------------------------------------------
598             sub pattern_input_image {
599 0     0 0 0 my ($self,$deb,$url,$fin,$base,$ref_tab_mail)=@_;
600 0         0 my $ur = URI::URL->new($url, $base)->abs;
601 0 0       0 if ($self->{_include} ne 'extern')
  0         0  
602             {push(@$ref_tab_mail,$self->create_image_part($ur));}
603 0 0       0 if ($self->{_include} eq 'cid')
  0         0  
604 0         0 {return '
605             else {return '
606             }
607              
608             sub input_image(\%$$) {
609 63     63 1 290 my ($self,$gabarit,$root)=@_;
610 63         98 my @mail;
611 63         2995 $gabarit=~s/]*)src\s*=\s*"?([^\"'> ]*)"?([^>]*)>
612 0         0 /$self->pattern_input_image($1,$2,$3,$root,\@mail)/iegmx;
613 63 50       8554 print "Done input image\n" if $self->{_DEBUG};
614 63         308 return ($gabarit,@mail);
615             }
616              
617             #------------------------------------------------------------------------------
618             # create_image_part
619             #------------------------------------------------------------------------------
620             sub create_image_part {
621 46     46 1 146 my ($self,$ur, $typ)=@_;
622            
623 46         76 my ($type, $buff1);
624             # Create MIME type
625 46 50       277 if ($typ) { $type = $typ; }
  0 100       0  
  40 50       692  
    50          
626 0         0 elsif (lc($ur)=~/\.gif$/i) {$type="image/gif";}
627 0         0 elsif (lc($ur)=~/\.jpg$/i) {$type = "image/jpg";}
628             elsif (lc($ur)=~/\.png$/i) {$type = "image/png";}
629 6         287 else { $type = "application/x-shockwave-flash"; }
630              
631             # Url is already in memory
632 46 50       264 if ($self->{_HASH_TEMPLATE}{$ur}) {
633 0 0       0 print "Using buffer on: ", $ur,"\n" if $self->{_DEBUG};
634 0         0 $buff1 = ref($self->{_HASH_TEMPLATE}{$ur}) eq "ARRAY"
635 0 0       0 ? join "", @{$self->{_HASH_TEMPLATE}{$ur}}
636             : $self->{_HASH_TEMPLATE}{$ur};
637 0         0 delete $self->{_HASH_TEMPLATE}{$ur};
638             } else { # Get image
639 46 100       650 print "Get img ", $ur,"\n" if $self->{_DEBUG};
640 46         7713 my $res2 = $self->{_AGENT}->
641             request(new HTTP::Request('GET' => $ur));
642 46 100       96353 if (!$res2->is_success) {$self->set_err("Can't get $ur\n");}
  30         469  
643 46         651 $buff1=$res2->decoded_content;
644             }
645              
646             # Create part
647 46         6112 my $mail = new MIME::Lite( Data => $buff1, Encoding =>'base64');
648              
649 46         34524 $mail->attr("Content-type"=>$type);
650             # With cid configuration, add a Content-ID field
651 46 100       871 if ($self->{_include} eq 'cid') {
652 23         116 $mail->attr('Content-ID' =>'<'.$self->cid($ur).'>');
653             } else { # Else (location) put a Content-Location field
654 23         158 $mail->attr('Content-Location'=>$ur);
655             }
656              
657             # Remove header for Eudora client
658 46         2292 $mail->replace("X-Mailer" => "");
659 46         1757 $mail->replace("MIME-Version" => "");
660 46         2779 $mail->replace("Content-Disposition" => "");
661 46         7162 return $mail;
662             }
663              
664             #------------------------------------------------------------------------------
665             # cid
666             #------------------------------------------------------------------------------
667             sub cid (\%$) {
668 53     53 1 759 my ($self, $url)=@_;
669             # rfc say: don't use '/'. So I do a pack on it.
670             # but as string can get long, I need to revert it to have
671             # difference at begin of url to avoid max size of cid
672             # I remove scheme always same in a document.
673 53         321 $url = reverse(substr($url, 7));
674 53         2840 return reverse(split("",unpack("h".length($url),$url))).'@MIME-Lite-HTML-'.
675             $VERSION;
676             }
677              
678              
679             #------------------------------------------------------------------------------
680             # link_form
681             #------------------------------------------------------------------------------
682             sub pattern_link_form {
683 9     9 0 46 my ($self,$deb,$url,$fin,$base)=@_;
684 9         15 my $type;
685 9         132 my $ur = URI::URL->new($url, $base)->abs;
686 9         5293 return '
';
687             }
688              
689             sub link_form
690             {
691 63     63 1 154 my ($self,$gabarit,$root)=@_;
692 63         172 my @mail;
693 63         2814 $gabarit=~s/]*)action="?([^\"'> ]*)"?([^>]*)>
694 9         61 /$self->pattern_link_form($1,$2,$3,$root)/iegmx;
695 63 50       10481 print "Done form\n" if $self->{_DEBUG};
696 63         361 return $gabarit;
697             }
698              
699             #------------------------------------------------------------------------------
700             # fill_template
701             #------------------------------------------------------------------------------
702             sub fill_template {
703 1     1 1 24 my ($self,$masque,$vars)=@_;
704 1 50       11 return unless $masque;
705 1         8 my @buf=split(/\n/,$masque);
706 1         2 my $i=0;
707 1         9 while (my ($n,$v)=each(%$vars)) {
708 2 50       6 if ($v) {map {s/<\?\s\$$n\s\?>/$v/gm} @buf;}
  2         7  
  2         51  
  0         0  
709 0         0 else {map {s/<\?\s\$$n\s\?>//gm} @buf;}
710 2         11 $i++;
711             }
712 1         10 return join("\n",@buf);
713             }
714              
715             #------------------------------------------------------------------------------
716             # set_err
717             #------------------------------------------------------------------------------
718             sub set_err {
719 30     30 0 454 my($self,$error) = @_;
720 30 50       4912 print $error,"\n" if ($self->{_DEBUG});
721 30         98 my @array;
722 30 100       143 if ($self->{_ERRORS}) {
723 24         43 @array = @{$self->{_ERRORS}};
  24         105  
724             }
725 30         67 push @array, $error;
726 30         79 $self->{_ERRORS} = \@array;
727 30         187 return 1;
728             }
729              
730             #------------------------------------------------------------------------------
731             # errstr
732             #------------------------------------------------------------------------------
733             sub errstr {
734 0     0 0   my($self) = @_;
735 0 0         return @{$self->{_ERRORS}} if ($self->{_ERRORS});
  0            
736 0           return ();
737             }
738              
739             __END__