Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Just another Perl shrine
 
PerlMonks  

Cool Uses for Perl

( #1044=superdoc: print w/ replies, xml ) Need Help??

This section is the place to post your general code offerings.

CUFP's
Connecting Javascript to Perl
No replies — Read more | Post response
by coyocanid
on May 24, 2013 at 14:42

    I've put together a new perl module on CPAN called Yote. It directly and automatically binds javascript client objects to perl server objects. The objects are container objects that live in an object database. The objects are lazily loaded as needed and are automatically stored with their contents automatically. The following example works out of the box as long as the Hello package is in the Yote server's perl classpath. The hello count will be preserved in Yote's data store.

    Server Side Perl
    package Hello; use base 'Yote::AppRoot'; sub hello { my( $self, $input ) = @_; $self->set_hello_count( $self->get_hello_count( 0 ) + 1 ); return "Hello $input, I have said hello ". $self->get_hello_count() . " times"; } 1;
    Client Side Javascript
    $.yote.init(); var hello_app = $.yote.fetch_app( 'Hello' ); alert( hello_app.hello( prompt( "What is your name?" ) ) );
Check network MTU size
2 direct replies — Read more / Contribute
by 5mi11er
on May 22, 2013 at 10:47
    I recently ran into a bunch of problems where our MPLS provider inadvertently modified the MTU sizes of several of our locations. Unfortunately at about the same time we had swapped out our firewall, so after spending significant time thinking we had weird issues with the new firewall, we finally discovered the actual problem was an incorrect MTU size for those sites.

    This wasn't the first time the MTU sizes had been monkeyed with, so I decided to throw something together that might help us identify MTU problems more quickly.

    I'd found Network Duplex speed test so, I used much of that for the actual ping packet creation, which referenced Net::Ping code, so I also compared the current version of that against what was given in the duplex test node. Then I had to figure out how to turn on the don't fragment flags of the packet. Anyway, the results are below.

    Hopefully someone else will find this useful.

    -Scott

Batch Printing in Linux
1 direct reply — Read more / Contribute
by jmlynesjr
on May 15, 2013 at 15:26

    I had a bunch of music lyrics that I wanted to print and I didn't want to manually drive gedit. I did, however, want to retain the document formatting. I found a hint in Re^2: using Brother QL-570 printer with Perl and also found sample commands in an Ubuntu Community Documentation post for using the Open Office command line interface for batch printing or viewing. The are also posts out there for doing a similar thing with MS-Word.

    The following is what I threw together. It does the job for me, YMMV. I needed to print UTF-8 text files, but Open Office will try to print whatever file you give it using the file extension as a guide to the file format. I have also printed .odt files.

    James

    There's never enough time to do it right, but always enough time to do it over...

Just for fun: relabel Perl variables and function names using Acme::MetaSyntactic and PPI
1 direct reply — Read more / Contribute
by tobyink
on May 14, 2013 at 08:52
    use v5.12; use PPI; use Perl::Critic::Utils; use Acme::MetaSyntactic; my $meta = "Acme::MetaSyntactic"->new("haddock"); my $input = <<'CODE'; use Foo qw(imported_func); sub announce { my $val = shift @_; print "$val\n"; } my @list = qw( foo bar baz ); for my $i (0 .. $#list) { my $value = imported_func($list[$i]); announce($value) if __PACKAGE__->can("announce"); } CODE my $doc = "PPI::Document"->new(\$input); my (%names, %localsub); for my $word (@{ $doc->find("PPI::Token::Word")||[] }) { if ($word->sprevious_sibling eq "sub") { $localsub{$word}++; } } for my $word (@{ $doc->find("PPI::Token::Word")||[] }) { my $case = ($word eq uc $word) ? sub { uc $_[0] } : ($word eq lc $word) ? sub { lc $_[0] } : sub { $_[0] }; if (Perl::Critic::Utils::is_perl_builtin($word)) { next; } elsif ($word->sprevious_sibling eq "sub" and $localsub{$word}) { $word->set_content($names{$word} ||= $case->($meta->name)); } elsif (Perl::Critic::Utils::is_function_call($word) and $localsub{ +$word}) { $word->set_content($names{$word} ||= $case->($meta->name)); } } for my $word (@{ $doc->find(sub { $_[1]->isa("PPI::Token::Symbol") or +$_[1]->isa("PPI::Token::ArrayIndex") })||[] }) { next if $word->isa("PPI::Token::Magic"); my $case = ($word eq uc $word) ? sub { uc $_[0] } : ($word eq lc $word) ? sub { lc $_[0] } : sub { $_[0] }; (my $sigil = "$word") =~ s/(\w.*)$//g; my $rest = $1; if ($word->isa("PPI::Token::Symbol")) { $names{$word->symbol} ||= $case->($meta->name); $word->set_content($sigil . $names{$word->symbol}); } else { $names{"\@$rest"} ||= $case->($meta->name); $word->set_content($sigil . $names{"\@$rest"}); } } for my $qq (@{ $doc->find(sub { $_[1]->isa("PPI::Token::Quote::Double" +) or $_[1]->isa("PPI::Token::Quote::Interpolate") })||[] }) { my $txt = "$qq"; if ($localsub{$qq->string}) { $txt =~ s/${\quotemeta($qq->string)}/$names{$qq->string}/eg; } else { $txt =~ s/([\$\@]\w+)/$names{$1}?substr($1,0,1).$names{$1}:$1/ +eg; } $qq->set_content($txt); } print $doc; __END__ use Foo qw(imported_func); sub cry_babies { my $numbskulls = shift @_; print "$numbskulls\n"; } my @two_timing_troglodytes = qw( foo bar baz ); for my $cheat (0 .. $#two_timing_troglodytes) { my $gyroscope = imported_func($two_timing_troglodytes[$cheat]); cry_babies($gyroscope) if __PACKAGE__->can("cry_babies"); }

    (Updated to add support for tracking locally defined versus imported functions; and ->can support.)

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Generic Broadcast SSH Launcher
1 direct reply — Read more / Contribute
by QM
on May 10, 2013 at 08:19
    I'm currently using the following to run commands on remote systems through ssh. I'd appreciate any comments or improvements.

    One specific question is how to capture STDERR and assign it to the remote host it came from. (I haven't spent much time investigating this issue, so there's probably some easy fix I've overlooked.)

    Here's the script:

Announcing: UAV::Pilot v0.1
1 direct reply — Read more / Contribute
by hardburn
on May 09, 2013 at 14:18

    UAV::Pilot is a Perl library for controlling UAVs. It currently works with the Parrot AR.Drone, with plans to expand to others in the future.

    Demo video

    The current library supports basic commands, such as takeoff, pitch, roll, yaw, vert speed, and land. All the preprogrammed flight animations are also in place. Navigation data and video are not yet supported–see the ROADMAP file for future plans.

    Github repository: https://github.com/frezik/UAV-Pilot

    CPAN: https://metacpan.org/module/TMURRAY/UAV-Pilot-0.1/lib/UAV/Pilot.pm


    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

Postfix: Piping an email into a PERL script
2 direct replies — Read more / Contribute
by Zzenmonk
on Apr 26, 2013 at 09:45

    I spend today reading about how to pipe a mail received by postfix into a perl script. I read a lot but could hardly find a solution for my setup. So I give one here.

    The case

    An application must be able to process email coming in from the net and it must be also able to respond to these emails.

    The setup:

    • The machine is configured to send all emails over an MTA somewhere in the network
    • The MTA hosts a virtual mail domain for which it forwards all its email to the machine
    • The machine holds an application written in PERL
    • A PERL script īs used as delivery agent to process some mails
    • The tested platform: Linux Ubuntu 12.04 LTS, postfix 2.9.6

    The postfix main.cf configuration created by dpkg-reconfigure postfix

    myhostname = [host name] alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases myorigin = /etc/mailname mydestination = [list for local delivery] relayhost = [the MTA name for sending emails] mynetworks = [see posfix documentation] mailbox_size_limit = [you would rather set it!] recipient_delimiter = + inet_interfaces = all inet_protocols = ipv4 mail_spool_directory = /var/mail

    My solution:

    As usual TIMTOWTDI but a simple alias will NOT work! My solution works without:

    • A cryptic central definition of a local delivery agent in master.cf
    • Having pcre compiled in postfix. I have no use for this.
    • Creating OS users or virtual users on the system.
    • No other ugly things I read.

    Now you have to:

    • Modify your main.cf to redirect the mail.
    • Create a redirect map for postfix
    • Create an alias which will fool postfix and deliver the mail to the script

    Modifications to the main.cf configuration

    To avoid creating whatsoever users, we will use a kind of redirect. So we add a line like the following to the main.cf file:

    virtual_alias_maps = hash:/etc/postfix/redirect

    Notice the hash: prefix to the file. This works well and avoid to re-compile postfix with pcre, in case it is not included.

    Creation of the redirect map

    Create the file defined above and enter a line with a regexp and a name in it:

    /[name]@[machine domain]/ [alias name]

    Notice you have to use a regexp as first argument on this line! The alias name does not matter. Only secure name@domain is the correct email address.

    Creation of the alias

    Now we create the alias which will pipe the email into our script. Add a line like the following to the /etc/aliases file:

    [alias name]: "|/usr/bin/perl /[path to]/thescript.pl"

    Notice you have to secure both alias name match!

    Activate the whole thing

    To activate all this you have to

    • Create your redirect map with postmap [path to ]/redirect
    • Activate your new aliases with newaliases
    • Load the new posfix configuration with posfix reload

    The result

    This is what you will get in the STDIN of your script

    From [who ever]@[whatever].com Mon Apr 22 17:48:08 2013 Return-Path: <[who ever]@[whatever].com > X-Original-To: [name]@[machine domain] Delivered-To: [name]@[machine domain] Received: by [No matter to you] To: <[name]@[machine domain]> Subject: [What so ever] X-Mailer: mail (GNU Mailutils 2.2) Message-Id: <20130422154808.4100143A9@lap01> Date: Mon, 22 Apr 2013 17:48:08 +0200 (CEST) From: [who ever]@[whatever].com lkjahsdlfkjhlahsdf lkjahdsflkjhasdlfh lkjahsdflkjhsaldfhk

    Notice: If you intent to open(OUT ">", $filename); in your PERL script it will fail with a missing privilege error. To avoid this you have to set default_privs = to an other user than nobody in the postfix main.cf. This has impact on the whole postfix setting. I did not analyse it until now. So if you do this, you do it at your own risk.

    Enjoy!

    K

    The best medicine against depression is a cold beer!
A multilingual solution for PERL CGI web applications
1 direct reply — Read more / Contribute
by Zzenmonk
on Apr 22, 2013 at 12:30

    Despite an incredible amount of literature on this topic, I could not find a proper solution for this issue. Accordingly I post my one here.

    I had to realize a relatively complex web application. This application bases on CGI.pm and mod_perl for performance reasons and supports several languages. I wanted to have one single code for the logic of the application. An additional requirement was be to be able to add languages easily. After reading a lot about solutions involving templates or dictionaries (typically gettext), I figured out using PERL language packages would fulfill most of my requirements. The problem was to load the appropriate language module at application start up time and to allow the user to change the language for example for print outs. Here is the solution I worked out.

    First make a set of simple language packages with names like EN.pm, FR.pm, DE.pm. Each of these modules holds hashes with the texts for the application's forms. For this solution to work properly, the hash names must be in lower case. Example for a log in form:

    - French in FR.pm: $login{msg1} = "Identifiant";

    - German in DE.pm: $login{msg1} = "Benutzername";

    - English in EN.pm: $login{msg1} = "User name";

    Next use the following at the beginning of each language package to export the content. Example for EN.pm:

    foreach $key (sort keys %EN::) { if ( $key !~ /[A-Z]+/ ) { push @EXPORT, "\%$key"; } }

    This will export all hashes in lower case and avoid for example the EXPORT array. Next you will have to import the correct languages package in your cgi script with a statement like use [Modulename];.

    Unfortunaltely you can hardly load modules dynamically and can hardly reference a variable in a module dynamically. Constructs like use $language; or ${language}::login{msg1}; will not work.

    Despite lot of posts on this topic, I haven't found a solution to solve this issue. This means so or so I will not be able to load the languages dynamically but will have to manage the supported languages in the code of the application's logic.

    My solution bases on a language variable I called syslang. This variable is either set by the calling cgi script or defined by the selected language of the client's browser. I begin my cgi scripts the following way and include a global language variable:

    # ---------------------------------------------------------------- +---------------- # Script header # ---------------------------------------------------------------- +---------------- # Loading perl modules my $start = time(); use FindBin qw($Bin); use File::Basename; use Cwd; use CGI qw/:standard *table tr td select/; use CGI::Carp; use CGI::Session; use Data::Dumper; use strict; # Our global language variable our $syslang = undef;

    Next I add the path to my application or packages to @INC array. My application packages are always in a lib directory. This is also the location of the language packages. For the solution to work the @INC array must be enhanced with a begin block or the script will not compile:

    # Notice: this will work with Apache, cheap web-server might be a +serious issue! # a) Detect if we are called by the web-server or not # b) Set the path accordingty BEGIN { # Adding application lib path my $libdir = undef; if ( not defined($ENV{SERVER_NAME}) ) { $libdir = getcwd; } else { $libdir = File::Basename::dirname($ENV{SCRIPT_FILENAME} +); } # I know.... but sometimes I am lazy! chdir "$libdir/../lib"; $libdir = getcwd; if ( not grep(/$libdir/, @INC) ) { push (@INC, $libdir); } undef $libdir; }

    Now we need to manage the languages. We need to load the package with the correct texts, knowing the user can change the language of the application. Because of mod_perl we need to unload the language modules first and the reload the correct module to force Apache to recompile the script. Here my solution for this:

    # Setting the language # This one is to fool the compiler! Don't ask! use EN; # Testing if the language has allready be set or using the one def +ines by the browser # frdlang is my cgi language parameter my $q = new CGI; if ( $q->param("frdlang") ) { $syslang = uc($q->param("frdlang")); + } elsif ( not $syslang ) { $syslang = uc(substr($ENV{HTTP_ACCEPT_LAN +GUAGE}, 0, 2)); } # Unloading language modules to force recompiling under mod_perl foreach my $lang ( grep(/DE.pm$|FR.pm$|EN.pm$/, keys(%INC)) ) { de +lete $INC {$lang}; } # Loading apropriate language module if ( uc($syslang) =~ /^DE/ ) { require DE; DE->import(); } elsif ( uc($syslang) =~ /^FR/ ) { require FR; FR->import(); } elsif ( uc($syslang) =~ /^EN/ ) { require EN; EN->import(); }

    Now we might have the issue that some packages return some part of the HTML form, tipically the menus. The language of these parts musst also be changed each time the user switches the language. So we need to reload all the modules impacted. Here my solution for this:

    # Unloading the application language related module to force recom +pile under mod perl foreach my $module ( grep(/utils.pm$|install.pm$|login.pm$/, keys( +%INC)) ) { delete $INC{$module}; } # setting languages for each modules to load $utils::syslang = $syslang; $install::syslang = $syslang; $login::syslang = $syslang; # Loading language dependent modules require utils; utils->import(); require install; install->import(); require login; login->import(); # ... your cgi code.

    This solution has beed tested extensively however any suggestion for something more decent is welcome.

    K.

    The best medicine against depression is a cold beer!
ppiwx / wxppi show PPI tree, and PPI::Statement::serialize / PPI::Token::HereDoc::here_line_range ## column_number / line_number
No replies — Read more | Post response
by Anonymous Monk
on Apr 22, 2013 at 09:40

    ppiwx / wxppi show PPI tree, and PPI::Statement::serialize / PPI::Token::HereDoc::here_line_range ## column_number / line_number

    wrote it a few years ago to explore PPI, now with color

    usage ppiwx utf8file.pl anotherutf8file.pl ...

    expects UTF-8 , so whateveryou need to do :) iconv -f UTF-16 -t UTF-8 < in > out or piconv -f UTF-16LE -t UTF-8 < in > out

    Code is in spoiler readmore tags :) to download just the code, click "Download Code" below

"em" - Emphasize text using regular expressions
3 direct replies — Read more / Contribute
by FloydATC
on Apr 18, 2013 at 15:16
    Not sure if this counts as "cool use" but this little thing has become one of my favorite tools over the past few years. Pass any plaintext data through it and emphasize any text you want using regular expressions. Useful for tcpdump, server logs...anything really.

    Update: After posting version 1 the problem of overlapping matches has been bugging me so much I've actually found a solution. Instead of using straight regex substitution I now do all the matching first, then apply the colors afterwards. I've tested it quite a bit but it's still experimental.

    #!/usr/bin/perl use strict; use warnings; use Term::ANSIColor; my @rules = @ARGV; while (my $line = <STDIN>) { print rewrite($line, @rules); } exit; # Process a single line sub rewrite { my $line = shift; my @rules = @_; my @marks = (); # Process each rule and find areas to mark while (@rules) { my $regex = shift @rules; my $color = shift @rules || 'bold yellow'; $color = color('reset').color($color); while ($line =~ /$regex/ig) { my $reset = undef; # Scan match area to find last color foreach my $i (reverse $-[0] .. $+[0]) { if (defined $marks[$i]) { $reset = $marks[$i] unless defined $reset; $marks[$i] = undef; # Cancel previous color } } # If necessary, keep scanning to beginning of line unless (defined $reset) { foreach my $i (reverse 0 .. $-[0]) { if (defined $marks[$i]) { $reset = $marks[$i]; last; } } } # Mark area $marks[$-[0]] = $color; $marks[$+[0]] = $reset || color('reset'); } } # Apply color codes to the string foreach my $i (reverse 0 .. $#marks) { substr($line, $i, 0, $marks[$i]) if defined $marks[$i]; } return $line; } =pod =head1 NAME em - console emphasis tool version 2 =head1 DESCRIPTION em is a command line tool for visually emphasizing text in log files e +tc. by colorizing the output matching regular expressions. =head1 SYNOPSIS em REGEX1 [COLOR1] [REGEX2 [COLOR2]] ... [REGEXn [COLORn]] =head1 USAGE REGEX is any regular expression recognized by Perl. For some shells this must be enclosed in double quotes ("") to prevent the shell from interpolating special characters like * or ?. COLOR is any ANSI color string accepted by Term::ANSIColor, such as 'green' or 'bold red'. Any number of REGEX-COLOR pairs may be specified. If the number of arg +uments is odd (i.e. no COLOR is specified for the last REGEX) em will use 'bo +ld yellow'. Overlapping rules are supported. For characters that match multiple ru +les, only the last rule will be applied. =head1 EXAMPLES In a system log, emphasize the words "error" and "ok": =over tail -f /var/log/messages | em error red ok green =back In a mail server log, show all email addresses between <> in white, su +ccesses in green: =over tail -f /var/log/maillog | em "(?<=\<)[\w\-\.]+?\@[\w\-\.]+?(?=\>)" "b +old white" "stored message|delivered ok" "bold green" =back In a web server log, show all URIs in yellow: =over tail -f /var/log/httpd/access_log | em "(?<=\"get).+?\s" =back =head1 BUGS AND LIMITATIONS Multi-line matching is not implemented. All regular expressions are matched without case sensitivity. =head1 AUTHOR Andreas Lund <floyd@atc.no> =head1 COPYRIGHT AND LICENSE Copyright 2009-2013 Andreas Lund <floyd@atc.no>. This program is free +software; you may redistribute it and/or modify it under the same terms as Perl +itself. =cut
    1. I would love for someone to adopt this and put it on CPAN so myself and others can get easy access to it
    2. There's one annoying limitation; overlapping matches don't behave the way they should, and I can't find a way to fix it.

    Update: There is one other cool way to use this tool, and that's regex testing. Simply type "em" and the regex you want to test. Example:
    em "0x[0-9a-f]+"
    Now input your test strings one by one, and "em" will show you exactly what matches and what doesn't. Hit Ctrl+D (EOF) to exit.

    -- Time flies when you don't know what you're doing
Cool way to parse Space Separated Value and CSV files
2 direct replies — Read more / Contribute
by greengaroo
on Apr 09, 2013 at 14:24

    As a programmer and teacher of the Perl programming language, I often get destabilizing questions. In one of the last class I gave, while I was talking about hashes, someone asked me "What is it used for? When would I ever need that?" Of course, for me (and you too, probably) hashes are quite practical, but being told that, on the spot, I didn't know what to say, so I talked about the %ENV hash and made an example with it.

    Today I found an interesting use for hashes. I wish I would have thought of it during my class but I didn't, so I would like to share it with you for the benefit of newer Perl programmers.

    Imagine you have to read a Space Separated Value file or Comma Separated Value (CSV) file. It's easy because the fields are always in the same order. For example:

    # firstname lastname age joe builder 9 bob plumber 66 dora squarepants 10 diego simpson 11

    You can do this:

    open( $l, "<file" ) || die "Error : $!"; my @lines = <$l>; close( $l ); foreach my $line ( @lines ) { # Skipping if the line is empty or a comment next if ( $line =~ /^\s*$/ ); next if ( $line =~ /^\s*#/ ); my ($firstname, $lastname, $age) = split( /\s+/, $line ); # then do whatever you have to }

    But then someday someone give you a new file with the fields in a different order plus new extra fields you don't need. Here is the new file:

    # lastname firstname age gender phone mcgee bobby 27 M 555-555-5555 kincaid marl 67 M 555-666-6666 hofhazards duke 22 M 555-696-6969

    What do you do? Do you change your code with a if statement? Do you alter the file to change the order of the fields and remove the extra fields? No! You use hashes!

    Here is the solution:

    open( $l, "<file" ) || die "Error : $!"; my @lines = <$l>; close( $l ); my @keys = split( /\s+/, $lines[0] ); shift( @keys ); # to remove the # as the first field foreach my $line ( @lines ) { # Skipping if the line is empty or a comment next if ( $line =~ /^\s*$/ ); next if ( $line =~ /^\s*#/ ); my %hash; @hash{ @keys } = split( /\s+/, $line ); # then do whatever you have to }

    Note that the first line in the file is important, it gives you the order of the fields. Even if it's not there when you receive the file, you can easily add it. Note the @hash{ } syntax. This is called a slice. You are slicing the hash using the array form, basically to access a list of element from the hash. The @keys array contains a list of keys in the same order written at the top of the file therefore, doing @hash{ @keys } is like doing @hash{ qw(lastname firstname age gender phone) } or @hash{ 'lastname', 'firstname', 'age', 'gender', 'phone' } except it doesn't matter if the fields in the file are not always in the same order as in the previous file.

    The split of the line returns a list so doing this:

    @hash{ @keys } = split( /\s+/, $line );

    is the same as this:

    @hash{'lastname', 'firstname', 'age', 'gender', 'phone' } = split( /\s+/, $line );

    or this:

    ($hash{'lastname'}, $hash{'firstname'}, $hash{'age'}, $hash{'gender'}, $hash{'phone'}) = split( /\s+/, $line );

    Also if some fields are not needed, you don't care. As long as all the required fields are there, your code will always work.

    I hope this will be useful for you someday! Good luck!

    A for will get you from A to Z; a while will get you everywhere.
wxperl_usage / wxperl-usage / wxPerl::Usage / Class Method Browser , available methods, method invocation syntax, link to docs
4 direct replies — Read more / Contribute
by Anonymous Monk
on Apr 07, 2013 at 12:58

    wxperl_usage / wxperl-usage / wxPerl::Usage / Class Method Browser , available methods, method invocation syntax, link to docs

    resizable layout, but mostly complete, wonky in places, mostly not oop, code in spoiler readmore tags

wxSplashScreenFakeText.pl - diy loading message
No replies — Read more | Post response
by Anonymous Monk
on Apr 05, 2013 at 05:51

    One way to splash some text on screen , shows reusing a frame, resizing an image

    #!/usr/bin/perl -- ## perltidy -olq -csc -csci=10 -cscl="sub : BEGIN END if " -otr -opr +-ce -nibc -i=4 -pt=0 "-nsak=*" use strict; use warnings; use Wx (); Main( @ARGV ); exit( 0 ); sub Main { my $app = Wx::SimpleApp->new; LogoSplasher( 2 ); my $frame = Wx::Frame->new( undef, -1, "wxSplashScreenFakeText.pl", [ -1, -1 ], [ -1, -1 ], Wx::wxDEFAULT_FRAME_STYLE() | Wx::wxTAB_TRAVERSAL() ); Initialize( $frame ); MainGuiProgram( $frame ); $frame->Raise; $frame->Maximize( 1 ); return $app->MainLoop; } ## end sub Main sub LogoSplasher { my( $seconds ) = @_; my $wxperl_icon = Wx::Bitmap->new( Wx::Image->new( Wx::GetWxPerlIcon() )->Scale( 320, 320 ) ); my $splasher = Wx::SplashScreen->new( $wxperl_icon, Wx::wxSPLASH_CENTRE_ON_SCREEN() | Wx::wxSPLASH_NO_TIMEOUT(), 6000, undef, -1 ); sleep $seconds; $splasher->Hide; $splasher->Update; $splasher->Destroy; } ## end sub Splasher sub Initialize { my( $frame ) = @_; my $text = Wx::TextCtrl->new( $frame, -1, "wxSplashScreenFakeText.pl Initializing...\n", [ -1, -1 ], [ -1, -1 ], Wx::wxTE_MULTILINE() ); $frame->Show( 1 ); for( 1 .. 10 ) { select undef, undef, undef, 0.25; $text->AppendText( "wxSplashScreenFakeText.pl $_\n" ); $frame->Update; } $text->Destroy; undef $text; } ## end sub Initialize sub MainGuiProgram { my( $frame ) = @_; my @text = map { Wx::TextCtrl->new( $frame, -1, "Yo $_" ) } 1 .. 3 +; my $frame_sizer = Wx::BoxSizer->new( Wx::wxVERTICAL() ); $frame_sizer->Add( $_, 1, Wx::wxEXPAND() ) for @text; $frame->SetSizer( $frame_sizer ); $frame_sizer->SetSizeHints( $frame ); $frame->Layout; $frame->Update; } ## end sub MainGuiProgram

    Interactive alternatives might be
    wxperl_demo --show wxProgressDialog
    wxperl_demo --show wxWizard

Parallel Unique Firefox Sessions
No replies — Read more | Post response
by ground0
on Apr 04, 2013 at 12:07

    My first CUFP, hope you like it!

    The following is an example of nested forks with Parallel::ForkManager, forked DBI calls with DBIx::Connector, and forked WWW::Mechanize::Firefox. This combination allows for easy concurrent unique HTTP sessions with WWW::Mechanize::Firefox on one URL.

    MySQL is used here for housing subscription/login data, and a table to store Firefox profile names. The latter is used to avoid a race condition on selecting the Firefox profile to use when constructing $mech objects. Each Firefox profile has been pre-created, and configured with the Mozrepl plugin on a unique TCP/IP port.

    The subsequent Perl module contains an example country subroutine which eludes to not-shown encapsulation of the WWW::Mechanize::Firefox and PDF::API2 calls.

    Special thanks to Corion, and perlmonks.org chat boxers :)

    fork_dbi_mech.pl
    #!/usr/bin/perl use DBIx::Connector; use Parallel::ForkManager; use lib './'; use fork_dbi_mech; use strict; # I use constant here for limiting nested forks (4*4) use constant MAXPROCS => 4; # DBI object constructor with dsn my $conn = DBIx::Connector->new( 'DBI:mysql:MyDatabase;host=localhost', 'login', 'password') or die $DBI::errstr; # fork object constructors my $fork_cases = new Parallel::ForkManager(MAXPROCS); my $fork_countries = new Parallel::ForkManager(MAXPROCS); # example SQL query to suss subs to process my $subscription = $conn->dbh->selectall_hashref('SELECT customer_id FROM subscriptions WHERE active = 1 GROUP BY customer_id', 'customer_id' ); # Now get each customer login/id, and suss # their active country subs foreach $subscription_key (keys %$subscription) { $sth = $conn->dbh->prepare('SELECT login FROM customer_info WHERE id = ?' ); $sth->execute($subscription_key); $login = $sth->fetchrow_hashref; $counties = $conn->dbh->selectall_hashref("SELECT country_id FROM subscription_info WHERE customer_id = $subscription_key AND active = 1", 'country_id' ); # First fork by customer's country subs # Then suss each country's cases foreach $country_key (keys %$countries) { $fork_countries->start and next; $sth = $conn->dbh->prepare('SELECT country FROM country_info WHERE id = ? AND active = 1' ); $sth->execute($country_key); $results = $sth->fetchrow_hashref; if ($results->{'country'}) { $country_name = $results->{'country'}; $sth = $conn->dbh->prepare('SELECT filename, case_no FROM batch_info WHERE country LIKE ? AND customer_id = ?' ); $sth->execute('%' . $country_name . '%', $subscription_key); $case = $sth->fetchall_hashref('filename'); # Second fork by customer's cases # Then call subroutine named after country foreach $case_no (keys %$case) { $fork_cases->start and next; $country_name =~ s/[-|\s]//g; # Create fork's own DBI object $conn = DBIx::Connector->new('DBI:mysql:MyDatabase;host=localhost' +, 'login', 'password') or die $DBI::errstr; # Lock the table to avoid race condition $sth = $conn->dbh->prepare('LOCK TABLE profile_info WRITE'); $sth->execute(); # Suss list of available Firefox profiles $sth = $conn->dbh->prepare('SELECT * FROM profile_info'); $sth->execute(); # Pick a random hash value # Delete that value from db $ff_profile_hash = $sth->fetchall_hashref('id'); delete $_->{id} for values %$ff_profile_hash; foreach $ff_profile_temp (keys %$ff_profile_hash) { $ff_profile_hash->{$ff_profile_temp} = $ff_profile_temp; } $ff_profile = $ff_profile_hash->{(keys %$ff_profile_hash)[rand key +s %$ff_profile_hash]}; $sth = $conn->dbh->prepare('DELETE FROM profile_info WHERE id = ?' ); $sth->execute($ff_profile); # Unlock table for next fork $sth = $conn->dbh->prepare('UNLOCK TABLES'); $sth->execute(); $sth->finish(); # Call country subroutine { no strict 'refs'; &$country_name($case->{$case_no}->{'case_no'}, $case_no, $login->{'login'}, $ff_profile ); } # Lock table again and replace Firefox profile $sth = $conn->dbh->prepare('LOCK TABLE profile_info WRITE'); $sth->execute(); $sth = $conn->dbh->prepare('INSERT INTO profile_info (id) VALUES (?)' ); $sth->execute($ff_profile); $sth = $conn->dbh->prepare('UNLOCK TABLES'); $sth->execute(); $sth->finish(); $fork_cases->finish; } $fork_cases->wait_all_children; } $fork_countries->finish; } $fork_countries->wait_all_children; } 1;
    fork_dbi_mech.pm
    #!/usr/bin/perl package fork_dbi_mech; require Exporter; use DBIx::Connector; use Error qw(:try); use PDF::API2; use String::Random; use Switch; use WWW::Mechanize::Firefox; use strict; our @ISA = qw(Exporter); our @EXPORT = qw( USA UK JAPAN ); # I use $rand to pad cache files for $mech->content, etc. my $rand = new String::Random; sub USA { $args_case = $_[0]; $args_filename = $_[1]; $args_login = $_[2]; $ff_profile = $_[3]; # I based my Mozrepl ports off the default 4242 * 10 # Ports are the sum of of this and the Firefox profile $ff_port = 42420 + $ff_profile; # Now construct the unique $mech object $m = WWW::Mechanize::Firefox->new( launch => ['firefox', '-P', $ff_profile, '-no-remote', '-width', '1024', '-height', '768'], repl => "localhost:$ff_port", bufsize => 10_000_000, tab => 'current', autoclose => 1 ); $url = 'http://usa.example.com'; # Try a $mech->get($url); &tryMech($args_filename, $args_login, $args_case, 'URL', undef, $url ); if ($mech_status == 1) { &tryMech($args_filename, $args_login, $args_case, 'field', 'CaseField', $args_case ); if ($mech_status == 1) { &tryMech($args_filename, $args_login, $args_case, 'click', 'Search' ); if ($mech_status == 1) { &makePDF($args_filename, $args_login, $args_case ); } } } undef $m; sleep(1); } 1;
Tartaglia's triangle
3 direct replies — Read more / Contribute
by Discipulus
on Apr 02, 2013 at 08:02
    ok hdb have burned me on time..

    This is my first math script. Any math or Perl suggestion welcome!
    #!/usr/bin/perl use strict; use warnings; { my @tartaglia ; sub tartaglia { my ($x,$y) = @_; if ($x == 0 or $y == 0) { $tartaglia[$x][$y]=1 ; return 1}; my $ret ; foreach my $yps (0..$y){ $ret += ( $tartaglia[$x-1][$yps] || &tartaglia($x-1,$yps) ); } $tartaglia[$x][$y] = $ret; return $ret; } } sub tartaglia_row { my $y = shift; my $x = 0; my @row; $row[0] = &tartaglia($x,$y+1); foreach my $pos (0..$y-1) {push @row, &tartaglia(++$x,--$y)} return @row; } for (0..5) {print join ' ', &tartaglia_row($_),"\n"} print "\n\n"; print &tartaglia(3,3),"\n"; my @third = &tartaglia_row(5); print "@third\n";
    there are no rules, there are no thumbs..

Add your CUFP
Title:
CUFP:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":


  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (7)
    As of 2013-05-25 14:24 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The best material for plates (tableware) is:









      Results (520 votes), past polls