# _____________________
# | |
# | Dilbert in MSWord©® |
# |_____________________|
#
# Objectif : Récupérer sur le site www.dilbert.com
# les strips et générer un document MSWord©® avec.
#
# Ce code reprend largement des parties de code de
# René Nyffenegger :
# http://www.adp-gmbh.ch/perl/word.html
#
# ainsi que de Randal L. Schwartz :
# http://www.stonehenge.com/merlyn/WebTechniques/col15.html
#
# La doc de Philippe 'BooK' Bruhat concernant LWP
# a été d'un grand secours :
# http://articles.mongueurs.net/magazines/linuxmag57.html
#
#
# Copyright 2004 by glb <glb@mongueurs.net>.
#
# This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
use warnings;
use strict;
use integer;
use Win32::OLE;
use Win32::OLE::Const 'Microsoft.Word'; # wd constants
use Win32::OLE::Const 'Microsoft Office'; # mso constants
use URI::URL;
use LWP::UserAgent;
use Term::ReadKey;
use Getopt::Long;
my $ua = LWP::UserAgent->new;
my $TMP = $ENV{TMP} ? $ENV{TMP} : "./" ;
my ($proxy, $noproxy, $number, $user, $passwd) ;
BEGIN {
print <<"EOF";
_________________________________________________
| |
| Recuperation des derniers Dilbert sur le net ! |
|_________________________________________________|
EOF
}
GetOptions( "noproxy" => \$noproxy, # --noproxy
"number=s" => \$number ); # --number=x
# Proxy ?
if ( not defined ($noproxy) ) {
my $prox = "http://proxy.domaine.com:8080/";
print "y'a-t-il des parametres proxy a renseigner ? [oui]";
my $rep =<>;
$rep = "oui" if $rep =~ m/^$/;
if ($rep =~m/^(o|y).*/) {
print "proxy ? [ $prox ] ";
$proxy = <> ;
$proxy = $prox if $proxy =~ m/^$/;
print "user ? ";
$user = <>;
print "password ? ";
ReadMode 2;
$passwd = <>;
ReadMode 0;
print "\n";
chomp $proxy; chomp $user; chomp $passwd;
} else {
undef $proxy;
}
}
if (not defined $number) {
my $nbr_def = 7;
my $nbr;
print "combien d'images a recuperer ? [$nbr_def] " ;
$nbr = <> ;
$nbr = $nbr_def if ( $nbr !~ m/^\d+$/ );
chomp $nbr;
$number = $nbr;
}
$number = ( $number < 32 ) ? $number : 32 ;
$ua->proxy('http', "$proxy" ) if defined $proxy;
# Les REGEXPs qui nous sont utiles
my $TOP = "http://www.unitedmedia.com/comics/dilbert/archive/";
my $HTML_RE = 'VALUE="(/comics/dilbert/archive/dilbert-\d+.html)"';
my $GIF_RE = '/comics/dilbert/archive/images/dilbert\d+\.(gif|jpg)';
my $NAME_RE = 'dilbert\d+\.(gif|jpg)';
my $cur_style = 'a';
my $cur_bookmark = 'a';
my $word;
print "get $TOP\n";
my $top = get_as_string("$TOP", $proxy, $user, $passwd);
my @gif_urls = ();
if (not defined $top) {
die "Impossible de recuperer $TOP";
} else {
my @old_urls = map url($_,$TOP)->abs, $top =~ m!$HTML_RE!og;
die "Pas de donnees recuperees ?!?" if (@old_urls < 1) ;
$word = CreateObject Win32::OLE 'Word.Application' or die $!;
$word->{'Visible'} = 1;
my $document = $word->Documents->Add;
# selection is the insertion point.
my $selection = $word->Selection;
my $st_bold_10_arial = create_style($document, "Arial", 10, 1, 0);
my $st_bold_20_arial = create_style($document, "Arial", 20, 1, 0);
my $st_italic_10_arial = create_style($document, "Arial", 10, 0, 1);
my $st_italic_20_arial = create_style($document, "Times new Roman", 20, 0, 1);
my $st_normal_8_courier= create_style($document, "Courier", 8, 0, 0);
set_style($document, $st_bold_20_arial);
text ($document, "Recent Dilberts");
enter ($document);
set_style($document, $st_normal_8_courier);
@old_urls = @old_urls[-$number..-1] if @old_urls > $number;
for my $url (@old_urls) {
print "get $url\n";
my $page = get_as_string("$url", $proxy, $user, $passwd);
my ($gif) = $page =~ m!($GIF_RE)!o;
my $url_img = url($gif,$url)->abs;
my ($name_img) = $url_img =~ m!($NAME_RE)!og;
my $rc = get_file ("$url_img", "$TMP/$name_img", $proxy, $user, $passwd);
text ($document, "$url");
enter ($document);
my $picture = insert_picture2($document, "$TMP/$name_img");
go_right($document);
enter ($document);
unlink ("$TMP/$name_img");
}
# insert something into the footer
switch_view($document, wdSeekCurrentPageFooter);
my $st_footer = create_style($document, "Verdana", 8, 0, 0);
style_alignment($document, $st_footer, "wdAlignParagraphRight");
set_style($document, $st_footer);
text ($document, localtime() . " - Recent Dilberts. ");
# Inserting current page, total page
text ($document, " Page ");
$selection->Fields->Add ($selection->{Range}, wdFieldPage );
text ($document, " of ");
$selection->Fields->Add ($selection->{Range}, wdFieldNumPages);
# go back to body of document
switch_view($document, wdSeekMainDocument);
# save_doc_as($document, 'e:/dilbert.doc');
# close_doc($document);
# $word->Quit;
}
#--> Fonctions <---------------------------------------------------------------------------
sub get_as_string {
my ($url, $proxy, $user, $passwd) = @_ ;
my $content;
if ( defined $proxy ) {
my $req = HTTP::Request->new(GET => "$url" );
$req->proxy_authorization_basic("$user", "$passwd");
$content = $ua->request($req)->as_string;
} else {
#my $top = get $TOP or die "cannot get $TOP : $!\n";;
$content = $ua->get($url)->as_string;
}
return $content ;
}
sub get_file {
my ($url, $file, $proxy, $user, $passwd) = @_ ;
my $rc ;
if ( defined $proxy ) {
my $req_file = HTTP::Request->new( GET => "$url" );
$req_file->proxy_authorization_basic( "$user", "$passwd" );
$rc = $ua->request( $req_file, "$file" );
} else {
$rc = $ua->get($url, ':content_file' => "$file");
}
return $rc ;
}
sub text {
my $document = shift;
my $text = shift;
$document->ActiveWindow->Selection -> TypeText($text);
}
# aka new line, newline or NL
sub enter {
my $document = shift;
$document->ActiveWindow->Selection -> TypeParagraph;
}
sub go_right {
my $document = shift ;
$document->ActiveWindow->Selection -> MoveRight ( wdCharacter, 1 );
}
sub set_style {
my $document = shift;
my $style_arg = shift;
$document->ActiveWindow->Selection -> {Style} = $style_arg -> {name};
}
sub create_style {
my $document = shift;
my $fontname = shift;
my $font_size = shift;
my $bold = shift;
my $italic = shift;
my $style = $document->Styles->Add($cur_style);
my $style_font = $style->{Font};
$style_font -> {Name } = $fontname;
$style_font -> {Size } = $font_size;
$style_font -> {Bold } = $bold;
$style_font -> {Italic} = $italic;
my %style;
$style{name} = $cur_style++;
return \%style;
}
# use switch_view to change to header, footer, main document and so on...
# possible constants for view are: wdSeekCurrentPageFooter
#
# o wdSeekCurrentPageHeader
# o wdSeekEndnotes
# o wdSeekEvenPagesFooter
# o wdSeekEvenPagesHeader
# o wdSeekFirstPageFooter
# o wdSeekFirstPageHeader
# o wdSeekFootnotes
# o wdSeekMainDocument
# o wdSeekPrimaryFooter
# o wdSeekPrimaryHeader
#
sub switch_view {
my $document = shift;
my $view = shift;
$document -> ActiveWindow -> ActivePane -> View -> {SeekView} = $view;
}
sub insert_picture {
my $document = shift;
my $file = shift;
my $left = shift;
my $top = shift;
my $width = shift;
my $height = shift;
my $picture =
$document-> Shapes -> AddPicture (
$file,
msoFalse, # link to file
msoTrue, # save with document
$left, $top, $width, $height,
$document->ActiveWindow->Selection->{Range}
);
return $picture;
}
sub insert_picture2 {
my $document = shift;
my $file = shift;
my $picture =
$document-> InlineShapes -> AddPicture (
$file,
msoFalse, # link to file
msoTrue, # save with document
$document->ActiveWindow->Selection->{Range}
);
return $picture;
}
sub bold {
my $document = shift;
my $bold = shift;
$document->ActiveWindow->Selection->{Font}->{Bold} = $bold ? msoTrue : msoFalse;
}
sub goto_bookmark {
my $document = shift;
my $bookmark = shift;
$document->ActiveWindow->Selection -> GoTo(wdGoToBookmark, 0, 0, $bookmark->{Name});
}
sub insert_bookmark {
my $document = shift;
my $bookmark = $document -> Bookmarks -> Add ($cur_bookmark++, $document->ActiveWindow->Selection->Range);
return $bookmark;
}
sub style_indents {
my $document = shift;
my $style_arg = shift;
my $first_line_indent = shift;
my $other_line_indent = shift;
my $style = $document->Styles($style_arg->{name});
$style->ParagraphFormat->{LeftIndent } = $other_line_indent;
$style->ParagraphFormat->{FirstLineIndent} = -$other_line_indent + $first_line_indent;
}
sub items {
my $document = shift;
my $title = shift;
my $style = shift;
my @array = @_;
enter($document);
set_style($document, $style);
bold($document, 1);
text($document, $title);
bold($document, 0);
text($document, "\x09");
foreach my $a (@array) {
text($document, $a);
text($document, "\x0b");
}
}
sub insert_box {
my $document = shift;
my $left = shift;
my $top = shift;
my $width = shift;
my $height = shift;
my $shape = $document->Shapes->AddTextbox(msoTextOrientationHorizontal, $left, $top, $width, $height);
$shape -> Select;
my $selection = $word->Selection;
$selection -> ShapeRange -> Line -> {DashStyle} = msoLineRoundDot;
return $shape
}
sub close_doc {
my $document = shift;
$document -> Close;
}
sub save_doc_as {
my $document = shift;
my $filename = shift;
$document->SaveAs($filename);
}
sub style_keep_with_next {
my $document = shift;
my $style_arg = shift;
my $style = $document->Styles($style_arg->{name});
$style->{ParagraphFormat}->{KeepWithNext} = msoTrue;
}
sub style_keep_together {
my $document = shift;
my $style_arg = shift;
my $style = $document->Styles($style_arg->{name});
$style->{ParagraphFormat}->{KeepTogether} = msoTrue;
}
sub style_border {
my $document = shift;
my $style_arg = shift;
my $border = shift;
my $border_style = shift;
my $border_width = shift;
my $border_color = shift;
my $style = $document->Styles($style_arg->{name});
$style->Borders($border) -> {LineStyle} = $border_style;
$style->Borders($border) -> {LineWidth} = $border_width;
$style->Borders($border) -> {Color } = $border_color;
}
sub style_tab_at_position {
my $document = shift;
my $style_arg = shift;
my $position = shift;
my $left_or_right= shift;
my $style = $document->Styles($style_arg->{name});
$style->ParagraphFormat->{TabStops}->Add($word->InchesToPoints($position), $left_or_right);
}
sub style_space_before {
my $document = shift;
my $style_arg = shift;
my $space = shift;
my $style = $document->Styles($style_arg->{name});
$style->ParagraphFormat->{SpaceBefore} = $space;
}
sub style_space_after {
my $document = shift;
my $style_arg = shift;
my $space = shift;
my $style = $document->Styles($style_arg->{name});
$style->ParagraphFormat->{SpaceAfter} = $space;
}
sub style_alignment {
my $document = shift;
my $style_arg = shift;
my $alignment = shift;
my $style = $document->Styles($style_arg->{name});
$style->ParagraphFormat->{Alignment} = $alignment;
}
sub goto_end_of_document {
my $document = shift;
$document->ActiveWindow->Selection->{Range} -> EndKey(wdStory);
#my $selection = $word->Selection;
#$selection -> EndKey (wdStory);
}
sub insert_page_break {
my $document = shift;
#my $selection = $word->Selection;
#$selection -> InsertBreak(wdPageBreak);
$document->ActiveWindow->Selection->{Range} -> InsertBreak(wdPageBreak);
}
sub landscape {
my $document = shift;
$document->PageSetup->{Orientation} = wdOrientLandscape;
}