AW: Q: add and remove wheels dynamically
"Alex" <[email protected]> Sun, 22 Jul 2012 10:34:00 +0200
| Newsgroups | gmane.comp.lang.perl.poe |
|---|---|
| Message-ID | <[email protected]> |
------=_NextPart_000_0001_01CD67F5.8222A750
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Hi!
I just notices that I replied to one person only. Maybe there is someone =
on
the list who can help me further. I'm still stuck with the problem :-(
The term "to run locally" matches my script. Please find the script =
below.
(NB: The script is intended for the German Perl Community, so there were
german comments and variable names only. I translated most of them, but
there surely are some left.)
Basically, a Tk main window is created with a menu, a notebook with tabs =
for
each watched file and a giant textarea for each file.
Using the menu, you can remove and add files.
I'm using ActiveState Perl and it's Tk. If you are using another Tk, I =
think
you have to adjust this line: use POE qw( Loop::TkActiveState
Wheel::FollowTail ); I don't know exactly how, I think you can simply =
omit
the Loop::TkActiveState.
Best regards,
Alex
[code]
#!perl
=3Dhead1 NAME
apacheLogParser_tk.pl - a programm to watch files
=3Dhead1 DESCRIPTION
Somewhere in this code, you can specify a list of files to be watched.
Search for "my $logdateien".
=3Dcut
use strict;
use warnings;
use Config::Auto;
use Data::Dumper qw/Dumper/;
use File::Spec;
use utf8;
use vars qw($VERSION);
$VERSION =3D 0.3;
# Tk support is enabled if the Tk module is used before POE itself.
use Tk;
use Tk::ToolBar;
use Tk::StatusBar;
# except when it isn't...
#
# ActiveState does something funky such that if you don't include #
Loop::TkActiveState here Loop::Tk won't be detected. The good news # is
that it does not appear to be necessary to special case this for # other
platforms.
#
# Are you using a non-ActiveState Perl? Then you have to adjust this =
line!
use POE qw( Loop::TkActiveState Wheel::FollowTail );
my $logdateien =3D [
File::Spec->catfile(qw(c: Apache logs error.log)),
#File::Spec->catfile(qw(c: Apache logs access.log)), ];
# Dubletten entfernen
my %seen =3D ();
@{$logdateien} =3D grep { ! $seen{ $_ }++ } @{$logdateien}; undef %seen;
foreach( @{$logdateien} ) {
die "Logdatei [$_] existiert nicht!\n" unless -e $_; }
# Create the session that will drive the user interface.
POE::Session->create(
inline_states =3D>
{ _start =3D> \&ui_start,
ev_count =3D> \&ui_count,
ev_clear =3D> \&ui_clear,
got_line =3D> \&updateLog_line,
got_error =3D> \&updateLog_error,
},
args =3D> \@{$logdateien},
);
# Run the program until it is exited.
$poe_kernel->run();
exit 0;
sub add_file_to_watchlist {
my ($heap, $logdatei) =3D @_;
=20
$heap->{notebookSeiten}{$logdatei}{seite} =3D
$heap->{notebook}->add($logdatei, -label =3D> $logdatei,);
$heap->{notebookSeiten}{$logdatei}{scr_txt} =3D
$heap->{notebookSeiten}{$logdatei}{seite}->Scrolled(
Text =3D> -scrollbars =3D> 'se',
)->pack(-expand =3D> 1, -fill =3D> 'both',);
=20
# -- Buttons
$heap->{notebookSeiten}{$logdatei}{btn_frame} =3D
$heap->{notebookSeiten}{$logdatei}{seite}->Frame();
$heap->{notebookSeiten}{$logdatei}{clear_btn} =3D
$heap->{notebookSeiten}{$logdatei}{btn_frame}->Button(
-text =3D> 'Anzeige leeren',
-command =3D> sub{
=20
$heap->{notebookSeiten}{$logdatei}{scr_txt}->Subwidget('scrolled')->delet=
e("
0.0", "end");
},
)->pack(-side =3D> 'left',);
$heap->{notebookSeiten}{$logdatei}{btn_frame}->pack(-side =3D> =
'left',);
# -- create Wheel
$heap->{wheel}->{$logdatei} =3D POE::Wheel::FollowTail->new(
Filename =3D> $logdatei,
InputEvent =3D> 'got_line',
ErrorEvent =3D> 'got_error',
SeekBack =3D> 1024,
);
=20
return;
} # /add_file_to_watchlist
=3Dhead2 METHODEN
=3Dhead3 ui_start
Populate the GUI. For each file in \@logdateien, we create a new tab.
=3Dcut
sub ui_start {
my ( $kernel, $session, $heap ) =3D @_[ KERNEL, SESSION, HEAP ];
# -- adjust window size
die "could not create a main Tk window" unless defined =
$poe_main_window;
$poe_main_window->configure(-width =3D> 1280, -height =3D> 480,);
$poe_main_window->packPropagate(0);
$poe_main_window->gridPropagate(0);
=20
# -- create Tk GUI
require Tk::NoteBook;
$heap->{notebook} =3D $poe_main_window->NoteBook();
foreach my $logdatei ( @{$logdateien} ) {
add_file_to_watchlist( $heap, $logdatei );
}
$heap->{notebook}->pack(-expand =3D> 1, -fill =3D> 'both',);
=20
=20
# -- Statusbar
# -> for the UI-Counter
$heap->{statusbar} =3D $poe_main_window->StatusBar();
$heap->{statusbar}->addLabel(
-relief =3D> 'flat',
-text =3D> "Welcome to the statusbar",
);
=20
$heap->{statusbar}->addLabel(
-text =3D> 'Frame:',
-width =3D> '10',
-anchor =3D> 'center',
);
=20
$heap->{statusbar}->addLabel(
-width =3D> 20,
-anchor =3D> 'center',
-textvariable =3D> \$heap->{counter},
-foreground =3D> 'blue',
);
=20
$heap->{statusbar}->addLabel(
-width =3D> 10,
-anchor =3D> 'center',
-text =3D> "Clear",
-foreground =3D> 'blue',
-command =3D> $session->postback("ev_clear"),
-event =3D> '<Button-1>',
);
=20
$heap->{first} =3D 0;
# -- Menu erstellen
$poe_main_window->update();
my $log_file_types =3D [
['Log Files', ['.log', '.txt']],
['All Files', '*', ],
];
my $menuitems =3D [
[Cascade =3D> "~File", -menuitems =3D>
[
[Button =3D> "~Add file", -command =3D> sub{
my $file =3D =
$poe_main_window->getOpenFile(-filetypes =3D>
$log_file_types);
if( $file ) {
# Eine Datei wurde ausgew=E4hlt. Diese soll nun =
auch
geloggt werden.
push @{$logdateien}, $file;
add_file_to_watchlist( $heap, $file );
print Dumper $heap->{wheel}->{$file};
}
return 1;
}],
[Button =3D> "~Remove file", -command =3D> sub{
my $aktuelle_seite =3D $heap->{notebook}->raised();
if( $aktuelle_seite ) {
$heap->{notebook}->delete($aktuelle_seite);
delete $heap->{notebookSeiten}{$aktuelle_seite};
delete $heap->{wheel}->{$aktuelle_seite};
#die('doesn\'t work yet ;-(');
}
return 1;
}],
[Separator =3D> ""],
[Button =3D> "~Beenden", -command =3D> sub{ exit(0); =
return 1;
}],
],
],
];
my $menu =3D $poe_main_window->Menu(-menuitems =3D> $menuitems);
$poe_main_window->configure(-menu =3D> $menu);
=20
# Loop starten
$kernel->yield("ev_count");
} # /ui_start
=3Dhead3 ui_count
Handle the "ev_count" event by increasing a counter and displaying its =
new
value.
=3Dcut
sub ui_count {
$_[HEAP]->{counter}++;
$_[KERNEL]->yield("ev_count");
} # /ui_count
=3Dhead3 ui_clear
Handle the "ev_clear" event by clearing and redisplaying the counter.
=3Dcut
sub ui_clear {
$_[HEAP]->{counter} =3D 0;
} # /ui_clear
=3Dhead3 updateLog_line
Inserts the new lines from the watched file into the textare on the =
related
notebook tab.
=3Dcut
sub updateLog_line {
my ( $kernel, $session, $heap ) =3D @_[ KERNEL, SESSION, HEAP ];
=20
my $eingabe =3D $_[ARG0];
my @eingaben =3D split m/\\r, /, $eingabe; =20
foreach my $eing ( @eingaben ) {
=20
$heap->{notebookSeiten}{$logdateien->[($_[ARG1]-1)]}{scr_txt}->insert("en=
d",
"normal: $eing\n") if $heap->{first}++;
}
} # /updateLog_line
=3Dhead3 updateLog_error
No idea what this is about
=3Dcut
sub updateLog_error {
warn "$_[ARG0]\n";
} # /pdateLog_error
[/code]
-----Urspr=FCngliche Nachricht-----
Von: Rocco Caputo [mailto:[email protected]]=20
Gesendet: Mittwoch, 13. Juni 2012 22:24
An: POE Mailing List
Betreff: Re: Q: add and remove wheels dynamically
Can you reduce the program to something I can run locally to see what's
going on? The parts you've quoted aren't enough context for me to =
answer
your question.
What you want to do should work fine. So the best answer I have (with =
the
information you've given) is "you're doing... something... wrong."
--
Rocco Caputo <[email protected]>
On Jun 12, 2012, at 16:10, Alex wrote:
> Hi!
>=20
> I have written a small Tk GUI that follows some log files. I would=20
> like to add the possibility to add and remove files on-the-fly.
> To do this, I added a menu where a user is provided with two menu=20
> items for
> this:
>=20
> [snip]
> my $logfiles =3D [ ... ]; # my personal list of files
>=20
> my $log_file_types =3D [
> ['Log Files', ['.log', '.txt']],
> ['All Files', '*', ],
> ];
>=20
> my $menuitems =3D [
> [Cascade =3D> "~Datei", -menuitems =3D>
> [
> [Button =3D> "~Add file", -command =3D> sub{
> my $file =3D =
$poe_main_window->getOpenFile(-filetypes=20
> =3D> $log_file_types);
> if( $file ) {
> # A file has been selected to be followed
> push @{$logfiles}, $file;
> add_file_to_watchlist( $heap, $file );
> }
> return 1;
> }],
> [Button =3D> "~Remove file", -command =3D> sub{
> my $ident =3D magic_way_to_get_this();
> delete $heap->{wheel}->{$ident};
> }
> return 1;
> }],
> [Separator =3D> ""],
> [Button =3D> "~Exit program", -command =3D> sub{ =
exit(0);=20
> return 1; }],
> ],
> ],
> ];
> my $menu =3D $poe_main_window->Menu(-menuitems =3D> $menuitems);
> $poe_main_window->configure(-menu =3D> $menu);
>=20
> sub add_file_to_watchlist {
> my ($heap, $logfile) =3D @_;
>=20
> # this ethod is called during the initial set-up, too.
> # some stuff here...
>=20
> # -- create new wheel
> $heap->{wheel}->{$logdatei} =3D POE::Wheel::FollowTail->new(
> Filename =3D> $ logfile,
> InputEvent =3D> 'got_line',
> ErrorEvent =3D> 'got_error',
> SeekBack =3D> 1024,
> );
>=20
> return;
> } # /add_file_to_watchlist
> [/snip]
>=20
> However, when I remove a file and add it again, it's not followed. If=20
> I add another file, it's not followed either.
> How do I do this? Is it possible?
>=20
> The code (the uncut version) works fine when the program starts up.=20
> Only adding files after the event loop has started doesn't work. Why?
>=20
> What is the proper way of saying: "hey Perl, stop following that file" =
> and "hey Perl, start following this file" while the POE event loop is
running?
>=20
> Best regards,
> Alex
>=20
-----
E-Mail ist virenfrei.
Von AVG =FCberpr=FCft - www.avg.de
Version: 2012.0.2180 / Virendatenbank: 2433/5067 - Ausgabedatum: =
13.06.2012=20
------=_NextPart_000_0001_01CD67F5.8222A750
Content-Type: text/plain;
name="apache_log_parser_en-wip.pl.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="apache_log_parser_en-wip.pl.txt"
#!perl
=3Dhead1 NAME
apacheLogParser_tk.pl - a programm to watch files
=3Dhead1 DESCRIPTION
Somewhere in this code, you can specify a list of files to be watched. =
Search for "my $logdateien".
=3Dcut
use strict;
use warnings;
use Config::Auto;
use Data::Dumper qw/Dumper/;
use File::Spec;
use utf8;
use vars qw($VERSION);
$VERSION =3D 0.3;
# Tk support is enabled if the Tk module is used before POE itself.
use Tk;
use Tk::ToolBar;
use Tk::StatusBar;
# except when it isn't...
#
# ActiveState does something funky such that if you don't include
# Loop::TkActiveState here Loop::Tk won't be detected. The good news
# is that it does not appear to be necessary to special case this for
# other platforms.
#
# Are you using a non-ActiveState Perl? Then you have to adjust this =
line!
use POE qw( Loop::TkActiveState Wheel::FollowTail );
my $logdateien =3D [
File::Spec->catfile(qw(c: Apache logs error.log)),
#File::Spec->catfile(qw(c: Apache logs access.log)),
];
# Dubletten entfernen
my %seen =3D ();
@{$logdateien} =3D grep { ! $seen{ $_ }++ } @{$logdateien};
undef %seen;
foreach( @{$logdateien} ) {
die "Logdatei [$_] existiert nicht!\n" unless -e $_;
}
# Create the session that will drive the user interface.
POE::Session->create(
inline_states =3D>
{ _start =3D> \&ui_start,
ev_count =3D> \&ui_count,
ev_clear =3D> \&ui_clear,
got_line =3D> \&updateLog_line,
got_error =3D> \&updateLog_error,
},
args =3D> \@{$logdateien},
);
# Run the program until it is exited.
$poe_kernel->run();
exit 0;
sub add_file_to_watchlist {
my ($heap, $logdatei) =3D @_;
=20
$heap->{notebookSeiten}{$logdatei}{seite} =3D =
$heap->{notebook}->add($logdatei, -label =3D> $logdatei,);
$heap->{notebookSeiten}{$logdatei}{scr_txt} =3D =
$heap->{notebookSeiten}{$logdatei}{seite}->Scrolled(
Text =3D> -scrollbars =3D> 'se',
)->pack(-expand =3D> 1, -fill =3D> 'both',);
=20
# -- Buttons
$heap->{notebookSeiten}{$logdatei}{btn_frame} =3D =
$heap->{notebookSeiten}{$logdatei}{seite}->Frame();
$heap->{notebookSeiten}{$logdatei}{clear_btn} =3D =
$heap->{notebookSeiten}{$logdatei}{btn_frame}->Button(
-text =3D> 'Anzeige leeren',
-command =3D> sub{
=
$heap->{notebookSeiten}{$logdatei}{scr_txt}->Subwidget('scrolled')->delet=
e("0.0", "end");
},
)->pack(-side =3D> 'left',);
$heap->{notebookSeiten}{$logdatei}{btn_frame}->pack(-side =3D> =
'left',);
# -- create Wheel
$heap->{wheel}->{$logdatei} =3D POE::Wheel::FollowTail->new(
Filename =3D> $logdatei,
InputEvent =3D> 'got_line',
ErrorEvent =3D> 'got_error',
SeekBack =3D> 1024,
);
=20
return;
} # /add_file_to_watchlist
=3Dhead2 METHODEN
=3Dhead3 ui_start
Populate the GUI. For each file in \@logdateien, we create a new tab.
=3Dcut
sub ui_start {
my ( $kernel, $session, $heap ) =3D @_[ KERNEL, SESSION, HEAP ];
# -- adjust window size
die "could not create a main Tk window" unless defined =
$poe_main_window;
$poe_main_window->configure(-width =3D> 1280, -height =3D> 480,);
$poe_main_window->packPropagate(0);
$poe_main_window->gridPropagate(0);
=20
# -- create Tk GUI
require Tk::NoteBook;
$heap->{notebook} =3D $poe_main_window->NoteBook();
foreach my $logdatei ( @{$logdateien} ) {
add_file_to_watchlist( $heap, $logdatei );
}
$heap->{notebook}->pack(-expand =3D> 1, -fill =3D> 'both',);
=20
=20
# -- Statusbar
# -> for the UI-Counter
$heap->{statusbar} =3D $poe_main_window->StatusBar();
$heap->{statusbar}->addLabel(
-relief =3D> 'flat',
-text =3D> "Welcome to the statusbar",
);
=20
$heap->{statusbar}->addLabel(
-text =3D> 'Frame:',
-width =3D> '10',
-anchor =3D> 'center',
);
=20
$heap->{statusbar}->addLabel(
-width =3D> 20,
-anchor =3D> 'center',
-textvariable =3D> \$heap->{counter},
-foreground =3D> 'blue',
);
=20
$heap->{statusbar}->addLabel(
-width =3D> 10,
-anchor =3D> 'center',
-text =3D> "Clear",
-foreground =3D> 'blue',
-command =3D> $session->postback("ev_clear"),
-event =3D> '<Button-1>',
);
=20
$heap->{first} =3D 0;
# -- Menu erstellen
$poe_main_window->update();
my $log_file_types =3D [
['Log Files', ['.log', '.txt']],
['All Files', '*', ],
];
my $menuitems =3D [
[Cascade =3D> "~File", -menuitems =3D>
[
[Button =3D> "~Add file", -command =3D> sub{
my $file =3D =
$poe_main_window->getOpenFile(-filetypes =3D> $log_file_types);
if( $file ) {
# Eine Datei wurde ausgew=C3=A4hlt. Diese soll =
nun auch geloggt werden.
push @{$logdateien}, $file;
add_file_to_watchlist( $heap, $file );
print Dumper $heap->{wheel}->{$file};
}
return 1;
}],
[Button =3D> "~Remove file", -command =3D> sub{
my $aktuelle_seite =3D $heap->{notebook}->raised();
if( $aktuelle_seite ) {
$heap->{notebook}->delete($aktuelle_seite);
delete $heap->{notebookSeiten}{$aktuelle_seite};
delete $heap->{wheel}->{$aktuelle_seite};
#die('doesn\'t work yet ;-(');
}
return 1;
}],
[Separator =3D> ""],
[Button =3D> "~Beenden", -command =3D> sub{ exit(0); =
return 1; }],
],
],
];
my $menu =3D $poe_main_window->Menu(-menuitems =3D> $menuitems);
$poe_main_window->configure(-menu =3D> $menu);
=20
# Loop starten
$kernel->yield("ev_count");
} # /ui_start
=3Dhead3 ui_count
Handle the "ev_count" event by increasing a counter and displaying
its new value.
=3Dcut
sub ui_count {
$_[HEAP]->{counter}++;
$_[KERNEL]->yield("ev_count");
} # /ui_count
=3Dhead3 ui_clear
Handle the "ev_clear" event by clearing and redisplaying the counter.
=3Dcut
sub ui_clear {
$_[HEAP]->{counter} =3D 0;
} # /ui_clear
=3Dhead3 updateLog_line
Inserts the new lines from the watched file into the textare on the =
related notebook tab.
=3Dcut
sub updateLog_line {
my ( $kernel, $session, $heap ) =3D @_[ KERNEL, SESSION, HEAP ];
=20
my $eingabe =3D $_[ARG0];
my @eingaben =3D split m/\\r, /, $eingabe; =20
foreach my $eing ( @eingaben ) {
=
$heap->{notebookSeiten}{$logdateien->[($_[ARG1]-1)]}{scr_txt}->insert("en=
d", "normal: $eing\n") if $heap->{first}++;
}
} # /updateLog_line
=3Dhead3 updateLog_error
No idea what this is about
=3Dcut
sub updateLog_error {
warn "$_[ARG0]\n";
} # /pdateLog_error
------=_NextPart_000_0001_01CD67F5.8222A750--